diff options
Diffstat (limited to 'mesalib/src/glsl/glsl_parser.yy')
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 90 |
1 files changed, 81 insertions, 9 deletions
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index fcc5620cd..e3a57ea02 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -254,6 +254,7 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state) %type <node> for_init_statement %type <for_rest_statement> for_rest_statement %type <n> integer_constant +%type <node> layout_defaults %right THEN ELSE %% @@ -1157,7 +1158,8 @@ layout_qualifier_id: memset(& $$, 0, sizeof($$)); /* Layout qualifiers for ARB_fragment_coord_conventions. */ - if (!$$.flags.i && state->ARB_fragment_coord_conventions_enable) { + if (!$$.flags.i && (state->ARB_fragment_coord_conventions_enable || + state->is_version(150, 0))) { if (strcmp($1, "origin_upper_left") == 0) { $$.flags.q.origin_upper_left = 1; } else if (strcmp($1, "pixel_center_integer") == 0) { @@ -1222,6 +1224,34 @@ layout_qualifier_id: } } + /* Layout qualifiers for GLSL 1.50 geometry shaders. */ + if (!$$.flags.i) { + struct { + const char *s; + GLenum e; + } map[] = { + { "points", GL_POINTS }, + { "lines", GL_LINES }, + { "lines_adjacency", GL_LINES_ADJACENCY }, + { "line_strip", GL_LINE_STRIP }, + { "triangles", GL_TRIANGLES }, + { "triangles_adjacency", GL_TRIANGLES_ADJACENCY }, + { "triangle_strip", GL_TRIANGLE_STRIP }, + }; + for (unsigned i = 0; i < Elements(map); i++) { + if (strcmp($1, map[i].s) == 0) { + $$.flags.q.prim_type = 1; + $$.prim_type = map[i].e; + break; + } + } + + if ($$.flags.i && !state->is_version(150, 0)) { + _mesa_glsl_error(& @1, state, "#version 150 layout " + "qualifier `%s' used", $1); + } + } + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'", $1); @@ -1264,6 +1294,23 @@ layout_qualifier_id: $$.binding = $3; } + if (strcmp("max_vertices", $1) == 0) { + $$.flags.q.max_vertices = 1; + + if ($3 < 0) { + _mesa_glsl_error(& @3, state, + "invalid max_vertices %d specified", $3); + YYERROR; + } else { + $$.max_vertices = $3; + if (!state->is_version(150, 0)) { + _mesa_glsl_error(& @3, state, + "#version 150 max_vertices qualifier " + "specified", $3); + } + } + } + /* If the identifier didn't match any known layout identifiers, * emit an error. */ @@ -2046,7 +2093,7 @@ external_declaration: function_definition { $$ = $1; } | declaration { $$ = $1; } | pragma_statement { $$ = NULL; } - | layout_defaults { $$ = NULL; } + | layout_defaults { $$ = $1; } ; function_definition: @@ -2197,25 +2244,22 @@ instance_name_opt: /* empty */ { $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, - NULL, NULL); + NULL, false, NULL); } | NEW_IDENTIFIER { $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, - $1, NULL); + $1, false, NULL); } | NEW_IDENTIFIER '[' constant_expression ']' { $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, - $1, $3); + $1, true, $3); } | NEW_IDENTIFIER '[' ']' { - _mesa_glsl_error(& @1, state, - "instance block arrays must be explicitly sized"); - $$ = new(state) ast_interface_block(*state->default_uniform_qualifier, - $1, NULL); + $1, true, NULL); } ; @@ -2263,4 +2307,32 @@ layout_defaults: if (!state->default_uniform_qualifier->merge_qualifier(& @1, state, $1)) { YYERROR; } + $$ = NULL; + } + + | layout_qualifier IN_TOK ';' + { + void *ctx = state; + if (state->target != geometry_shader) { + _mesa_glsl_error(& @1, state, + "input layout qualifiers only valid in " + "geometry shaders"); + } else if (!$1.flags.q.prim_type) { + _mesa_glsl_error(& @1, state, + "input layout qualifiers must specify a primitive" + " type"); + } + $$ = new(ctx) ast_gs_input_layout(@1, $1.prim_type); + } + + | layout_qualifier OUT_TOK ';' + { + if (state->target != geometry_shader) { + _mesa_glsl_error(& @1, state, + "out layout qualifiers only valid in " + "geometry shaders"); + } else if (!state->out_qualifier->merge_qualifier(& @1, state, $1)) { + YYERROR; + } + $$ = NULL; } |