[Mesa-dev] [PATCH 09/10] glsl: Fix prorgram interface query locations biasing for SSO.

Kenneth Graunke kenneth at whitecape.org
Thu Mar 31 18:53:42 UTC 2016


With SSO, the GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT interfaces refer to
the first and last shader stage linked into a program.  This may not be
the vertex and fragment shader stages.

So, subtracting VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 is bogus.
We need to subtract VERT_ATTRIB_GENERIC0 for VS inputs,
FRAG_RESULT_DATA0 for FS outputs, and VARYING_SLOT_VAR0 for other cases.

Note that built-in variables get a location of -1.

Fixes 4 dEQP-GLES31.functional.program_interface_query tests:
- program_input.location.separable_fragment.var_explicit_location
- program_input.location.separable_fragment.var_array_explicit_location
- program_output.location.separable_vertex.var_array_explicit_location
- program_output.location.separable_vertex.var_array_explicit_location

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/compiler/glsl/linker.cpp   | 18 +++++++++++++-----
 src/mesa/main/shader_query.cpp | 11 +++--------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 77a09a7..0c62124 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -3498,7 +3498,8 @@ build_stageref(struct gl_shader_program *shProg, const char *name,
  */
 static gl_shader_variable *
 create_shader_variable(struct gl_shader_program *shProg,
-                       const ir_variable *in, bool use_implicit_location)
+                       const ir_variable *in, bool use_implicit_location,
+                       int location_bias)
 {
    gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable);
    if (!out)
@@ -3536,7 +3537,7 @@ create_shader_variable(struct gl_shader_program *shProg,
        !(in->data.explicit_location || use_implicit_location)) {
       out->location = -1;
    } else {
-      out->location = in->data.location;
+      out->location = in->data.location - location_bias;
    }
 
    out->type = in->type;
@@ -3558,6 +3559,8 @@ add_interface_variables(struct gl_shader_program *shProg,
       if (!var)
          continue;
 
+      int loc_bias;
+
       switch (var->data.mode) {
       case ir_var_system_value:
          /* We use gl_BaseVertex internally for gl_VertexID lowering.
@@ -3572,10 +3575,14 @@ add_interface_variables(struct gl_shader_program *shProg,
       case ir_var_shader_in:
          if (programInterface != GL_PROGRAM_INPUT)
             continue;
+         loc_bias = (stage == MESA_SHADER_VERTEX) ? int(VERT_ATTRIB_GENERIC0)
+                                                  : int(VARYING_SLOT_VAR0);
          break;
       case ir_var_shader_out:
          if (programInterface != GL_PROGRAM_OUTPUT)
             continue;
+         loc_bias = (stage == MESA_SHADER_FRAGMENT) ? int(FRAG_RESULT_DATA0)
+                                                    : int(VARYING_SLOT_VAR0);
          break;
       default:
          continue;
@@ -3598,7 +3605,7 @@ add_interface_variables(struct gl_shader_program *shProg,
          (stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out);
 
       gl_shader_variable *sha_v =
-         create_shader_variable(shProg, var, vs_input_or_fs_output);
+         create_shader_variable(shProg, var, vs_input_or_fs_output, loc_bias);
       if (!sha_v)
          return false;
 
@@ -3633,7 +3640,7 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type)
 
          if (type == iface) {
             gl_shader_variable *sha_v =
-               create_shader_variable(shProg, var, false);
+               create_shader_variable(shProg, var, false, VARYING_SLOT_VAR0);
             if (!sha_v)
                return false;
             if (!add_program_resource(shProg, iface, sha_v,
@@ -3658,7 +3665,8 @@ add_fragdata_arrays(struct gl_shader_program *shProg)
       ir_variable *var = node->as_variable();
       if (var) {
          assert(var->data.mode == ir_var_shader_out);
-         gl_shader_variable *sha_v = create_shader_variable(shProg, var, true);
+         gl_shader_variable *sha_v =
+            create_shader_variable(shProg, var, true, FRAG_RESULT_DATA0);
          if (!sha_v)
             return false;
          if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v,
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 190f638..4650a5c 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -780,10 +780,6 @@ program_resource_location(struct gl_shader_program *shProg,
                           struct gl_program_resource *res, const char *name,
                           unsigned array_index)
 {
-   /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these
-    * offsets are used internally to differentiate between built-in attributes
-    * and user-defined attributes.
-    */
    switch (res->Type) {
    case GL_PROGRAM_INPUT: {
       const gl_shader_variable *var = RESOURCE_VAR(res);
@@ -796,9 +792,8 @@ program_resource_location(struct gl_shader_program *shProg,
           && array_index >= var->type->length) {
          return -1;
       }
-      return (var->location +
-	      (array_index * var->type->without_array()->matrix_columns) -
-	      VERT_ATTRIB_GENERIC0);
+      return var->location +
+	     (array_index * var->type->without_array()->matrix_columns);
    }
    case GL_PROGRAM_OUTPUT:
       if (RESOURCE_VAR(res)->location == -1)
@@ -809,7 +804,7 @@ program_resource_location(struct gl_shader_program *shProg,
           && array_index >= RESOURCE_VAR(res)->type->length) {
          return -1;
       }
-      return RESOURCE_VAR(res)->location + array_index - FRAG_RESULT_DATA0;
+      return RESOURCE_VAR(res)->location + array_index;
    case GL_UNIFORM:
       /* If the uniform is built-in, fail. */
       if (RESOURCE_UNI(res)->builtin)
-- 
2.7.4



More information about the mesa-dev mailing list