draw: make sure viewport index is fetched from leading vertex
authorZack Rusin <zackr@vmware.com>
Sat, 25 May 2013 05:46:16 +0000 (01:46 -0400)
committerZack Rusin <zackr@vmware.com>
Sat, 25 May 2013 13:49:20 +0000 (09:49 -0400)
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@vmware.com>
Reviewed-by: José Fonseca<jfonseca@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/draw/draw_cliptest_tmp.h
src/gallium/auxiliary/draw/draw_pipe_clip.c
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
src/gallium/auxiliary/draw/draw_pt_post_vs.c

index d316b777154bfe4b292d098218d29ae7e799c0e0..7351559810d1008f82fb3d181cbfc1691ab19909 100644 (file)
@@ -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);
 
index aacda15f46679c6a253998b7e63bfcf0ec7a5c70..e83586eedf263d8d3494b81c9dd34b485bb8e5e0 100644 (file)
@@ -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 {
index dca836859cc258b0acbfffb466e5422b6b49de9b..29e5499f383eec0eeb1184c6efb759394b8b44ec 100644 (file)
@@ -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,
index ea2a5d68e39f043654d82ec0071e7acca49d3a11..6d1bd116ba7d01c18b4c9d4cd85bdafb88183a83 100644 (file)
@@ -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;
       }
index 5d2993eaa1738c95c858691741c2cf37d42d05f8..ecb7a6b8f759f75f49e5bc5c7e820ee1ef0881d7 100644 (file)
@@ -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;
index 021265633f764239eefad91da820253efe9cb53c..d717d05d88e7035fb8fdf202917fc72abbd10a66 100644 (file)
@@ -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 );
 }