Mesa (master): draw: fixes for vertex shaders outputting layer or viewport index

Roland Scheidegger sroland at kemper.freedesktop.org
Wed Nov 19 17:35:54 UTC 2014


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

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Tue Nov 18 22:46:00 2014 +0100

draw: fixes for vertex shaders outputting layer or viewport index

Mostly add a couple cases so we don't just check gs for this.
There's only one gotcha, the built-in vp transform in the llvm vs can't
handle it (this would be fixable though non-trivial due to vp index being
non-constant for the SoA outputs, but we don't use it if there's a gs
neither - the whole clip/vp transform integration there is suboptimal).

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/draw/draw_context.c               |    4 ++--
 src/gallium/auxiliary/draw/draw_llvm.c                  |    6 +++++-
 .../auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c  |    6 +++---
 src/gallium/auxiliary/draw/draw_pt_post_vs.c            |    2 +-
 src/gallium/auxiliary/draw/draw_vs.c                    |    4 +++-
 src/gallium/auxiliary/draw/draw_vs.h                    |    1 +
 src/gallium/auxiliary/tgsi/tgsi_scan.c                  |   15 ++++++---------
 7 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index bb8c03c..f46f8b4 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -806,7 +806,7 @@ draw_current_shader_viewport_index_output(const struct draw_context *draw)
 {
    if (draw->gs.geometry_shader)
       return draw->gs.geometry_shader->viewport_index_output;
-   return 0;
+   return draw->vs.vertex_shader->viewport_index_output;
 }
 
 /**
@@ -818,7 +818,7 @@ draw_current_shader_uses_viewport_index(const struct draw_context *draw)
 {
    if (draw->gs.geometry_shader)
       return draw->gs.geometry_shader->info.writes_viewport_index;
-   return FALSE;
+   return draw->vs.vertex_shader->info.writes_viewport_index;
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 1c26560..a2e6112 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1522,8 +1522,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
    /* If geometry shader is present we need to skip both the viewport
     * transformation and clipping otherwise the inputs to the geometry
     * shader will be incorrect.
+    * The code can't handle vp transform when vs writes vp index neither
+    * (though this would be fixable here, but couldn't just broadcast
+    * the values).
     */
-   const boolean bypass_viewport = key->has_gs || key->bypass_viewport;
+   const boolean bypass_viewport = key->has_gs || key->bypass_viewport ||
+                                   llvm->draw->vs.vertex_shader->info.writes_viewport_index;
    const boolean enable_cliptest = !key->has_gs && (key->clip_xy ||
                                                     key->clip_z  ||
                                                     key->clip_user);
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 49341ff..cc83736 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
@@ -169,8 +169,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
    draw_pt_so_emit_prepare( fpme->so_emit, gs == NULL );
 
    if (!(opt & PT_PIPELINE)) {
-      draw_pt_emit_prepare( fpme->emit,
-			    out_prim,
+      draw_pt_emit_prepare( fpme->emit, out_prim,
                             max_vertices );
 
       *max_vertices = MAX2( *max_vertices, 4096 );
@@ -442,7 +441,8 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
     * will try to access non-existent position output.
     */
    if (draw_current_shader_position_output(draw) != -1) {
-      if ((opt & PT_SHADE) && gshader) {
+      if ((opt & PT_SHADE) && (gshader ||
+                               draw->vs.vertex_shader->info.writes_viewport_index)) {
          clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info );
       }
       if (clipped) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 9279cd1..71a7d39 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -117,7 +117,7 @@ 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, prim_info );
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index dc50870..f24354e 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -85,7 +85,9 @@ draw_create_vertex_shader(struct draw_context *draw,
                   vs->info.output_semantic_index[i] == 0) {
             found_clipvertex = TRUE;
             vs->clipvertex_output = i;
-         } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
+         } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
+            vs->viewport_index_output = i;
+         else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
             debug_assert(vs->info.output_semantic_index[i] <
                          PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
             vs->clipdistance_output[vs->info.output_semantic_index[i]] = i;
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index 79dbfb7..1d54e7e 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -110,6 +110,7 @@ struct draw_vertex_shader {
 
    struct tgsi_shader_info info;
    unsigned position_output;
+   unsigned viewport_index_output;
    unsigned edgeflag_output;
    unsigned clipvertex_output;
    unsigned clipdistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index 42bc61e..a23bb40 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -232,6 +232,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                         info->num_written_culldistance +=
                            util_bitcount(fulldecl->Declaration.UsageMask);
                      }
+                     else if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) {
+                        info->writes_viewport_index = TRUE;
+                     }
+                     else if (semName == TGSI_SEMANTIC_LAYER) {
+                        info->writes_layer = TRUE;
+                     }
                   }
 
                   if (procType == TGSI_PROCESSOR_FRAGMENT) {
@@ -248,15 +254,6 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                         info->writes_edgeflag = TRUE;
                      }
                   }
-
-                  if (procType == TGSI_PROCESSOR_GEOMETRY) {
-                     if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) {
-                        info->writes_viewport_index = TRUE;
-                     }
-                     else if (semName == TGSI_SEMANTIC_LAYER) {
-                        info->writes_layer = TRUE;
-                     }
-                  }
                }
             }
          }




More information about the mesa-commit mailing list