summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_render.c')
-rw-r--r--src/gallium/drivers/r300/r300_render.c31
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;
}