glsl: allow any l-value of an input variable as interpolant in interpolateAt*
The intended rule has been clarified in GLSL 4.60, Section 8.13.2 (Interpolation Functions): "For all of the interpolation functions, interpolant must be an l-value from an in declaration; this can include a variable, a block or structure member, an array element, or some combination of these. Component selection operators (e.g., .xy) may be used when specifying interpolant." For members of interface blocks, var->data.must_be_shader_input must be determined on-the-fly after lowering interface blocks, since we don't want to disable varying packing for an entire block just because one input in it is used in interpolateAt*. v2: keep setting must_be_shader_input in ast_function (Ian) v3: follow the relaxed rule of GLSL 4.60 v4: only apply the relaxed rules to desktop GL (the ES WG decided that the relaxed rules may apply in a future version but not retroactively; see also dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_centroid.negative.*) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101378 Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v1) Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
@@ -227,19 +227,28 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
|
|||||||
val = ((ir_swizzle *)val)->val;
|
val = ((ir_swizzle *)val)->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (val->ir_type == ir_type_dereference_array) {
|
for (;;) {
|
||||||
|
if (val->ir_type == ir_type_dereference_array) {
|
||||||
val = ((ir_dereference_array *)val)->array;
|
val = ((ir_dereference_array *)val)->array;
|
||||||
|
} else if (val->ir_type == ir_type_dereference_record &&
|
||||||
|
!state->es_shader) {
|
||||||
|
val = ((ir_dereference_record *)val)->record;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!val->as_dereference_variable() ||
|
ir_variable *var = NULL;
|
||||||
val->variable_referenced()->data.mode != ir_var_shader_in) {
|
if (const ir_dereference_variable *deref_var = val->as_dereference_variable())
|
||||||
|
var = deref_var->variable_referenced();
|
||||||
|
|
||||||
|
if (!var || var->data.mode != ir_var_shader_in) {
|
||||||
_mesa_glsl_error(&loc, state,
|
_mesa_glsl_error(&loc, state,
|
||||||
"parameter `%s` must be a shader input",
|
"parameter `%s` must be a shader input",
|
||||||
formal->name);
|
formal->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
val->variable_referenced()->data.must_be_shader_input = 1;
|
var->data.must_be_shader_input = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
|
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
|
||||||
|
@@ -115,6 +115,7 @@ public:
|
|||||||
void run(exec_list *instructions);
|
void run(exec_list *instructions);
|
||||||
|
|
||||||
virtual ir_visitor_status visit_leave(ir_assignment *);
|
virtual ir_visitor_status visit_leave(ir_assignment *);
|
||||||
|
virtual ir_visitor_status visit_leave(ir_expression *);
|
||||||
virtual void handle_rvalue(ir_rvalue **rvalue);
|
virtual void handle_rvalue(ir_rvalue **rvalue);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -238,6 +239,23 @@ flatten_named_interface_blocks_declarations::visit_leave(ir_assignment *ir)
|
|||||||
return rvalue_visit(ir);
|
return rvalue_visit(ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ir_visitor_status
|
||||||
|
flatten_named_interface_blocks_declarations::visit_leave(ir_expression *ir)
|
||||||
|
{
|
||||||
|
ir_visitor_status status = rvalue_visit(ir);
|
||||||
|
|
||||||
|
if (ir->operation == ir_unop_interpolate_at_centroid ||
|
||||||
|
ir->operation == ir_binop_interpolate_at_offset ||
|
||||||
|
ir->operation == ir_binop_interpolate_at_sample) {
|
||||||
|
const ir_rvalue *val = ir->operands[0];
|
||||||
|
|
||||||
|
/* This disables varying packing for this input. */
|
||||||
|
val->variable_referenced()->data.must_be_shader_input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
|
flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user