diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_render.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index b4197e03520..f58d511e11b 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -425,7 +425,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, if (transfer[vbi]) { vbuf = &r300->vertex_buffer[vbi]; - pipe_buffer_unmap(&r300->context, vbuf->buffer, transfer[vbi]); + pipe_buffer_unmap(&r300->context, transfer[vbi]); transfer[vbi] = NULL; } } @@ -551,7 +551,27 @@ static void r300_draw_range_elements(struct pipe_context* pipe, &start, count); r300_update_derived_state(r300); - r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset); + + /* Fallback for misaligned ushort indices. */ + if (indexSize == 2 && start % 2 == 1) { + struct pipe_transfer *transfer; + struct pipe_resource *userbuf; + uint16_t *ptr = pipe_buffer_map(pipe, indexBuffer, + PIPE_TRANSFER_READ, &transfer); + + /* 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 u_upload_mgr is aligned. */ + userbuf = pipe->screen->user_buffer_create(pipe->screen, + ptr + start, count * 2, + PIPE_BIND_INDEX_BUFFER); + indexBuffer = userbuf; + r300_upload_index_buffer(r300, &indexBuffer, indexSize, 0, count, &new_offset); + pipe_resource_reference(&userbuf, NULL); + pipe_buffer_unmap(pipe, transfer); + } else { + r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset); + } start = new_offset; @@ -750,14 +770,13 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, for (i = 0; i < r300->vertex_buffer_count; i++) { if (r300->vertex_buffer[i].buffer) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); + pipe_buffer_unmap(pipe, vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, NULL); } } if (indexed) { - pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer); + pipe_buffer_unmap(pipe, ib_transfer); draw_set_mapped_index_buffer(r300->draw, NULL); } } @@ -857,7 +876,7 @@ static void r300_render_unmap_vertices(struct vbuf_render* render, r300render->vbo_max_used = MAX2(r300render->vbo_max_used, r300render->vertex_size * (max + 1)); - pipe_buffer_unmap(context, r300->vbo, r300render->vbo_transfer); + pipe_buffer_unmap(context, r300render->vbo_transfer); r300render->vbo_transfer = NULL; } |