summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ir.h9
-rw-r--r--src/glsl/linker.cpp18
2 files changed, 23 insertions, 4 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 89c516c877d..e2ecb3d9dfd 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -437,6 +437,15 @@ public:
unsigned has_initializer:1;
/**
+ * Is this variable a generic output or input that has not yet been matched
+ * up to a variable in another stage of the pipeline?
+ *
+ * This is used by the linker as scratch storage while assigning locations
+ * to generic inputs and outputs.
+ */
+ unsigned is_unmatched_generic_inout:1;
+
+ /**
* \brief Layout qualifier for gl_FragDepth.
*
* This is not equal to \c ir_depth_layout_none if and only if this
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 2523dc99d6f..ee6dc2596d0 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -225,6 +225,11 @@ link_invalidate_variable_locations(gl_shader *sh, int input_base,
*/
if ((var->location >= base) && !var->explicit_location)
var->location = -1;
+
+ if ((var->location == -1) && !var->explicit_location)
+ var->is_unmatched_generic_inout = 1;
+ else
+ var->is_unmatched_generic_inout = 0;
}
}
@@ -1362,6 +1367,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
if (prog->AttributeBindings->get(binding, var->name)) {
assert(binding >= VERT_ATTRIB_GENERIC0);
var->location = binding;
+ var->is_unmatched_generic_inout = 0;
}
} else if (target_index == MESA_SHADER_FRAGMENT) {
unsigned binding;
@@ -1370,6 +1376,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
if (prog->FragDataBindings->get(binding, var->name)) {
assert(binding >= FRAG_RESULT_DATA0);
var->location = binding;
+ var->is_unmatched_generic_inout = 0;
if (prog->FragDataIndexBindings->get(index, var->name)) {
var->index = index;
@@ -1485,6 +1492,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
}
to_assign[i].var->location = generic_base + location;
+ to_assign[i].var->is_unmatched_generic_inout = 0;
used_locations |= (use_mask << location);
}
@@ -1508,7 +1516,7 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
* its value is used by other shader stages. This will cause the variable
* to have a location assigned.
*/
- if (var->location == -1) {
+ if (var->is_unmatched_generic_inout) {
var->mode = ir_var_auto;
}
}
@@ -1985,7 +1993,7 @@ void
assign_varying_location(ir_variable *input_var, ir_variable *output_var,
unsigned *input_index, unsigned *output_index)
{
- if (output_var->location != -1) {
+ if (!output_var->is_unmatched_generic_inout) {
/* Location already assigned. */
return;
}
@@ -1993,9 +2001,11 @@ assign_varying_location(ir_variable *input_var, ir_variable *output_var,
if (input_var) {
assert(input_var->location == -1);
input_var->location = *input_index;
+ input_var->is_unmatched_generic_inout = 0;
}
output_var->location = *output_index;
+ output_var->is_unmatched_generic_inout = 0;
/* FINISHME: Support for "varying" records in GLSL 1.50. */
assert(!output_var->type->is_record());
@@ -2105,7 +2115,7 @@ assign_varying_locations(struct gl_context *ctx,
if (!tfeedback_decls[i].is_assigned() &&
tfeedback_decls[i].matches_var(output_var)) {
- if (output_var->location == -1) {
+ if (output_var->is_unmatched_generic_inout) {
assign_varying_location(input_var, output_var, &input_index,
&output_index);
}
@@ -2124,7 +2134,7 @@ assign_varying_locations(struct gl_context *ctx,
if ((var == NULL) || (var->mode != ir_var_in))
continue;
- if (var->location == -1) {
+ if (var->is_unmatched_generic_inout) {
if (prog->Version <= 120) {
/* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
*