[Mesa-dev] [PATCH 07/21] glsl: fix cross validation for explicit locations on structs and arrays
Timothy Arceri
timothy.arceri at collabora.com
Mon Dec 21 22:01:54 PST 2015
---
src/glsl/link_varyings.cpp | 53 ++++++++++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 16 deletions(-)
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index fd4b27c..06882fc 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -239,18 +239,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++;
+ }
}
}
@@ -298,14 +304,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);
@@ -1097,15 +1114,19 @@ varying_matches::assign_locations(struct gl_shader_program *prog,
const ir_variable *var;
const glsl_type *type;
+ bool is_vertex_input = false;
if (matches[i].consumer_var) {
var = matches[i].consumer_var;
type = get_varying_type(var, consumer_stage);
+ is_vertex_input = false;
+ if (consumer_stage == MESA_SHADER_VERTEX)
+ is_vertex_input = true;
} else {
var = matches[i].producer_var;
type = get_varying_type(var, producer_stage);
}
- unsigned num_elements = type->count_attribute_slots();
+ unsigned num_elements = type->count_attribute_slots(is_vertex_input);
unsigned slot_end = this->disable_varying_packing ? 4 :
type->without_array()->vector_elements;
slot_end += *location - 1;
@@ -1533,8 +1554,8 @@ reserved_varying_slot(struct gl_shader *stage, ir_variable_mode io_mode)
var_slot = var->data.location - VARYING_SLOT_VAR0;
- unsigned num_elements =
- get_varying_type(var, stage->Stage)->count_attribute_slots();
+ unsigned num_elements = get_varying_type(var, stage->Stage)
+ ->count_attribute_slots(stage->Stage == MESA_SHADER_VERTEX);
for (unsigned i = 0; i < num_elements; i++) {
if (var_slot >= 0 && var_slot < MAX_VARYING)
slots |= 1u << var_slot;
--
2.4.3
More information about the mesa-dev
mailing list