[Mesa-dev] [PATCH 14/19] linker: Treat I/O within the pipeline differently than the end points

Ian Romanick idr at freedesktop.org
Thu Mar 27 14:40:20 PDT 2014


From: Ian Romanick <ian.d.romanick at intel.com>

Outputs that go from one shader stage to the next need slightly
different treatment than outputs from the fragement shader.  Likewise
for inputs.  If an output (or input) is intrastage and not a built-in,
smash its location to 0, and set explicit_location to false.  The
location set in the shader test is still tracked by user_location.

This could probably be done elsewhere before linking, but this seems the
most reasonable place.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 src/glsl/linker.cpp                          | 37 ++++++++++++++++++++++------
 src/glsl/linker.h                            |  2 +-
 src/glsl/tests/invalidate_locations_test.cpp | 12 ++++-----
 3 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index e02ce87..5e495d5 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -365,7 +365,7 @@ parse_program_resource_name(const GLchar *name,
 
 
 void
-link_invalidate_variable_locations(exec_list *ir)
+link_invalidate_variable_locations(exec_list *ir, unsigned stage)
 {
    foreach_list(node, ir) {
       ir_variable *const var = ((ir_instruction *) node)->as_variable();
@@ -373,16 +373,34 @@ link_invalidate_variable_locations(exec_list *ir)
       if (var == NULL)
          continue;
 
+      bool intrastage_io = false;
+      switch (stage) {
+      case MESA_SHADER_VERTEX:
+         intrastage_io = (var->data.mode == ir_var_shader_out)
+            && var->data.location >= VARYING_SLOT_VAR0;
+         break;
+
+      case MESA_SHADER_GEOMETRY:
+         intrastage_io = ((var->data.mode == ir_var_shader_in)
+                          || (var->data.mode == ir_var_shader_out))
+            && var->data.location >= VARYING_SLOT_VAR0;
+         break;
+
+      case MESA_SHADER_FRAGMENT:
+         intrastage_io = (var->data.mode == ir_var_shader_in)
+            && var->data.location >= VARYING_SLOT_VAR0;
+         break;
+
+      default:
+         assert(!"Should not get here.");
+         unreachable();
+      }
+
       /* Only assign locations for variables that lack an explicit location.
        * Explicit locations are set for all built-in variables, generic vertex
        * shader inputs (via layout(location=...)), and generic fragment shader
        * outputs (also via layout(location=...)).
        */
-      if (!var->data.explicit_location) {
-         var->data.location = -1;
-         var->data.location_frac = 0;
-      }
-
       /* ir_variable::is_unmatched_generic_inout is used by the linker while
        * connecting outputs from one stage to inputs of the next stage.
        *
@@ -395,8 +413,11 @@ link_invalidate_variable_locations(exec_list *ir)
        * GL_ARB_separate_shader_objects is supported.  When that extension is
        * implemented, this function will need some modifications.
        */
-      if (!var->data.explicit_location) {
+      if (!var->data.explicit_location || intrastage_io) {
+         var->data.location = -1;
+         var->data.location_frac = 0;
          var->data.is_unmatched_generic_inout = 1;
+         var->data.explicit_location = false;
       } else {
          var->data.is_unmatched_generic_inout = 0;
       }
@@ -2306,7 +2327,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    /* Mark all generic shader inputs and outputs as unpaired. */
    for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
       if (prog->_LinkedShaders[i] != NULL) {
-         link_invalidate_variable_locations(prog->_LinkedShaders[i]->ir);
+         link_invalidate_variable_locations(prog->_LinkedShaders[i]->ir, i);
       }
    }
 
diff --git a/src/glsl/linker.h b/src/glsl/linker.h
index 130915d..43283b9 100644
--- a/src/glsl/linker.h
+++ b/src/glsl/linker.h
@@ -31,7 +31,7 @@ link_function_calls(gl_shader_program *prog, gl_shader *main,
 		    gl_shader **shader_list, unsigned num_shaders);
 
 extern void
-link_invalidate_variable_locations(exec_list *ir);
+link_invalidate_variable_locations(exec_list *ir, unsigned stage);
 
 extern void
 link_assign_uniform_locations(struct gl_shader_program *prog);
diff --git a/src/glsl/tests/invalidate_locations_test.cpp b/src/glsl/tests/invalidate_locations_test.cpp
index 997592f..10526a0 100644
--- a/src/glsl/tests/invalidate_locations_test.cpp
+++ b/src/glsl/tests/invalidate_locations_test.cpp
@@ -72,7 +72,7 @@ TEST_F(invalidate_locations, simple_vertex_in_generic)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(-1, var->data.location);
    EXPECT_EQ(0u, var->data.location_frac);
@@ -95,7 +95,7 @@ TEST_F(invalidate_locations, explicit_location_vertex_in_generic)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location);
    EXPECT_EQ(0u, var->data.location_frac);
@@ -119,7 +119,7 @@ TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location);
    EXPECT_EQ(2u, var->data.location_frac);
@@ -142,7 +142,7 @@ TEST_F(invalidate_locations, vertex_in_builtin)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(VERT_ATTRIB_POS, var->data.location);
    EXPECT_EQ(0u, var->data.location_frac);
@@ -164,7 +164,7 @@ TEST_F(invalidate_locations, simple_vertex_out_generic)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(-1, var->data.location);
    EXPECT_EQ(0u, var->data.location_frac);
@@ -187,7 +187,7 @@ TEST_F(invalidate_locations, vertex_out_builtin)
 
    ir.push_tail(var);
 
-   link_invalidate_variable_locations(&ir);
+   link_invalidate_variable_locations(&ir, MESA_SHADER_VERTEX);
 
    EXPECT_EQ(VARYING_SLOT_COL0, var->data.location);
    EXPECT_EQ(0u, var->data.location_frac);
-- 
1.8.1.4



More information about the mesa-dev mailing list