[Mesa-dev] [PATCH 3/4] glsl/linker: outputs in the same location must share interpolation

Iago Toral Quiroga itoral at igalia.com
Thu Oct 19 16:31:38 UTC 2017


>From ARB_enhanced_layouts:

"[...]when location aliasing, the aliases sharing the location
 must have the same underlying numerical type (floating-point or
 integer) and the same auxiliary storage and
 interpolation qualification.[...]"

Add code to the linker to validate that aliased locations do
have the same interpolation.

Fixes:
KHR-GL45.enhanced_layouts.varying_location_aliasing_with_mixed_interpolation
---
 src/compiler/glsl/link_varyings.cpp | 45 +++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index 5dc2704321..764042ca5e 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -406,6 +406,7 @@ compute_variable_location_slot(ir_variable *var, gl_shader_stage stage)
 struct explicit_location_info {
    ir_variable *var;
    unsigned base_type;
+   unsigned interpolation;
 };
 
 static bool
@@ -415,6 +416,7 @@ check_location_aliasing(struct explicit_location_info explicit_locations[][4],
                         unsigned component,
                         unsigned location_limit,
                         const glsl_type *type,
+                        unsigned interpolation,
                         gl_shader_program *prog,
                         gl_shader_stage stage)
 {
@@ -431,6 +433,38 @@ check_location_aliasing(struct explicit_location_info explicit_locations[][4],
 
    while (location < location_limit) {
       unsigned i = component;
+
+      /* If there are other outputs assigned to the same location
+       * they must have the same interpolation
+       */
+      unsigned comp = 0;
+      while (comp < 4) {
+         /* Skip the components used by this output, we only care about
+         * other outputs in the same location
+          */
+         if (comp == i) {
+            comp = last_comp;
+            continue;
+         }
+
+         struct explicit_location_info *info =
+            &explicit_locations[location][comp];
+
+         if (info->var) {
+            if (info->interpolation != interpolation) {
+               linker_error(prog,
+                            "%s shader has multiple outputs at explicit "
+                            "location %u with different interpolation "
+                            "settings\n",
+                            _mesa_shader_stage_to_string(stage), location);
+               return false;
+            }
+         }
+
+         comp++;
+      }
+
+      /* Component aliasing is not allowed */
       while (i < last_comp) {
          if (explicit_locations[location][i].var != NULL) {
             linker_error(prog,
@@ -458,6 +492,7 @@ check_location_aliasing(struct explicit_location_info explicit_locations[][4],
          explicit_locations[location][i].var = var;
          explicit_locations[location][i].base_type =
             type->without_array()->base_type;
+         explicit_locations[location][i].interpolation = interpolation;
          i++;
 
          /* We need to do some special handling for doubles as dvec3 and
@@ -526,18 +561,20 @@ cross_validate_outputs_to_inputs(struct gl_context *ctx,
                const glsl_type *field_type = type->fields.structure[i].type;
                unsigned field_location =
                      type->fields.structure[i].location - VARYING_SLOT_VAR0;
+               unsigned interpolation = type->fields.structure[i].interpolation;
                if (!check_location_aliasing(explicit_locations, var,
                                             field_location,
                                             0, field_location + 1,
-                                            field_type, prog,
-                                            producer->Stage)) {
+                                            field_type, interpolation,
+                                            prog, producer->Stage)) {
                   return;
                }
             }
          } else if (!check_location_aliasing(explicit_locations, var,
                                              idx, var->data.location_frac,
-                                             slot_limit, type, prog,
-                                             producer->Stage)) {
+                                             slot_limit, type,
+                                             var->data.interpolation,
+                                             prog, producer->Stage)) {
             return;
          }
       }
-- 
2.11.0



More information about the mesa-dev mailing list