diff options
-rw-r--r-- | src/glsl/ast.h | 14 | ||||
-rw-r--r-- | src/glsl/glsl_lexer.lpp | 1 | ||||
-rw-r--r-- | src/glsl/glsl_parser.ypp | 55 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 7 | ||||
-rw-r--r-- | src/glsl/glsl_parser_extras.h | 2 |
5 files changed, 75 insertions, 4 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 5fa932ec806..e5aa5c1b3b5 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -343,9 +343,23 @@ struct ast_type_qualifier { unsigned origin_upper_left:1; unsigned pixel_center_integer:1; /*@}*/ + + /** + * Flag set if GL_ARB_explicit_attrib_location "location" layout + * qualifier is used. + */ + unsigned explicit_location:1; } q; unsigned i; } flags; + + /** + * Location specified via GL_ARB_explicit_attrib_location layout + * + * \note + * This field is only valid if \c explicit_location is set. + */ + unsigned location; }; class ast_struct_specifier : public ast_node { diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp index ed3cb251a1a..8be5c67fc2b 100644 --- a/src/glsl/glsl_lexer.lpp +++ b/src/glsl/glsl_lexer.lpp @@ -218,6 +218,7 @@ void return VOID_TOK; layout { if ((yyextra->language_version >= 140) + || yyextra->ARB_explicit_attrib_location_enable || (yyextra->ARB_fragment_coord_conventions_enable)){ return LAYOUT_TOK; } else { diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 16d39dc565e..ed18179beb7 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -983,10 +983,19 @@ layout_qualifier_id_list: layout_qualifier_id | layout_qualifier_id_list ',' layout_qualifier_id { - /* FINISHME: Should check for conflicting / duplicate flags here. - */ - $$ = $1; - $$.flags.i |= $3.flags.i; + if (($1.flags.i & $3.flags.i) != 0) { + _mesa_glsl_error(& @3, state, + "duplicate layout qualifiers used\n"); + YYERROR; + } + + $$.flags.i = $1.flags.i | $3.flags.i; + + if ($1.flags.q.explicit_location) + $$.location = $1.location; + + if ($3.flags.q.explicit_location) + $$.location = $3.location; } ; @@ -1020,6 +1029,44 @@ layout_qualifier_id: "identifier `%s' used\n", $1); } } + | IDENTIFIER '=' INTCONSTANT + { + bool got_one = false; + + memset(& $$, 0, sizeof($$)); + + if (state->ARB_explicit_attrib_location_enable) { + /* FINISHME: Handle 'index' once GL_ARB_blend_func_exteneded and + * FINISHME: GLSL 1.30 (or later) are supported. + */ + if (strcmp("location", $1) == 0) { + got_one = true; + + $$.flags.q.explicit_location = 1; + + if ($3 >= 0) { + $$.location = $3; + } else { + _mesa_glsl_error(& @3, state, + "invalid location %d specified\n", $3); + YYERROR; + } + } + } + + /* If the identifier didn't match any known layout identifiers, + * emit an error. + */ + if (!got_one) { + _mesa_glsl_error(& @1, state, "unrecognized layout identifier " + "`%s'\n", $1); + YYERROR; + } else if (state->ARB_explicit_attrib_location_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_explicit_attrib_location layout " + "identifier `%s' used\n", $1); + } + } ; interpolation_qualifier: diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 26e0721cede..844a746c65c 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -181,6 +181,13 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, state->ARB_draw_buffers_enable = (ext_mode != extension_disable); state->ARB_draw_buffers_warn = (ext_mode == extension_warn); } + } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { + state->ARB_explicit_attrib_location_enable = + (ext_mode != extension_disable); + state->ARB_explicit_attrib_location_warn = + (ext_mode == extension_warn); + + unsupported = !state->extensions->ARB_explicit_attrib_location; } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { state->ARB_fragment_coord_conventions_enable = (ext_mode != extension_disable); diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index ddc2138b765..b573831d5f0 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -125,6 +125,8 @@ struct _mesa_glsl_parse_state { /*@{*/ unsigned ARB_draw_buffers_enable:1; unsigned ARB_draw_buffers_warn:1; + unsigned ARB_explicit_attrib_location_enable:1; + unsigned ARB_explicit_attrib_location_warn:1; unsigned ARB_fragment_coord_conventions_enable:1; unsigned ARB_fragment_coord_conventions_warn:1; unsigned ARB_texture_rectangle_enable:1; |