diff options
author | Marek Olšák <maraeo@gmail.com> | 2010-06-12 21:16:41 +0200 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2010-06-13 17:43:37 +0200 |
commit | aa5422327d6f49d8940c2b933c2342ad8968032c (patch) | |
tree | 7a7f6b13f9364deafe5355cce00567113c622dc4 /src/gallium/drivers/r300/r300_render_translate.c | |
parent | 028459b0bf2bb778b55493f9b23ab7f2c9b355a0 (diff) | |
download | external_mesa3d-aa5422327d6f49d8940c2b933c2342ad8968032c.zip external_mesa3d-aa5422327d6f49d8940c2b933c2342ad8968032c.tar.gz external_mesa3d-aa5422327d6f49d8940c2b933c2342ad8968032c.tar.bz2 |
r300g: move index buffer translate functions to their new home
Diffstat (limited to 'src/gallium/drivers/r300/r300_render_translate.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_render_translate.c | 140 |
1 files changed, 137 insertions, 3 deletions
diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c index b03582a..ea3c966 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; + } +} |