summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/link_varyings.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2015-12-24 10:33:45 +1100
committerTimothy Arceri <[email protected]>2016-04-22 20:59:57 +1000
commit72b5d00c9cdffea1452341657f07461725b6962f (patch)
tree3eb60863df47596cabe3eb910b836a2957d495eb /src/compiler/glsl/link_varyings.cpp
parent39e9cf6cb18cc4e8ee828006107de42482668b81 (diff)
glsl: fix cross validation for explicit locations on structs and arrays
Reviewed-by: Anuj Phogat <[email protected]> Reviewed-by: Edward O'Callaghan <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/compiler/glsl/link_varyings.cpp')
-rw-r--r--src/compiler/glsl/link_varyings.cpp43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index 87606be9337..c222ede9291 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -367,18 +367,24 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
/* User-defined varyings with explicit locations are handled
* differently because they do not need to have matching names.
*/
- const unsigned idx = var->data.location - VARYING_SLOT_VAR0;
+ const glsl_type *type = get_varying_type(var, producer->Stage);
+ unsigned num_elements = type->count_attribute_slots(false);
+ unsigned idx = var->data.location - VARYING_SLOT_VAR0;
+ unsigned slot_limit = idx + num_elements;
- if (explicit_locations[idx] != NULL) {
- linker_error(prog,
+ while (idx < slot_limit) {
+ if (explicit_locations[idx] != NULL) {
+ linker_error(prog,
"%s shader has multiple outputs explicitly "
"assigned to location %d\n",
_mesa_shader_stage_to_string(producer->Stage),
idx);
- return;
- }
+ return;
+ }
- explicit_locations[idx] = var;
+ explicit_locations[idx] = var;
+ idx++;
+ }
}
}
@@ -426,14 +432,25 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
ir_variable *output = NULL;
if (input->data.explicit_location
&& input->data.location >= VARYING_SLOT_VAR0) {
- output = explicit_locations[input->data.location - VARYING_SLOT_VAR0];
- if (output == NULL) {
- linker_error(prog,
- "%s shader input `%s' with explicit location "
- "has no matching output\n",
- _mesa_shader_stage_to_string(consumer->Stage),
- input->name);
+ const glsl_type *type = get_varying_type(input, consumer->Stage);
+ unsigned num_elements = type->count_attribute_slots(false);
+ unsigned idx = input->data.location - VARYING_SLOT_VAR0;
+ unsigned slot_limit = idx + num_elements;
+
+ while (idx < slot_limit) {
+ output = explicit_locations[idx];
+
+ if (output == NULL ||
+ input->data.location != output->data.location) {
+ linker_error(prog,
+ "%s shader input `%s' with explicit location "
+ "has no matching output\n",
+ _mesa_shader_stage_to_string(consumer->Stage),
+ input->name);
+ break;
+ }
+ idx++;
}
} else {
output = parameters.get_variable(input->name);