draw: rework splitting of fan/loop prims in varray.c, fix flatshade issues
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 10 Jun 2008 08:16:34 +0000 (09:16 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 10 Jun 2008 08:23:45 +0000 (09:23 +0100)
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h

index f5495a80c78cc848f667eb363874ffe3d8475d02..4479963db177198162ca11ed5c2e8c0df344ad2f 100644 (file)
@@ -31,7 +31,7 @@
 #include "draw/draw_pt.h"
 
 #define FETCH_MAX 256
-#define DRAW_MAX (16*FETCH_MAX)
+#define DRAW_MAX (FETCH_MAX+8)
 
 struct varray_frontend {
    struct draw_pt_front_end base;
@@ -40,11 +40,6 @@ struct varray_frontend {
    ushort draw_elts[DRAW_MAX];
    unsigned fetch_elts[FETCH_MAX];
 
-   unsigned draw_count;
-   unsigned fetch_count;
-
-   unsigned fetch_start;
-
    unsigned driver_fetch_max;
    unsigned fetch_max;
 
@@ -54,121 +49,86 @@ struct varray_frontend {
    unsigned output_prim;
 };
 
-static void varray_flush(struct varray_frontend *varray)
-{
-   if (varray->draw_count) {
-#if 0
-      debug_printf("FLUSH fc = %d, dc = %d\n",
-                   varray->fetch_count,
-                   varray->draw_count);
-      debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n",
-                   varray->fetch_elts[0],
-                   varray->fetch_elts[varray->fetch_count-1],
-                   varray->draw_elts[0],
-                   varray->draw_elts[varray->draw_count-1]);
-#endif
-      varray->middle->run(varray->middle,
-                          varray->fetch_elts,
-                          varray->fetch_count,
-                          varray->draw_elts,
-                          varray->draw_count);
-   }
-
-   varray->fetch_count = 0;
-   varray->draw_count = 0;
-}
 
 static void varray_flush_linear(struct varray_frontend *varray,
                                 unsigned start, unsigned count)
 {
    if (count) {
-#if 0
-      debug_printf("FLUSH LINEAR start = %d, count = %d\n",
-                   start,
-                   count);
-#endif
       assert(varray->middle->run_linear);
       varray->middle->run_linear(varray->middle, start, count);
    }
 }
 
-static INLINE void fetch_init(struct varray_frontend *varray,
-                              unsigned count)
+static void varray_line_loop_segment(struct varray_frontend *varray,
+                                     unsigned start,
+                                     unsigned segment_start,
+                                     unsigned segment_count,
+                                     boolean end )
 {
-   unsigned idx;
-#if 0
-      debug_printf("FETCH INIT c = %d, fs = %d\n",
-                   count,
-                   varray->fetch_start);
-#endif
-   for (idx = 0; idx < count; ++idx) {
-      varray->fetch_elts[idx] = varray->fetch_start + idx;
-   }
-   varray->fetch_start += idx;
-   varray->fetch_count = idx;
-}
+   assert(segment_count+1 < varray->fetch_max);
+   if (segment_count >= 1) {
+      unsigned nr = 0, i;
 
+      for (i = 0; i < segment_count; i++) 
+         varray->fetch_elts[nr++] = start + segment_start + i;
 
+      if (end) 
+         varray->fetch_elts[nr++] = start;
 
+      assert(nr < FETCH_MAX);
 
-static INLINE void add_draw_el(struct varray_frontend *varray,
-                               unsigned idx)
-{
-   varray->draw_elts[varray->draw_count++] = (ushort)idx;
+      varray->middle->run(varray->middle, 
+                          varray->fetch_elts,
+                          nr,
+                          varray->draw_elts, /* ie. linear */
+                          nr);
+   }
 }
 
 
-static INLINE void varray_triangle( struct varray_frontend *varray,
-                                    unsigned i0,
-                                    unsigned i1,
-                                    unsigned i2 )
-{
-   add_draw_el(varray, i0);
-   add_draw_el(varray, i1);
-   add_draw_el(varray, i2);
-}
 
-static INLINE void varray_line( struct varray_frontend *varray,
-                                unsigned i0,
-                                unsigned i1 )
+static void varray_fan_segment(struct varray_frontend *varray,
+                               unsigned start, 
+                               unsigned segment_start,
+                               unsigned segment_count )
 {
-   add_draw_el(varray, i0);
-   add_draw_el(varray, i1);
-}
+   assert(segment_count+1 < varray->fetch_max);
+   if (segment_count >= 2) {
+      unsigned nr = 0, i;
 
+      if (segment_start != 0)
+         varray->fetch_elts[nr++] = start;
 
-static INLINE void varray_point( struct varray_frontend *varray,
-                                 unsigned i0 )
-{
-   add_draw_el(varray, i0);
+      for (i = 0 ; i < segment_count; i++) 
+         varray->fetch_elts[nr++] = start + segment_start + i;
+
+      assert(nr < FETCH_MAX);
+
+      varray->middle->run(varray->middle, 
+                          varray->fetch_elts,
+                          nr,
+                          varray->draw_elts, /* ie. linear */
+                          nr);
+   }
 }
 
 
-#if 0
-#define TRIANGLE(flags,i0,i1,i2)       varray_triangle(varray,i0,i1,i2)
-#define LINE(flags,i0,i1)              varray_line(varray,i0,i1)
-#define POINT(i0)                      varray_point(varray,i0)
-#define FUNC varray_decompose
-#include "draw_pt_decompose.h"
-#else
-#define TRIANGLE(vc,i0,i1,i2)       varray_triangle(vc,i0,i1,i2)
-#define LINE(vc,i0,i1)              varray_line(vc,i0,i1)
-#define POINT(vc,i0)                varray_point(vc,i0)
+
+
 #define FUNC varray_run
 #include "draw_pt_varray_tmp_linear.h"
-#endif
 
 static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
    PIPE_PRIM_POINTS,
    PIPE_PRIM_LINES,
-   PIPE_PRIM_LINES,             /* decomposed LINELOOP */
+   PIPE_PRIM_LINE_STRIP,        /* decomposed LINELOOP */
    PIPE_PRIM_LINE_STRIP,
    PIPE_PRIM_TRIANGLES,
    PIPE_PRIM_TRIANGLE_STRIP,
-   PIPE_PRIM_TRIANGLES,         /* decomposed TRI_FAN */
+   PIPE_PRIM_TRIANGLE_FAN, 
    PIPE_PRIM_QUADS,
    PIPE_PRIM_QUAD_STRIP,
-   PIPE_PRIM_TRIANGLES          /* decomposed POLYGON */
+   PIPE_PRIM_POLYGON
 };
 
 
@@ -186,7 +146,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
    varray->output_prim = decompose_prim[prim];
 
    varray->middle = middle;
-   middle->prepare(middle, varray->output_prim, opt, &varray->fetch_max );
+   middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max );
+   varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max);
 }
 
 
