Remove dependency on TGSI_ATTRIB_x tokens in draw_twoside.c
authorBrian <brian.paul@tungstengraphics.com>
Thu, 30 Aug 2007 22:37:56 +0000 (16:37 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 30 Aug 2007 22:37:56 +0000 (16:37 -0600)
Added a new draw_set_twoside_attributes() function for specifying which
vertex attributes are to be copied/replaced when a polygon is back-facing.

src/mesa/pipe/draw/draw_context.c
src/mesa/pipe/draw/draw_context.h
src/mesa/pipe/draw/draw_private.h
src/mesa/pipe/draw/draw_twoside.c
src/mesa/pipe/i915simple/i915_state_derived.c
src/mesa/pipe/softpipe/sp_state_derived.c

index b14de34..c15f765 100644 (file)
@@ -67,6 +67,11 @@ struct draw_context *draw_create( void )
         draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * MAX_VERTEX_SIZE);
    }
 
+   draw->attrib_front0 = -1;
+   draw->attrib_back0 = -1;
+   draw->attrib_front1 = -1;
+   draw->attrib_back1 = -1;
+
    return draw;
 }
 
@@ -210,3 +215,39 @@ draw_set_vertex_shader(struct draw_context *draw,
 {
    draw->vertex_shader = *shader;
 }
+
+
+/**
+ * This function is used to tell the draw module about attributes
+ * (like colors) that need to be selected based on front/back face
+ * orientation.
+ *
+ * The logic is:
+ *    if (polygon is back-facing) {
+ *       vertex->attrib[front0] = vertex->attrib[back0];
+ *       vertex->attrib[front1] = vertex->attrib[back1];
+ *    }
+ *
+ * \param front0  first attrib to replace if the polygon is back-facing
+ * \param back0  first attrib to copy if the polygon is back-facing
+ * \param front1  second attrib to replace if the polygon is back-facing
+ * \param back1  second attrib to copy if the polygon is back-facing
+ *
+ * Pass -1 to disable two-sided attributes.
+ */
+void
+draw_set_twoside_attributes(struct draw_context *draw,
+                            uint front0, uint back0,
+                            uint front1, uint back1)
+{
+   /* XXX we could alternately pass an array of front/back attribs if there's
+    * ever need for more than two.  One could imagine a shader extension
+    * that allows arbitrary attributes to be selected based on polygon
+    * orientation...
+    */
+   draw->attrib_front0 = front0;
+   draw->attrib_back0 = back0;
+   draw->attrib_front1 = front1;
+   draw->attrib_back1 = back1;
+}
+
index 4c9e64a..21ee18e 100644 (file)
@@ -92,6 +92,10 @@ void draw_set_vertex_attributes( struct draw_context *draw,
                                 const uint *attrs, const uint *interp_mode,
                                 unsigned nr_attrs );
 
+void draw_set_twoside_attributes(struct draw_context *draw,
+                                 uint front0, uint back0,
+                                 uint front1, uint back1);
+
 unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr );
 
 unsigned draw_trim( unsigned count, unsigned first, unsigned incr );
index e61f228..80c97ad 100644 (file)
@@ -158,6 +158,9 @@ struct draw_context
 
    /** Describes the layout of post-transformation vertices */
    struct vertex_info vertex_info;
+   /** Two-sided attributes: */
+   uint attrib_front0, attrib_back0;
+   uint attrib_front1, attrib_back1;
 
    unsigned nr_vertices;
 
index a05eea4..98eb088 100644 (file)
@@ -61,15 +61,11 @@ static void twoside_begin( struct draw_stage *stage )
 }
 
 
