redo the linear paths
authorZack Rusin <zack@tungstengraphics.com>
Tue, 6 May 2008 22:59:45 +0000 (18:59 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Thu, 8 May 2008 19:26:26 +0000 (15:26 -0400)
src/gallium/auxiliary/draw/draw_pipe.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_varray_tmp.h
src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h [new file with mode: 0644]

index 46afb0f41f721a421924a3b00f72bbf136220dcc..cb97f955b29bbae7358a9c41852aa57804deafdc 100644 (file)
@@ -212,6 +212,45 @@ void draw_pipeline_run( struct draw_context *draw,
    draw->pipeline.vertex_count = 0;
 }
 
+void draw_pipeline_run_linear( struct draw_context *draw,
+                               unsigned prim,
+                               struct vertex_header *vertices,
+                               unsigned count,
+                               unsigned stride )
+{
+   char *verts = (char *)vertices;
+   unsigned i;
+
+   draw->pipeline.verts = verts;
+   draw->pipeline.vertex_stride = stride;
+   draw->pipeline.vertex_count = count;
+
+   switch (prim) {
+   case PIPE_PRIM_POINTS:
+      for (i = 0; i < count; i++)
+         do_point( draw,
+                   verts + stride * i );
+      break;
+   case PIPE_PRIM_LINES:
+      for (i = 0; i+1 < count; i += 2)
+         do_line( draw,
+                  i+0,  /* flags */
+                  verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
+                  verts + stride * (i+1));
+      break;
+   case PIPE_PRIM_TRIANGLES:
+      for (i = 0; i+2 < count; i += 3)
+         do_triangle( draw,
+                      (i+0),  /* flags */
+                      verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK),
+                      verts + stride * (i+1),
+                      verts + stride * (i+2));
+      break;
+   }
+
+   draw->pipeline.verts = NULL;
+   draw->pipeline.vertex_count = 0;
+}
 
 
 void draw_pipeline_flush( struct draw_context *draw, 
index cee58bbf73ead6144aa3a015b5304e7e6beefa95..e036d498b8789137452d46f6d9eeb8d905b2bc67 100644 (file)
@@ -247,6 +247,12 @@ void draw_pipeline_run( struct draw_context *draw,
                         const ushort *elts,
                         unsigned count );
 
+void draw_pipeline_run_linear( struct draw_context *draw,
+                               unsigned prim,
+                               struct vertex_header *vertices,
+                               unsigned count,
+                               unsigned stride );
+
 
 
 void draw_pipeline_flush( struct draw_context *draw, 
index 2f96ceaf00dcaefda841898b0121a3ab6c7e7f25..312fdbe4f4067bca74e2299f5575db325f44633c 100644 (file)
@@ -93,10 +93,8 @@ struct draw_pt_middle_end {
                 unsigned draw_count );
 
    void (*run_linear)(struct draw_pt_middle_end *,
-                      unsigned fetch_start,
-                      unsigned fetch_count,
-                      const ushort *draw_elts,
-                      unsigned draw_count);
+                      unsigned start,
+                      unsigned count);
 
    void (*finish)( struct draw_pt_middle_end * );
    void (*destroy)( struct draw_pt_middle_end * );
index 6d5a54cf0e2aba0c53de90619c251c0bc0c426ef..8df4241b82cc42e2133f37b9f5a93ebf46f4ae13 100644 (file)
@@ -258,10 +258,8 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
 
 
 static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
-                                   unsigned fetch_start,
-                                   unsigned fetch_count,
-                                   const ushort *draw_elts,
-                                   unsigned draw_count )
+                                   unsigned start,
+                                   unsigned count )
 {
    struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
    struct draw_context *draw = feme->draw;
@@ -273,7 +271,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
 
    hw_verts = draw->render->allocate_vertices( draw->render,
                                                (ushort)feme->translate->key.output_stride,
-                                               (ushort)fetch_count );
+                                               (ushort)count );
    if (!hw_verts) {
       assert(0);
       return;
@@ -282,13 +280,13 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
    /* Single routine to fetch vertices and emit HW verts.
     */
    feme->translate->run( feme->translate,
-                         fetch_start,
-                         fetch_count,
+                         start,
+                         count,
                          hw_verts );
 
    if (0) {
       unsigned i;
-      for (i = 0; i < fetch_count; i++) {
+      for (i = 0; i < count; i++) {
          debug_printf("\n\nvertex %d:\n", i);
          draw_dump_emitted_vertex( feme->vinfo,
                                    (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i );
@@ -300,14 +298,14 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
     */
    draw->render->draw_arrays( draw->render,
                               0, /*start*/
-                              draw_count );
+                              count );
 
    /* Done -- that was easy, wasn't it:
     */
    draw->render->release_vertices( draw->render,
                                    hw_verts,
                                    feme->translate->key.output_stride,
-                                   fetch_count );
+                                   count );
 
 }
 
index b1e08a8f4023e94242e5736b7bf8e49ba6940ac5..dad54690a5a00744205e571bd2a5f1b35c738dfb 100644 (file)
@@ -178,18 +178,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
 
 
 static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
-                                       unsigned fetch_start,
-                                       unsigned fetch_count,
-                                       const ushort *draw_elts,
-                                       unsigned draw_count )
+                                       unsigned start,
+                                       unsigned count)
 {
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
    struct draw_vertex_shader *shader = draw->vertex_shader;
    unsigned opt = fpme->opt;
-   unsigned alloc_count = align_int( fetch_count, 4 );
+   unsigned alloc_count = align_int( count, 4 );
 
-   struct vertex_header *pipeline_verts = 
+   struct vertex_header *pipeline_verts =
       (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
 
    if (!pipeline_verts) {
@@ -202,8 +200,8 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
    /* Fetch into our vertex buffer
     */
    draw_pt_fetch_run_linear( fpme->fetch,
-                             fetch_start,
-                             fetch_count,
+                             start,
+                             count,
                              (char *)pipeline_verts );
 
    /* Run the shader, note that this overwrites the data[] parts of
@@ -213,18 +211,18 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_SHADE)
    {
-      shader->run_linear(shader, 
+      shader->run_linear(shader,
                         (const float (*)[4])pipeline_verts->data,
                         (      float (*)[4])pipeline_verts->data,
                         (const float (*)[4])draw->pt.user.constants,
-                        fetch_count,
+                        count,
                         fpme->vertex_size,
                         fpme->vertex_size);
    }
 
    if (draw_pt_post_vs_run( fpme->post_vs,
                            pipeline_verts,
-                           fetch_count,
+                           count,
                            fpme->vertex_size ))
    {
       opt |= PT_PIPELINE;
@@ -233,21 +231,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
    /* Do we need to run the pipeline?
     */
    if (opt & PT_PIPELINE) {
-      draw_pipeline_run( fpme->draw,
-                         fpme->prim,
-                         pipeline_verts,
-                         fetch_count,
-                         fpme->vertex_size,
-                         draw_elts,
-                         draw_count );
+      draw_pipeline_run_linear( fpme->draw,
+                                fpme->prim,
+                                pipeline_verts,
+                                count,
+                                fpme->vertex_size);
    }
    else {
       draw_pt_emit_linear( fpme->emit,
                            (const float (*)[4])pipeline_verts->data,
-                           fetch_count,
+                           count,
                            fpme->vertex_size,
                            0, /*start*/
-                           draw_count );
+                           count );
    }
 
    FREE(pipeline_verts);
index e7e21e4bf6d7cf1c914959de127fb50ca492d053..59a9569270c5da4282e997e33112df4399e4ff11 100644 (file)
@@ -75,29 +75,18 @@ static void varray_flush(struct varray_frontend *varray)
    varray->draw_count = 0;
 }
 
-static void varray_flush_linear(struct varray_frontend *varray)
+static void varray_flush_linear(struct varray_frontend *varray,
+                                unsigned start, unsigned count)
 {
-   if (varray->draw_count) {
+   if (count) {
 #if 0
-      debug_printf("FLUSH LINEAR 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]);
+      debug_printf("FLUSH LINEAR start = %d, count = %d\n",
+                   start,
+                   count);
 #endif
       assert(varray->middle->run_linear);
-      varray->middle->run_linear(varray->middle,
-                                 varray->fetch_start,
-                                 varray->fetch_count,
-                                 varray->draw_elts,
-                                 varray->draw_count);
+      varray->middle->run_linear(varray->middle, start, count);
    }
-
-   varray->fetch_count = 0;
-   varray->draw_count = 0;
 }
 
 static INLINE void fetch_init(struct varray_frontend *varray,
@@ -261,7 +250,7 @@ static INLINE void varray_ef_quad( struct varray_frontend *varray,
 #define LINE(vc,flags,i0,i1)        varray_line(vc,i0,i1)
 #define POINT(vc,i0)                varray_point(vc,i0)
 #define FUNC varray_run
-#include "draw_pt_varray_tmp.h"
+#include "draw_pt_varray_tmp_linear.h"
 
 
 
index 10ac08ea3002e5e9506f1c513a8cab31b2a51a73..335c4c89ca64b67c2312d8326557fdaab7b006c4 100644 (file)
@@ -92,9 +92,8 @@ static void FUNC(struct draw_pt_front_end *frontend,
                      i + 0, i + 1, i + 2);
          }
          i = end;
-         varray->fetch_count = end;
-         varray_flush_linear(varray);
-         varray->fetch_start += end;
+         fetch_init(varray, end);
+         varray_flush(varray);
       }
       break;
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
new file mode 100644 (file)
index 0000000..dfa4338
--- /dev/null
@@ -0,0 +1,198 @@
+
+static void FUNC(struct draw_pt_front_end *frontend,
+                 pt_elt_func get_elt,
+                 const void *elts,
+                 unsigned count)
+{
+   struct varray_frontend *varray = (struct varray_frontend *)frontend;
+   struct draw_context *draw = varray->draw;
+   unsigned start = (unsigned)elts;
+
+   boolean flatfirst = (draw->rasterizer->flatshade &&
+                        draw->rasterizer->flatshade_first);
+   unsigned i, j, flags;
+   unsigned first, incr;
+
+   varray->fetch_start = start;
+
+   split_prim_inplace(varray->input_prim, &first, &incr);
+
+#if 0
+   debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
+                varray->input_prim,
+                start, count);
+#endif
+
+   switch (varray->input_prim) {
+   case PIPE_PRIM_POINTS:
+   case PIPE_PRIM_LINES:
+   case PIPE_PRIM_TRIANGLES:
+      j = 0;
+      while (j + first <= count) {
+         unsigned end = MIN2(FETCH_MAX, count - j);
+         end -= (end % incr);
+         varray_flush_linear(varray, start + j, end);
+         j += end;
+      }
+      break;
+
+   case PIPE_PRIM_LINE_LOOP:
+      if (count >= 2) {
+         flags = DRAW_PIPE_RESET_STIPPLE;
+
+         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);
+            i = end;
+            fetch_init(varray, end);
+            varray_flush(varray);
+         }
+      }
+      break;
+
+   case PIPE_PRIM_LINE_STRIP:
+      flags = DRAW_PIPE_RESET_STIPPLE;
+      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);
+         }
+         i = end;
+         fetch_init(varray, end);
+         varray_flush(varray);
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      if (flatfirst) {
+         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));
+            }
+            i = end;
+            fetch_init(varray, end);
+            varray_flush(varray);
+         }
+      }
+      else {
+         for (j = 0; j + first <= count;) {
+            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);
+            j += end;
+            if (j <= count)
+               j -= incr;
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      if (count >= 3) {
+         if (flatfirst) {
+            flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+            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);
+               }
+               i = end;
+               fetch_init(varray, end);
+               varray_flush(varray);
+            }
+         }
+         else {
+            flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
+            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);
+               }
+               i = end;
+               fetch_init(varray, end);
+               varray_flush(varray);
+            }
+         }
+      }
+      break;
+
+   case PIPE_PRIM_QUADS:
+      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);
+         }
+         i = end;
+         fetch_init(varray, end);
+         varray_flush(varray);
+      }
+      break;
+
+   case PIPE_PRIM_QUAD_STRIP:
+      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);
+         }
+         i = end;
+         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 (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);
+         }
+         i = end;
+         fetch_init(varray, end);
+         varray_flush(varray);
+      }
+   }
+   break;
+
+   default:
+      assert(0);
+      break;
+   }
+
+   varray_flush(varray);
+}
+
+#undef TRIANGLE
+#undef QUAD
+#undef POINT
+#undef LINE
+#undef FUNC