[Mesa-dev] [PATCH 15/21] glsl: add support for explicit components to frag outputs

Timothy Arceri timothy.arceri at collabora.com
Mon Dec 21 22:02:02 PST 2015


---
 src/glsl/linker.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 827d07f..4c2f24b 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2411,7 +2411,12 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
       }
    } to_assign[16];
 
+   /* Temporary array for the set of attributes that have locations assigned.
+    */
+   ir_variable *assigned[16];
+
    unsigned num_attr = 0;
+   unsigned assigned_attr = 0;
 
    foreach_in_list(ir_instruction, node, sh->ir) {
       ir_variable *const var = node->as_variable();
@@ -2573,7 +2578,53 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
 	     * attribute overlaps any previously allocated bits.
 	     */
 	    if ((~(use_mask << attr) & used_locations) != used_locations) {
-               if (target_index == MESA_SHADER_FRAGMENT ||
+               if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) {
+                  /* From section 4.4.2 (Output Layout Qualifiers) of the GLSL
+                   * 4.40 spec:
+                   *
+                   *    "Additionally, for fragment shader outputs, if two
+                   *    variables are placed within the same location, they
+                   *    must have the same underlying type (floating-point or
+                   *    integer). No component aliasing of output variables or
+                   *    members is allowed.
+                   */
+                  int frag_out_end_loc = (var->type->is_array() ?
+                     var->type->arrays_of_arrays_size() : 1) +
+                     var->data.location;
+
+                  for (unsigned i = 0; i < assigned_attr; i++) {
+                     for (int j = var->data.location; j < frag_out_end_loc;
+                          j++) {
+                        if (assigned[i]->data.location == j) {
+                           if (assigned[i]->type->without_array()->base_type !=
+                               var->type->without_array()->base_type) {
+                              linker_error(prog,
+                                           "types do not match for aliased"
+                                           " %ss %s and %s\n", string,
+                                           assigned[i]->name, var->name);
+                              return false;
+                           }
+
+                           if ((assigned[i]->data.location_frac ==
+                                var->data.location_frac) ||
+                              ((assigned[i]->data.location_frac <
+                                var->data.location_frac) &&
+                                ((assigned[i]->data.location_frac +
+                                  assigned[i]->type->vector_elements) >
+                                 var->data.location_frac))) {
+                              linker_error(prog,
+                                           "overlapping component is "
+                                           "assigned to %ss %s and %s "
+                                           "(component=%d)\n",
+                                           string, assigned[i]->name,
+                                           var->name,
+                                           var->data.location_frac);
+                              return false;
+                           }
+                        }
+                     }
+                  }
+               } else if (target_index == MESA_SHADER_FRAGMENT ||
                    (prog->IsES && prog->Version >= 300)) {
                   linker_error(prog,
                                "overlapping location is assigned "
@@ -2614,6 +2665,9 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
                double_storage_locations |= (use_mask << attr);
 	 }
 
+         assigned[assigned_attr] = var;
+         assigned_attr++;
+
 	 continue;
       }
 
-- 
2.4.3



More information about the mesa-dev mailing list