diff options
author | Andres Gomez <[email protected]> | 2016-10-18 18:18:21 +0300 |
---|---|---|
committer | Andres Gomez <[email protected]> | 2016-11-25 13:18:30 +0200 |
commit | 70456aca8d1934ec53c24cfe1cfb4273d2bc9397 (patch) | |
tree | cfc6e17d371f45b571dc4ee2f8ac59d7d01ab82d /src/compiler/glsl/glsl_parser.yy | |
parent | 9f13d0c64bee2935ba41a318196f8851a92ad348 (diff) |
glsl: merge layouts into the default one as the last step in interface blocks
Consider this example:
" #version 150 core
#extension GL_ARB_shading_language_420pack: require
#extension GL_ARB_explicit_attrib_location: require
layout(location=0) out vec4 o;
layout(binding=2) layout(binding=3, std140) uniform U {
vec4 a;
} u[2];"
As there is 2 layout-qualifiers for the uniform U and the binding
layout-qualifier-id is duplicated, the rules set by the
ARB_shading_language_420pack spec state that the rightmost should
prevail.
Our ast_type_qualifier merges with others in a way that if the value
for a layout-qualifier-id is set in both, the object being merged
overwrites the value of the object invoking the merge. Hence, the
merge has to happen from the left layout towards the right one and
this was not happening for interface blocks because we were merging
into the default layout qualifier.
Now, the merge is done from left to right and, as a last step, we
merge into the default layout qualifier if needed, so the values of
the explicit layouts prevail over it.
V2: added a default_layout variable instead of a layout_helper and
make the merge directly over the layout one. Suggested by Timothy.
Reviewed-by: Timothy Arceri <[email protected]>
Signed-off-by: Andres Gomez <[email protected]>
Diffstat (limited to 'src/compiler/glsl/glsl_parser.yy')
-rw-r--r-- | src/compiler/glsl/glsl_parser.yy | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index a48dc68b00e..f0f212c1722 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -838,6 +838,14 @@ declaration: } | interface_block { + ast_interface_block *block = (ast_interface_block *) $1; + if (block->layout.has_layout() || block->layout.has_memory()) { + if (!block->default_layout.merge_qualifier(& @1, state, block->layout, false)) { + YYERROR; + } + } + block->layout = block->default_layout; + $$ = $1; } ; @@ -2705,17 +2713,16 @@ interface_block: { ast_interface_block *block = (ast_interface_block *) $2; - if (!state->has_420pack_or_es31() && block->layout.has_layout() && - !block->layout.is_default_qualifier) { + if (!state->has_420pack_or_es31() && block->layout.has_layout()) { _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); YYERROR; } - if (!block->layout.merge_qualifier(& @1, state, $1, false)) { + if (!$1.merge_qualifier(& @1, state, block->layout, false)) { YYERROR; } - block->layout.is_default_qualifier = false; + block->layout = $1; $$ = block; } @@ -2723,14 +2730,15 @@ interface_block: { ast_interface_block *block = (ast_interface_block *)$2; - if (!block->layout.flags.q.buffer) { + if (!block->default_layout.flags.q.buffer) { _mesa_glsl_error(& @1, state, "memory qualifiers can only be used in the " "declaration of shader storage blocks"); } - if (!block->layout.merge_qualifier(& @1, state, $1, false)) { + if (!$1.merge_qualifier(& @1, state, block->layout, false)) { YYERROR; } + block->layout = $1; $$ = block; } ; @@ -2741,9 +2749,9 @@ basic_interface_block: ast_interface_block *const block = $6; if ($1.flags.q.uniform) { - block->layout = *state->default_uniform_qualifier; + block->default_layout = *state->default_uniform_qualifier; } else if ($1.flags.q.buffer) { - block->layout = *state->default_shader_storage_qualifier; + block->default_layout = *state->default_shader_storage_qualifier; } block->block_name = $2; block->declarations.push_degenerate_list_at_head(& $4->link); |