diff options
author | Timothy Arceri <[email protected]> | 2015-12-24 10:33:45 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2016-04-22 20:59:57 +1000 |
commit | 72b5d00c9cdffea1452341657f07461725b6962f (patch) | |
tree | 3eb60863df47596cabe3eb910b836a2957d495eb /src/compiler/glsl | |
parent | 39e9cf6cb18cc4e8ee828006107de42482668b81 (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')
-rw-r--r-- | src/compiler/glsl/link_varyings.cpp | 43 |
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); |