mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
glsl: update parser to allow duplicate default layout qualifiers
In order to only create a single node for each default declaration we add a new boolean parameter to the in/out merge function to only create one once we reach the rightmost layout qualifier. From the ARB_shading_language_420pack spec: "More than one layout qualifier may appear in a single declaration. If the same layout-qualifier-name occurs in multiple layout qualifiers for the same declaration, the last one overrides the former ones." Acked-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
This commit is contained in:
parent
a0a93470e3
commit
564009986f
3 changed files with 73 additions and 15 deletions
|
|
@ -704,12 +704,12 @@ struct ast_type_qualifier {
|
|||
bool merge_out_qualifier(YYLTYPE *loc,
|
||||
_mesa_glsl_parse_state *state,
|
||||
const ast_type_qualifier &q,
|
||||
ast_node* &node);
|
||||
ast_node* &node, bool create_node);
|
||||
|
||||
bool merge_in_qualifier(YYLTYPE *loc,
|
||||
_mesa_glsl_parse_state *state,
|
||||
const ast_type_qualifier &q,
|
||||
ast_node* &node);
|
||||
ast_node* &node, bool create_node);
|
||||
|
||||
ast_subroutine_list *subroutine_list;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ bool
|
|||
ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
|
||||
_mesa_glsl_parse_state *state,
|
||||
const ast_type_qualifier &q,
|
||||
ast_node* &node)
|
||||
ast_node* &node, bool create_node)
|
||||
{
|
||||
void *mem_ctx = state;
|
||||
const bool r = this->merge_qualifier(loc, state, q);
|
||||
|
|
@ -314,7 +314,9 @@ ast_type_qualifier::merge_out_qualifier(YYLTYPE *loc,
|
|||
/* Allow future assigments of global out's stream id value */
|
||||
this->flags.q.explicit_stream = 0;
|
||||
} else if (state->stage == MESA_SHADER_TESS_CTRL) {
|
||||
node = new(mem_ctx) ast_tcs_output_layout(*loc);
|
||||
if (create_node) {
|
||||
node = new(mem_ctx) ast_tcs_output_layout(*loc);
|
||||
}
|
||||
} else {
|
||||
_mesa_glsl_error(loc, state, "out layout qualifiers only valid in "
|
||||
"tessellation control or geometry shaders");
|
||||
|
|
@ -327,7 +329,7 @@ bool
|
|||
ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
|
||||
_mesa_glsl_parse_state *state,
|
||||
const ast_type_qualifier &q,
|
||||
ast_node* &node)
|
||||
ast_node* &node, bool create_node)
|
||||
{
|
||||
void *mem_ctx = state;
|
||||
bool create_gs_ast = false;
|
||||
|
|
@ -467,10 +469,12 @@ ast_type_qualifier::merge_in_qualifier(YYLTYPE *loc,
|
|||
this->point_mode = q.point_mode;
|
||||
}
|
||||
|
||||
if (create_gs_ast) {
|
||||
node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type);
|
||||
} else if (create_cs_ast) {
|
||||
node = new(mem_ctx) ast_cs_input_layout(*loc, q.local_size);
|
||||
if (create_node) {
|
||||
if (create_gs_ast) {
|
||||
node = new(mem_ctx) ast_gs_input_layout(*loc, q.prim_type);
|
||||
} else if (create_cs_ast) {
|
||||
node = new(mem_ctx) ast_cs_input_layout(*loc, q.local_size);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2742,7 +2742,20 @@ member_declaration:
|
|||
;
|
||||
|
||||
layout_uniform_defaults:
|
||||
layout_qualifier UNIFORM ';'
|
||||
layout_qualifier layout_uniform_defaults
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->has_420pack_or_es31()) {
|
||||
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
|
||||
YYERROR;
|
||||
} else {
|
||||
if (!state->default_uniform_qualifier->
|
||||
merge_qualifier(& @1, state, $1)) {
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
| layout_qualifier UNIFORM ';'
|
||||
{
|
||||
if (!state->default_uniform_qualifier->merge_qualifier(& @1, state, $1)) {
|
||||
YYERROR;
|
||||
|
|
@ -2752,7 +2765,20 @@ layout_uniform_defaults:
|
|||
;
|
||||
|
||||
layout_buffer_defaults:
|
||||
layout_qualifier BUFFER ';'
|
||||
layout_qualifier layout_buffer_defaults
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->has_420pack_or_es31()) {
|
||||
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
|
||||
YYERROR;
|
||||
} else {
|
||||
if (!state->default_shader_storage_qualifier->
|
||||
merge_qualifier(& @1, state, $1)) {
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
| layout_qualifier BUFFER ';'
|
||||
{
|
||||
if (!state->default_shader_storage_qualifier->merge_qualifier(& @1, state, $1)) {
|
||||
YYERROR;
|
||||
|
|
@ -2773,20 +2799,48 @@ layout_buffer_defaults:
|
|||
;
|
||||
|
||||
layout_in_defaults:
|
||||
layout_qualifier IN_TOK ';'
|
||||
layout_qualifier layout_in_defaults
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->in_qualifier->merge_in_qualifier(& @1, state, $1, $$)) {
|
||||
if (!state->has_420pack_or_es31()) {
|
||||
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
|
||||
YYERROR;
|
||||
} else {
|
||||
if (!state->in_qualifier->
|
||||
merge_in_qualifier(& @1, state, $1, $$, false)) {
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
| layout_qualifier IN_TOK ';'
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->in_qualifier->
|
||||
merge_in_qualifier(& @1, state, $1, $$, true)) {
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
layout_out_defaults:
|
||||
layout_qualifier OUT_TOK ';'
|
||||
layout_qualifier layout_out_defaults
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->out_qualifier->merge_out_qualifier(& @1, state, $1, $$))
|
||||
if (!state->has_420pack_or_es31()) {
|
||||
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
|
||||
YYERROR;
|
||||
} else {
|
||||
if (!state->out_qualifier->
|
||||
merge_out_qualifier(& @1, state, $1, $$, false)) {
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
| layout_qualifier OUT_TOK ';'
|
||||
{
|
||||
$$ = NULL;
|
||||
if (!state->out_qualifier->
|
||||
merge_out_qualifier(& @1, state, $1, $$, true))
|
||||
YYERROR;
|
||||
}
|
||||
;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue