[Mesa-dev] [PATCH 3/3] draw: make sure viewport index is fetched from leading vertex

Zack Rusin zackr at vmware.com
Fri May 24 23:12:29 PDT 2013


Viewport index should only be used on a per primitive basis, so
instead of fetching it from each vertex, potentially making each
vertex in a primitive use a different viewport index, which is
obviously broken, make sure that we only fetch from the first
vertex in the primitive making the viewport index the same
for the entire primtive.

Signed-off-by: Zack Rusin <zackr at vmware.com>
---
 src/gallium/auxiliary/draw/draw_cliptest_tmp.h     |   25 ++++++++----
 src/gallium/auxiliary/draw/draw_pipe_clip.c        |   40 +++++++++++++-------
 src/gallium/auxiliary/draw/draw_pt.h               |    3 +-
 .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c  |    2 +-
 .../draw/draw_pt_fetch_shade_pipeline_llvm.c       |    2 +-
 src/gallium/auxiliary/draw/draw_pt_post_vs.c       |    9 +++--
 6 files changed, 53 insertions(+), 28 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index 6e4a247..2f2b88e 100644
--- a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
@@ -26,7 +26,8 @@
  **************************************************************************/
 
 static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
-                                 struct draw_vertex_info *info )
+                                 struct draw_vertex_info *info,
+                                 const struct draw_prim_info *prim_info )
 {
    struct vertex_header *out = info->verts;
    /* const */ float (*plane)[4] = pvs->draw->plane;
@@ -42,6 +43,9 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
    bool have_cd = false;
    unsigned viewport_index_output =
       draw_current_shader_viewport_index_output(pvs->draw);
+   int viewport_index = 
+      draw_current_shader_uses_viewport_index(pvs->draw) ?
+      *((unsigned*)out->data[viewport_index_output]): 0;
       
    cd[0] = draw_current_shader_clipdistance_output(pvs->draw, 0);
    cd[1] = draw_current_shader_clipdistance_output(pvs->draw, 1);
@@ -51,14 +55,19 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
 
    for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
-      int viewport_index = 
-         draw_current_shader_uses_viewport_index(pvs->draw) ?
-         *((unsigned*)out->data[viewport_index_output]): 0;
       unsigned mask = 0x0;
-      const float *scale = pvs->draw->viewports[
-         DRAW_CLAMP_VIEWPORT_IDX(viewport_index) ].scale;
-      const float *trans = pvs->draw->viewports[
-         DRAW_CLAMP_VIEWPORT_IDX(viewport_index)].translate;
+      float *scale = pvs->draw->viewports[0].scale;
+      float *trans = pvs->draw->viewports[0].translate;
+      if (draw_current_shader_uses_viewport_index(pvs->draw)) {
+         unsigned verts_per_prim = u_vertices_per_prim(prim_info->prim);
+         /* only change the viewport_index for the leading vertex */
+         if (!(j % verts_per_prim)) {
+            viewport_index = *((unsigned*)out->data[viewport_index_output]);
+            viewport_index = DRAW_CLAMP_VIEWPORT_IDX(viewport_index);
+         }
+         scale = pvs->draw->viewports[viewport_index].scale;
+         trans = pvs->draw->viewports[viewport_index].translate;
+      }
   
       initialize_vertex_header(out);
 
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index 3b82be9..ff11e36 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -118,15 +118,14 @@ static void interp( const struct clip_stage *clip,
 		    struct vertex_header *dst,
 		    float t,
 		    const struct vertex_header *out, 
-		    const struct vertex_header *in )
+		    const struct vertex_header *in,
+                    unsigned viewport_index )
 {
    const unsigned nr_attrs = draw_current_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;
    float t_nopersp;
-   unsigned viewport_index_output =
-      draw_current_shader_viewport_index_output(clip->stage.draw);
 
    /* Vertex header.
     */
@@ -145,16 +144,11 @@ static void interp( const struct clip_stage *clip,
     * new window coordinates:
     */
    {
-      int viewport_index = 
-         draw_current_shader_uses_viewport_index(clip->stage.draw) ?
-         *((unsigned*)in->data[viewport_index_output]) : 0;
       const float *pos = dst->pre_clip_pos;
       const float *scale =
-         clip->stage.draw->viewports[
-            DRAW_CLAMP_VIEWPORT_IDX(viewport_index)].scale;
+         clip->stage.draw->viewports[viewport_index].scale;
       const float *trans =
-         clip->stage.draw->viewports[
-            DRAW_CLAMP_VIEWPORT_IDX(viewport_index)].translate;
+         clip->stage.draw->viewports[viewport_index].translate;
       const float oow = 1.0f / pos[3];
 
       dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
@@ -332,11 +326,20 @@ do_clip_tri( struct draw_stage *stage,
    boolean bEdges[MAX_CLIPPED_VERTICES];
    boolean *inEdges = aEdges;
    boolean *outEdges = bEdges;
+   unsigned viewport_index_output =
+      draw_current_shader_viewport_index_output(clipper->stage.draw);
+   int viewport_index = 0;
 
    inlist[0] = header->v[0];
    inlist[1] = header->v[1];
    inlist[2] = header->v[2];
 
+   if (draw_current_shader_uses_viewport_index(clipper->stage.draw)) {
+      const struct vertex_header *leading_vertex = inlist[0];
+      viewport_index = *((unsigned*)leading_vertex->data[viewport_index_output]);
+      viewport_index = DRAW_CLAMP_VIEWPORT_IDX(viewport_index);
+   }
+
    if (DEBUG_CLIP) {
       const float *v0 = header->v[0]->clip;
       const float *v1 = header->v[1]->clip;
@@ -411,7 +414,7 @@ do_clip_tri( struct draw_stage *stage,
 		* know dp != dp_prev from DIFFERENT_SIGNS, above.
 		*/
 	       float t = dp / (dp - dp_prev);
-	       interp( clipper, new_vert, t, vert, vert_prev );
+	       interp( clipper, new_vert, t, vert, vert_prev, viewport_index );
 	       
 	       /* Whether or not to set edge flag for the new vert depends
                 * on whether it's a user-defined clipping plane.  We're
@@ -432,7 +435,7 @@ do_clip_tri( struct draw_stage *stage,
 	       /* Coming back in.
 		*/
 	       float t = dp_prev / (dp_prev - dp);
-	       interp( clipper, new_vert, t, vert_prev, vert );
+	       interp( clipper, new_vert, t, vert_prev, vert, viewport_index );
 
 	       /* Copy starting vert's edgeflag:
 		*/
@@ -505,6 +508,15 @@ do_clip_line( struct draw_stage *stage,
    float t0 = 0.0F;
    float t1 = 0.0F;
    struct prim_header newprim;
+   unsigned viewport_index_output =
+      draw_current_shader_viewport_index_output(clipper->stage.draw);
+   int viewport_index = 0;
+
+   if (draw_current_shader_uses_viewport_index(clipper->stage.draw)) {
+      const struct vertex_header *leading_vertex = v0;
+      viewport_index = *((unsigned*)leading_vertex->data[viewport_index_output]);
+      viewport_index = DRAW_CLAMP_VIEWPORT_IDX(viewport_index);
+   }
 
    while (clipmask) {
       const unsigned plane_idx = ffs(clipmask)-1;
@@ -528,7 +540,7 @@ do_clip_line( struct draw_stage *stage,
    }
 
    if (v0->clipmask) {
-      interp( clipper, stage->tmp[0], t0, v0, v1 );
+      interp( clipper, stage->tmp[0], t0, v0, v1, viewport_index );
       copy_flat(stage, stage->tmp[0], v0);
       newprim.v[0] = stage->tmp[0];
    }
@@ -537,7 +549,7 @@ do_clip_line( struct draw_stage *stage,
    }
 
    if (v1->clipmask) {
-      interp( clipper, stage->tmp[1], t1, v1, v0 );
+      interp( clipper, stage->tmp[1], t1, v1, v0, viewport_index );
       newprim.v[1] = stage->tmp[1];
    }
    else {
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index dca8368..29e5499 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -225,7 +225,8 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw );
 struct pt_post_vs;
 
 boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
-			     struct draw_vertex_info *info );
+			     struct draw_vertex_info *info,
+                             const struct draw_prim_info *prim_info );
 
 void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean clip_xy,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index ea2a5d6..6d1bd11 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -323,7 +323,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
     */
    if (draw_current_shader_position_output(draw) != -1) {
 
-      if (draw_pt_post_vs_run( fpme->post_vs, vert_info ))
+      if (draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info ))
       {
          opt |= PT_PIPELINE;
       }
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 5d2993e..ecb7a6b 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -417,7 +417,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
     */
    if (draw_current_shader_position_output(draw) != -1) {
       if ((opt & PT_SHADE) && gshader) {
-         clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info );
+         clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info );
       }
       if (clipped) {
          opt |= PT_PIPELINE;
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 0212656..d717d05 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -27,6 +27,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_prim.h"
 #include "pipe/p_context.h"
 #include "draw/draw_context.h"
 #include "draw/draw_private.h"
@@ -48,7 +49,8 @@ struct pt_post_vs {
    unsigned flags;
 
    boolean (*run)( struct pt_post_vs *pvs,
-                   struct draw_vertex_info *info );
+                   struct draw_vertex_info *info,
+                   const struct draw_prim_info *prim_info );
 };
 
 static INLINE void
@@ -115,9 +117,10 @@ dot4(const float *a, const float *b)
 
 
 boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
-			     struct draw_vertex_info *info )
+			     struct draw_vertex_info *info,
+                             const struct draw_prim_info *prim_info )
 {
-   return pvs->run( pvs, info );
+   return pvs->run( pvs, info, prim_info );
 }
 
 
-- 
1.7.10.4


More information about the mesa-dev mailing list