r300g: align misaligned ushort vertex indices
authorMarek Olšák <maraeo@gmail.com>
Sun, 21 Mar 2010 03:49:35 +0000 (04:49 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sun, 21 Mar 2010 04:42:50 +0000 (05:42 +0100)
src/gallium/drivers/r300/r300_render.c

index afd871ae302ef17e45287385799cc0418c141d59..2fed263a7a90508d542f688f839cf0390b9e4c3d 100644 (file)
@@ -303,7 +303,6 @@ static void r300_emit_draw_elements(struct r300_context *r300,
 #endif
     CS_LOCALS(r300);
 
-    assert((start * indexSize) % 4 == 0);
     assert(count < (1 << 24));
 
     maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
@@ -385,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,
@@ -413,6 +438,9 @@ void r300_draw_range_elements(struct pipe_context* pipe,
         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);