diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 129 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_render_translate.c | 140 |
3 files changed, 144 insertions, 130 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index c99c2af55e9..0c5256184a5 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -504,8 +504,13 @@ void r300_init_render_functions(struct r300_context *r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_resource_functions(struct r300_context* r300); +/* r300_render_translate.c */ void r300_begin_vertex_translate(struct r300_context *r300); void r300_end_vertex_translate(struct r300_context *r300); +void r300_translate_index_buffer(struct r300_context *r300, + struct pipe_resource **index_buffer, + unsigned *index_size, unsigned index_offset, + unsigned *start, unsigned count); boolean r300_check_cs(struct r300_context *r300, unsigned size); void r300_finish(struct r300_context *r300); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index e2617b84090..e83dbab092e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -482,111 +482,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } -static void r300_shorten_ubyte_elts(struct r300_context* r300, - struct pipe_resource** elts, - int index_bias, - unsigned start, - unsigned count) -{ - struct pipe_context* context = &r300->context; - struct pipe_screen* screen = r300->context.screen; - struct pipe_resource* new_elts; - unsigned char *in_map; - unsigned short *out_map; - struct pipe_transfer *src_transfer, *dst_transfer; - unsigned i; - - new_elts = pipe_buffer_create(screen, - PIPE_BIND_INDEX_BUFFER, - 2 * count); - - in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer); - out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); - - in_map += start; - - for (i = 0; i < count; i++) { - *out_map = (unsigned short)(*in_map + index_bias); - in_map++; - out_map++; - } - - pipe_buffer_unmap(context, *elts, src_transfer); - pipe_buffer_unmap(context, new_elts, dst_transfer); - - *elts = new_elts; -} - -static void r300_rebuild_ushort_elts(struct r300_context *r300, - struct pipe_resource **elts, - int index_bias, - unsigned start, unsigned count) -{ - struct pipe_context *context = &r300->context; - struct pipe_transfer *in_transfer = NULL; - struct pipe_transfer *out_transfer = NULL; - struct pipe_resource *new_elts; - unsigned short *in_map; - unsigned short *out_map; - unsigned i; - - new_elts = pipe_buffer_create(context->screen, - PIPE_BIND_INDEX_BUFFER, - 2 * count); - - in_map = pipe_buffer_map(context, *elts, - PIPE_TRANSFER_READ, &in_transfer); - out_map = pipe_buffer_map(context, new_elts, - PIPE_TRANSFER_WRITE, &out_transfer); - - in_map += start; - for (i = 0; i < count; i++) { - *out_map = (unsigned short)(*in_map + index_bias); - in_map++; - out_map++; - } - - pipe_buffer_unmap(context, *elts, in_transfer); - pipe_buffer_unmap(context, new_elts, out_transfer); - - *elts = new_elts; -} - -static void r300_rebuild_uint_elts(struct r300_context *r300, - struct pipe_resource **elts, - int index_bias, - unsigned start, unsigned count) -{ - struct pipe_context *context = &r300->context; - struct pipe_transfer *in_transfer = NULL; - struct pipe_transfer *out_transfer = NULL; - struct pipe_resource *new_elts; - unsigned int *in_map; - unsigned int *out_map; - unsigned i; - - new_elts = pipe_buffer_create(context->screen, - PIPE_BIND_INDEX_BUFFER, - 2 * count); - - in_map = pipe_buffer_map(context, *elts, - PIPE_TRANSFER_READ, &in_transfer); - out_map = pipe_buffer_map(context, new_elts, - PIPE_TRANSFER_WRITE, &out_transfer); - - in_map += start; - for (i = 0; i < count; i++) { - *out_map = (unsigned int)(*in_map + index_bias); - in_map++; - out_map++; - } - - pipe_buffer_unmap(context, *elts, in_transfer); - pipe_buffer_unmap(context, new_elts, out_transfer); - - *elts = new_elts; -} - /* This is the fast-path drawing & emission for HW TCL. */ static void r300_draw_range_elements(struct pipe_context* pipe, struct pipe_resource* indexBuffer, @@ -625,28 +520,8 @@ static void r300_draw_range_elements(struct pipe_context* pipe, r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset); } - /* Rebuild the index buffer if needed. */ - switch (indexSize) { - case 1: - r300_shorten_ubyte_elts(r300, &indexBuffer, index_offset, start, count); - indexSize = 2; - start = 0; - break; - - case 2: - if (start % 2 != 0 || index_offset) { - r300_rebuild_ushort_elts(r300, &indexBuffer, index_offset, start, count); - start = 0; - } - break; - - case 4: - if (index_offset) { - r300_rebuild_uint_elts(r300, &indexBuffer, index_offset, start, count); - start = 0; - } - break; - } + 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); diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c index b03582aac32..ea3c9668f7e 100644 --- a/src/gallium/drivers/r300/r300_render_translate.c +++ b/src/gallium/drivers/r300/r300_render_translate.c @@ -21,9 +21,10 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** - * The functions below translate vertex buffers to the layout compatible - * with the hardware, so that all vertex fetches are be DWORD-aligned and all - * used vertex formats are supported. + * The functions below translate vertex and index buffers to the layout + * compatible with the hardware, so that all vertex and index fetches are + * DWORD-aligned and all used vertex and index formats are supported. + * For indices, an optional index offset is added to each index. */ #include "r300_context.h" @@ -163,3 +164,136 @@ void r300_end_vertex_translate(struct r300_context *r300) pipe_resource_reference(&r300->vertex_buffer[r300->tran.vb_slot].buffer, NULL); } + +static void r300_shorten_ubyte_elts(struct r300_context* r300, + struct pipe_resource** elts, + int index_bias, + unsigned start, + unsigned count) +{ + struct pipe_context* context = &r300->context; + struct pipe_screen* screen = r300->context.screen; + struct pipe_resource* new_elts; + unsigned char *in_map; + unsigned short *out_map; + struct pipe_transfer *src_transfer, *dst_transfer; + unsigned i; + + new_elts = pipe_buffer_create(screen, + PIPE_BIND_INDEX_BUFFER, + 2 * count); + + in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer); + out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); + + in_map += start; + + for (i = 0; i < count; i++) { + *out_map = (unsigned short)(*in_map + index_bias); + in_map++; + out_map++; + } + + pipe_buffer_unmap(context, *elts, src_transfer); + pipe_buffer_unmap(context, new_elts, dst_transfer); + + *elts = new_elts; +} + +static void r300_rebuild_ushort_elts(struct r300_context *r300, + struct pipe_resource **elts, + int index_bias, + unsigned start, unsigned count) +{ + struct pipe_context *context = &r300->context; + struct pipe_transfer *in_transfer = NULL; + struct pipe_transfer *out_transfer = NULL; + struct pipe_resource *new_elts; + unsigned short *in_map; + unsigned short *out_map; + unsigned i; + + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + 2 * count); + + in_map = pipe_buffer_map(context, *elts, + PIPE_TRANSFER_READ, &in_transfer); + out_map = pipe_buffer_map(context, new_elts, + PIPE_TRANSFER_WRITE, &out_transfer); + + in_map += start; + for (i = 0; i < count; i++) { + *out_map = (unsigned short)(*in_map + index_bias); + in_map++; + out_map++; + } + + pipe_buffer_unmap(context, *elts, in_transfer); + pipe_buffer_unmap(context, new_elts, out_transfer); + + *elts = new_elts; +} + +static void r300_rebuild_uint_elts(struct r300_context *r300, + struct pipe_resource **elts, + int index_bias, + unsigned start, unsigned count) +{ + struct pipe_context *context = &r300->context; + struct pipe_transfer *in_transfer = NULL; + struct pipe_transfer *out_transfer = NULL; + struct pipe_resource *new_elts; + unsigned int *in_map; + unsigned int *out_map; + unsigned i; + + new_elts = pipe_buffer_create(context->screen, + PIPE_BIND_INDEX_BUFFER, + 2 * count); + + in_map = pipe_buffer_map(context, *elts, + PIPE_TRANSFER_READ, &in_transfer); + out_map = pipe_buffer_map(context, new_elts, + PIPE_TRANSFER_WRITE, &out_transfer); + + in_map += start; + for (i = 0; i < count; i++) { + *out_map = (unsigned int)(*in_map + index_bias); + in_map++; + out_map++; + } + + pipe_buffer_unmap(context, *elts, in_transfer); + pipe_buffer_unmap(context, new_elts, out_transfer); + + *elts = new_elts; +} + +void r300_translate_index_buffer(struct r300_context *r300, + struct pipe_resource **index_buffer, + unsigned *index_size, unsigned index_offset, + unsigned *start, unsigned count) +{ + switch (*index_size) { + case 1: + r300_shorten_ubyte_elts(r300, index_buffer, index_offset, *start, count); + *index_size = 2; + *start = 0; + break; + + case 2: + if (*start % 2 != 0 || index_offset) { + r300_rebuild_ushort_elts(r300, index_buffer, index_offset, *start, count); + *start = 0; + } + break; + + case 4: + if (index_offset) { + r300_rebuild_uint_elts(r300, index_buffer, index_offset, *start, count); + *start = 0; + } + break; + } +} |