gallium: Handle client-supplied edgeflags.
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 4 Apr 2008 16:02:20 +0000 (17:02 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 4 Apr 2008 16:05:27 +0000 (17:05 +0100)
Also, implement support in the draw module.  We were hardwiring these
to one for quite a long time...

Currently using a draw_set_edgeflags() function, may be better to push
the argument into the draw_arrays() function.  TBD.

src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
src/gallium/auxiliary/draw/draw_pt_pipeline.c
src/gallium/auxiliary/draw/draw_vertex_cache.c
src/gallium/include/pipe/p_context.h

index 470c1c5..b3c65c9 100644 (file)
@@ -444,3 +444,19 @@ void draw_set_render( struct draw_context *draw,
 {
    draw->render = render;
 }
+
+void draw_set_edgeflags( struct draw_context *draw,
+                         const unsigned *edgeflag )
+{
+   draw->user.edgeflag = edgeflag;
+}
+
+
+boolean draw_get_edgeflag( struct draw_context *draw,
+                           unsigned idx )
+{
+   if (draw->user.edgeflag)
+      return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
+   else
+      return 1;
+}
index 84bae3b..c7ac32b 100644 (file)
@@ -155,6 +155,9 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw,
 void draw_set_mapped_constant_buffer(struct draw_context *draw,
                                      const void *buffer);
 
+void draw_set_edgeflags( struct draw_context *draw,
+                         const unsigned *edgeflag );
+
 
 /***********************************************************************
  * draw_prim.c 
index 48545af..4d056f6 100644 (file)
@@ -250,6 +250,8 @@ struct draw_context
 
    /* user-space vertex data, buffers */
    struct {
+      const unsigned *edgeflag;
+
       /** vertex element/index buffer (ex: glDrawElements) */
       const void *elts;
       /** bytes per index (0, 1, 2 or 4) */
@@ -402,15 +404,6 @@ void draw_pt_run_pipeline( struct draw_context *draw,
                            unsigned count );
 
 
-/* Prototype/hack (DEPRECATED)
- */
-boolean
-draw_passthrough_arrays(struct draw_context *draw, 
-                        unsigned prim,
-                        unsigned start, 
-                        unsigned count);
-
-
 #define DRAW_FLUSH_SHADER_QUEUE              0x1 /* sized not to overflow, never raised */
 #define DRAW_FLUSH_PRIM_QUEUE                0x2
 #define DRAW_FLUSH_VERTEX_CACHE              0x4
@@ -420,6 +413,8 @@ draw_passthrough_arrays(struct draw_context *draw,
 
 void draw_do_flush( struct draw_context *draw, unsigned flags );
 
+boolean draw_get_edgeflag( struct draw_context *draw,
+                           unsigned idx );
 
 
 /**
index 0ddb400..ba95420 100644 (file)
@@ -72,6 +72,8 @@ struct fetch_pipeline_middle_end {
    struct draw_pt_middle_end base;
    struct draw_context *draw;
 
+   void (*header)( const unsigned *edgeflag, unsigned count, float **out);
+
    struct {
       const ubyte *ptr;
       unsigned pitch;
@@ -85,12 +87,6 @@ struct fetch_pipeline_middle_end {
 };
 
 
-static void fetch_NULL( const void *from,
-                        float *attrib )
-{
-}
-
-
 
 static void emit_R32_FLOAT( const float *attrib,
                             float **out )
@@ -126,8 +122,9 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib,
    (*out) += 4;
 }
 
-static void emit_header( const float *attrib,
-                         float **out )
+static void header( const unsigned *edgeflag,
+                    unsigned idx,
+                    float **out )
 {
    struct vertex_header *header = (struct vertex_header *) (*out);
 
@@ -143,6 +140,26 @@ static void emit_header( const float *attrib,
    (*out) += 5;
 }
 
+
+static void header_ef( const unsigned *edgeflag,
+                       unsigned idx,
+                       float **out )
+{
+   struct vertex_header *header = (struct vertex_header *) (*out);
+
+   header->clipmask = 0;
+   header->edgeflag = (edgeflag[idx/32] & (1 << (idx%32))) != 0;
+   header->pad = 0;
+   header->vertex_id = UNDEFINED_VERTEX_ID;
+
+   (*out)[1] = 0;
+   (*out)[2] = 0;
+   (*out)[3] = 0;
+   (*out)[3] = 1;
+   (*out) += 5;
+}
+
+
 /**
  * General-purpose fetch from user's vertex arrays, emit to driver's
  * vertex buffer.
@@ -155,12 +172,15 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme,
                      const unsigned *fetch_elts,
                      unsigned count )
 {
+   const unsigned *edgeflag = fpme->draw->user.edgeflag;
    float *out = (float *)out_ptr;
    uint i, j;
 
    for (i = 0; i < count; i++) {
       unsigned elt = fetch_elts[i];
       
+      fpme->header( edgeflag, i, &out );
+
       for (j = 0; j < fpme->nr_fetch; j++) {
          float attrib[4];
          const ubyte *from = (fpme->fetch[j].ptr +
@@ -200,12 +220,11 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
 
    /* Emit the vertex header and empty clipspace coord field:
     */
-   {
-      fpme->fetch[nr].ptr = NULL;
-      fpme->fetch[nr].pitch = 0;
-      fpme->fetch[nr].fetch = fetch_NULL;
-      fpme->fetch[nr].emit = emit_header;
-      nr++;
+   if (draw->user.edgeflag) {
+      fpme->header = header_ef;
+   }
+   else {
+      fpme->header = header;
    }
    
 
@@ -232,7 +251,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
    }
 
    fpme->nr_fetch = nr;
-   fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float);
+   fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
 }
 
 
index 6e46d39..942df51 100644 (file)
@@ -86,12 +86,14 @@ static void do_triangle( struct draw_context *draw,
    struct prim_header prim;
    
 //   _mesa_printf("tri %d %d %d\n", i0, i1, i2);
-   prim.reset_line_stipple = 1;
-   prim.edgeflags = ~0;
-   prim.pad = 0;
    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.pad = 0;
 
    draw->pipeline.first->tri( draw->pipeline.first, &prim );
 }
index 161b247..c024897 100644 (file)
@@ -101,7 +101,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw,
 
       draw->vs.queue[out].elt = i;
       draw->vs.queue[out].vertex->clipmask = 0;
-      draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */
+      draw->vs.queue[out].vertex->edgeflag = draw_get_edgeflag(draw, i);
       draw->vs.queue[out].vertex->pad = 0;
       draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID;
 
index 324f701..f3a9c2c 100644 (file)
@@ -57,6 +57,14 @@ struct pipe_context {
 
    void (*destroy)( struct pipe_context * );
 
+   
+   /* Possible interface for setting edgeflags.  These aren't really
+    * vertex elements, so don't fit there.
+    */
+   void (*set_edgeflags)( struct pipe_context *,
+                          const unsigned *bitfield );
+
+
    /**
     * VBO drawing (return false on fallbacks (temporary??))
     */