r300g: optimize the fallback for misaligned ushort indices
authorMarek Olšák <maraeo@gmail.com>
Sun, 19 Dec 2010 01:54:43 +0000 (02:54 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sun, 19 Dec 2010 03:05:34 +0000 (04:05 +0100)
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_translate.c

index b4197e03520f30b5146f6321b94602e672555e12..1d26eb9f9189ffe1e246ebb7ec26fc885c246ef8 100644 (file)
@@ -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;
 
index 41a43b04de77a3ecf4ba256744f039a8b10d98f8..90b2f40be5f705106498870b583c26340b18cb03 100644 (file)
@@ -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;