summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/glsl_parser.yy
diff options
context:
space:
mode:
authorAndres Gomez <[email protected]>2016-10-22 17:01:11 +0300
committerAndres Gomez <[email protected]>2016-11-25 13:18:30 +0200
commitbe54a58da3ee5485d18c04e1ccc0a1c6137a46a3 (patch)
treec1ed597cc1e13800535a63688357b024b1360dcc /src/compiler/glsl/glsl_parser.yy
parentb95793b9a7e8b18eb9b5d80eb79c4913063c8840 (diff)
glsl: ignore all but the rightmost layout qualifier name from the rightmost layout qualifier
From page 46 (page 52 of the PDF) of the GLSL 4.20 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." Consider this example: " #version 150 #extension GL_ARB_shading_language_420pack: enable layout(max_vertices=2) layout(max_vertices=3) out; layout(max_vertices=3) out;" Although different values for "max_vertices" results in a compilation error. The above code is valid because max_vertices=2 is ignored. Hence, when merging qualifiers in an ast_type_qualifier, we now ignore new appearances of a same layout-qualifier-name if the new "is_multiple_layouts_merge" parameter is on, since the GLSL parser works in this case from right to left. In addition, any special treatment for the buffer, uniform, in or out layout defaults has been moved in the GLSL parser to the rule triggered just after any previous processing/merging on the layout-qualifiers has happened in a single declaration since it was run too soon previously. Fixes GL44-CTS.shading_language_420pack.qualifier_override_layout 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.yy130
1 files changed, 63 insertions, 67 deletions
diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy
index 82501af6456..5a8f854ece8 100644
--- a/src/compiler/glsl/glsl_parser.yy
+++ b/src/compiler/glsl/glsl_parser.yy
@@ -297,10 +297,10 @@ static bool match_layout_qualifier(const char *s1, const char *s2,
%type <node> for_init_statement
%type <for_rest_statement> for_rest_statement
%type <node> layout_defaults
-%type <node> layout_uniform_defaults
-%type <node> layout_buffer_defaults
-%type <node> layout_in_defaults
-%type <node> layout_out_defaults
+%type <type_qualifier> layout_uniform_defaults
+%type <type_qualifier> layout_buffer_defaults
+%type <type_qualifier> layout_in_defaults
+%type <type_qualifier> layout_out_defaults
%right THEN ELSE
%%
@@ -1891,7 +1891,7 @@ type_qualifier:
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
$$ = $1;
- $$.merge_qualifier(&@1, state, $2, false);
+ $$.merge_qualifier(& @1, state, $2, false, $2.has_layout());
}
| subroutine_qualifier type_qualifier
{
@@ -2718,7 +2718,8 @@ interface_block:
YYERROR;
}
- if (!$1.merge_qualifier(& @1, state, block->layout, false)) {
+ if (!$1.merge_qualifier(& @1, state, block->layout, false,
+ block->layout.has_layout())) {
YYERROR;
}
@@ -2853,123 +2854,118 @@ member_declaration:
layout_uniform_defaults:
layout_qualifier layout_uniform_defaults
{
- $$ = NULL;
+ $$ = $1;
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, false)) {
- YYERROR;
- }
}
- }
- | layout_qualifier UNIFORM ';'
- {
- if (!state->default_uniform_qualifier->
- merge_qualifier(& @1, state, $1, false)) {
+ if (!$$.merge_qualifier(& @1, state, $2, false, true)) {
YYERROR;
}
- $$ = NULL;
}
+ | layout_qualifier UNIFORM ';'
;
layout_buffer_defaults:
layout_qualifier layout_buffer_defaults
{
- $$ = NULL;
+ $$ = $1;
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, false)) {
- YYERROR;
- }
}
- }
- | layout_qualifier BUFFER ';'
- {
- if (!state->default_shader_storage_qualifier->
- merge_qualifier(& @1, state, $1, false)) {
+ if (!$$.merge_qualifier(& @1, state, $2, false, true)) {
YYERROR;
}
-
- /* From the GLSL 4.50 spec, section 4.4.5:
- *
- * "It is a compile-time error to specify the binding identifier for
- * the global scope or for block member declarations."
- */
- if (state->default_shader_storage_qualifier->flags.q.explicit_binding) {
- _mesa_glsl_error(& @1, state,
- "binding qualifier cannot be set for default layout");
- }
-
- $$ = NULL;
}
+ | layout_qualifier BUFFER ';'
;
layout_in_defaults:
layout_qualifier layout_in_defaults
{
- $$ = NULL;
+ $$ = $1;
if (!state->has_420pack_or_es31()) {
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
YYERROR;
- } else {
- if (!$1.validate_in_qualifier(& @1, state)) {
- YYERROR;
- }
- if (!$1.merge_into_in_qualifier(& @1, state, $$, false)) {
- YYERROR;
- }
- $$ = $2;
+ }
+ if (!$$.merge_qualifier(& @1, state, $2, false, true)) {
+ YYERROR;
+ }
+ if (!$$.validate_in_qualifier(& @1, state)) {
+ YYERROR;
}
}
| layout_qualifier IN_TOK ';'
{
- $$ = NULL;
if (!$1.validate_in_qualifier(& @1, state)) {
YYERROR;
}
- if (!$1.merge_into_in_qualifier(& @1, state, $$, true)) {
- YYERROR;
- }
}
;
layout_out_defaults:
layout_qualifier layout_out_defaults
{
- $$ = NULL;
+ $$ = $1;
if (!state->has_420pack_or_es31()) {
_mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers");
YYERROR;
- } else {
- if (!$1.validate_out_qualifier(& @1, state)) {
- YYERROR;
- }
- if (!$1.merge_into_out_qualifier(& @1, state, $$, false)) {
- YYERROR;
- }
- $$ = $2;
+ }
+ if (!$$.merge_qualifier(& @1, state, $2, false, true)) {
+ YYERROR;
+ }
+ if (!$$.validate_out_qualifier(& @1, state)) {
+ YYERROR;
}
}
| layout_qualifier OUT_TOK ';'
{
- $$ = NULL;
if (!$1.validate_out_qualifier(& @1, state)) {
YYERROR;
}
- if (!$1.merge_into_out_qualifier(& @1, state, $$, true)) {
- YYERROR;
- }
}
;
layout_defaults:
layout_uniform_defaults
+ {
+ $$ = NULL;
+ if (!state->default_uniform_qualifier->
+ merge_qualifier(& @1, state, $1, false)) {
+ YYERROR;
+ }
+ }
| layout_buffer_defaults
+ {
+ $$ = NULL;
+ if (!state->default_shader_storage_qualifier->
+ merge_qualifier(& @1, state, $1, false)) {
+ YYERROR;
+ }
+
+ /* From the GLSL 4.50 spec, section 4.4.5:
+ *
+ * "It is a compile-time error to specify the binding identifier for
+ * the global scope or for block member declarations."
+ */
+ if (state->default_shader_storage_qualifier->flags.q.explicit_binding) {
+ _mesa_glsl_error(& @1, state,
+ "binding qualifier cannot be set for default layout");
+ }
+ }
| layout_in_defaults
+ {
+ $$ = NULL;
+ if (!$1.merge_into_in_qualifier(& @1, state, $$, true)) {
+ YYERROR;
+ }
+ }
| layout_out_defaults
+ {
+ $$ = NULL;
+ if (!$1.merge_into_out_qualifier(& @1, state, $$, true)) {
+ YYERROR;
+ }
+ }
;