aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/glsl_parser.yy
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/glsl_parser.yy')
-rw-r--r--mesalib/src/glsl/glsl_parser.yy90
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;
}