r300g: Use indices to translate index buffers of ubytes.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Thu, 14 Jan 2010 04:44:49 +0000 (20:44 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Thu, 14 Jan 2010 04:44:49 +0000 (20:44 -0800)
progs/redbook/aapoly, among others, works fine now.

src/gallium/drivers/r300/r300_render.c

index 8b07d31000a93275db6f4528c1a6aafceab904ca..6645688fc58abf5e91bc965ed4f2f70e7be43c5f 100644 (file)
@@ -26,6 +26,8 @@
 #include "draw/draw_context.h"
 #include "draw/draw_vbuf.h"
 
+#include "indices/u_indices.h"
+
 #include "pipe/p_inlines.h"
 
 #include "util/u_memory.h"
@@ -245,15 +247,55 @@ validate:
     return TRUE;
 }
 
+static struct pipe_buffer* r300_translate_elts(struct r300_context* r300,
+                                               struct pipe_buffer* elts,
+                                               unsigned* size,
+                                               unsigned* mode,
+                                               unsigned* count)
+{
+    struct pipe_screen* screen = r300->context.screen;
+    struct pipe_buffer* new_elts;
+    void *in_map, *out_map;
+    unsigned out_prim, out_index_size, out_nr;
+    u_translate_func out_translate;
+
+    (void)u_index_translator(~0, *mode, *size, *count, PV_LAST, PV_LAST,
+        &out_prim, &out_index_size, &out_nr, &out_translate);
+
+    debug_printf("r300: old mode %d, new mode %d\n", *mode, out_prim);
+    debug_printf("r300: old count %d, new count %d\n", *count, out_nr);
+    debug_printf("r300: old size %d, new size %d\n", *size, out_index_size);
+
+    new_elts = screen->buffer_create(screen, 32,
+                                     PIPE_BUFFER_USAGE_INDEX |
+                                     PIPE_BUFFER_USAGE_CPU_WRITE |
+                                     PIPE_BUFFER_USAGE_GPU_READ,
+                                     out_index_size * out_nr);
+
+    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);
+
+    out_translate(in_map, *count, out_map);
+
+    pipe_buffer_unmap(screen, elts);
+    pipe_buffer_unmap(screen, new_elts);
+
+    *size = out_index_size;
+    *mode = out_prim;
+    *count = out_nr;
+
+    return 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,
-                                 unsigned indexSize,
-                                 unsigned minIndex,
-                                 unsigned maxIndex,
-                                 unsigned mode,
-                                 unsigned start,
-                                 unsigned count)
+                              struct pipe_buffer* indexBuffer,
+                              unsigned indexSize,
+                              unsigned minIndex,
+                              unsigned maxIndex,
+                              unsigned mode,
+                              unsigned start,
+                              unsigned count)
 {
     struct r300_context* r300 = r300_context(pipe);
 
@@ -274,6 +316,11 @@ void r300_draw_range_elements(struct pipe_context* pipe,
         return;
     }
 
+    if (indexSize == 1) {
+        indexBuffer = r300_translate_elts(r300, indexBuffer,
+            &indexSize, &mode, &count);
+    }
+
     if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
                                   RADEON_GEM_DOMAIN_GTT, 0)) {
         return;
@@ -289,6 +336,10 @@ void r300_draw_range_elements(struct pipe_context* pipe,
 
     r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex,
                             mode, start, count);
+
+    if (indexSize == 1) {
+        pipe->screen->buffer_destroy(indexBuffer);
+    }
 }
 
 /* Simple helpers for context setup. Should probably be moved to util. */