X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fglsl_parser.yy;h=ec2dd6a05138c059f183a74d19f6464b9c7bd171;hb=5d2b2b59c451915c0b11184ae47c0673fdff3146;hp=4ab9e145001e9046d16a9a2143b9da23379a2ed1;hpb=58709d36d73419c21b899d4b9d08a4a82a2cc28b;p=mesa.git diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index 4ab9e145001..ec2dd6a0513 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -33,6 +33,8 @@ #include "glsl_parser_extras.h" #include "compiler/glsl_types.h" #include "main/context.h" +#include "util/u_string.h" +#include "util/format/u_format.h" #ifdef _MSC_VER #pragma warning( disable : 4065 ) // switch statement contains 'default' but no 'case' labels @@ -90,6 +92,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, @$.last_line = 1; @$.last_column = 1; @$.source = 0; + @$.path = NULL; } %lex-param {struct _mesa_glsl_parse_state *state} @@ -97,6 +100,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %union { int n; + int64_t n64; float real; double dreal; const char *identifier; @@ -131,40 +135,17 @@ static bool match_layout_qualifier(const char *s1, const char *s2, ast_node *then_statement; ast_node *else_statement; } selection_rest_statement; + + const glsl_type *type; } -%token ATTRIBUTE CONST_TOK BOOL_TOK FLOAT_TOK INT_TOK UINT_TOK DOUBLE_TOK -%token BREAK BUFFER CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT -%token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4 DVEC2 DVEC3 DVEC4 +%token ATTRIBUTE CONST_TOK +%token BASIC_TYPE_TOK +%token BREAK BUFFER CONTINUE DO ELSE FOR IF DEMOTE DISCARD RETURN SWITCH CASE DEFAULT %token CENTROID IN_TOK OUT_TOK INOUT_TOK UNIFORM VARYING SAMPLE %token NOPERSPECTIVE FLAT SMOOTH -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 -%token DMAT2X2 DMAT2X3 DMAT2X4 -%token DMAT3X2 DMAT3X3 DMAT3X4 -%token DMAT4X2 DMAT4X3 DMAT4X4 -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW -%token ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY ISAMPLERCUBEARRAY -%token USAMPLER1D USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER1DARRAY -%token USAMPLER2DARRAY USAMPLERCUBEARRAY -%token SAMPLER2DRECT ISAMPLER2DRECT USAMPLER2DRECT SAMPLER2DRECTSHADOW -%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER -%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS -%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY -%token SAMPLEREXTERNALOES -%token IMAGE1D IMAGE2D IMAGE3D IMAGE2DRECT IMAGECUBE IMAGEBUFFER -%token IMAGE1DARRAY IMAGE2DARRAY IMAGECUBEARRAY IMAGE2DMS IMAGE2DMSARRAY -%token IIMAGE1D IIMAGE2D IIMAGE3D IIMAGE2DRECT IIMAGECUBE IIMAGEBUFFER -%token IIMAGE1DARRAY IIMAGE2DARRAY IIMAGECUBEARRAY IIMAGE2DMS IIMAGE2DMSARRAY -%token UIMAGE1D UIMAGE2D UIMAGE3D UIMAGE2DRECT UIMAGECUBE UIMAGEBUFFER -%token UIMAGE1DARRAY UIMAGE2DARRAY UIMAGECUBEARRAY UIMAGE2DMS UIMAGE2DMSARRAY %token IMAGE1DSHADOW IMAGE2DSHADOW IMAGE1DARRAYSHADOW IMAGE2DARRAYSHADOW %token COHERENT VOLATILE RESTRICT READONLY WRITEONLY -%token ATOMIC_UINT %token SHARED %token STRUCT VOID_TOK WHILE %token IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER @@ -173,6 +154,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token FLOATCONSTANT %token DOUBLECONSTANT %token INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token INT64CONSTANT UINT64CONSTANT %token FIELD_SELECTION %token LEFT_OP RIGHT_OP %token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP @@ -185,6 +167,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token VERSION_TOK EXTENSION LINE COLON EOL INTERFACE OUTPUT %token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF %token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF +%token PRAGMA_WARNING_ON PRAGMA_WARNING_OFF %token PRAGMA_INVARIANT_ALL %token LAYOUT_TOK %token DOT_TOK @@ -222,7 +205,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %type type_specifier %type type_specifier_nonarray %type array_specifier -%type basic_type_specifier_nonarray +%type basic_type_specifier_nonarray %type fully_specified_type %type function_prototype %type function_header @@ -267,6 +250,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %type unary_operator %type function_identifier %type external_declaration +%type pragma_statement %type init_declarator_list %type single_declaration %type initializer @@ -274,6 +258,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %type declaration %type declaration_statement %type jump_statement +%type demote_statement %type interface_block %type basic_interface_block %type struct_specifier @@ -297,10 +282,10 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %type for_init_statement %type for_rest_statement %type layout_defaults -%type layout_uniform_defaults -%type layout_buffer_defaults -%type layout_in_defaults -%type layout_out_defaults +%type layout_uniform_defaults +%type layout_buffer_defaults +%type layout_in_defaults +%type layout_out_defaults %right THEN ELSE %% @@ -349,10 +334,10 @@ version_statement: ; pragma_statement: - PRAGMA_DEBUG_ON EOL - | PRAGMA_DEBUG_OFF EOL - | PRAGMA_OPTIMIZE_ON EOL - | PRAGMA_OPTIMIZE_OFF EOL + PRAGMA_DEBUG_ON EOL { $$ = NULL; } + | PRAGMA_DEBUG_OFF EOL { $$ = NULL; } + | PRAGMA_OPTIMIZE_ON EOL { $$ = NULL; } + | PRAGMA_OPTIMIZE_OFF EOL { $$ = NULL; } | PRAGMA_INVARIANT_ALL EOL { /* Pragma invariant(all) cannot be used in a fragment shader. @@ -374,6 +359,18 @@ pragma_statement: } else { state->all_invariant = true; } + + $$ = NULL; + } + | PRAGMA_WARNING_ON EOL + { + void *mem_ctx = state->linalloc; + $$ = new(mem_ctx) ast_warnings_toggle(true); + } + | PRAGMA_WARNING_OFF EOL + { + void *mem_ctx = state->linalloc; + $$ = new(mem_ctx) ast_warnings_toggle(false); } ; @@ -432,42 +429,56 @@ variable_identifier: primary_expression: variable_identifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.identifier = $1; } | INTCONSTANT { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.int_constant = $1; } | UINTCONSTANT { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.uint_constant = $1; } + | INT64CONSTANT + { + void *ctx = state->linalloc; + $$ = new(ctx) ast_expression(ast_int64_constant, NULL, NULL, NULL); + $$->set_location(@1); + $$->primary_expression.int64_constant = $1; + } + | UINT64CONSTANT + { + void *ctx = state->linalloc; + $$ = new(ctx) ast_expression(ast_uint64_constant, NULL, NULL, NULL); + $$->set_location(@1); + $$->primary_expression.uint64_constant = $1; + } | FLOATCONSTANT { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.float_constant = $1; } | DOUBLECONSTANT { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_double_constant, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.double_constant = $1; } | BOOLCONSTANT { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); $$->set_location(@1); $$->primary_expression.bool_constant = $1; @@ -482,7 +493,7 @@ postfix_expression: primary_expression | postfix_expression '[' integer_expression ']' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); $$->set_location_range(@1, @4); } @@ -492,20 +503,20 @@ postfix_expression: } | postfix_expression DOT_TOK FIELD_SELECTION { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); $$->set_location_range(@1, @3); $$->primary_expression.identifier = $3; } | postfix_expression INC_OP { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); $$->set_location_range(@1, @2); } | postfix_expression DEC_OP { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); $$->set_location_range(@1, @2); } @@ -558,13 +569,13 @@ function_call_header: function_identifier: type_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_function_expression($1); $$->set_location(@1); } | postfix_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_function_expression($1); $$->set_location(@1); } @@ -579,19 +590,19 @@ unary_expression: postfix_expression | INC_OP unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); $$->set_location(@1); } | DEC_OP unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); $$->set_location(@1); } | unary_operator unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression($1, $2, NULL, NULL); $$->set_location_range(@1, @2); } @@ -609,19 +620,19 @@ multiplicative_expression: unary_expression | multiplicative_expression '*' unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); $$->set_location_range(@1, @3); } | multiplicative_expression '/' unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); $$->set_location_range(@1, @3); } | multiplicative_expression '%' unary_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); $$->set_location_range(@1, @3); } @@ -631,13 +642,13 @@ additive_expression: multiplicative_expression | additive_expression '+' multiplicative_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); $$->set_location_range(@1, @3); } | additive_expression '-' multiplicative_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); $$->set_location_range(@1, @3); } @@ -647,13 +658,13 @@ shift_expression: additive_expression | shift_expression LEFT_OP additive_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); $$->set_location_range(@1, @3); } | shift_expression RIGHT_OP additive_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); $$->set_location_range(@1, @3); } @@ -663,25 +674,25 @@ relational_expression: shift_expression | relational_expression '<' shift_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); $$->set_location_range(@1, @3); } | relational_expression '>' shift_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); $$->set_location_range(@1, @3); } | relational_expression LE_OP shift_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); $$->set_location_range(@1, @3); } | relational_expression GE_OP shift_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); $$->set_location_range(@1, @3); } @@ -691,13 +702,13 @@ equality_expression: relational_expression | equality_expression EQ_OP relational_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); $$->set_location_range(@1, @3); } | equality_expression NE_OP relational_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); $$->set_location_range(@1, @3); } @@ -707,7 +718,7 @@ and_expression: equality_expression | and_expression '&' equality_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_bit_and, $1, $3); $$->set_location_range(@1, @3); } @@ -717,7 +728,7 @@ exclusive_or_expression: and_expression | exclusive_or_expression '^' and_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); $$->set_location_range(@1, @3); } @@ -727,7 +738,7 @@ inclusive_or_expression: exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); $$->set_location_range(@1, @3); } @@ -737,7 +748,7 @@ logical_and_expression: inclusive_or_expression | logical_and_expression AND_OP inclusive_or_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); $$->set_location_range(@1, @3); } @@ -747,7 +758,7 @@ logical_xor_expression: logical_and_expression | logical_xor_expression XOR_OP logical_and_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); $$->set_location_range(@1, @3); } @@ -757,7 +768,7 @@ logical_or_expression: logical_xor_expression | logical_or_expression OR_OP logical_xor_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); $$->set_location_range(@1, @3); } @@ -767,7 +778,7 @@ conditional_expression: logical_or_expression | logical_or_expression '?' expression ':' assignment_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); $$->set_location_range(@1, @5); } @@ -777,7 +788,7 @@ assignment_expression: conditional_expression | unary_expression assignment_operator assignment_expression { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression($2, $1, $3, NULL); $$->set_location_range(@1, @3); } @@ -804,7 +815,7 @@ expression: } | expression ',' assignment_expression { - void *ctx = state; + void *ctx = state->linalloc; if ($1->oper != ast_sequence) { $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); $$->set_location_range(@1, @3); @@ -838,6 +849,16 @@ 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; + if (!block->layout.push_to_global(& @1, state)) { + YYERROR; + } $$ = $1; } ; @@ -867,13 +888,13 @@ function_header_with_parameters: function_header: fully_specified_type variable_identifier '(' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_function(); $$->set_location(@2); $$->return_type = $1; $$->identifier = $2; - if ($1->qualifier.flags.q.subroutine) { + if ($1->qualifier.is_subroutine_decl()) { /* add type for IDENTIFIER search */ state->symbols->add_type($2, glsl_type::get_subroutine_instance($2)); } else @@ -885,7 +906,7 @@ function_header: parameter_declarator: type_specifier any_identifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_parameter_declarator(); $$->set_location_range(@1, @2); $$->type = new(ctx) ast_fully_specified_type(); @@ -894,9 +915,26 @@ parameter_declarator: $$->identifier = $2; state->symbols->add_variable(new(state) ir_variable(NULL, $2, ir_var_auto)); } + | layout_qualifier type_specifier any_identifier + { + if (state->allow_layout_qualifier_on_function_parameter) { + void *ctx = state->linalloc; + $$ = new(ctx) ast_parameter_declarator(); + $$->set_location_range(@2, @3); + $$->type = new(ctx) ast_fully_specified_type(); + $$->type->set_location(@2); + $$->type->specifier = $2; + $$->identifier = $3; + state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto)); + } else { + _mesa_glsl_error(&@1, state, + "is is not allowed on function parameter"); + YYERROR; + } + } | type_specifier any_identifier array_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_parameter_declarator(); $$->set_location_range(@1, @3); $$->type = new(ctx) ast_fully_specified_type(); @@ -913,15 +951,21 @@ parameter_declaration: { $$ = $2; $$->type->qualifier = $1; + if (!$$->type->qualifier.push_to_global(& @1, state)) { + YYERROR; + } } | parameter_qualifier parameter_type_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_parameter_declarator(); $$->set_location(@2); $$->type = new(ctx) ast_fully_specified_type(); $$->type->set_location_range(@1, @2); $$->type->qualifier = $1; + if (!$$->type->qualifier.push_to_global(& @1, state)) { + YYERROR; + } $$->type->specifier = $2; } ; @@ -1004,7 +1048,7 @@ init_declarator_list: single_declaration | init_declarator_list ',' any_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($3, NULL, NULL); decl->set_location(@3); @@ -1014,7 +1058,7 @@ init_declarator_list: } | init_declarator_list ',' any_identifier array_specifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($3, $4, NULL); decl->set_location_range(@3, @4); @@ -1024,7 +1068,7 @@ init_declarator_list: } | init_declarator_list ',' any_identifier array_specifier '=' initializer { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($3, $4, $6); decl->set_location_range(@3, @4); @@ -1034,7 +1078,7 @@ init_declarator_list: } | init_declarator_list ',' any_identifier '=' initializer { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($3, NULL, $5); decl->set_location(@3); @@ -1048,14 +1092,14 @@ init_declarator_list: single_declaration: fully_specified_type { - void *ctx = state; + void *ctx = state->linalloc; /* Empty declaration list is valid. */ $$ = new(ctx) ast_declarator_list($1); $$->set_location(@1); } | fully_specified_type any_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); decl->set_location(@2); @@ -1066,7 +1110,7 @@ single_declaration: } | fully_specified_type any_identifier array_specifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, $3, NULL); decl->set_location_range(@2, @3); @@ -1077,7 +1121,7 @@ single_declaration: } | fully_specified_type any_identifier array_specifier '=' initializer { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, $3, $5); decl->set_location_range(@2, @3); @@ -1088,7 +1132,7 @@ single_declaration: } | fully_specified_type any_identifier '=' initializer { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, $4); decl->set_location(@2); @@ -1099,7 +1143,7 @@ single_declaration: } | INVARIANT variable_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); decl->set_location(@2); @@ -1111,7 +1155,7 @@ single_declaration: } | PRECISE variable_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, NULL); decl->set_location(@2); @@ -1126,17 +1170,20 @@ single_declaration: fully_specified_type: type_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_fully_specified_type(); $$->set_location(@1); $$->specifier = $1; } | type_qualifier type_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_fully_specified_type(); $$->set_location_range(@1, @2); $$->qualifier = $1; + if (!$$->qualifier.push_to_global(& @1, state)) { + YYERROR; + } $$->specifier = $2; if ($$->specifier->structure != NULL && $$->specifier->structure->is_declaration) { @@ -1191,14 +1238,18 @@ layout_qualifier_id: state->ARB_conservative_depth_enable || state->is_version(420, 0))) { if (match_layout_qualifier($1, "depth_any", state) == 0) { - $$.flags.q.depth_any = 1; + $$.flags.q.depth_type = 1; + $$.depth_type = ast_depth_any; } else if (match_layout_qualifier($1, "depth_greater", state) == 0) { - $$.flags.q.depth_greater = 1; + $$.flags.q.depth_type = 1; + $$.depth_type = ast_depth_greater; } else if (match_layout_qualifier($1, "depth_less", state) == 0) { - $$.flags.q.depth_less = 1; + $$.flags.q.depth_type = 1; + $$.depth_type = ast_depth_less; } else if (match_layout_qualifier($1, "depth_unchanged", state) == 0) { - $$.flags.q.depth_unchanged = 1; + $$.flags.q.depth_type = 1; + $$.depth_type = ast_depth_unchanged; } if ($$.flags.i && state->AMD_conservative_depth_warn) { @@ -1282,12 +1333,11 @@ layout_qualifier_id: } /* Layout qualifiers for ARB_shader_image_load_store. */ - if (state->ARB_shader_image_load_store_enable || - state->is_version(420, 310)) { + if (state->has_shader_image_load_store()) { if (!$$.flags.i) { static const struct { const char *name; - GLenum format; + enum pipe_format format; glsl_base_type base_type; /** Minimum desktop GLSL version required for the image * format. Use 130 if already present in the original @@ -1296,52 +1346,75 @@ layout_qualifier_id: unsigned required_glsl; /** Minimum GLSL ES version required for the image format. */ unsigned required_essl; + /* NV_image_formats */ + bool nv_image_formats; + bool ext_qualifiers; } map[] = { - { "rgba32f", GL_RGBA32F, GLSL_TYPE_FLOAT, 130, 310 }, - { "rgba16f", GL_RGBA16F, GLSL_TYPE_FLOAT, 130, 310 }, - { "rg32f", GL_RG32F, GLSL_TYPE_FLOAT, 130, 0 }, - { "rg16f", GL_RG16F, GLSL_TYPE_FLOAT, 130, 0 }, - { "r11f_g11f_b10f", GL_R11F_G11F_B10F, GLSL_TYPE_FLOAT, 130, 0 }, - { "r32f", GL_R32F, GLSL_TYPE_FLOAT, 130, 310 }, - { "r16f", GL_R16F, GLSL_TYPE_FLOAT, 130, 0 }, - { "rgba32ui", GL_RGBA32UI, GLSL_TYPE_UINT, 130, 310 }, - { "rgba16ui", GL_RGBA16UI, GLSL_TYPE_UINT, 130, 310 }, - { "rgb10_a2ui", GL_RGB10_A2UI, GLSL_TYPE_UINT, 130, 0 }, - { "rgba8ui", GL_RGBA8UI, GLSL_TYPE_UINT, 130, 310 }, - { "rg32ui", GL_RG32UI, GLSL_TYPE_UINT, 130, 0 }, - { "rg16ui", GL_RG16UI, GLSL_TYPE_UINT, 130, 0 }, - { "rg8ui", GL_RG8UI, GLSL_TYPE_UINT, 130, 0 }, - { "r32ui", GL_R32UI, GLSL_TYPE_UINT, 130, 310 }, - { "r16ui", GL_R16UI, GLSL_TYPE_UINT, 130, 0 }, - { "r8ui", GL_R8UI, GLSL_TYPE_UINT, 130, 0 }, - { "rgba32i", GL_RGBA32I, GLSL_TYPE_INT, 130, 310 }, - { "rgba16i", GL_RGBA16I, GLSL_TYPE_INT, 130, 310 }, - { "rgba8i", GL_RGBA8I, GLSL_TYPE_INT, 130, 310 }, - { "rg32i", GL_RG32I, GLSL_TYPE_INT, 130, 0 }, - { "rg16i", GL_RG16I, GLSL_TYPE_INT, 130, 0 }, - { "rg8i", GL_RG8I, GLSL_TYPE_INT, 130, 0 }, - { "r32i", GL_R32I, GLSL_TYPE_INT, 130, 310 }, - { "r16i", GL_R16I, GLSL_TYPE_INT, 130, 0 }, - { "r8i", GL_R8I, GLSL_TYPE_INT, 130, 0 }, - { "rgba16", GL_RGBA16, GLSL_TYPE_FLOAT, 130, 0 }, - { "rgb10_a2", GL_RGB10_A2, GLSL_TYPE_FLOAT, 130, 0 }, - { "rgba8", GL_RGBA8, GLSL_TYPE_FLOAT, 130, 310 }, - { "rg16", GL_RG16, GLSL_TYPE_FLOAT, 130, 0 }, - { "rg8", GL_RG8, GLSL_TYPE_FLOAT, 130, 0 }, - { "r16", GL_R16, GLSL_TYPE_FLOAT, 130, 0 }, - { "r8", GL_R8, GLSL_TYPE_FLOAT, 130, 0 }, - { "rgba16_snorm", GL_RGBA16_SNORM, GLSL_TYPE_FLOAT, 130, 0 }, - { "rgba8_snorm", GL_RGBA8_SNORM, GLSL_TYPE_FLOAT, 130, 310 }, - { "rg16_snorm", GL_RG16_SNORM, GLSL_TYPE_FLOAT, 130, 0 }, - { "rg8_snorm", GL_RG8_SNORM, GLSL_TYPE_FLOAT, 130, 0 }, - { "r16_snorm", GL_R16_SNORM, GLSL_TYPE_FLOAT, 130, 0 }, - { "r8_snorm", GL_R8_SNORM, GLSL_TYPE_FLOAT, 130, 0 } + { "rgba32f", PIPE_FORMAT_R32G32B32A32_FLOAT, GLSL_TYPE_FLOAT, 130, 310, false, false }, + { "rgba16f", PIPE_FORMAT_R16G16B16A16_FLOAT, GLSL_TYPE_FLOAT, 130, 310, false, false }, + { "rg32f", PIPE_FORMAT_R32G32_FLOAT, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rg16f", PIPE_FORMAT_R16G16_FLOAT, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r11f_g11f_b10f", PIPE_FORMAT_R11G11B10_FLOAT, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r32f", PIPE_FORMAT_R32_FLOAT, GLSL_TYPE_FLOAT, 130, 310, false, false }, + { "r16f", PIPE_FORMAT_R16_FLOAT, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rgba32ui", PIPE_FORMAT_R32G32B32A32_UINT, GLSL_TYPE_UINT, 130, 310, false, false }, + { "rgba16ui", PIPE_FORMAT_R16G16B16A16_UINT, GLSL_TYPE_UINT, 130, 310, false, false }, + { "rgb10_a2ui", PIPE_FORMAT_R10G10B10A2_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "rgba8ui", PIPE_FORMAT_R8G8B8A8_UINT, GLSL_TYPE_UINT, 130, 310, false, false }, + { "rg32ui", PIPE_FORMAT_R32G32_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "rg16ui", PIPE_FORMAT_R16G16_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "rg8ui", PIPE_FORMAT_R8G8_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "r32ui", PIPE_FORMAT_R32_UINT, GLSL_TYPE_UINT, 130, 310, false, false }, + { "r16ui", PIPE_FORMAT_R16_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "r8ui", PIPE_FORMAT_R8_UINT, GLSL_TYPE_UINT, 130, 0, true, false }, + { "rgba32i", PIPE_FORMAT_R32G32B32A32_SINT, GLSL_TYPE_INT, 130, 310, false, false }, + { "rgba16i", PIPE_FORMAT_R16G16B16A16_SINT, GLSL_TYPE_INT, 130, 310, false, false }, + { "rgba8i", PIPE_FORMAT_R8G8B8A8_SINT, GLSL_TYPE_INT, 130, 310, false, false }, + { "rg32i", PIPE_FORMAT_R32G32_SINT, GLSL_TYPE_INT, 130, 0, true, false }, + { "rg16i", PIPE_FORMAT_R16G16_SINT, GLSL_TYPE_INT, 130, 0, true, false }, + { "rg8i", PIPE_FORMAT_R8G8_SINT, GLSL_TYPE_INT, 130, 0, true, false }, + { "r32i", PIPE_FORMAT_R32_SINT, GLSL_TYPE_INT, 130, 310, false, false }, + { "r16i", PIPE_FORMAT_R16_SINT, GLSL_TYPE_INT, 130, 0, true, false }, + { "r8i", PIPE_FORMAT_R8_SINT, GLSL_TYPE_INT, 130, 0, true, false }, + { "rgba16", PIPE_FORMAT_R16G16B16A16_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rgb10_a2", PIPE_FORMAT_R10G10B10A2_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rgba8", PIPE_FORMAT_R8G8B8A8_UNORM, GLSL_TYPE_FLOAT, 130, 310, false, false }, + { "rg16", PIPE_FORMAT_R16G16_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rg8", PIPE_FORMAT_R8G8_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r16", PIPE_FORMAT_R16_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r8", PIPE_FORMAT_R8_UNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rgba16_snorm", PIPE_FORMAT_R16G16B16A16_SNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rgba8_snorm", PIPE_FORMAT_R8G8B8A8_SNORM, GLSL_TYPE_FLOAT, 130, 310, false, false }, + { "rg16_snorm", PIPE_FORMAT_R16G16_SNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "rg8_snorm", PIPE_FORMAT_R8G8_SNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r16_snorm", PIPE_FORMAT_R16_SNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + { "r8_snorm", PIPE_FORMAT_R8_SNORM, GLSL_TYPE_FLOAT, 130, 0, true, false }, + + /* From GL_EXT_shader_image_load_store: */ + /* base_type is incorrect but it'll be patched later when we know + * the variable type. See ast_to_hir.cpp */ + { "size1x8", PIPE_FORMAT_R8_SINT, GLSL_TYPE_VOID, 130, 0, false, true }, + { "size1x16", PIPE_FORMAT_R16_SINT, GLSL_TYPE_VOID, 130, 0, false, true }, + { "size1x32", PIPE_FORMAT_R32_SINT, GLSL_TYPE_VOID, 130, 0, false, true }, + { "size2x32", PIPE_FORMAT_R32G32_SINT, GLSL_TYPE_VOID, 130, 0, false, true }, + { "size4x32", PIPE_FORMAT_R32G32B32A32_SINT, GLSL_TYPE_VOID, 130, 0, false, true }, }; for (unsigned i = 0; i < ARRAY_SIZE(map); i++) { - if (state->is_version(map[i].required_glsl, - map[i].required_essl) && + if ((state->is_version(map[i].required_glsl, + map[i].required_essl) || + (state->NV_image_formats_enable && + map[i].nv_image_formats)) && match_layout_qualifier($1, map[i].name, state) == 0) { + /* Skip ARB_shader_image_load_store qualifiers if not enabled */ + if (!map[i].ext_qualifiers && !(state->ARB_shader_image_load_store_enable || + state->is_version(420, 310))) { + continue; + } + /* Skip EXT_shader_image_load_store qualifiers if not enabled */ + if (map[i].ext_qualifiers && !state->EXT_shader_image_load_store_enable) { + continue; + } $$.flags.q.explicit_image_format = 1; $$.image_format = map[i].format; $$.image_base_type = map[i].base_type; @@ -1349,9 +1422,10 @@ layout_qualifier_id: } } } + } - if (!$$.flags.i && - match_layout_qualifier($1, "early_fragment_tests", state) == 0) { + if (!$$.flags.i) { + if (match_layout_qualifier($1, "early_fragment_tests", state) == 0) { /* From section 4.4.1.3 of the GLSL 4.50 specification * (Fragment Shader Inputs): * @@ -1369,11 +1443,84 @@ layout_qualifier_id: $$.flags.q.early_fragment_tests = 1; } + + if (match_layout_qualifier($1, "inner_coverage", state) == 0) { + if (state->stage != MESA_SHADER_FRAGMENT) { + _mesa_glsl_error(& @1, state, + "inner_coverage layout qualifier only " + "valid in fragment shaders"); + } + + if (state->INTEL_conservative_rasterization_enable) { + $$.flags.q.inner_coverage = 1; + } else { + _mesa_glsl_error(& @1, state, + "inner_coverage layout qualifier present, " + "but the INTEL_conservative_rasterization extension " + "is not enabled."); + } + } + + if (match_layout_qualifier($1, "post_depth_coverage", state) == 0) { + if (state->stage != MESA_SHADER_FRAGMENT) { + _mesa_glsl_error(& @1, state, + "post_depth_coverage layout qualifier only " + "valid in fragment shaders"); + } + + if (state->ARB_post_depth_coverage_enable || + state->INTEL_conservative_rasterization_enable) { + $$.flags.q.post_depth_coverage = 1; + } else { + _mesa_glsl_error(& @1, state, + "post_depth_coverage layout qualifier present, " + "but the GL_ARB_post_depth_coverage extension " + "is not enabled."); + } + } + + if ($$.flags.q.post_depth_coverage && $$.flags.q.inner_coverage) { + _mesa_glsl_error(& @1, state, + "post_depth_coverage & inner_coverage layout qualifiers " + "are mutually exclusive"); + } + } + + const bool pixel_interlock_ordered = match_layout_qualifier($1, + "pixel_interlock_ordered", state) == 0; + const bool pixel_interlock_unordered = match_layout_qualifier($1, + "pixel_interlock_unordered", state) == 0; + const bool sample_interlock_ordered = match_layout_qualifier($1, + "sample_interlock_ordered", state) == 0; + const bool sample_interlock_unordered = match_layout_qualifier($1, + "sample_interlock_unordered", state) == 0; + + if (pixel_interlock_ordered + pixel_interlock_unordered + + sample_interlock_ordered + sample_interlock_unordered > 0 && + state->stage != MESA_SHADER_FRAGMENT) { + _mesa_glsl_error(& @1, state, "interlock layout qualifiers: " + "pixel_interlock_ordered, pixel_interlock_unordered, " + "sample_interlock_ordered and sample_interlock_unordered, " + "only valid in fragment shader input layout declaration."); + } else if (pixel_interlock_ordered + pixel_interlock_unordered + + sample_interlock_ordered + sample_interlock_unordered > 0 && + !state->ARB_fragment_shader_interlock_enable && + !state->NV_fragment_shader_interlock_enable) { + _mesa_glsl_error(& @1, state, + "interlock layout qualifier present, but the " + "GL_ARB_fragment_shader_interlock or " + "GL_NV_fragment_shader_interlock extension is not " + "enabled."); + } else { + $$.flags.q.pixel_interlock_ordered = pixel_interlock_ordered; + $$.flags.q.pixel_interlock_unordered = pixel_interlock_unordered; + $$.flags.q.sample_interlock_ordered = sample_interlock_ordered; + $$.flags.q.sample_interlock_unordered = sample_interlock_unordered; } /* Layout qualifiers for tessellation evaluation shaders. */ if (!$$.flags.i) { - struct { + static const struct { const char *s; GLenum e; } map[] = { @@ -1396,13 +1543,13 @@ layout_qualifier_id: } } if (!$$.flags.i) { - struct { + static const struct { const char *s; - GLenum e; + enum gl_tess_spacing e; } map[] = { - { "equal_spacing", GL_EQUAL }, - { "fractional_odd_spacing", GL_FRACTIONAL_ODD }, - { "fractional_even_spacing", GL_FRACTIONAL_EVEN }, + { "equal_spacing", TESS_SPACING_EQUAL }, + { "fractional_odd_spacing", TESS_SPACING_FRACTIONAL_ODD }, + { "fractional_even_spacing", TESS_SPACING_FRACTIONAL_EVEN }, }; for (unsigned i = 0; i < ARRAY_SIZE(map); i++) { if (match_layout_qualifier($1, map[i].s, state) == 0) { @@ -1446,6 +1593,141 @@ layout_qualifier_id: } } + if (!$$.flags.i) { + static const struct { + const char *s; + uint32_t mask; + } map[] = { + { "blend_support_multiply", BITFIELD_BIT(BLEND_MULTIPLY) }, + { "blend_support_screen", BITFIELD_BIT(BLEND_SCREEN) }, + { "blend_support_overlay", BITFIELD_BIT(BLEND_OVERLAY) }, + { "blend_support_darken", BITFIELD_BIT(BLEND_DARKEN) }, + { "blend_support_lighten", BITFIELD_BIT(BLEND_LIGHTEN) }, + { "blend_support_colordodge", BITFIELD_BIT(BLEND_COLORDODGE) }, + { "blend_support_colorburn", BITFIELD_BIT(BLEND_COLORBURN) }, + { "blend_support_hardlight", BITFIELD_BIT(BLEND_HARDLIGHT) }, + { "blend_support_softlight", BITFIELD_BIT(BLEND_SOFTLIGHT) }, + { "blend_support_difference", BITFIELD_BIT(BLEND_DIFFERENCE) }, + { "blend_support_exclusion", BITFIELD_BIT(BLEND_EXCLUSION) }, + { "blend_support_hsl_hue", BITFIELD_BIT(BLEND_HSL_HUE) }, + { "blend_support_hsl_saturation", BITFIELD_BIT(BLEND_HSL_SATURATION) }, + { "blend_support_hsl_color", BITFIELD_BIT(BLEND_HSL_COLOR) }, + { "blend_support_hsl_luminosity", BITFIELD_BIT(BLEND_HSL_LUMINOSITY) }, + { "blend_support_all_equations", (1u << (BLEND_HSL_LUMINOSITY + 1)) - 2 }, + }; + for (unsigned i = 0; i < ARRAY_SIZE(map); i++) { + if (match_layout_qualifier($1, map[i].s, state) == 0) { + $$.flags.q.blend_support = 1; + state->fs_blend_support |= map[i].mask; + break; + } + } + + if ($$.flags.i && + !state->KHR_blend_equation_advanced_enable && + !state->is_version(0, 320)) { + _mesa_glsl_error(& @1, state, + "advanced blending layout qualifiers require " + "ESSL 3.20 or KHR_blend_equation_advanced"); + } + + if ($$.flags.i && state->stage != MESA_SHADER_FRAGMENT) { + _mesa_glsl_error(& @1, state, + "advanced blending layout qualifiers only " + "valid in fragment shaders"); + } + } + + /* Layout qualifiers for ARB_compute_variable_group_size. */ + if (!$$.flags.i) { + if (match_layout_qualifier($1, "local_size_variable", state) == 0) { + $$.flags.q.local_size_variable = 1; + } + + if ($$.flags.i && !state->ARB_compute_variable_group_size_enable) { + _mesa_glsl_error(& @1, state, + "qualifier `local_size_variable` requires " + "ARB_compute_variable_group_size"); + } + } + + /* Layout qualifiers for ARB_bindless_texture. */ + if (!$$.flags.i) { + if (match_layout_qualifier($1, "bindless_sampler", state) == 0) + $$.flags.q.bindless_sampler = 1; + if (match_layout_qualifier($1, "bound_sampler", state) == 0) + $$.flags.q.bound_sampler = 1; + + if (state->has_shader_image_load_store()) { + if (match_layout_qualifier($1, "bindless_image", state) == 0) + $$.flags.q.bindless_image = 1; + if (match_layout_qualifier($1, "bound_image", state) == 0) + $$.flags.q.bound_image = 1; + } + + if ($$.flags.i && !state->has_bindless()) { + _mesa_glsl_error(& @1, state, + "qualifier `%s` requires " + "ARB_bindless_texture", $1); + } + } + + if (!$$.flags.i && + state->EXT_shader_framebuffer_fetch_non_coherent_enable) { + if (match_layout_qualifier($1, "noncoherent", state) == 0) + $$.flags.q.non_coherent = 1; + } + + // Layout qualifiers for NV_compute_shader_derivatives. + if (!$$.flags.i) { + if (match_layout_qualifier($1, "derivative_group_quadsNV", state) == 0) { + $$.flags.q.derivative_group = 1; + $$.derivative_group = DERIVATIVE_GROUP_QUADS; + } else if (match_layout_qualifier($1, "derivative_group_linearNV", state) == 0) { + $$.flags.q.derivative_group = 1; + $$.derivative_group = DERIVATIVE_GROUP_LINEAR; + } + + if ($$.flags.i) { + if (!state->has_compute_shader()) { + _mesa_glsl_error(& @1, state, + "qualifier `%s' requires " + "a compute shader", $1); + } + + if (!state->NV_compute_shader_derivatives_enable) { + _mesa_glsl_error(& @1, state, + "qualifier `%s' requires " + "NV_compute_shader_derivatives", $1); + } + + if (state->NV_compute_shader_derivatives_warn) { + _mesa_glsl_warning(& @1, state, + "NV_compute_shader_derivatives layout " + "qualifier `%s' used", $1); + } + } + } + + /* Layout qualifier for NV_viewport_array2. */ + if (!$$.flags.i && state->stage != MESA_SHADER_FRAGMENT) { + if (match_layout_qualifier($1, "viewport_relative", state) == 0) { + $$.flags.q.viewport_relative = 1; + } + + if ($$.flags.i && !state->NV_viewport_array2_enable) { + _mesa_glsl_error(& @1, state, + "qualifier `%s' requires " + "GL_NV_viewport_array2", $1); + } + + if ($$.flags.i && state->NV_viewport_array2_warn) { + _mesa_glsl_warning(& @1, state, + "GL_NV_viewport_array2 layout " + "identifier `%s' used", $1); + } + } + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'", $1); @@ -1455,7 +1737,7 @@ layout_qualifier_id: | any_identifier '=' constant_expression { memset(& $$, 0, sizeof($$)); - void *ctx = state; + void *ctx = state->linalloc; if ($3->oper != ast_int_constant && $3->oper != ast_uint_constant && @@ -1587,8 +1869,10 @@ layout_qualifier_id: if (match_layout_qualifier("invocations", $1, state) == 0) { $$.flags.q.invocations = 1; $$.invocations = new(ctx) ast_layout_expression(@1, $3); - if (!state->is_version(400, 0) && - !state->ARB_gpu_shader5_enable) { + if (!state->is_version(400, 320) && + !state->ARB_gpu_shader5_enable && + !state->OES_geometry_shader_enable && + !state->EXT_geometry_shader_enable) { _mesa_glsl_error(& @3, state, "GL_ARB_gpu_shader5 invocations " "qualifier specified", $3); @@ -1667,7 +1951,7 @@ subroutine_qualifier: | SUBROUTINE '(' subroutine_type_list ')' { memset(& $$, 0, sizeof($$)); - $$.flags.q.subroutine_def = 1; + $$.flags.q.subroutine = 1; $$.subroutine_list = $3; } ; @@ -1675,7 +1959,7 @@ subroutine_qualifier: subroutine_type_list: any_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($1, NULL, NULL); decl->set_location(@1); @@ -1684,7 +1968,7 @@ subroutine_type_list: } | subroutine_type_list ',' any_identifier { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($3, NULL, NULL); decl->set_location(@3); @@ -1774,8 +2058,10 @@ type_qualifier: * variables. As only outputs can be declared as invariant, an invariant * output from one shader stage will still match an input of a subsequent * stage without the input being declared as invariant." + * + * On the desktop side, this text first appears in GLSL 4.30. */ - if (state->es_shader && state->language_version >= 300 && $$.flags.q.in) + if (state->is_version(430, 300) && $$.flags.q.in) _mesa_glsl_error(&@1, state, "invariant qualifiers cannot be used with shader inputs"); } | interpolation_qualifier type_qualifier @@ -1813,11 +2099,8 @@ type_qualifier: * precise qualifiers since these are useful in ARB_separate_shader_objects. * There is no clear spec guidance on this either. */ - if (!state->has_420pack_or_es31() && $2.has_layout()) - _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 { @@ -1831,7 +2114,7 @@ type_qualifier: "duplicate auxiliary storage qualifier (centroid or sample)"); } - if (!state->has_420pack_or_es31() && + if ((!state->has_420pack_or_es31() && !state->EXT_gpu_shader4_enable) && ($2.flags.q.precise || $2.flags.q.invariant || $2.has_interpolation() || $2.has_layout())) { _mesa_glsl_error(&@1, state, "auxiliary storage qualifiers must come " @@ -1845,8 +2128,13 @@ type_qualifier: /* Section 4.3 of the GLSL 1.20 specification states: * "Variable declarations may have a storage qualifier specified..." * 1.30 clarifies this to "may have one storage qualifier". + * + * GL_EXT_gpu_shader4 allows "varying out" in fragment shaders. */ - if ($2.has_storage()) + if ($2.has_storage() && + (!state->EXT_gpu_shader4_enable || + state->stage != MESA_SHADER_FRAGMENT || + !$1.flags.q.varying || !$2.flags.q.out)) _mesa_glsl_error(&@1, state, "duplicate storage qualifier"); if (!state->has_420pack_or_es31() && @@ -1942,6 +2230,18 @@ storage_qualifier: $$.xfb_buffer = state->out_qualifier->xfb_buffer; } } + | INOUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.in = 1; + $$.flags.q.out = 1; + + if (!state->has_framebuffer_fetch() || + !state->is_version(130, 300) || + state->stage != MESA_SHADER_FRAGMENT) + _mesa_glsl_error(&@1, state, "A single interface variable cannot be " + "declared as both input and output"); + } | UNIFORM { memset(& $$, 0, sizeof($$)); @@ -1991,7 +2291,7 @@ memory_qualifier: array_specifier: '[' ']' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_array_specifier(@1, new(ctx) ast_expression( ast_unsized_array_dim, NULL, NULL, NULL)); @@ -1999,13 +2299,13 @@ array_specifier: } | '[' constant_expression ']' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_array_specifier(@1, $2); $$->set_location_range(@1, @3); } | array_specifier '[' ']' { - void *ctx = state; + void *ctx = state->linalloc; $$ = $1; if (state->check_arrays_of_arrays_allowed(& @1)) { @@ -2035,139 +2335,36 @@ type_specifier: type_specifier_nonarray: basic_type_specifier_nonarray { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_type_specifier($1); $$->set_location(@1); } | struct_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_type_specifier($1); $$->set_location(@1); } | TYPE_IDENTIFIER { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_type_specifier($1); $$->set_location(@1); } ; basic_type_specifier_nonarray: - VOID_TOK { $$ = "void"; } - | FLOAT_TOK { $$ = "float"; } - | DOUBLE_TOK { $$ = "double"; } - | INT_TOK { $$ = "int"; } - | UINT_TOK { $$ = "uint"; } - | BOOL_TOK { $$ = "bool"; } - | VEC2 { $$ = "vec2"; } - | VEC3 { $$ = "vec3"; } - | VEC4 { $$ = "vec4"; } - | BVEC2 { $$ = "bvec2"; } - | BVEC3 { $$ = "bvec3"; } - | BVEC4 { $$ = "bvec4"; } - | IVEC2 { $$ = "ivec2"; } - | IVEC3 { $$ = "ivec3"; } - | IVEC4 { $$ = "ivec4"; } - | UVEC2 { $$ = "uvec2"; } - | UVEC3 { $$ = "uvec3"; } - | UVEC4 { $$ = "uvec4"; } - | DVEC2 { $$ = "dvec2"; } - | DVEC3 { $$ = "dvec3"; } - | DVEC4 { $$ = "dvec4"; } - | MAT2X2 { $$ = "mat2"; } - | MAT2X3 { $$ = "mat2x3"; } - | MAT2X4 { $$ = "mat2x4"; } - | MAT3X2 { $$ = "mat3x2"; } - | MAT3X3 { $$ = "mat3"; } - | MAT3X4 { $$ = "mat3x4"; } - | MAT4X2 { $$ = "mat4x2"; } - | MAT4X3 { $$ = "mat4x3"; } - | MAT4X4 { $$ = "mat4"; } - | DMAT2X2 { $$ = "dmat2"; } - | DMAT2X3 { $$ = "dmat2x3"; } - | DMAT2X4 { $$ = "dmat2x4"; } - | DMAT3X2 { $$ = "dmat3x2"; } - | DMAT3X3 { $$ = "dmat3"; } - | DMAT3X4 { $$ = "dmat3x4"; } - | DMAT4X2 { $$ = "dmat4x2"; } - | DMAT4X3 { $$ = "dmat4x3"; } - | DMAT4X4 { $$ = "dmat4"; } - | SAMPLER1D { $$ = "sampler1D"; } - | SAMPLER2D { $$ = "sampler2D"; } - | SAMPLER2DRECT { $$ = "sampler2DRect"; } - | SAMPLER3D { $$ = "sampler3D"; } - | SAMPLERCUBE { $$ = "samplerCube"; } - | SAMPLEREXTERNALOES { $$ = "samplerExternalOES"; } - | SAMPLER1DSHADOW { $$ = "sampler1DShadow"; } - | SAMPLER2DSHADOW { $$ = "sampler2DShadow"; } - | SAMPLER2DRECTSHADOW { $$ = "sampler2DRectShadow"; } - | SAMPLERCUBESHADOW { $$ = "samplerCubeShadow"; } - | SAMPLER1DARRAY { $$ = "sampler1DArray"; } - | SAMPLER2DARRAY { $$ = "sampler2DArray"; } - | SAMPLER1DARRAYSHADOW { $$ = "sampler1DArrayShadow"; } - | SAMPLER2DARRAYSHADOW { $$ = "sampler2DArrayShadow"; } - | SAMPLERBUFFER { $$ = "samplerBuffer"; } - | SAMPLERCUBEARRAY { $$ = "samplerCubeArray"; } - | SAMPLERCUBEARRAYSHADOW { $$ = "samplerCubeArrayShadow"; } - | ISAMPLER1D { $$ = "isampler1D"; } - | ISAMPLER2D { $$ = "isampler2D"; } - | ISAMPLER2DRECT { $$ = "isampler2DRect"; } - | ISAMPLER3D { $$ = "isampler3D"; } - | ISAMPLERCUBE { $$ = "isamplerCube"; } - | ISAMPLER1DARRAY { $$ = "isampler1DArray"; } - | ISAMPLER2DARRAY { $$ = "isampler2DArray"; } - | ISAMPLERBUFFER { $$ = "isamplerBuffer"; } - | ISAMPLERCUBEARRAY { $$ = "isamplerCubeArray"; } - | USAMPLER1D { $$ = "usampler1D"; } - | USAMPLER2D { $$ = "usampler2D"; } - | USAMPLER2DRECT { $$ = "usampler2DRect"; } - | USAMPLER3D { $$ = "usampler3D"; } - | USAMPLERCUBE { $$ = "usamplerCube"; } - | USAMPLER1DARRAY { $$ = "usampler1DArray"; } - | USAMPLER2DARRAY { $$ = "usampler2DArray"; } - | USAMPLERBUFFER { $$ = "usamplerBuffer"; } - | USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; } - | SAMPLER2DMS { $$ = "sampler2DMS"; } - | ISAMPLER2DMS { $$ = "isampler2DMS"; } - | USAMPLER2DMS { $$ = "usampler2DMS"; } - | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; } - | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; } - | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; } - | IMAGE1D { $$ = "image1D"; } - | IMAGE2D { $$ = "image2D"; } - | IMAGE3D { $$ = "image3D"; } - | IMAGE2DRECT { $$ = "image2DRect"; } - | IMAGECUBE { $$ = "imageCube"; } - | IMAGEBUFFER { $$ = "imageBuffer"; } - | IMAGE1DARRAY { $$ = "image1DArray"; } - | IMAGE2DARRAY { $$ = "image2DArray"; } - | IMAGECUBEARRAY { $$ = "imageCubeArray"; } - | IMAGE2DMS { $$ = "image2DMS"; } - | IMAGE2DMSARRAY { $$ = "image2DMSArray"; } - | IIMAGE1D { $$ = "iimage1D"; } - | IIMAGE2D { $$ = "iimage2D"; } - | IIMAGE3D { $$ = "iimage3D"; } - | IIMAGE2DRECT { $$ = "iimage2DRect"; } - | IIMAGECUBE { $$ = "iimageCube"; } - | IIMAGEBUFFER { $$ = "iimageBuffer"; } - | IIMAGE1DARRAY { $$ = "iimage1DArray"; } - | IIMAGE2DARRAY { $$ = "iimage2DArray"; } - | IIMAGECUBEARRAY { $$ = "iimageCubeArray"; } - | IIMAGE2DMS { $$ = "iimage2DMS"; } - | IIMAGE2DMSARRAY { $$ = "iimage2DMSArray"; } - | UIMAGE1D { $$ = "uimage1D"; } - | UIMAGE2D { $$ = "uimage2D"; } - | UIMAGE3D { $$ = "uimage3D"; } - | UIMAGE2DRECT { $$ = "uimage2DRect"; } - | UIMAGECUBE { $$ = "uimageCube"; } - | UIMAGEBUFFER { $$ = "uimageBuffer"; } - | UIMAGE1DARRAY { $$ = "uimage1DArray"; } - | UIMAGE2DARRAY { $$ = "uimage2DArray"; } - | UIMAGECUBEARRAY { $$ = "uimageCubeArray"; } - | UIMAGE2DMS { $$ = "uimage2DMS"; } - | UIMAGE2DMSARRAY { $$ = "uimage2DMSArray"; } - | ATOMIC_UINT { $$ = "atomic_uint"; } + VOID_TOK { $$ = glsl_type::void_type; } + | BASIC_TYPE_TOK { $$ = $1; } + | UNSIGNED BASIC_TYPE_TOK + { + if ($2 == glsl_type::int_type) { + $$ = glsl_type::uint_type; + } else { + _mesa_glsl_error(&@1, state, + "\"unsigned\" is only allowed before \"int\""); + } + } ; precision_qualifier: @@ -2191,15 +2388,23 @@ precision_qualifier: struct_specifier: STRUCT any_identifier '{' struct_declaration_list '}' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_struct_specifier($2, $4); $$->set_location_range(@2, @5); state->symbols->add_type($2, glsl_type::void_type); } | STRUCT '{' struct_declaration_list '}' { - void *ctx = state; - $$ = new(ctx) ast_struct_specifier(NULL, $3); + void *ctx = state->linalloc; + + /* All anonymous structs have the same name. This simplifies matching of + * globals whose type is an unnamed struct. + * + * It also avoids a memory leak when the same shader is compiled over and + * over again. + */ + $$ = new(ctx) ast_struct_specifier("#anon_struct", $3); + $$->set_location_range(@2, @4); } ; @@ -2220,14 +2425,33 @@ struct_declaration_list: struct_declaration: fully_specified_type struct_declarator_list ';' { - void *ctx = state; + void *ctx = state->linalloc; ast_fully_specified_type *const type = $1; type->set_location(@1); - if (type->qualifier.flags.i != 0) - _mesa_glsl_error(&@1, state, - "only precision qualifiers may be applied to " - "structure members"); + if (state->has_bindless()) { + ast_type_qualifier input_layout_mask; + + /* Allow to declare qualifiers for images. */ + input_layout_mask.flags.i = 0; + input_layout_mask.flags.q.coherent = 1; + input_layout_mask.flags.q._volatile = 1; + input_layout_mask.flags.q.restrict_flag = 1; + input_layout_mask.flags.q.read_only = 1; + input_layout_mask.flags.q.write_only = 1; + input_layout_mask.flags.q.explicit_image_format = 1; + + if ((type->qualifier.flags.i & ~input_layout_mask.flags.i) != 0) { + _mesa_glsl_error(&@1, state, + "only precision and image qualifiers may be " + "applied to structure members"); + } + } else { + if (type->qualifier.flags.i != 0) + _mesa_glsl_error(&@1, state, + "only precision qualifiers may be applied to " + "structure members"); + } $$ = new(ctx) ast_declarator_list(type); $$->set_location(@2); @@ -2252,13 +2476,13 @@ struct_declarator_list: struct_declarator: any_identifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_declaration($1, NULL, NULL); $$->set_location(@1); } | any_identifier array_specifier { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_declaration($1, $2, NULL); $$->set_location_range(@1, @2); } @@ -2279,7 +2503,7 @@ initializer: initializer_list: initializer { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_aggregate_initializer(); $$->set_location(@1); $$->expressions.push_tail(& $1->link); @@ -2308,12 +2532,13 @@ simple_statement: | switch_statement | iteration_statement | jump_statement + | demote_statement ; compound_statement: '{' '}' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_compound_statement(true, NULL); $$->set_location_range(@1, @2); } @@ -2323,7 +2548,7 @@ compound_statement: } statement_list '}' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_compound_statement(true, $3); $$->set_location_range(@1, @4); state->symbols->pop_scope(); @@ -2338,13 +2563,13 @@ statement_no_new_scope: compound_statement_no_new_scope: '{' '}' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_compound_statement(false, NULL); $$->set_location_range(@1, @2); } | '{' statement_list '}' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_compound_statement(false, $2); $$->set_location_range(@1, @3); } @@ -2370,18 +2595,27 @@ statement_list: $$ = $1; $$->link.insert_before(& $2->link); } + | statement_list extension_statement + { + if (!state->allow_extension_directive_midshader) { + _mesa_glsl_error(& @1, state, + "#extension directive is not allowed " + "in the middle of a shader"); + YYERROR; + } + } ; expression_statement: ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_statement(NULL); $$->set_location(@1); } | expression ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_expression_statement($1); $$->set_location(@1); } @@ -2390,8 +2624,8 @@ expression_statement: selection_statement: IF '(' expression ')' selection_rest_statement { - $$ = new(state) ast_selection_statement($3, $5.then_statement, - $5.else_statement); + $$ = new(state->linalloc) ast_selection_statement($3, $5.then_statement, + $5.else_statement); $$->set_location_range(@1, @5); } ; @@ -2416,7 +2650,7 @@ condition: } | fully_specified_type any_identifier '=' initializer { - void *ctx = state; + void *ctx = state->linalloc; ast_declaration *decl = new(ctx) ast_declaration($2, NULL, $4); ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); decl->set_location_range(@2, @4); @@ -2434,7 +2668,7 @@ condition: switch_statement: SWITCH '(' expression ')' switch_body { - $$ = new(state) ast_switch_statement($3, $5); + $$ = new(state->linalloc) ast_switch_statement($3, $5); $$->set_location_range(@1, @5); } ; @@ -2442,12 +2676,12 @@ switch_statement: switch_body: '{' '}' { - $$ = new(state) ast_switch_body(NULL); + $$ = new(state->linalloc) ast_switch_body(NULL); $$->set_location_range(@1, @2); } | '{' case_statement_list '}' { - $$ = new(state) ast_switch_body($2); + $$ = new(state->linalloc) ast_switch_body($2); $$->set_location_range(@1, @3); } ; @@ -2455,12 +2689,12 @@ switch_body: case_label: CASE expression ':' { - $$ = new(state) ast_case_label($2); + $$ = new(state->linalloc) ast_case_label($2); $$->set_location(@2); } | DEFAULT ':' { - $$ = new(state) ast_case_label(NULL); + $$ = new(state->linalloc) ast_case_label(NULL); $$->set_location(@2); } ; @@ -2468,7 +2702,7 @@ case_label: case_label_list: case_label { - ast_case_label_list *labels = new(state) ast_case_label_list(); + ast_case_label_list *labels = new(state->linalloc) ast_case_label_list(); labels->labels.push_tail(& $1->link); $$ = labels; @@ -2484,7 +2718,7 @@ case_label_list: case_statement: case_label_list statement { - ast_case_statement *stmts = new(state) ast_case_statement($1); + ast_case_statement *stmts = new(state->linalloc) ast_case_statement($1); stmts->set_location(@2); stmts->stmts.push_tail(& $2->link); @@ -2500,7 +2734,7 @@ case_statement: case_statement_list: case_statement { - ast_case_statement_list *cases= new(state) ast_case_statement_list(); + ast_case_statement_list *cases= new(state->linalloc) ast_case_statement_list(); cases->set_location(@1); cases->cases.push_tail(& $1->link); @@ -2516,21 +2750,21 @@ case_statement_list: iteration_statement: WHILE '(' condition ')' statement_no_new_scope { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, NULL, $3, NULL, $5); $$->set_location_range(@1, @4); } | DO statement WHILE '(' expression ')' ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, NULL, $5, NULL, $2); $$->set_location_range(@1, @6); } | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, $3, $4.cond, $4.rest, $6); $$->set_location_range(@1, @6); @@ -2567,47 +2801,57 @@ for_rest_statement: jump_statement: CONTINUE ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); $$->set_location(@1); } | BREAK ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); $$->set_location(@1); } | RETURN ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); $$->set_location(@1); } | RETURN expression ';' { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); $$->set_location_range(@1, @2); } | DISCARD ';' // Fragment shader only. { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); $$->set_location(@1); } ; +demote_statement: + DEMOTE ';' + { + void *ctx = state->linalloc; + $$ = new(ctx) ast_demote_statement(); + $$->set_location(@1); + } + ; + external_declaration: function_definition { $$ = $1; } | declaration { $$ = $1; } - | pragma_statement { $$ = NULL; } + | pragma_statement { $$ = $1; } | layout_defaults { $$ = $1; } + | ';' { $$ = NULL; } ; function_definition: function_prototype compound_statement_no_new_scope { - void *ctx = state; + void *ctx = state->linalloc; $$ = new(ctx) ast_function_definition(); $$->set_location_range(@1, @2); $$->prototype = $1; @@ -2627,17 +2871,12 @@ 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) { - _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); + if (!$1.merge_qualifier(& @1, state, block->layout, false, + block->layout.has_layout())) { YYERROR; } - if (!block->layout.merge_qualifier(& @1, state, $1, false)) { - YYERROR; - } - - block->layout.is_default_qualifier = false; + block->layout = $1; $$ = block; } @@ -2645,14 +2884,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; } ; @@ -2663,9 +2903,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); @@ -2697,21 +2937,32 @@ interface_qualifier: memset(& $$, 0, sizeof($$)); $$.flags.q.buffer = 1; } + | auxiliary_storage_qualifier interface_qualifier + { + if (!$1.flags.q.patch) { + _mesa_glsl_error(&@1, state, "invalid interface qualifier"); + } + if ($2.has_auxiliary_storage()) { + _mesa_glsl_error(&@1, state, "duplicate patch qualifier"); + } + $$ = $2; + $$.flags.q.patch = 1; + } ; instance_name_opt: /* empty */ { - $$ = new(state) ast_interface_block(NULL, NULL); + $$ = new(state->linalloc) ast_interface_block(NULL, NULL); } | NEW_IDENTIFIER { - $$ = new(state) ast_interface_block($1, NULL); + $$ = new(state->linalloc) ast_interface_block($1, NULL); $$->set_location(@1); } | NEW_IDENTIFIER array_specifier { - $$ = new(state) ast_interface_block($1, $2); + $$ = new(state->linalloc) ast_interface_block($1, $2); $$->set_location_range(@1, @2); } ; @@ -2732,7 +2983,7 @@ member_list: member_declaration: fully_specified_type struct_declarator_list ';' { - void *ctx = state; + void *ctx = state->linalloc; ast_fully_specified_type *type = $1; type->set_location(@1); @@ -2756,82 +3007,39 @@ member_declaration: layout_uniform_defaults: layout_qualifier layout_uniform_defaults { - $$ = NULL; - if (!state->has_420pack_or_es31()) { - _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); + $$ = $1; + if (!$$.merge_qualifier(& @1, state, $2, false, true)) { 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)) { - YYERROR; - } - $$ = NULL; - } ; layout_buffer_defaults: layout_qualifier layout_buffer_defaults { - $$ = NULL; - if (!state->has_420pack_or_es31()) { - _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); + $$ = $1; + if (!$$.merge_qualifier(& @1, state, $2, false, true)) { 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)) { - 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_in_defaults: layout_qualifier layout_in_defaults { - $$ = NULL; - if (!state->has_420pack_or_es31()) { - _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); + $$ = $1; + if (!$$.merge_qualifier(& @1, state, $2, false, true)) { + YYERROR; + } + if (!$$.validate_in_qualifier(& @1, state)) { YYERROR; - } else { - if (!state->in_qualifier-> - merge_in_qualifier(& @1, state, $1, $$, false)) { - YYERROR; - } - $$ = $2; } } | layout_qualifier IN_TOK ';' { - $$ = NULL; - if (!state->in_qualifier-> - merge_in_qualifier(& @1, state, $1, $$, true)) { + if (!$1.validate_in_qualifier(& @1, state)) { YYERROR; } } @@ -2840,30 +3048,75 @@ layout_in_defaults: layout_out_defaults: layout_qualifier layout_out_defaults { - $$ = NULL; - if (!state->has_420pack_or_es31()) { - _mesa_glsl_error(&@1, state, "duplicate layout(...) qualifiers"); + $$ = $1; + if (!$$.merge_qualifier(& @1, state, $2, false, true)) { + YYERROR; + } + if (!$$.validate_out_qualifier(& @1, state)) { YYERROR; - } else { - if (!state->out_qualifier-> - merge_out_qualifier(& @1, state, $1, $$, false)) { - YYERROR; - } - $$ = $2; } } | layout_qualifier OUT_TOK ';' { - $$ = NULL; - if (!state->out_qualifier-> - merge_out_qualifier(& @1, state, $1, $$, true)) + if (!$1.validate_out_qualifier(& @1, state)) { YYERROR; + } } ; layout_defaults: layout_uniform_defaults + { + $$ = NULL; + if (!state->default_uniform_qualifier-> + merge_qualifier(& @1, state, $1, false)) { + YYERROR; + } + if (!state->default_uniform_qualifier-> + push_to_global(& @1, state)) { + YYERROR; + } + } | layout_buffer_defaults + { + $$ = NULL; + if (!state->default_shader_storage_qualifier-> + merge_qualifier(& @1, state, $1, false)) { + YYERROR; + } + if (!state->default_shader_storage_qualifier-> + push_to_global(& @1, state)) { + 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, $$)) { + YYERROR; + } + if (!state->in_qualifier->push_to_global(& @1, state)) { + YYERROR; + } + } | layout_out_defaults + { + $$ = NULL; + if (!$1.merge_into_out_qualifier(& @1, state, $$)) { + YYERROR; + } + if (!state->out_qualifier->push_to_global(& @1, state)) { + YYERROR; + } + } ;