split larger primitives in the simple varray pt
authorZack Rusin <zack@tungstengraphics.com>
Fri, 2 May 2008 03:54:39 +0000 (23:54 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Thu, 8 May 2008 19:26:03 +0000 (15:26 -0400)
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_varray_tmp.h

index c9c5d183135997fd33be9ba884ddcd69681f3ce5..bccde6c5fd2692a71ea7aca41ed739c97153af99 100644 (file)
@@ -80,8 +80,7 @@ draw_pt_arrays(struct draw_context *draw,
 
    /* Pick the right frontend
     */
-   if (draw->pt.user.elts ||
-       count >= 256) {
+   if (draw->pt.user.elts) {
       frontend = draw->pt.front.vcache;
    } else {
       frontend = draw->pt.front.varray;
index b0bd2b983e497c3367f7f710fb0efb273fca58ad..c9843bded0dec64d8fd37b4b7dea409bc97e2103 100644 (file)
@@ -58,6 +58,11 @@ static void varray_flush(struct varray_frontend *varray)
       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,
@@ -71,18 +76,69 @@ static void varray_flush(struct varray_frontend *varray)
 }
 
 static INLINE void fetch_init(struct varray_frontend *varray,
-                              unsigned current_count,
                               unsigned count)
 {
    unsigned idx;
-   const unsigned end = MIN2(FETCH_MAX, count - current_count);
-   for (idx = 0; idx < end; ++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;
 }
 
+
+static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
+{
+   switch (prim) {
+   case PIPE_PRIM_POINTS:
+      *first = 1;
+      *incr = 1;
+      return TRUE;
+   case PIPE_PRIM_LINES:
+      *first = 2;
+      *incr = 2;
+      return TRUE;
+   case PIPE_PRIM_LINE_STRIP:
+      *first = 2;
+      *incr = 1;
+      return TRUE;
+   case PIPE_PRIM_TRIANGLES:
+      *first = 3;
+      *incr = 3;
+      return TRUE;
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      *first = 3;
+      *incr = 1;
+      return TRUE;
+   case PIPE_PRIM_TRIANGLE_FAN:
+      *first = 3;
+      *incr = 1;
+      return TRUE;
+   case PIPE_PRIM_QUADS:
+      *first = 4;
+      *incr = 4;
+      return TRUE;
+   case PIPE_PRIM_QUAD_STRIP:
+      *first = 4;
+      *incr = 2;
+      return TRUE;
+   case PIPE_PRIM_POLYGON:
+      *first = 3;
+      *incr = 1;
+      return TRUE;
+   default:
+      *first = 0;
+      *incr = 1;               /* set to one so that count % incr works */
+      return FALSE;
+   }
+}
+
+
 static INLINE void add_draw_el(struct varray_frontend *varray,
                                int idx, ushort flags)
 {
index a3509613f50056c4ac139692eb9b7724a72062ec..073c1aadbf4e792bbe6fbb9adbf9e7653df8c6c9 100644 (file)
@@ -10,30 +10,42 @@ static void FUNC(struct draw_pt_front_end *frontend,
 
    boolean flatfirst = (draw->rasterizer->flatshade &&
                         draw->rasterizer->flatshade_first);
-   unsigned i, flags;
+   unsigned i, j, flags;
+   unsigned first, incr;
 
-#if 0
-   debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count);
-#endif
-#if 0
-   debug_printf("INPUT PRIM = %d (start = %d, count = %d)\n", varray->input_prim,
+   varray->fetch_start = start;
+
+   split_prim_inplace(varray->input_prim, &first, &incr);
+
+#if 1
+   debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
+                varray->input_prim,
                 start, count);
 #endif
 
-   varray->fetch_start = start;
-   fetch_init(varray, 0, count);
-
    switch (varray->input_prim) {
    case PIPE_PRIM_POINTS:
-      for (i = 0; i < count; i ++) {
-         POINT(varray, i + 0);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i < count; i ++) {
+            POINT(varray, i + 0);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
    case PIPE_PRIM_LINES:
-      for (i = 0; i+1 < count; i += 2) {
-         LINE(varray, DRAW_PIPE_RESET_STIPPLE,
-              i + 0, i + 1);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i+1 < end; i += 2) {
+            LINE(varray, DRAW_PIPE_RESET_STIPPLE,
+                 i + 0, i + 1);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
@@ -41,38 +53,68 @@ static void FUNC(struct draw_pt_front_end *frontend,
       if (count >= 2) {
          flags = DRAW_PIPE_RESET_STIPPLE;
 
-         for (i = 1; i < count; i++, flags = 0) {
-            LINE(varray, flags, i - 1, i);
+         for (j = 0; j + first <= count; j += i) {
+            unsigned end = MIN2(FETCH_MAX, count - j);
+            end -= (end % incr);
+            for (i = 1; i < end; i++, flags = 0) {
+               LINE(varray, flags, i - 1, i);
+            }
+            LINE(varray, flags, i - 1, 0);
+            fetch_init(varray, end);
+            varray_flush(varray);
          }
-         LINE(varray, flags, i - 1, 0);
       }
       break;
 
    case PIPE_PRIM_LINE_STRIP:
       flags = DRAW_PIPE_RESET_STIPPLE;
-      for (i = 1; i < count; i++, flags = 0) {
-         LINE(varray, flags, i - 1, i);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 1; i < end; i++, flags = 0) {
+            LINE(varray, flags, i - 1, i);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
    case PIPE_PRIM_TRIANGLES:
-      for (i = 0; i+2 < count; i += 3) {
-         TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
-                  i + 0, i + 1, i + 2);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i+2 < end; i += 3) {
+            TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+                     i + 0, i + 1, i + 2);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
    case PIPE_PRIM_TRIANGLE_STRIP:
       if (flatfirst) {
-         for (i = 0; i+2 < count; i++) {
-            TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
-                     i + 0, i + 1 + (i&1), i + 2 - (i&1));
+         for (j = 0; j + first <= count; j += i) {
+            unsigned end = MIN2(FETCH_MAX, count - j);
+            end -= (end % incr);
+            for (i = 0; i+2 < end; i++) {
+               TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+                        i + 0, i + 1 + (i&1), i + 2 - (i&1));
+            }
+            fetch_init(varray, end);
+            varray_flush(varray);
          }
       }
       else {
-         for (i = 0; i+2 < count; i++) {
-            TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
-                     i + 0 + (i&1), i + 1 - (i&1), i + 2);
+         for (j = 0; j + first <= count; j += i) {
+            unsigned end = MIN2(FETCH_MAX, count - j);
+            end -= (end % incr);
+            for (i = 0; i+2 < end; i++) {
+               TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL,
+                        i + 0 + (i&1), i + 1 - (i&1), i + 2);
+            }
+            fetch_init(varray, end);
+            varray_flush(varray);
          }
       }
       break;
@@ -81,51 +123,80 @@ static void FUNC(struct draw_pt_front_end *frontend,
       if (count >= 3) {
          if (flatfirst) {
             flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
-            for (i = 0; i+2 < count; i++) {
-               TRIANGLE(varray, flags, i + 1, i + 2, 0);
+            for (j = 0; j + first <= count; j += i) {
+               unsigned end = MIN2(FETCH_MAX, count - j);
+               end -= (end % incr);
+               for (i = 0; i+2 < end; i++) {
+                  TRIANGLE(varray, flags, i + 1, i + 2, 0);
+               }
+               fetch_init(varray, end);
+               varray_flush(varray);
             }
          }
          else {
             flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
-            for (i = 0; i+2 < count; i++) {
-               TRIANGLE(varray, flags, 0, i + 1, i + 2);
+            for (j = 0; j + first <= count; j += i) {
+               unsigned end = MIN2(FETCH_MAX, count - j);
+               end -= (end % incr);
+               for (i = 0; i+2 < end; i++) {
+                  TRIANGLE(varray, flags, 0, i + 1, i + 2);
+               }
+               fetch_init(varray, end);
+               varray_flush(varray);
             }
          }
       }
       break;
 
    case PIPE_PRIM_QUADS:
-      for (i = 0; i+3 < count; i += 4) {
-         QUAD(varray, i + 0, i + 1, i + 2, i + 3);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i+3 < end; i += 4) {
+            QUAD(varray, i + 0, i + 1, i + 2, i + 3);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
    case PIPE_PRIM_QUAD_STRIP:
-      for (i = 0; i+3 < count; i += 2) {
-         QUAD(varray, i + 2, i + 0, i + 1, i + 3);
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i+3 < end; i += 2) {
+            QUAD(varray, i + 2, i + 0, i + 1, i + 3);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
    case PIPE_PRIM_POLYGON:
    {
-         /* These bitflags look a little odd because we submit the
-          * vertices as (1,2,0) to satisfy flatshade requirements.
-          */
-         const unsigned edge_first  = DRAW_PIPE_EDGE_FLAG_2;
-         const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
-         const unsigned edge_last   = DRAW_PIPE_EDGE_FLAG_1;
-
-         flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
-
-        for (i = 0; i+2 < count; i++, flags = edge_middle) {
+      /* These bitflags look a little odd because we submit the
+       * vertices as (1,2,0) to satisfy flatshade requirements.
+       */
+      const unsigned edge_first  = DRAW_PIPE_EDGE_FLAG_2;
+      const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+      const unsigned edge_last   = DRAW_PIPE_EDGE_FLAG_1;
+
+      flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
+      for (j = 0; j + first <= count; j += i) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         for (i = 0; i+2 < end; i++, flags = edge_middle) {
 
             if (i + 3 == count)
                flags |= edge_last;
 
-           TRIANGLE(varray, flags, i + 1, i + 2, 0);
-        }
+            TRIANGLE(varray, flags, i + 1, i + 2, 0);
+         }
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
-      break;
+   }
+   break;
 
    default:
       assert(0);