summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/ast_function.cpp2
-rw-r--r--src/compiler/glsl/link_varyings.cpp17
-rw-r--r--src/compiler/glsl/lower_packed_varyings.cpp7
3 files changed, 19 insertions, 7 deletions
diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp
index 9f03f321483..1b90937ec8c 100644
--- a/src/compiler/glsl/ast_function.cpp
+++ b/src/compiler/glsl/ast_function.cpp
@@ -235,6 +235,8 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
formal->name);
return false;
}
+
+ val->variable_referenced()->data.must_be_shader_input = 1;
}
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp
index e6947692aff..6bcec72f5fc 100644
--- a/src/compiler/glsl/link_varyings.cpp
+++ b/src/compiler/glsl/link_varyings.cpp
@@ -1461,17 +1461,24 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
? consumer_stage : producer_stage;
const glsl_type *type = get_varying_type(var, stage);
+ if (producer_var && consumer_var &&
+ consumer_var->data.must_be_shader_input) {
+ producer_var->data.must_be_shader_input = 1;
+ }
+
this->matches[this->num_matches].packing_class
= this->compute_packing_class(var);
this->matches[this->num_matches].packing_order
= this->compute_packing_order(var);
- if (this->disable_varying_packing && !is_varying_packing_safe(type, var)) {
+ if ((this->disable_varying_packing && !is_varying_packing_safe(type, var)) ||
+ var->data.must_be_shader_input) {
unsigned slots = type->count_attribute_slots(false);
this->matches[this->num_matches].num_components = slots * 4;
} else {
this->matches[this->num_matches].num_components
= type->component_slots();
}
+
this->matches[this->num_matches].producer_var = producer_var;
this->matches[this->num_matches].consumer_var = consumer_var;
this->num_matches++;
@@ -1544,7 +1551,8 @@ varying_matches::assign_locations(struct gl_shader_program *prog,
* we can pack varyings together that are only used for transform
* feedback.
*/
- if ((this->disable_varying_packing &&
+ if (var->data.must_be_shader_input ||
+ (this->disable_varying_packing &&
!(previous_var_xfb_only && var->data.is_xfb_only)) ||
(i > 0 && this->matches[i - 1].packing_class
!= this->matches[i].packing_class )) {
@@ -1660,8 +1668,9 @@ varying_matches::compute_packing_class(const ir_variable *var)
* Therefore, the packing class depends only on the interpolation type.
*/
unsigned packing_class = var->data.centroid | (var->data.sample << 1) |
- (var->data.patch << 2);
- packing_class *= 4;
+ (var->data.patch << 2) |
+ (var->data.must_be_shader_input << 3);
+ packing_class *= 8;
packing_class += var->is_interpolation_flat()
? unsigned(INTERP_MODE_FLAT) : var->data.interpolation;
return packing_class;
diff --git a/src/compiler/glsl/lower_packed_varyings.cpp b/src/compiler/glsl/lower_packed_varyings.cpp
index 13f7e5b52da..b1a3b49b1d5 100644
--- a/src/compiler/glsl/lower_packed_varyings.cpp
+++ b/src/compiler/glsl/lower_packed_varyings.cpp
@@ -742,10 +742,11 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
bool
lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
{
- /* Things composed of vec4's and varyings with explicitly assigned
- * locations don't need lowering. Everything else does.
+ /* Things composed of vec4's, varyings with explicitly assigned
+ * locations or varyings marked as must_be_shader_input (which might be used
+ * by interpolateAt* functions) shouldn't be lowered. Everything else can be.
*/
- if (var->data.explicit_location)
+ if (var->data.explicit_location || var->data.must_be_shader_input)
return false;
/* Override disable_varying_packing if the var is only used by transform