diff options
-rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_render_translate.c | 2 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index b4197e03520..1d26eb9f918 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -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, indexBuffer, transfer); + } else { + r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset); + } start = new_offset; diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c index 41a43b04de7..90b2f40be5f 100644 --- a/src/gallium/drivers/r300/r300_render_translate.c +++ b/src/gallium/drivers/r300/r300_render_translate.c @@ -204,7 +204,7 @@ void r300_translate_index_buffer(struct r300_context *r300, break; case 2: - if (*start % 2 != 0 || index_offset) { + if (index_offset) { util_rebuild_ushort_elts(&r300->context, index_buffer, index_offset, *start, count); *start = 0; r300->validate_buffers = TRUE; |