diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_render.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 47100c83b0..2fed263a7a 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -141,7 +141,7 @@ static boolean immd_is_good_idea(struct r300_context *r300, unsigned vertex_element_count = r300->velems->count; unsigned i, vbi; - if (count > 4) { + if (count > 10) { return FALSE; } @@ -155,8 +155,7 @@ static boolean immd_is_good_idea(struct r300_context *r300, if (!checked[vbi]) { vbuf = &r300->vertex_buffer[vbi]; - if (r300_buffer_is_referenced(r300, - vbuf->buffer)) { + if (r300_buffer_is_referenced(r300, vbuf->buffer)) { /* It's a very bad idea to map it... */ return FALSE; } @@ -304,10 +303,9 @@ static void r300_emit_draw_elements(struct r300_context *r300, #endif CS_LOCALS(r300); - assert((start * indexSize) % 4 == 0); assert(count < (1 << 24)); - maxIndex = MIN3(maxIndex, r300->vertex_buffer_max_index, count - minIndex); + maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", count, minIndex, maxIndex); @@ -354,6 +352,7 @@ static void r300_emit_draw_elements(struct r300_context *r300, static void r300_shorten_ubyte_elts(struct r300_context* r300, struct pipe_buffer** elts, + unsigned start, unsigned count) { struct pipe_screen* screen = r300->context.screen; @@ -371,6 +370,8 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300, in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); + in_map += start; + for (i = 0; i < count; i++) { *out_map = (unsigned short)*in_map; in_map++; @@ -383,6 +384,32 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300, *elts = new_elts; } +static void r300_align_ushort_elts(struct r300_context *r300, + struct pipe_buffer **elts, + unsigned start, unsigned count) +{ + struct pipe_screen* screen = r300->context.screen; + struct pipe_buffer* new_elts; + unsigned short *in_map; + unsigned short *out_map; + + new_elts = screen->buffer_create(screen, 32, + PIPE_BUFFER_USAGE_INDEX | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ, + 2 * count); + + in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); + out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); + + memcpy(out_map, in_map+start, 2 * count); + + pipe_buffer_unmap(screen, *elts); + pipe_buffer_unmap(screen, new_elts); + + *elts = new_elts; +} + /* This is the fast-path drawing & emission for HW TCL. */ void r300_draw_range_elements(struct pipe_context* pipe, struct pipe_buffer* indexBuffer, @@ -408,8 +435,12 @@ void r300_draw_range_elements(struct pipe_context* pipe, } if (indexSize == 1) { - r300_shorten_ubyte_elts(r300, &indexBuffer, count); + r300_shorten_ubyte_elts(r300, &indexBuffer, start, count); indexSize = 2; + start = 0; + } else if (indexSize == 2 && start % 2 != 0) { + r300_align_ushort_elts(r300, &indexBuffer, start, count); + start = 0; } r300_update_derived_state(r300); |