mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-29 08:00:12 +01:00
glsl: Don't allow gl_PerVertex to be redeclared after it's been used.
Fixes piglit tests: - spec/glsl-1.50/compiler/gs-redeclares-pervertex-in-after-other-usage.geom - spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-after-other-usage.geom - spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-after-usage.geom - spec/glsl-1.50/compiler/vs-redeclares-pervertex-out-after-other-usage.vert - spec/glsl-1.50/compiler/vs-redeclares-pervertex-out-after-usage.vert Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
84b9fa83a0
commit
8cb9cce040
1 changed files with 53 additions and 0 deletions
|
|
@ -4611,6 +4611,39 @@ ast_struct_specifier::hir(exec_list *instructions,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Visitor class which detects whether a given interface block has been used.
|
||||
*/
|
||||
class interface_block_usage_visitor : public ir_hierarchical_visitor
|
||||
{
|
||||
public:
|
||||
interface_block_usage_visitor(ir_variable_mode mode, const glsl_type *block)
|
||||
: mode(mode), block(block), found(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ir_visitor_status visit(ir_dereference_variable *ir)
|
||||
{
|
||||
if (ir->var->mode == mode && ir->var->get_interface_type() == block) {
|
||||
found = true;
|
||||
return visit_stop;
|
||||
}
|
||||
return visit_continue;
|
||||
}
|
||||
|
||||
bool usage_found() const
|
||||
{
|
||||
return this->found;
|
||||
}
|
||||
|
||||
private:
|
||||
ir_variable_mode mode;
|
||||
const glsl_type *block;
|
||||
bool found;
|
||||
};
|
||||
|
||||
|
||||
ir_rvalue *
|
||||
ast_interface_block::hir(exec_list *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
|
|
@ -4737,6 +4770,26 @@ ast_interface_block::hir(exec_list *instructions,
|
|||
earlier_per_vertex->fields.structure[j].location;
|
||||
}
|
||||
}
|
||||
|
||||
/* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10
|
||||
* spec:
|
||||
*
|
||||
* If a built-in interface block is redeclared, it must appear in
|
||||
* the shader before any use of any member included in the built-in
|
||||
* declaration, or a compilation error will result.
|
||||
*
|
||||
* This appears to be a clarification to the behaviour established for
|
||||
* gl_PerVertex by GLSL 1.50, therefore we implement this behaviour
|
||||
* regardless of GLSL version.
|
||||
*/
|
||||
interface_block_usage_visitor v(var_mode, earlier_per_vertex);
|
||||
v.run(instructions);
|
||||
if (v.usage_found()) {
|
||||
_mesa_glsl_error(&loc, state,
|
||||
"redeclaration of a built-in interface block must "
|
||||
"appear before any use of any member of the "
|
||||
"interface block");
|
||||
}
|
||||
}
|
||||
|
||||
const glsl_type *block_type =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue