[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