mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 04:50:11 +01:00
glsl: Support redeclaration of VS and GS gl_PerVertex output.
Fixes piglit tests: - spec/glsl-1.50/execution/redeclare-pervertex-out-subset-gs - spec/glsl-1.50/execution/redeclare-pervertex-subset-vs Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
79f515251a
commit
1b4a7378e9
1 changed files with 60 additions and 2 deletions
|
|
@ -2328,7 +2328,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
||||||
*/
|
*/
|
||||||
static ir_variable *
|
static ir_variable *
|
||||||
get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
|
get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
|
||||||
struct _mesa_glsl_parse_state *state)
|
struct _mesa_glsl_parse_state *state,
|
||||||
|
bool allow_all_redeclarations)
|
||||||
{
|
{
|
||||||
/* Check if this declaration is actually a re-declaration, either to
|
/* Check if this declaration is actually a re-declaration, either to
|
||||||
* resize an array or add qualifiers to an existing variable.
|
* resize an array or add qualifiers to an existing variable.
|
||||||
|
|
@ -2431,6 +2432,16 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
|
||||||
|
|
||||||
earlier->depth_layout = var->depth_layout;
|
earlier->depth_layout = var->depth_layout;
|
||||||
|
|
||||||
|
} else if (allow_all_redeclarations) {
|
||||||
|
if (earlier->mode != var->mode) {
|
||||||
|
_mesa_glsl_error(&loc, state,
|
||||||
|
"redeclaration of `%s' with incorrect qualifiers",
|
||||||
|
var->name);
|
||||||
|
} else if (earlier->type != var->type) {
|
||||||
|
_mesa_glsl_error(&loc, state,
|
||||||
|
"redeclaration of `%s' has incorrect type",
|
||||||
|
var->name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
|
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
|
||||||
}
|
}
|
||||||
|
|
@ -3220,7 +3231,8 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||||
*/
|
*/
|
||||||
exec_list initializer_instructions;
|
exec_list initializer_instructions;
|
||||||
ir_variable *earlier =
|
ir_variable *earlier =
|
||||||
get_variable_being_redeclared(var, decl->get_location(), state);
|
get_variable_being_redeclared(var, decl->get_location(), state,
|
||||||
|
false /* allow_all_redeclarations */);
|
||||||
|
|
||||||
if (decl->initializer != NULL) {
|
if (decl->initializer != NULL) {
|
||||||
result = process_initializer((earlier == NULL) ? var : earlier,
|
result = process_initializer((earlier == NULL) ? var : earlier,
|
||||||
|
|
@ -4816,6 +4828,20 @@ ast_interface_block::hir(exec_list *instructions,
|
||||||
var_mode);
|
var_mode);
|
||||||
var->init_interface_type(block_type);
|
var->init_interface_type(block_type);
|
||||||
|
|
||||||
|
if (redeclaring_per_vertex) {
|
||||||
|
ir_variable *earlier =
|
||||||
|
get_variable_being_redeclared(var, loc, state,
|
||||||
|
true /* allow_all_redeclarations */);
|
||||||
|
if (strncmp(var->name, "gl_", 3) != 0 || earlier == NULL) {
|
||||||
|
_mesa_glsl_error(&loc, state,
|
||||||
|
"redeclaration of gl_PerVertex can only "
|
||||||
|
"include built-in variables");
|
||||||
|
} else {
|
||||||
|
earlier->reinit_interface_type(block_type);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (state->symbols->get_variable(var->name) != NULL)
|
if (state->symbols->get_variable(var->name) != NULL)
|
||||||
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
|
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
|
||||||
|
|
||||||
|
|
@ -4829,6 +4855,38 @@ ast_interface_block::hir(exec_list *instructions,
|
||||||
state->symbols->add_variable(var);
|
state->symbols->add_variable(var);
|
||||||
instructions->push_tail(var);
|
instructions->push_tail(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (redeclaring_per_vertex && block_type != earlier_per_vertex) {
|
||||||
|
/* From section 7.1 ("Built-in Language Variables") of the GLSL 4.10 spec:
|
||||||
|
*
|
||||||
|
* It is also a compilation error ... to redeclare a built-in
|
||||||
|
* block and then use a member from that built-in block that was
|
||||||
|
* not included in the redeclaration.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* To prevent the shader from using a member that was not included in
|
||||||
|
* the redeclaration, we disable any ir_variables that are still
|
||||||
|
* associated with the old declaration of gl_PerVertex (since we've
|
||||||
|
* already updated all of the variables contained in the new
|
||||||
|
* gl_PerVertex to point to it).
|
||||||
|
*
|
||||||
|
* As a side effect this will prevent
|
||||||
|
* validate_intrastage_interface_blocks() from getting confused and
|
||||||
|
* thinking there are conflicting definitions of gl_PerVertex in the
|
||||||
|
* shader.
|
||||||
|
*/
|
||||||
|
foreach_list_safe(node, instructions) {
|
||||||
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
if (var != NULL &&
|
||||||
|
var->get_interface_type() == earlier_per_vertex) {
|
||||||
|
state->symbols->disable_variable(var->name);
|
||||||
|
var->remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue