예제 #1
0
/* This is the fast-path drawing & emission for HW TCL. */
boolean r300_draw_range_elements(struct pipe_context* pipe,
                                 struct pipe_buffer* indexBuffer,
                                 unsigned indexSize,
                                 unsigned minIndex,
                                 unsigned maxIndex,
                                 unsigned mode,
                                 unsigned start,
                                 unsigned count)
{
    struct r300_context* r300 = r300_context(pipe);

    if (!u_trim_pipe_prim(mode, &count)) {
        return FALSE;
    }

    if (count > 65535) {
        return FALSE;
    }

    r300_update_derived_state(r300);

    if (!r300_setup_vertex_buffers(r300)) {
        return FALSE;
    }

    setup_vertex_attributes(r300);

    setup_index_buffer(r300, indexBuffer, indexSize);

    r300_emit_dirty_state(r300);

    r300_emit_aos(r300, 0);

    r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
                            mode, start, count);

    return TRUE;
}
예제 #2
0
static void r300_draw_elements(struct r300_context *r300,
                               const struct pipe_draw_info *info,
                               int instance_id)
{
    struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
    unsigned indexSize = r300->index_buffer.index_size;
    struct pipe_resource* orgIndexBuffer = indexBuffer;
    unsigned start = info->start;
    unsigned count = info->count;
    boolean alt_num_verts = r300->screen->caps.is_r500 &&
                            count > 65536;
    unsigned short_count;
    int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
    uint16_t indices3[3];

    if (info->index_bias && !r300->screen->caps.is_r500) {
        r300_split_index_bias(r300, info->index_bias, &buffer_offset,
                              &index_offset);
    }

    r300_translate_index_buffer(r300, &r300->index_buffer, &indexBuffer,
                                &indexSize, index_offset, &start, count);

    /* Fallback for misaligned ushort indices. */
    if (indexSize == 2 && (start & 1) && indexBuffer) {
        /* If we got here, then orgIndexBuffer == indexBuffer. */
        uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->cs_buf,
                                              r300->cs,
                                              PIPE_TRANSFER_READ |
                                              PIPE_TRANSFER_UNSYNCHRONIZED);

        if (info->mode == PIPE_PRIM_TRIANGLES) {
           memcpy(indices3, ptr + start, 6);
        } else {
            /* Copy the mapped index buffer directly to the upload buffer.
             * The start index will be aligned simply from the fact that
             * every sub-buffer in the upload buffer is aligned. */
            r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start,
                                     count, (uint8_t*)ptr);
        }
    } else {
        if (r300->index_buffer.user_buffer)
            r300_upload_index_buffer(r300, &indexBuffer, indexSize,
                                     &start, count,
                                     r300->index_buffer.user_buffer);
    }

    /* 19 dwords for emit_draw_elements. Give up if the function fails. */
    if (!r300_prepare_for_rendering(r300,
            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
            PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
            instance_id))
        goto done;

    if (alt_num_verts || count <= 65535) {
        r300_emit_draw_elements(r300, indexBuffer, indexSize,
                                info->max_index, info->mode, start, count,
                                indices3);
    } else {
        do {
            /* The maximum must be divisible by 4 and 3,
             * so that quad and triangle lists are split correctly.
             *
             * Strips, loops, and fans won't work. */
            short_count = MIN2(count, 65532);

            r300_emit_draw_elements(r300, indexBuffer, indexSize,
                                     info->max_index,
                                     info->mode, start, short_count, indices3);

            start += short_count;
            count -= short_count;

            /* 15 dwords for emit_draw_elements */
            if (count) {
                if (!r300_prepare_for_rendering(r300,
                        PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
                        indexBuffer, 19, buffer_offset, info->index_bias,
                        instance_id))
                    goto done;
            }
        } while (count);
    }

done:
    if (indexBuffer != orgIndexBuffer) {
        pipe_resource_reference( &indexBuffer, NULL );
    }
}
예제 #3
0
/* This is the fast-path drawing & emission for HW TCL. */
static void r300_draw_range_elements(struct pipe_context* pipe,
                                     struct pipe_resource* indexBuffer,
                                     unsigned indexSize,
                                     int indexBias,
                                     unsigned minIndex,
                                     unsigned maxIndex,
                                     unsigned mode,
                                     unsigned start,
                                     unsigned count)
{
    struct r300_context* r300 = r300_context(pipe);
    struct pipe_resource* orgIndexBuffer = indexBuffer;
    boolean alt_num_verts = r300->screen->caps.is_r500 &&
                            count > 65536 &&
                            r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
    unsigned short_count;
    int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
    boolean translate = FALSE;
    unsigned new_offset;

    if (r300->skip_rendering) {
        return;
    }

    if (!u_trim_pipe_prim(mode, &count)) {
        return;
    }

    /* Index buffer range checking. */
    if ((start + count) * indexSize > indexBuffer->width0) {
        fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n");
        return;
    }

    /* Set up fallback for incompatible vertex layout if needed. */
    if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
        r300_begin_vertex_translate(r300);
        translate = TRUE;
    }

    if (indexBias && !r500_index_bias_supported(r300)) {
        r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
    }

    r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
                                &start, count);

    r300_update_derived_state(r300);
    r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset);

    start = new_offset;

    /* 15 dwords for emit_draw_elements. Give up if the function fails. */
    if (!r300_prepare_for_rendering(r300,
            PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
            PREP_INDEXED, indexBuffer, 15, buffer_offset, indexBias))
        goto done;

    if (alt_num_verts || count <= 65535) {
        r300_emit_draw_elements(r300, indexBuffer, indexSize,
				minIndex, maxIndex, mode, start, count);
    } else {
        do {
            short_count = MIN2(count, 65534);
            r300_emit_draw_elements(r300, indexBuffer, indexSize,
                                     minIndex, maxIndex,
                                     mode, start, short_count);

            start += short_count;
            count -= short_count;

            /* 15 dwords for emit_draw_elements */
            if (count) {
                if (!r300_prepare_for_rendering(r300,
                        PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
                        indexBuffer, 15, buffer_offset, indexBias))
                    goto done;
            }
        } while (count);
    }

done:
    if (indexBuffer != orgIndexBuffer) {
        pipe_resource_reference( &indexBuffer, NULL );
    }

    if (translate) {
        r300_end_vertex_translate(r300);
    }
}