@@ -207,6 +168,7 @@ static void varray_destroy(struct draw_pt_front_end *frontend)
 
 struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw)
 {
+   unsigned i;
    struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend);
    if (varray == NULL)
       return NULL;
@@ -217,5 +179,9 @@ struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw)
    varray->base.destroy = varray_destroy;
    varray->draw = draw;
 
+   for (i = 0; i < DRAW_MAX; i++) {
+      varray->draw_elts[i] = i;
+   }
+
    return &varray->base;
 }
index 6e5e30f38e533404ea708199d57aa401695d9330..55a8e6521dc4e3709a441a43b236c5f877dc0d8c 100644 (file)
@@ -11,11 +11,9 @@ static void FUNC(struct draw_pt_front_end *frontend,
    struct varray_frontend *varray = (struct varray_frontend *)frontend;
    unsigned start = (unsigned)elts;
 
-   unsigned i, j;
+   unsigned j;
    unsigned first, incr;
 
-   varray->fetch_start = start;
-
    draw_pt_split_prim(varray->input_prim, &first, &incr);
    
    /* Sanitize primitive length:
@@ -40,7 +38,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
    case PIPE_PRIM_QUAD_STRIP:
       for (j = 0; j < count;) {
          unsigned remaining = count - j;
-         unsigned nr = trim( MIN2(varray->fetch_max, remaining), first, incr );
+         unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr );
          varray_flush_linear(varray, start + j, nr);
          j += nr;
          if (nr != remaining) 
@@ -49,45 +47,41 @@ static void FUNC(struct draw_pt_front_end *frontend,
       break;
 
    case PIPE_PRIM_LINE_LOOP:
-      if (count >= 2) {
-         unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max);
-         for (j = 0; j + first <= count; j += i) {
-            unsigned end = MIN2(fetch_max, count - j);
-            end -= (end % incr);
-            for (i = 1; i < end; i++) {
-               LINE(varray, i - 1, i);
-            }
-            LINE(varray, i - 1, 0);
-            i = end;
-            fetch_init(varray, end);
-            varray_flush(varray);
-         }
+      /* Always have to decompose as we've stated that this will be
+       * emitted as a line-strip.
+       */
+      for (j = 0; j < count;) {
+         unsigned remaining = count - j;
+         unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr );
+         varray_line_loop_segment(varray, start, j, nr, nr == remaining);
+         j += nr;
+         if (nr != remaining) 
+            j -= (first - incr);
       }
       break;
 
 
    case PIPE_PRIM_POLYGON:
-   case PIPE_PRIM_TRIANGLE_FAN: {
-      unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max);
-      for (j = 0; j + first <= count; j += i) {
-         unsigned end = MIN2(fetch_max, count - j);
-         end -= (end % incr);
-         for (i = 2; i < end; i++) {
-            TRIANGLE(varray, 0, i - 1, i);
+   case PIPE_PRIM_TRIANGLE_FAN: 
+      if (count < varray->driver_fetch_max) {
+         varray_flush_linear(varray, start, count);
+      }
+      else {
+         for ( j = 0; j < count;) {
+            unsigned remaining = count - j;
+            unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr );
+            varray_fan_segment(varray, start, j, nr);
+            j += nr;
+            if (nr != remaining) 
+               j -= (first - incr);
          }
-         i = end;
-         fetch_init(varray, end);
-         varray_flush(varray);
       }
       break;
-   }
 
    default:
       assert(0);
       break;
    }
-
-   varray_flush(varray);
 }
 
 #undef TRIANGLE