-static INLINE void copy_color( unsigned attr_dst,
+static INLINE void copy_attrib( unsigned attr_dst,
                               unsigned attr_src,
                               struct vertex_header *v )
 {
-   if (attr_dst && attr_src) {
-      memcpy( v->data[attr_dst],
-             v->data[attr_src],
-             sizeof(v->data[0]) );
-   }
+   COPY_4FV(v->data[attr_dst], v->data[attr_src]);
 }
 
 
@@ -78,14 +74,16 @@ static struct vertex_header *copy_bfc( struct twoside_stage *twoside,
                                       unsigned idx )
 {   
    struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
+   const struct draw_context *draw = twoside->stage.draw;
    
-   copy_color( twoside->lookup[TGSI_ATTRIB_COLOR0], 
-              twoside->lookup[TGSI_ATTRIB_BFC0],
-              tmp );
-
-   copy_color( twoside->lookup[TGSI_ATTRIB_COLOR1], 
-              twoside->lookup[TGSI_ATTRIB_BFC1],
-              tmp );
+   if (draw->attrib_front0) {
+      assert(draw->attrib_back0);
+      copy_attrib(draw->attrib_front0, draw->attrib_back0, tmp);
+   }
+   if (draw->attrib_front1) {
+      assert(draw->attrib_back1);
+      copy_attrib(draw->attrib_front1, draw->attrib_back1, tmp);
+   }
 
    return tmp;
 }
@@ -104,7 +102,7 @@ static void twoside_tri( struct draw_stage *stage,
 
       tmp.det = header->det;
       tmp.edgeflags = header->edgeflags;
-      /* copy back colors to front color slots */
+      /* 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);
       tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
index e156766..4b97223 100644 (file)
@@ -35,8 +35,9 @@
 #include "i915_fpc.h"
 
 
-static INLINE void
-emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint interp)
+static INLINE uint
+emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format,
+                 uint interp)
 {
    const uint n = vinfo->num_attribs;
    vinfo->attr_mask |= (1 << vfAttr);
@@ -44,6 +45,7 @@ emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format, uint inter
    vinfo->format[n] = format;
    vinfo->interp_mode[n] = interp;
    vinfo->num_attribs++;
+   return n;
 }
 
 
@@ -93,6 +95,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
    const uint colorInterp
       = i915->setup.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
    struct vertex_info *vinfo = &i915->current.vertex_info;
+   uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
    boolean needW = 0;
 
    memset(vinfo, 0, sizeof(*vinfo));
@@ -103,14 +106,16 @@ static void calculate_vertex_layout( struct i915_context *i915 )
 
    /* color0 */
    if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
-      emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, FORMAT_4UB, colorInterp);
+      front0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0,
+                                FORMAT_4UB, colorInterp);
       vinfo->hwfmt[0] |= S4_VFMT_COLOR;
    }
 
    /* color 1 */
    if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) {
       assert(0); /* untested */
-      emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, FORMAT_4UB, colorInterp);
+      front1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1,
+                                FORMAT_4UB, colorInterp);
       vinfo->hwfmt[0] |= S4_VFMT_SPEC_FOG;
    }
 
@@ -149,10 +154,12 @@ static void calculate_vertex_layout( struct i915_context *i915 )
     */
    if (i915->setup.light_twoside) {
       if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
-         emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, FORMAT_OMIT, colorInterp);
+         back0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0,
+                                  FORMAT_OMIT, colorInterp);
       }            
       if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) {
-         emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, FORMAT_OMIT, colorInterp);
+         back1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1,
+                                  FORMAT_OMIT, colorInterp);
       }
    }
 
@@ -166,6 +173,9 @@ static void calculate_vertex_layout( struct i915_context *i915 )
                                vinfo->interp_mode,
                               vinfo->num_attribs);
 
+   draw_set_twoside_attributes(i915->draw,
+                               front0, back0, front1, back1);
+
    /* Need to set this flag so that the LIS2/4 registers get set.
     * It also means the i915_update_immediate() function must be called
     * after this one, in i915_update_derived().
index ff0a275..41b7340 100644 (file)
 
 
 
-static void
+/**
+ * Add another attribute to the given vertex_info object.
+ * \return slot in which the attribute was added
+ */
+static uint
 emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format,
                  uint interp)
 {
    const uint n = vinfo->num_attribs;
    vinfo->attr_mask |= (1 << vfAttr);
    vinfo->slot_to_attrib[n] = vfAttr;
-   vinfo->interp_mode[n] = interp;
    vinfo->format[n] = format;
+   vinfo->interp_mode[n] = interp;
    vinfo->num_attribs++;
+   return n;
 }
 
 
@@ -62,6 +67,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
    const uint colorInterp
       = softpipe->setup.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
    struct vertex_info *vinfo = &softpipe->vertex_info;
+   uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
    uint i;
 
    memset(vinfo, 0, sizeof(*vinfo));
@@ -89,12 +95,14 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
  
    /* color0 */
    if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
-      emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0, FORMAT_4F, colorInterp);
+      front0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR0,
+                                FORMAT_4F, colorInterp);
    }
 
    /* color1 */
    if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) {
-      emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1, FORMAT_4F, colorInterp);
+      front1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_COLOR1,
+                                FORMAT_4F, colorInterp);
    }
 
    /* fog */
@@ -124,11 +132,13 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
     */
    if (softpipe->setup.light_twoside) {
       if (inputsRead & (1 << TGSI_ATTRIB_COLOR0)) {
-         emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0, FORMAT_OMIT, INTERP_LINEAR);
+         back0 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC0,
+                                  FORMAT_OMIT, colorInterp);
       }
            
       if (inputsRead & (1 << TGSI_ATTRIB_COLOR1)) {
-         emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1, FORMAT_OMIT, INTERP_LINEAR);
+         back1 = emit_vertex_attr(vinfo, TGSI_ATTRIB_BFC1,
+                                  FORMAT_OMIT, colorInterp);
       }
    }
 
@@ -143,6 +153,9 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
                                   vinfo->slot_to_attrib,
                                   vinfo->interp_mode,
                                   vinfo->num_attribs);
+
+      draw_set_twoside_attributes(softpipe->draw,
+                                  front0, back0, front1, back1);
    }
 }