diff options
Diffstat (limited to 'mesalib/src/glsl/glsl_parser.yy')
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 165 |
1 files changed, 134 insertions, 31 deletions
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 5ca8740c4..337337591 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -155,6 +155,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <type_qualifier> interpolation_qualifier %type <type_qualifier> layout_qualifier %type <type_qualifier> layout_qualifier_id_list layout_qualifier_id +%type <type_qualifier> uniform_block_layout_qualifier %type <type_specifier> type_specifier %type <type_specifier> type_specifier_no_prec %type <type_specifier> type_specifier_nonarray @@ -213,11 +214,14 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <node> declaration %type <node> declaration_statement %type <node> jump_statement +%type <node> uniform_block %type <struct_specifier> struct_specifier -%type <node> struct_declaration_list +%type <declarator_list> struct_declaration_list %type <declarator_list> struct_declaration %type <declaration> struct_declarator %type <declaration> struct_declarator_list +%type <declarator_list> member_list +%type <declarator_list> member_declaration %type <node> selection_statement %type <selection_rest_statement> selection_rest_statement %type <node> switch_statement @@ -800,6 +804,10 @@ declaration: $3->is_precision_statement = true; $$ = $3; } + | uniform_block + { + $$ = $1; + } ; function_prototype: @@ -1100,13 +1108,8 @@ layout_qualifier_id_list: YYERROR; } - $$.flags.i = $1.flags.i | $3.flags.i; - - if ($1.flags.q.explicit_location) - $$.location = $1.location; - - if ($1.flags.q.explicit_index) - $$.index = $1.index; + $$ = $1; + $$.flags.i |= $3.flags.i; if ($3.flags.q.explicit_location) $$.location = $3.location; @@ -1119,21 +1122,17 @@ layout_qualifier_id_list: layout_qualifier_id: any_identifier { - bool got_one = false; - memset(& $$, 0, sizeof($$)); /* Layout qualifiers for ARB_fragment_coord_conventions. */ - if (!got_one && state->ARB_fragment_coord_conventions_enable) { + if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) { if (strcmp($1, "origin_upper_left") == 0) { - got_one = true; $$.flags.q.origin_upper_left = 1; } else if (strcmp($1, "pixel_center_integer") == 0) { - got_one = true; $$.flags.q.pixel_center_integer = 1; } - if (got_one && state->ARB_fragment_coord_conventions_warn) { + if ($$.flags.i && state->ARB_fragment_coord_conventions_warn) { _mesa_glsl_warning(& @1, state, "GL_ARB_fragment_coord_conventions layout " "identifier `%s' used\n", $1); @@ -1141,36 +1140,49 @@ layout_qualifier_id: } /* Layout qualifiers for AMD/ARB_conservative_depth. */ - if (!got_one && + if (!$$.flags.i && (state->AMD_conservative_depth_enable || state->ARB_conservative_depth_enable)) { if (strcmp($1, "depth_any") == 0) { - got_one = true; $$.flags.q.depth_any = 1; } else if (strcmp($1, "depth_greater") == 0) { - got_one = true; $$.flags.q.depth_greater = 1; } else if (strcmp($1, "depth_less") == 0) { - got_one = true; $$.flags.q.depth_less = 1; } else if (strcmp($1, "depth_unchanged") == 0) { - got_one = true; $$.flags.q.depth_unchanged = 1; } - if (got_one && state->AMD_conservative_depth_warn) { + if ($$.flags.i && state->AMD_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, "GL_AMD_conservative_depth " "layout qualifier `%s' is used\n", $1); } - if (got_one && state->ARB_conservative_depth_warn) { + if ($$.flags.i && state->ARB_conservative_depth_warn) { _mesa_glsl_warning(& @1, state, "GL_ARB_conservative_depth " "layout qualifier `%s' is used\n", $1); } } - if (!got_one) { + /* See also uniform_block_layout_qualifier. */ + if (!$$.flags.i && state->ARB_uniform_buffer_object_enable) { + if (strcmp($1, "std140") == 0) { + $$.flags.q.std140 = 1; + } else if (strcmp($1, "shared") == 0) { + $$.flags.q.shared = 1; + } else if (strcmp($1, "column_major") == 0) { + $$.flags.q.column_major = 1; + } + + if ($$.flags.i && state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } + } + + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'\n", $1); YYERROR; @@ -1178,8 +1190,6 @@ layout_qualifier_id: } | any_identifier '=' INTCONSTANT { - bool got_one = false; - memset(& $$, 0, sizeof($$)); if (state->ARB_explicit_attrib_location_enable) { @@ -1187,8 +1197,6 @@ layout_qualifier_id: * FINISHME: GLSL 1.30 (or later) are supported. */ if (strcmp("location", $1) == 0) { - got_one = true; - $$.flags.q.explicit_location = 1; if ($3 >= 0) { @@ -1201,8 +1209,6 @@ layout_qualifier_id: } if (strcmp("index", $1) == 0) { - got_one = true; - $$.flags.q.explicit_index = 1; if ($3 >= 0) { @@ -1218,7 +1224,7 @@ layout_qualifier_id: /* If the identifier didn't match any known layout identifiers, * emit an error. */ - if (!got_one) { + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'\n", $1); YYERROR; @@ -1228,6 +1234,38 @@ layout_qualifier_id: "identifier `%s' used\n", $1); } } + | uniform_block_layout_qualifier + { + $$ = $1; + /* Layout qualifiers for ARB_uniform_buffer_object. */ + if (!state->ARB_uniform_buffer_object_enable) { + _mesa_glsl_error(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } else if (state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "layout qualifier `%s' is used\n", $1); + } + } + ; + +/* This is a separate language rule because we parse these as tokens + * (due to them being reserved keywords) instead of identifiers like + * most qualifiers. See the any_identifier path of + * layout_qualifier_id for the others. + */ +uniform_block_layout_qualifier: + ROW_MAJOR + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.row_major = 1; + } + | PACKED_TOK + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.packed = 1; + } ; interpolation_qualifier: @@ -1498,12 +1536,12 @@ struct_specifier: struct_declaration_list: struct_declaration { - $$ = (ast_node *) $1; + $$ = $1; $1->link.self_link(); } | struct_declaration_list struct_declaration { - $$ = (ast_node *) $1; + $$ = $1; $$->link.insert_before(& $2->link); } ; @@ -1881,3 +1919,68 @@ function_definition: state->symbols->pop_scope(); } ; + +/* layout_qualifieropt is packed into this rule */ +uniform_block: + UNIFORM NEW_IDENTIFIER '{' member_list '}' ';' + { + void *ctx = state; + ast_type_qualifier no_qual; + memset(&no_qual, 0, sizeof(no_qual)); + $$ = new(ctx) ast_uniform_block(no_qual, $2, $4); + } + | layout_qualifier UNIFORM NEW_IDENTIFIER '{' member_list '}' ';' + { + void *ctx = state; + $$ = new(ctx) ast_uniform_block($1, $3, $5); + } + ; + +member_list: + member_declaration + { + $$ = $1; + $1->link.self_link(); + } + | member_declaration member_list + { + $$ = $1; + $2->link.insert_before(& $$->link); + } + ; + +/* Specifying "uniform" inside of a uniform block is redundant. */ +uniformopt: + /* nothing */ + | UNIFORM + ; + +member_declaration: + layout_qualifier uniformopt type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->qualifier = $1; + type->qualifier.flags.q.uniform = true; + type->specifier = $3; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $4->link); + } + | uniformopt type_specifier struct_declarator_list ';' + { + void *ctx = state; + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); + type->set_location(yylloc); + + type->qualifier.flags.q.uniform = true; + type->specifier = $2; + $$ = new(ctx) ast_declarator_list(type); + $$->set_location(yylloc); + + $$->declarations.push_degenerate_list_at_head(& $3->link); + } + ; |