draw: handle edgeflags and reset-line-stipple again
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 24 Apr 2008 11:38:15 +0000 (12:38 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 24 Apr 2008 11:39:09 +0000 (12:39 +0100)
13 files changed:
src/gallium/auxiliary/draw/draw_pipe.c
src/gallium/auxiliary/draw/draw_pipe.h
src/gallium/auxiliary/draw/draw_pipe_clip.c
src/gallium/auxiliary/draw/draw_pipe_flatshade.c
src/gallium/auxiliary/draw/draw_pipe_offset.c
src/gallium/auxiliary/draw/draw_pipe_stipple.c
src/gallium/auxiliary/draw/draw_pipe_twoside.c
src/gallium/auxiliary/draw/draw_pipe_unfilled.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_fetch.c
src/gallium/auxiliary/draw/draw_pt_vcache.c
src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h [new file with mode: 0644]

index d0890203a5eeef6431cb1bfc9eb2aa19402cb6e3..1c9d8650e2d48075639c0f4ca55103ed2fdb0b6e 100644 (file)
@@ -116,8 +116,7 @@ static void do_point( struct draw_context *draw,
 {
    struct prim_header prim;
    
-   prim.reset_line_stipple = 0;
-   prim.edgeflags = 1;
+   prim.flags = 0;
    prim.pad = 0;
    prim.v[0] = (struct vertex_header *)v0;
 
@@ -126,13 +125,13 @@ static void do_point( struct draw_context *draw,
 
 
 static void do_line( struct draw_context *draw,
+                     ushort flags,
                     const char *v0,
                     const char *v1 )
 {
    struct prim_header prim;
    
-   prim.reset_line_stipple = 1; /* fixme */
-   prim.edgeflags = 1;
+   prim.flags = flags;
    prim.pad = 0;
    prim.v[0] = (struct vertex_header *)v0;
    prim.v[1] = (struct vertex_header *)v1;
@@ -142,6 +141,7 @@ static void do_line( struct draw_context *draw,
 
 
 static void do_triangle( struct draw_context *draw,
+                         ushort flags,
                         char *v0,
                         char *v1,
                         char *v2 )
@@ -151,10 +151,7 @@ static void do_triangle( struct draw_context *draw,
    prim.v[0] = (struct vertex_header *)v0;
    prim.v[1] = (struct vertex_header *)v1;
    prim.v[2] = (struct vertex_header *)v2;
-   prim.reset_line_stipple = 1;
-   prim.edgeflags = ((prim.v[0]->edgeflag)      |
-                     (prim.v[1]->edgeflag << 1) |
-                     (prim.v[2]->edgeflag << 2));
+   prim.flags = flags;
    prim.pad = 0;
 
    draw->pipeline.first->tri( draw->pipeline.first, &prim );
@@ -197,13 +194,15 @@ void draw_pipeline_run( struct draw_context *draw,
    case PIPE_PRIM_LINES:
       for (i = 0; i+1 < count; i += 2) 
          do_line( draw, 
-                  verts + stride * elts[i+0],
+                  elts[i+0],
+                  verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
                   verts + stride * elts[i+1]);
       break;
    case PIPE_PRIM_TRIANGLES:
       for (i = 0; i+2 < count; i += 3)
          do_triangle( draw, 
-                      verts + stride * elts[i+0],
+                      elts[i+0],
+                      verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
                       verts + stride * elts[i+1],
                       verts + stride * elts[i+2]);
       break;
index 2476abb2b2345da6df1aa8fbe735a39201672972..f1cb0891caa5bbb9e166d68d0ac9f1619e690358 100644 (file)
 #include "draw_private.h"       /* for sizeof(vertex_header) */
 
 
+/**
+ * Basic info for a point/line/triangle primitive.
+ */
+struct prim_header {
+   float det;                 /**< front/back face determinant */
+   ushort flags;
+   ushort pad;
+   struct vertex_header *v[3];  /**< 1 to 3 vertex pointers */
+};
+
+
 
 /**
  * Base class for all primitive drawing stages.
index 21216addeab14bab783ac17dab3383b860edd0e3..ce80c9416393006e939d1ee82d12f054ab238b52 100644 (file)
@@ -119,7 +119,7 @@ static void interp( const struct clipper *clip,
     */
    {
       dst->clipmask = 0;
-      dst->edgeflag = 0;
+      dst->edgeflag = 0;        /* will get overwritten later */
       dst->pad = 0;
       dst->vertex_id = UNDEFINED_VERTEX_ID;
    }
@@ -162,45 +162,39 @@ static void emit_poly( struct draw_stage *stage,
    struct prim_header header;
    unsigned i;
 
+   const ushort edge_first  = DRAW_PIPE_EDGE_FLAG_2;
+   const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+   const ushort edge_last   = DRAW_PIPE_EDGE_FLAG_1;
+
    /* later stages may need the determinant, but only the sign matters */
    header.det = origPrim->det;
+   header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
+   header.pad = 0;
 
-   for (i = 2; i < n; i++) {
+   for (i = 2; i < n; i++, header.flags = 0) {
       header.v[0] = inlist[i-1];
       header.v[1] = inlist[i];
       header.v[2] = inlist[0]; /* keep in v[2] for flatshading */
-       
-      {
-        unsigned tmp1 = header.v[1]->edgeflag;
-        unsigned tmp2 = header.v[2]->edgeflag;
-
-        if (i != n-1) header.v[1]->edgeflag = 0;
-        if (i != 2)   header.v[2]->edgeflag = 0;
-
-         header.edgeflags = ((header.v[0]->edgeflag << 0) | 
-                             (header.v[1]->edgeflag << 1) | 
-                             (header.v[2]->edgeflag << 2));
-
-         if (0) {
-            const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
-            uint j, k;
-            debug_printf("Clipped tri:\n");
-            for (j = 0; j < 3; j++) {
-               for (k = 0; k < vs->info.num_outputs; k++) {
-                  debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
-                         header.v[j]->data[k][0],
-                         header.v[j]->data[k][1],
-                         header.v[j]->data[k][2],
-                         header.v[j]->data[k][3]);
-               }
+
+      if (i == n-1)
+        header.flags |= edge_last;
+
+      if (0) {
+         const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+         uint j, k;
+         debug_printf("Clipped tri:\n");
+         for (j = 0; j < 3; j++) {
+            for (k = 0; k < vs->info.num_outputs; k++) {
+               debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
+                            header.v[j]->data[k][0],
+                            header.v[j]->data[k][1],
+                            header.v[j]->data[k][2],
+                            header.v[j]->data[k][3]);
             }
          }
-
-        stage->next->tri( stage->next, &header );
-
-        header.v[1]->edgeflag = tmp1;
-        header.v[2]->edgeflag = tmp2;
       }
+
+      stage->next->tri( stage->next, &header );
    }
 }
 
index 205000cbea57db259b8443b23ef9586c88ac579a..09b68c455997199c37eb265466d5326f54d1f12c 100644 (file)
@@ -91,7 +91,8 @@ static void flatshade_tri_0( struct draw_stage *stage,
    struct prim_header tmp;
 
    tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
+   tmp.flags = header->flags;
+   tmp.pad = header->pad;
    tmp.v[0] = header->v[0];
    tmp.v[1] = dup_vert(stage, header->v[1], 0);
    tmp.v[2] = dup_vert(stage, header->v[2], 1);
@@ -108,7 +109,8 @@ static void flatshade_tri_2( struct draw_stage *stage,
    struct prim_header tmp;
 
    tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
+   tmp.flags = header->flags;
+   tmp.pad = header->pad;
    tmp.v[0] = dup_vert(stage, header->v[0], 0);
    tmp.v[1] = dup_vert(stage, header->v[1], 1);
    tmp.v[2] = header->v[2];
index ffec85ccdd8aea7d64ae5bde196fa4840881d374..ea6de8c571eb1e203c9085352eaa8376705afa7c 100644 (file)
@@ -106,7 +106,8 @@ static void offset_tri( struct draw_stage *stage,
    struct prim_header tmp;
 
    tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
+   tmp.flags = header->flags;
+   tmp.pad = header->pad;
    tmp.v[0] = dup_vert(stage, header->v[0], 0);
    tmp.v[1] = dup_vert(stage, header->v[1], 1);
    tmp.v[2] = dup_vert(stage, header->v[2], 2);
index 9cf5840ccee689044cd183148c3e56178414c273..3cbced362e894346ecf7bb65b017e4faaeefe213 100644 (file)
@@ -135,6 +135,10 @@ stipple_line(struct draw_stage *stage, struct prim_header *header)
    float length = MAX2(dx, dy);
    int i;
 
+   if (header->flags & DRAW_PIPE_RESET_STIPPLE)
+      stipple->counter = 0;
+
+
    /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table.
     */
    for (i = 0; i < length; i++) {
index 5910dccc43cc216eef8e5f2996487c5bd2b702a2..50872fdbe93a0666ec77133e24dd66abb6406443 100644 (file)
@@ -85,7 +85,8 @@ static void twoside_tri( struct draw_stage *stage,
       struct prim_header tmp;
 
       tmp.det = header->det;
-      tmp.edgeflags = header->edgeflags;
+      tmp.flags = header->flags;
+      tmp.pad = header->pad;
       /* copy back attribs to front attribs */
       tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
       tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
index eeb2bc43f913ded06ca5b180f2a105afcad819e6..8f97fdedaac3936fd1b5af32b1f87aaab1e590a4 100644 (file)
@@ -83,9 +83,9 @@ static void points( struct draw_stage *stage,
    struct vertex_header *v1 = header->v[1];
    struct vertex_header *v2 = header->v[2];
 
-   if (header->edgeflags & 0x1) point( stage, v0 );
-   if (header->edgeflags & 0x2) point( stage, v1 );
-   if (header->edgeflags & 0x4) point( stage, v2 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) point( stage, v0 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) point( stage, v1 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) point( stage, v2 );
 }
 
 
@@ -96,22 +96,22 @@ static void lines( struct draw_stage *stage,
    struct vertex_header *v1 = header->v[1];
    struct vertex_header *v2 = header->v[2];
 
-#if 0
-   assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag);
-   assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag);
-   assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag);
-#endif
+   if (header->flags & DRAW_PIPE_RESET_STIPPLE)
+      stage->next->reset_stipple_counter( stage->next );
 
-   if (header->edgeflags & 0x4) line( stage, v2, v0 );
-   if (header->edgeflags & 0x1) line( stage, v0, v1 );
-   if (header->edgeflags & 0x2) line( stage, v1, v2 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) line( stage, v2, v0 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) line( stage, v0, v1 );
+   if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) line( stage, v1, v2 );
 }
 
 
 /* Unfilled tri:  
  *
  * Note edgeflags in the vertex struct is not sufficient as we will
- * need to manipulate them when decomposing primitives???
+ * need to manipulate them when decomposing primitives.  
+ * 
+ * We currently keep the vertex edgeflag and primitive edgeflag mask
+ * separate until the last possible moment.
  */
 static void unfilled_tri( struct draw_stage *stage,
                          struct prim_header *header )
index ca5021c5c65912b5504ed52bcc210ecccec44cf9..49593c8fadad5126b214b40a0296f1838c11e577 100644 (file)
@@ -78,25 +78,6 @@ struct vertex_header {
 #define UNDEFINED_VERTEX_ID 0xffff
 
 
-/**
- * Basic info for a point/line/triangle primitive.
- */
-struct prim_header {
-   float det;                 /**< front/back face determinant */
-   unsigned reset_line_stipple:1;
-   unsigned edgeflags:3;
-   unsigned pad:28;
-   struct vertex_header *v[3];  /**< 1 to 3 vertex pointers */
-};
-
-
-
-
-#define PT_SHADE      0x1
-#define PT_CLIPTEST   0x2
-#define PT_PIPELINE   0x4
-#define PT_MAX_MIDDLE 0x8
-
 /**
  * Private context for the drawing module.
  */
@@ -238,6 +219,25 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw );
 boolean draw_pipeline_init( struct draw_context *draw );
 void draw_pipeline_destroy( struct draw_context *draw );
 
+
+
+
+
+/* We use the top few bits in the elts[] parameter to convey a little
+ * API information.  This limits the number of vertices we can address
+ * to only 4096 -- if that becomes a problem, we can switch to 32-bit
+ * draw indices.
+ *
+ * These flags expected at first vertex of lines & triangles when
+ * unfilled and/or line stipple modes are operational.
+ */
+#define DRAW_PIPE_EDGE_FLAG_0   (0x1<<12)
+#define DRAW_PIPE_EDGE_FLAG_1   (0x2<<12)
+#define DRAW_PIPE_EDGE_FLAG_2   (0x4<<12)
+#define DRAW_PIPE_EDGE_FLAG_ALL (0x7<<12)
+#define DRAW_PIPE_RESET_STIPPLE (0x8<<12)
+#define DRAW_PIPE_FLAG_MASK     (0xf<<12)
+
 void draw_pipeline_run( struct draw_context *draw,
                         unsigned prim,
                         struct vertex_header *vertices,
@@ -246,6 +246,8 @@ void draw_pipeline_run( struct draw_context *draw,
                         const ushort *elts,
                         unsigned count );
 
+
+
 void draw_pipeline_flush( struct draw_context *draw, 
                           unsigned flags );
 
index fd0d158fcf7cb43dc44bb83559bd899652059ec8..df5c29fc36420d63e09e40ece948f2364a5b082d 100644 (file)
@@ -40,15 +40,6 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx );
 struct draw_pt_middle_end;
 struct draw_context;
 
-/* We use the top couple of bits in the vertex fetch index to convey a
- * little API information.  This limits the number of vertices we can
- * address to only 1 billion -- if that becomes a problem, these could
- * be moved out & passed separately.
- */
-#define DRAW_PT_EDGEFLAG      (1<<30)
-#define DRAW_PT_RESET_STIPPLE (1<<31)
-#define DRAW_PT_FLAG_MASK     (3<<30)
-
 
 #define PT_SHADE      0x1
 #define PT_CLIPTEST   0x2
index cc61b113fd4b5dbc86b23bd14319ca96fd8fcffa..9f74806e11c579428ce0362b18ab6b75bb3283a2 100644 (file)
@@ -41,6 +41,7 @@ struct pt_fetch {
    struct translate *translate;
 
    unsigned vertex_size;
+   boolean need_edgeflags;
 
    struct translate_cache *cache;
 };
@@ -121,6 +122,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
                                      0);
       }
    }
+
+   fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+                             draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
+                            draw->pt.user.edgeflag);
 }
 
 
@@ -147,6 +152,18 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
                        elts, 
                        count,
                        verts );
+
+   /* Edgeflags are hard to fit into a translate program, populate
+    * them separately if required.  In the setup above they are
+    * defaulted to one, so only need this if there is reason to change
+    * that default:
+    */
+   if (fetch->need_edgeflags) {
+      for (i = 0; i < count; i++) {
+         struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
+         vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
+      }
+   }
 }
 
 
index 153055417d528b7e6ec230abd5c30a30fdae8af7..b3133359e06a4325a0977679b7fa07f64e12a399 100644 (file)
@@ -33,8 +33,6 @@
 #include "pipe/p_util.h"
 #include "draw/draw_context.h"
 #include "draw/draw_private.h"
-//#include "draw/draw_vbuf.h"
-//#include "draw/draw_vertex.h"
 #include "draw/draw_pt.h"
 
 
@@ -86,8 +84,9 @@ static void vcache_check_flush( struct vcache_frontend *vcache )
 }
 
 
-static void vcache_elt( struct vcache_frontend *vcache,
-                        unsigned felt )
+static INLINE void vcache_elt( struct vcache_frontend *vcache,
+                               unsigned felt,
+                               ushort flags )
 {
    unsigned idx = felt % CACHE_MAX;
 
@@ -99,28 +98,9 @@ static void vcache_elt( struct vcache_frontend *vcache,
       vcache->fetch_elts[vcache->fetch_count++] = felt;
    }
 
-   vcache->draw_elts[vcache->draw_count++] = vcache->out[idx];
+   vcache->draw_elts[vcache->draw_count++] = vcache->out[idx] | flags;
 }
 
-static unsigned add_edgeflag( struct vcache_frontend *vcache,
-                              unsigned idx, 
-                              unsigned mask )
-{
-   if (0 && mask && draw_pt_get_edgeflag(vcache->draw, idx)) 
-      return idx | DRAW_PT_EDGEFLAG;
-   else
-      return idx;
-}
-
-
-static unsigned add_reset_stipple( unsigned idx,
-                                   unsigned reset )
-{
-   if (0 && reset)
-      return idx | DRAW_PT_RESET_STIPPLE;
-   else
-      return idx;
-}
 
                    
 static void vcache_triangle( struct vcache_frontend *vcache,
@@ -128,49 +108,42 @@ static void vcache_triangle( struct vcache_frontend *vcache,
                              unsigned i1,
                              unsigned i2 )
 {
-   vcache_elt(vcache, i0 /* | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE */ );
-   vcache_elt(vcache, i1 /* | DRAW_PT_EDGEFLAG */);
-   vcache_elt(vcache, i2 /* | DRAW_PT_EDGEFLAG */);
+   vcache_elt(vcache, i0, 0);
+   vcache_elt(vcache, i1, 0);
+   vcache_elt(vcache, i2, 0);
    vcache_check_flush(vcache);
 }
 
                          
-static void vcache_ef_triangle( struct vcache_frontend *vcache,
-                                boolean reset_stipple,
-                                unsigned ef_mask,
-                                unsigned i0,
-                                unsigned i1,
-                                unsigned i2 )
+static void vcache_triangle_flags( struct vcache_frontend *vcache,
+                                   ushort flags,
+                                   unsigned i0,
+                                   unsigned i1,
+                                   unsigned i2 )
 {
-/*
-   i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 );
-   i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 );
-   i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 );
-   i0 = add_reset_stipple( i0, reset_stipple );
-*/
-
-   vcache_elt(vcache, i0);
-   vcache_elt(vcache, i1);
-   vcache_elt(vcache, i2);
+   vcache_elt(vcache, i0, flags);
+   vcache_elt(vcache, i1, 0);
+   vcache_elt(vcache, i2, 0);
    vcache_check_flush(vcache);
-
-   if (0) debug_printf("emit tri ef: %d %d %d\n", 
-                       !!(i0 & DRAW_PT_EDGEFLAG),
-                       !!(i1 & DRAW_PT_EDGEFLAG),
-                       !!(i2 & DRAW_PT_EDGEFLAG));
-   
 }
 
-
 static void vcache_line( struct vcache_frontend *vcache,
-                         boolean reset_stipple,
                          unsigned i0,
                          unsigned i1 )
 {
-   i0 = add_reset_stipple( i0, reset_stipple );
+   vcache_elt(vcache, i0, 0);
+   vcache_elt(vcache, i1, 0);
+   vcache_check_flush(vcache);
+}
+
 
-   vcache_elt(vcache, i0);
-   vcache_elt(vcache, i1);
+static void vcache_line_flags( struct vcache_frontend *vcache,
+                               ushort flags,
+                               unsigned i0,
+                               unsigned i1 )
+{
+   vcache_elt(vcache, i0, flags);
+   vcache_elt(vcache, i1, 0);
    vcache_check_flush(vcache);
 }
 
@@ -178,7 +151,7 @@ static void vcache_line( struct vcache_frontend *vcache,
 static void vcache_point( struct vcache_frontend *vcache,
                           unsigned i0 )
 {
-   vcache_elt(vcache, i0);
+   vcache_elt(vcache, i0, 0);
    vcache_check_flush(vcache);
 }
 
@@ -198,237 +171,36 @@ static void vcache_ef_quad( struct vcache_frontend *vcache,
                             unsigned i2,
                             unsigned i3 )
 {
-   const unsigned omitEdge2 = ~(1 << 1);
-   const unsigned omitEdge3 = ~(1 << 2);
-   vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 );
-   vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 );
-}
+   const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2;
+   const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1;
 
+   vcache_triangle_flags( vcache, 
+                          DRAW_PIPE_RESET_STIPPLE | omitEdge1, 
+                          i0, i1, i3 );
 
+   vcache_triangle_flags( vcache, 
+                          omitEdge2, 
+                          i1, i2, i3 );
+}
 
+/* At least for now, we're back to using a template include file for
+ * this.  The two paths aren't too different though - it may be
+ * possible to reunify them.
+ */
+#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2)
+#define QUAD(vc,i0,i1,i2,i3)        vcache_ef_quad(vc,i0,i1,i2,i3)
+#define LINE(vc,flags,i0,i1)        vcache_line_flags(vc,flags,i0,i1)
+#define POINT(vc,i0)                vcache_point(vc,i0)
+#define FUNC vcache_run_extras
+#include "draw_pt_vcache_tmp.h"
+
+#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2)
+#define QUAD(vc,i0,i1,i2,i3)        vcache_quad(vc,i0,i1,i2,i3)
+#define LINE(vc,flags,i0,i1)        vcache_line(vc,i0,i1)
+#define POINT(vc,i0)                vcache_point(vc,i0)
+#define FUNC vcache_run
+#include "draw_pt_vcache_tmp.h"
 
-static void vcache_run( struct draw_pt_front_end *frontend, 
-                        pt_elt_func get_elt,
-                        const void *elts,
-                        unsigned count )
-{
-   struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
-   struct draw_context *draw = vcache->draw;
-
-   boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
-                      draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL);
-
-   boolean flatfirst = (draw->rasterizer->flatshade && 
-                        draw->rasterizer->flatshade_first);
-   unsigned i;
-
-//   debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
-
-   switch (vcache->input_prim) {
-   case PIPE_PRIM_POINTS:
-      for (i = 0; i < count; i ++) {
-        vcache_point( vcache,
-                       get_elt(elts, i + 0) );
-      }
-      break;
-
-   case PIPE_PRIM_LINES:
-      for (i = 0; i+1 < count; i += 2) {
-         vcache_line( vcache, 
-                      TRUE,
-                      get_elt(elts, i + 0),
-                      get_elt(elts, i + 1));
-      }
-      break;
-
-   case PIPE_PRIM_LINE_LOOP:  
-      if (count >= 2) {
-        for (i = 1; i < count; i++) {
-           vcache_line( vcache, 
-                         i == 1,       /* XXX: only if vb not split */
-                         get_elt(elts, i - 1),
-                         get_elt(elts, i ));
-        }
-
-        vcache_line( vcache, 
-                      0,
-                      get_elt(elts, count - 1),
-                      get_elt(elts, 0 ));
-      }
-      break;
-
-   case PIPE_PRIM_LINE_STRIP:
-      for (i = 1; i < count; i++) {
-         vcache_line( vcache,
-                      i == 1,
-                      get_elt(elts, i - 1),
-                      get_elt(elts, i ));
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLES:
-      if (unfilled) {
-         for (i = 0; i+2 < count; i += 3) {
-            vcache_ef_triangle( vcache,
-                                1, 
-                                ~0,
-                                get_elt(elts, i + 0),
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2 ));
-         }
-      } 
-      else {
-         for (i = 0; i+2 < count; i += 3) {
-            vcache_triangle( vcache,
-                             get_elt(elts, i + 0),
-                             get_elt(elts, i + 1),
-                             get_elt(elts, i + 2 ));
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      if (flatfirst) {
-         for (i = 0; i+2 < count; i++) {
-            if (i & 1) {
-               vcache_triangle( vcache,
-                                get_elt(elts, i + 0),
-                                get_elt(elts, i + 2),
-                                get_elt(elts, i + 1 ));
-            }
-            else {
-               vcache_triangle( vcache,
-                                get_elt(elts, i + 0),
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2 ));
-            }
-         }
-      }
-      else {
-         for (i = 0; i+2 < count; i++) {
-            if (i & 1) {
-               vcache_triangle( vcache,
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 0),
-                                get_elt(elts, i + 2 ));
-            }
-            else {
-               vcache_triangle( vcache,
-                                get_elt(elts, i + 0),
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2 ));
-            }
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_FAN:
-      if (count >= 3) {
-         if (flatfirst) {
-            for (i = 0; i+2 < count; i++) {
-               vcache_triangle( vcache,
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2),
-                                get_elt(elts, 0 ));
-            }
-         }
-         else {
-            for (i = 0; i+2 < count; i++) {
-               vcache_triangle( vcache,
-                                get_elt(elts, 0),
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2 ));
-            }
-         }
-      }
-      break;
-
-
-   case PIPE_PRIM_QUADS:
-      if (unfilled) {
-        for (i = 0; i+3 < count; i += 4) {
-           vcache_ef_quad( vcache,
-                            get_elt(elts, i + 0),
-                            get_elt(elts, i + 1),
-                            get_elt(elts, i + 2),
-                            get_elt(elts, i + 3));
-        }
-      }
-      else {
-        for (i = 0; i+3 < count; i += 4) {
-           vcache_quad( vcache,
-                         get_elt(elts, i + 0),
-                         get_elt(elts, i + 1),
-                         get_elt(elts, i + 2),
-                         get_elt(elts, i + 3));
-        }
-      }
-      break;
-
-   case PIPE_PRIM_QUAD_STRIP:
-      if (unfilled) {
-        for (i = 0; i+3 < count; i += 2) {
-           vcache_ef_quad( vcache,
-                            get_elt(elts, i + 2),
-                            get_elt(elts, i + 0),
-                            get_elt(elts, i + 1),
-                            get_elt(elts, i + 3));
-        }
-      }
-      else {
-        for (i = 0; i+3 < count; i += 2) {
-           vcache_quad( vcache,
-                         get_elt(elts, i + 2),
-                         get_elt(elts, i + 0),
-                         get_elt(elts, i + 1),
-                         get_elt(elts, i + 3));
-        }
-      }
-      break;
-
-   case PIPE_PRIM_POLYGON:
-      if (unfilled) {
-         /* These bitflags look a little odd because we submit the
-          * vertices as (1,2,0) to satisfy flatshade requirements.  
-          */
-         const unsigned edge_first  = (1<<2);
-         const unsigned edge_middle = (1<<0);
-         const unsigned edge_last   = (1<<1);
-
-        for (i = 0; i+2 < count; i++) {
-            unsigned ef_mask = edge_middle;
-
-            if (i == 0)
-               ef_mask |= edge_first;
-
-            if (i + 3 == count)
-              ef_mask |= edge_last;
-
-           vcache_ef_triangle( vcache,
-                                i == 0,
-                                ef_mask,
-                                get_elt(elts, i + 1),
-                                get_elt(elts, i + 2),
-                                get_elt(elts, 0));
-        }
-      }
-      else {
-        for (i = 0; i+2 < count; i++) {
-           vcache_triangle( vcache,
-                             get_elt(elts, i + 1),
-                             get_elt(elts, i + 2),
-                             get_elt(elts, 0));
-        }
-      }
-      break;
-
-   default:
-      assert(0);
-      break;
-   }
-   
-   vcache_flush( vcache );
-}
 
 
 
