Mesa (master): draw: make sure viewport index is fetched from leading vertex

Zack Rusin zack at kemper.freedesktop.org
Wed May 29 22:08:54 UTC 2013


Module: Mesa
Branch: master
Commit: c08baef508a109cdd49d2ebbc2cd0a8cc94117d3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c08baef508a109cdd49d2ebbc2cd0a8cc94117d3

Author: Zack Rusin <zackr at vmware.com>
Date:   Sat May 25 01:46:16 2013 -0400

draw: make sure viewport index is fetched from leading vertex

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>
Reviewed-by: José Fonseca<jfonseca at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/gallium/auxiliary/draw/draw_cliptest_tmp.h     |   25 ++++++++----
 src/gallium/auxiliary/draw/draw_pipe_clip.c        |   41 +++++++++++++-------
 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, 54 insertions(+), 28 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_cliptest_tmp.h b/src/gallium/auxiliary/draw/draw_cliptest_tmp.h
index d316b77..7351559 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 aacda15..e83586e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -79,6 +79,21 @@ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
    return (struct clip_stage *)stage;
 }
 
+static INLINE unsigned
+draw_viewport_index(struct draw_context *draw,
+                    const struct vertex_header *leading_vertex)
+{
+   if (draw_current_shader_uses_viewport_index(draw)) {
+      unsigned viewport_index_output =
+         draw_current_shader_viewport_index_output(draw);
+      unsigned viewport_index =
+         *((unsigned*)leading_vertex->data[viewport_index_output]);
+      return draw_clamp_viewport_idx(viewport_index);
+   } else {
+      return 0;
+   }
+}
+
 
 #define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
 
@@ -118,15 +133,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 +159,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 +341,14 @@ do_clip_tri( struct draw_stage *stage,
    boolean bEdges[MAX_CLIPPED_VERTICES];
    boolean *inEdges = aEdges;
    boolean *outEdges = bEdges;
+   int viewport_index = 0;
 
    inlist[0] = header->v[0];
    inlist[1] = header->v[1];
    inlist[2] = header->v[2];
 
+   viewport_index = draw_viewport_index(clipper->stage.draw, inlist[0]);
+
    if (DEBUG_CLIP) {
       const float *v0 = header->v[0]->clip;
       const float *v1 = header->v[1]->clip;
@@ -411,7 +423,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 +444,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 +517,7 @@ do_clip_line( struct draw_stage *stage,
    float t0 = 0.0F;
    float t1 = 0.0F;
    struct prim_header newprim;
+   int viewport_index = draw_viewport_index(clipper->stage.draw, v0);
 
    while (clipmask) {
       const unsigned plane_idx = ffs(clipmask)-1;
@@ -528,7 +541,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 +550,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 );
 }
 
 




More information about the mesa-commit mailing list