[Mesa-dev] [PATCH 4/8] draw: make sure clipping works with injected outputs

Zack Rusin zackr at vmware.com
Thu Aug 1 23:28:16 PDT 2013


clipping would drop the extra outputs because it always
used the number of standard vertex shader outputs, without
geometry shader or extra outputs. The commit makes sure
that clipping with geometry shaders which have more outputs
than the current vertex shader and with extra outputs correctly
propagates the entire vertex.

Signed-off-by: Zack Rusin <zackr at vmware.com>
---
 src/gallium/auxiliary/draw/draw_pipe_clip.c |   89 ++++++++++++++++-----------
 1 file changed, 54 insertions(+), 35 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index e83586e..b76e9a5 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -136,7 +136,7 @@ static void interp( const struct clip_stage *clip,
 		    const struct vertex_header *in,
                     unsigned viewport_index )
 {
-   const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
+   const unsigned nr_attrs = draw_num_shader_outputs(clip->stage.draw);
    const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
    const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
    unsigned j;
@@ -264,7 +264,6 @@ static void emit_poly( struct draw_stage *stage,
          header.flags |= edge_last;
 
       if (DEBUG_CLIP) {
-         const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
          uint j, k;
          debug_printf("Clipped tri: (flat-shade-first = %d)\n",
                       stage->draw->rasterizer->flatshade_first);
@@ -274,7 +273,7 @@ static void emit_poly( struct draw_stage *stage,
                          header.v[j]->clip[1],
                          header.v[j]->clip[2],
                          header.v[j]->clip[3]);
-            for (k = 0; k < vs->info.num_outputs; k++) {
+            for (k = 0; k < draw_num_shader_outputs(stage->draw); 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],
@@ -283,7 +282,6 @@ static void emit_poly( struct draw_stage *stage,
             }
          }
       }
-
       stage->next->tri( stage->next, &header );
    }
 }
@@ -609,6 +607,35 @@ clip_tri( struct draw_stage *stage,
 }
 
 
+static int
+find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
+            uint semantic_name, uint semantic_index)
+{
+   int interp;
+   /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
+    * from the array we've filled before. */
+   if (semantic_name == TGSI_SEMANTIC_COLOR ||
+       semantic_name == TGSI_SEMANTIC_BCOLOR) {
+      interp = indexed_interp[semantic_index];
+   } else {
+      /* Otherwise, search in the FS inputs, with a decent default
+       * if we don't find it.
+       */
+      uint j;
+      interp = TGSI_INTERPOLATE_PERSPECTIVE;
+      if (fs) {
+         for (j = 0; j < fs->info.num_inputs; j++) {
+            if (semantic_name == fs->info.input_semantic_name[j] &&
+                semantic_index == fs->info.input_semantic_index[j]) {
+               interp = fs->info.input_interpolate[j];
+               break;
+            }
+         }
+      }
+   }
+   return interp;
+}
+
 /* Update state.  Could further delay this until we hit the first
  * primitive that really requires clipping.
  */
@@ -616,11 +643,9 @@ static void
 clip_init_state( struct draw_stage *stage )
 {
    struct clip_stage *clipper = clip_stage( stage );
-   const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
-   const struct draw_geometry_shader *gs = stage->draw->gs.geometry_shader;
    const struct draw_fragment_shader *fs = stage->draw->fs.fragment_shader;
-   uint i;
-   const struct tgsi_shader_info *vs_info = gs ? &gs->info : &vs->info;
+   uint i, j;
+   const struct tgsi_shader_info *info = draw_get_shader_info(stage->draw);
 
    /* We need to know for each attribute what kind of interpolation is
     * done on it (flat, smooth or noperspective).  But the information
@@ -663,42 +688,36 @@ clip_init_state( struct draw_stage *stage )
 
    clipper->num_flat_attribs = 0;
    memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs));
-   for (i = 0; i < vs_info->num_outputs; i++) {
-      /* Find the interpolation mode for a specific attribute
-       */
-      int interp;
-
-      /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
-       * from the array we've filled before. */
-      if (vs_info->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
-          vs_info->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         interp = indexed_interp[vs_info->output_semantic_index[i]];
-      } else {
-         /* Otherwise, search in the FS inputs, with a decent default
-          * if we don't find it.
-          */
-         uint j;
-         interp = TGSI_INTERPOLATE_PERSPECTIVE;
-         if (fs) {
-            for (j = 0; j < fs->info.num_inputs; j++) {
-               if (vs_info->output_semantic_name[i] == fs->info.input_semantic_name[j] &&
-                   vs_info->output_semantic_index[i] == fs->info.input_semantic_index[j]) {
-                  interp = fs->info.input_interpolate[j];
-                  break;
-               }
-            }
-         }
-      }
-
+   for (i = 0; i < info->num_outputs; i++) {
+      /* Find the interpolation mode for a specific attribute */
+      int interp = find_interp(fs, indexed_interp,
+                               info->output_semantic_name[i],
+                               info->output_semantic_index[i]);
       /* If it's flat, add it to the flat vector.  Otherwise update
        * the noperspective mask.
        */
+
       if (interp == TGSI_INTERPOLATE_CONSTANT) {
          clipper->flat_attribs[clipper->num_flat_attribs] = i;
          clipper->num_flat_attribs++;
       } else
          clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR;
    }
+   /* Search the extra vertex attributes */
+   for (j = 0; j < stage->draw->extra_shader_outputs.num; j++) {
+      /* Find the interpolation mode for a specific attribute */
+      int interp = find_interp(fs, indexed_interp,
+                               stage->draw->extra_shader_outputs.semantic_name[j],
+                               stage->draw->extra_shader_outputs.semantic_index[j]);
+      /* If it's flat, add it to the flat vector.  Otherwise update
+       * the noperspective mask.
+       */
+      if (interp == TGSI_INTERPOLATE_CONSTANT) {
+         clipper->flat_attribs[clipper->num_flat_attribs] = i + j;
+         clipper->num_flat_attribs++;
+      } else
+         clipper->noperspective_attribs[i + j] = interp == TGSI_INTERPOLATE_LINEAR;
+   }
    
    stage->tri = clip_tri;
    stage->line = clip_line;
-- 
1.7.10.4


More information about the mesa-dev mailing list