@@ -453,15 +225,21 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
                            unsigned opt )
 {
    struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+   const struct pipe_rasterizer_state *rasterizer = vcache->draw->rasterizer;
+
 
-/*
-   if (vcache->draw->rasterizer->flatshade_first)
-      vcache->base.run = vcache_run_pv0;
-   else
-      vcache->base.run = vcache_run_pv2;
-*/ 
+   if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+       rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL ||
+       rasterizer->line_stipple_enable)
+   {
+      assert(opt & PT_PIPELINE);
+      vcache->base.run = vcache_run_extras;
+   }
+   else 
+   {
+      vcache->base.run = vcache_run;
+   }
 
-   vcache->base.run = vcache_run;
    vcache->input_prim = prim;
    vcache->output_prim = reduced_prim[prim];
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
new file mode 100644 (file)
index 0000000..cf9f394
--- /dev/null
@@ -0,0 +1,174 @@
+
+
+static void FUNC( struct draw_pt_front_end *frontend, 
+                  pt_elt_func get_elt,
+                  const void *elts,
+                  unsigned count )
+{
+   struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+   struct draw_context *draw = vcache->draw;
+
+   boolean flatfirst = (draw->rasterizer->flatshade && 
+                        draw->rasterizer->flatshade_first);
+   unsigned i, flags;
+
+
+   switch (vcache->input_prim) {
+   case PIPE_PRIM_POINTS:
+      for (i = 0; i < count; i ++) {
+        POINT( vcache,
+                get_elt(elts, i + 0) );
+      }
+      break;
+
+   case PIPE_PRIM_LINES:
+      for (i = 0; i+1 < count; i += 2) {
+         LINE( vcache, 
+               DRAW_PIPE_RESET_STIPPLE,
+               get_elt(elts, i + 0),
+               get_elt(elts, i + 1));
+      }
+      break;
+
+   case PIPE_PRIM_LINE_LOOP:  
+      if (count >= 2) {
+         flags = DRAW_PIPE_RESET_STIPPLE;
+
+         for (i = 1; i < count; i++, flags = 0) {
+            LINE( vcache, 
+                  flags,
+                  get_elt(elts, i - 1),
+                  get_elt(elts, i ));
+         }
+
+        LINE( vcache, 
+               flags,
+               get_elt(elts, i - 1),
+               get_elt(elts, 0 ));
+      }
+      break;
+
+   case PIPE_PRIM_LINE_STRIP:
+      flags = DRAW_PIPE_RESET_STIPPLE;
+      for (i = 1; i < count; i++, flags = 0) {
+         LINE( vcache, 
+               flags,
+               get_elt(elts, i - 1),
+               get_elt(elts, i ));
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLES:
+      for (i = 0; i+2 < count; i += 3) {
+         TRIANGLE( vcache,
+                   DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, 
+                   get_elt(elts, i + 0),
+                   get_elt(elts, i + 1),
+                   get_elt(elts, i + 2 ));
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      if (flatfirst) {
+         for (i = 0; i+2 < count; i++) {
+            TRIANGLE( vcache,
+                      DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, 
+                      get_elt(elts, i + 0),
+                      get_elt(elts, i + 1 + (i&1)),
+                      get_elt(elts, i + 2 - (i&1)));
+         }
+      }
+      else {
+         for (i = 0; i+2 < count; i++) {
+            TRIANGLE( vcache,
+                      DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, 
+                      get_elt(elts, i + 0 + (i&1)),
+                      get_elt(elts, i + 1 - (i&1)),
+                      get_elt(elts, i + 2 ));
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      if (count >= 3) {
+         if (flatfirst) {
+            for (i = 0; i+2 < count; i++) {
+               TRIANGLE( vcache,
+                         DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, 
+                         get_elt(elts, i + 1),
+                         get_elt(elts, i + 2),
+                         get_elt(elts, 0 ));
+            }
+         }
+         else {
+            for (i = 0; i+2 < count; i++) {
+               TRIANGLE( vcache,
+                         DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, 
+                         get_elt(elts, 0),
+                         get_elt(elts, i + 1),
+                         get_elt(elts, i + 2 ));
+            }
+         }
+      }
+      break;
+
+
+   case PIPE_PRIM_QUADS:
+      for (i = 0; i+3 < count; i += 4) {
+         QUAD( vcache,
+               get_elt(elts, i + 0),
+               get_elt(elts, i + 1),
+               get_elt(elts, i + 2),
+               get_elt(elts, i + 3));
+      }
+      break;
+
+   case PIPE_PRIM_QUAD_STRIP:
+      for (i = 0; i+3 < count; i += 2) {
+         QUAD( vcache,
+               get_elt(elts, i + 2),
+               get_elt(elts, i + 0),
+               get_elt(elts, i + 1),
+               get_elt(elts, i + 3));
+      }
+      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) {
+
+            if (i + 3 == count)
+               flags |= edge_last;
+
+           TRIANGLE( vcache,
+                      flags,
+                      get_elt(elts, i + 1),
+                      get_elt(elts, i + 2),
+                      get_elt(elts, 0));
+        }
+      }
+      break;
+
+   default:
+      assert(0);
+      break;
+   }
+   
+   vcache_flush( vcache );
+}
+
+
+#undef TRIANGLE
+#undef QUAD
+#undef POINT
+#undef LINE
+#undef FUNC