From dd93035a4df9daaad8cb47f2cc412d5dd3a9e3c8 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Oct 2010 16:14:18 -0700 Subject: glsl: Refactor 'layout' grammar to match GLSL 1.60 spec grammar --- src/glsl/glsl_parser.ypp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/glsl/glsl_parser.ypp') diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 0df1e480ce..9d311093ba 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -139,7 +139,7 @@ %type type_qualifier %type storage_qualifier %type interpolation_qualifier -%type opt_layout_qualifier layout_qualifier +%type layout_qualifier %type layout_qualifier_id_list layout_qualifier_id %type type_specifier %type type_specifier_no_prec @@ -959,11 +959,6 @@ fully_specified_type: } ; -opt_layout_qualifier: - { $$.i = 0; } - | layout_qualifier - ; - layout_qualifier: LAYOUT_TOK '(' layout_qualifier_id_list ')' { @@ -1025,23 +1020,39 @@ parameter_type_qualifier: type_qualifier: storage_qualifier - | interpolation_qualifier type_qualifier + | layout_qualifier + | layout_qualifier storage_qualifier + { + $$.i = $1.i | $2.i; + } + | interpolation_qualifier + | interpolation_qualifier storage_qualifier { $$.i = $1.i | $2.i; } - | INVARIANT type_qualifier + | INVARIANT storage_qualifier { $$ = $2; $$.q.invariant = 1; } + | INVARIANT interpolation_qualifier storage_qualifier + { + $$.i = $2.i | $3.i; + $$.q.invariant = 1; + } + | INVARIANT + { + $$.i = 0; + $$.q.invariant = 1; + } ; storage_qualifier: CONST_TOK { $$.i = 0; $$.q.constant = 1; } | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; } - | opt_layout_qualifier VARYING { $$.i = $1.i; $$.q.varying = 1; } + | VARYING { $$.i = 0; $$.q.varying = 1; } | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; } - | opt_layout_qualifier IN_TOK { $$.i = 0; $$.q.in = 1; } + | IN_TOK { $$.i = 0; $$.q.in = 1; } | OUT_TOK { $$.i = 0; $$.q.out = 1; } | CENTROID IN_TOK { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; } | CENTROID OUT_TOK { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; } -- cgit v1.2.3 From fd2aa7d313b2546dc25f9f7810a0b3767ee679f9 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Oct 2010 16:18:56 -0700 Subject: glsl: Slight refactor of error / warning checking for ARB_fcc layout --- src/glsl/glsl_parser.ypp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/glsl/glsl_parser.ypp') diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 9d311093ba..649f4379af 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -977,11 +977,11 @@ layout_qualifier_id_list: layout_qualifier_id: IDENTIFIER { + bool got_one = false; + $$.i = 0; if (state->ARB_fragment_coord_conventions_enable) { - bool got_one = false; - if (strcmp($1, "origin_upper_left") == 0) { got_one = true; $$.q.origin_upper_left = 1; @@ -989,21 +989,19 @@ layout_qualifier_id: got_one = true; $$.q.pixel_center_integer = 1; } - - if (state->ARB_fragment_coord_conventions_warn && got_one) { - _mesa_glsl_warning(& @1, state, - "GL_ARB_fragment_coord_conventions layout " - "identifier `%s' used\n", $1); - } } /* If the identifier didn't match any known layout identifiers, * emit an error. */ - if ($$.i == 0) { + if (!got_one) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'\n", $1); YYERROR; + } else if (state->ARB_fragment_coord_conventions_warn) { + _mesa_glsl_warning(& @1, state, + "GL_ARB_fragment_coord_conventions layout " + "identifier `%s' used\n", $1); } } ; -- cgit v1.2.3 From 5ff4cfb788291ef7c8d6412d65aee708b41bac86 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Oct 2010 16:23:32 -0700 Subject: glsl: Clear type_qualifier using memset --- src/glsl/glsl_parser.ypp | 105 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 19 deletions(-) (limited to 'src/glsl/glsl_parser.ypp') diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 649f4379af..be763ed9f0 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -793,10 +793,25 @@ parameter_declaration: ; parameter_qualifier: - /* empty */ { $$.i = 0; } - | IN_TOK { $$.i = 0; $$.q.in = 1; } - | OUT_TOK { $$.i = 0; $$.q.out = 1; } - | INOUT_TOK { $$.i = 0; $$.q.in = 1; $$.q.out = 1; } + /* empty */ + { + memset(& $$, 0, sizeof($$)); + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.out = 1; + } + | INOUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.in = 1; $$.q.out = 1; + } ; parameter_type_specifier: @@ -979,7 +994,7 @@ layout_qualifier_id: { bool got_one = false; - $$.i = 0; + memset(& $$, 0, sizeof($$)); if (state->ARB_fragment_coord_conventions_enable) { if (strcmp($1, "origin_upper_left") == 0) { @@ -1007,13 +1022,29 @@ layout_qualifier_id: ; interpolation_qualifier: - SMOOTH { $$.i = 0; $$.q.smooth = 1; } - | FLAT { $$.i = 0; $$.q.flat = 1; } - | NOPERSPECTIVE { $$.i = 0; $$.q.noperspective = 1; } + SMOOTH + { + memset(& $$, 0, sizeof($$)); + $$.q.smooth = 1; + } + | FLAT + { + memset(& $$, 0, sizeof($$)); + $$.q.flat = 1; + } + | NOPERSPECTIVE + { + memset(& $$, 0, sizeof($$)); + $$.q.noperspective = 1; + } ; parameter_type_qualifier: - CONST_TOK { $$.i = 0; $$.q.constant = 1; } + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.constant = 1; + } ; type_qualifier: @@ -1040,21 +1071,57 @@ type_qualifier: } | INVARIANT { - $$.i = 0; + memset(& $$, 0, sizeof($$)); $$.q.invariant = 1; } ; storage_qualifier: - CONST_TOK { $$.i = 0; $$.q.constant = 1; } - | ATTRIBUTE { $$.i = 0; $$.q.attribute = 1; } - | VARYING { $$.i = 0; $$.q.varying = 1; } - | CENTROID VARYING { $$.i = 0; $$.q.centroid = 1; $$.q.varying = 1; } - | IN_TOK { $$.i = 0; $$.q.in = 1; } - | OUT_TOK { $$.i = 0; $$.q.out = 1; } - | CENTROID IN_TOK { $$.i = 0; $$.q.centroid = 1; $$.q.in = 1; } - | CENTROID OUT_TOK { $$.i = 0; $$.q.centroid = 1; $$.q.out = 1; } - | UNIFORM { $$.i = 0; $$.q.uniform = 1; } + CONST_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.constant = 1; + } + | ATTRIBUTE + { + memset(& $$, 0, sizeof($$)); + $$.q.attribute = 1; + } + | VARYING + { + memset(& $$, 0, sizeof($$)); + $$.q.varying = 1; + } + | CENTROID VARYING + { + memset(& $$, 0, sizeof($$)); + $$.q.centroid = 1; $$.q.varying = 1; + } + | IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.in = 1; + } + | OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.out = 1; + } + | CENTROID IN_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.centroid = 1; $$.q.in = 1; + } + | CENTROID OUT_TOK + { + memset(& $$, 0, sizeof($$)); + $$.q.centroid = 1; $$.q.out = 1; + } + | UNIFORM + { + memset(& $$, 0, sizeof($$)); + $$.q.uniform = 1; + } ; type_specifier: -- cgit v1.2.3 From e24d35a5b59ca1e75b69a32db6294787378a963f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Oct 2010 16:38:47 -0700 Subject: glsl: Wrap ast_type_qualifier contents in a struct in a union This will ease adding non-bit fields in the near future. --- src/glsl/ast.h | 39 ++++++++++++--------- src/glsl/ast_to_hir.cpp | 63 +++++++++++++++++---------------- src/glsl/ast_type.cpp | 6 +--- src/glsl/glsl_parser.ypp | 77 ++++++++++++++++++++++------------------- src/glsl/glsl_parser_extras.cpp | 24 ++++++------- 5 files changed, 109 insertions(+), 100 deletions(-) (limited to 'src/glsl/glsl_parser.ypp') diff --git a/src/glsl/ast.h b/src/glsl/ast.h index d7bf90925c..5fa932ec80 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -324,23 +324,28 @@ enum { }; struct ast_type_qualifier { - unsigned invariant:1; - unsigned constant:1; - unsigned attribute:1; - unsigned varying:1; - unsigned in:1; - unsigned out:1; - unsigned centroid:1; - unsigned uniform:1; - unsigned smooth:1; - unsigned flat:1; - unsigned noperspective:1; - - /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ - /*@{*/ - unsigned origin_upper_left:1; - unsigned pixel_center_integer:1; - /*@}*/ + union { + struct { + unsigned invariant:1; + unsigned constant:1; + unsigned attribute:1; + unsigned varying:1; + unsigned in:1; + unsigned out:1; + unsigned centroid:1; + unsigned uniform:1; + unsigned smooth:1; + unsigned flat:1; + unsigned noperspective:1; + + /** \name Layout qualifiers for GL_ARB_fragment_coord_conventions */ + /*@{*/ + unsigned origin_upper_left:1; + unsigned pixel_center_integer:1; + /*@}*/ + } q; + unsigned i; + } flags; }; class ast_struct_specifier : public ast_node { diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 0cbb4315ac..fb25dc166a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1552,18 +1552,19 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - if (qual->invariant) + if (qual->flags.q.invariant) var->invariant = 1; /* FINISHME: Mark 'in' variables at global scope as read-only. */ - if (qual->constant || qual->attribute || qual->uniform - || (qual->varying && (state->target == fragment_shader))) + if (qual->flags.q.constant || qual->flags.q.attribute + || qual->flags.q.uniform + || (qual->flags.q.varying && (state->target == fragment_shader))) var->read_only = 1; - if (qual->centroid) + if (qual->flags.q.centroid) var->centroid = 1; - if (qual->attribute && state->target != vertex_shader) { + if (qual->flags.q.attribute && state->target != vertex_shader) { var->type = glsl_type::error_type; _mesa_glsl_error(loc, state, "`attribute' variables may not be declared in the " @@ -1577,7 +1578,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of * these." */ - if (qual->varying) { + if (qual->flags.q.varying) { const glsl_type *non_array_type; if (var->type && var->type->is_array()) @@ -1595,28 +1596,29 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, /* If there is no qualifier that changes the mode of the variable, leave * the setting alone. */ - if (qual->in && qual->out) + if (qual->flags.q.in && qual->flags.q.out) var->mode = ir_var_inout; - else if (qual->attribute || qual->in - || (qual->varying && (state->target == fragment_shader))) + else if (qual->flags.q.attribute || qual->flags.q.in + || (qual->flags.q.varying && (state->target == fragment_shader))) var->mode = ir_var_in; - else if (qual->out || (qual->varying && (state->target == vertex_shader))) + else if (qual->flags.q.out + || (qual->flags.q.varying && (state->target == vertex_shader))) var->mode = ir_var_out; - else if (qual->uniform) + else if (qual->flags.q.uniform) var->mode = ir_var_uniform; - if (qual->flat) + if (qual->flags.q.flat) var->interpolation = ir_var_flat; - else if (qual->noperspective) + else if (qual->flags.q.noperspective) var->interpolation = ir_var_noperspective; else var->interpolation = ir_var_smooth; - var->pixel_center_integer = qual->pixel_center_integer; - var->origin_upper_left = qual->origin_upper_left; - if ((qual->origin_upper_left || qual->pixel_center_integer) + var->pixel_center_integer = qual->flags.q.pixel_center_integer; + var->origin_upper_left = qual->flags.q.origin_upper_left; + if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer) && (strcmp(var->name, "gl_FragCoord") != 0)) { - const char *const qual_string = (qual->origin_upper_left) + const char *const qual_string = (qual->flags.q.origin_upper_left) ? "origin_upper_left" : "pixel_center_integer"; _mesa_glsl_error(loc, state, @@ -1754,13 +1756,13 @@ ast_declarator_list::hir(exec_list *instructions, * This is relaxed in GLSL 1.30. */ if (state->language_version < 120) { - if (this->type->qualifier.out) { + if (this->type->qualifier.flags.q.out) { _mesa_glsl_error(& loc, state, "`out' qualifier in declaration of `%s' " "only valid for function parameters in GLSL 1.10.", decl->identifier); } - if (this->type->qualifier.in) { + if (this->type->qualifier.flags.q.in) { _mesa_glsl_error(& loc, state, "`in' qualifier in declaration of `%s' " "only valid for function parameters in GLSL 1.10.", @@ -1772,7 +1774,7 @@ ast_declarator_list::hir(exec_list *instructions, apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc); - if (this->type->qualifier.invariant) { + if (this->type->qualifier.flags.q.invariant) { if ((state->target == vertex_shader) && !(var->mode == ir_var_out || var->mode == ir_var_inout)) { /* FINISHME: Note that this doesn't work for invariant on @@ -1799,16 +1801,16 @@ ast_declarator_list::hir(exec_list *instructions, /* There is no need to check for 'inout' here because the parser will * only allow that in function parameter lists. */ - if (this->type->qualifier.attribute) { + if (this->type->qualifier.flags.q.attribute) { mode = "attribute"; - } else if (this->type->qualifier.uniform) { + } else if (this->type->qualifier.flags.q.uniform) { mode = "uniform"; - } else if (this->type->qualifier.varying) { + } else if (this->type->qualifier.flags.q.varying) { mode = "varying"; - } else if (this->type->qualifier.in) { + } else if (this->type->qualifier.flags.q.in) { mode = "in"; extra = " or in function parameter list"; - } else if (this->type->qualifier.out) { + } else if (this->type->qualifier.flags.q.out) { mode = "out"; extra = " or in function parameter list"; } @@ -1914,7 +1916,8 @@ ast_declarator_list::hir(exec_list *instructions, /* Calculate the constant value if this is a const or uniform * declaration. */ - if (this->type->qualifier.constant || this->type->qualifier.uniform) { + if (this->type->qualifier.flags.q.constant + || this->type->qualifier.flags.q.uniform) { ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); if (new_rhs != NULL) { rhs = new_rhs; @@ -1924,7 +1927,7 @@ ast_declarator_list::hir(exec_list *instructions, _mesa_glsl_error(& initializer_loc, state, "initializer of %s variable `%s' must be a " "constant expression", - (this->type->qualifier.constant) + (this->type->qualifier.flags.q.constant) ? "const" : "uniform", decl->identifier); if (var->type->is_numeric()) { @@ -1949,12 +1952,12 @@ ast_declarator_list::hir(exec_list *instructions, if (rhs && !rhs->type->is_error()) { bool temp = var->read_only; - if (this->type->qualifier.constant) + if (this->type->qualifier.flags.q.constant) var->read_only = false; /* Never emit code to initialize a uniform. */ - if (!this->type->qualifier.uniform) + if (!this->type->qualifier.flags.q.uniform) result = do_assignment(&initializer_instructions, state, lhs, rhs, this->get_location()); @@ -1968,7 +1971,7 @@ ast_declarator_list::hir(exec_list *instructions, * its declaration, so they must be initialized when * declared." */ - if (this->type->qualifier.constant && decl->initializer == NULL) { + if (this->type->qualifier.flags.q.constant && decl->initializer == NULL) { _mesa_glsl_error(& loc, state, "const declaration of `%s' must be initialized"); } diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp index 9a957044e7..b7488cf6e9 100644 --- a/src/glsl/ast_type.cpp +++ b/src/glsl/ast_type.cpp @@ -114,9 +114,5 @@ ast_type_specifier::ast_type_specifier(int specifier) bool ast_fully_specified_type::has_qualifiers() const { - return qualifier.invariant || qualifier.constant || qualifier.attribute - || qualifier.varying || qualifier.in - || qualifier.out || qualifier.centroid - || qualifier.uniform || qualifier.smooth - || qualifier.flat || qualifier.noperspective; + return this->qualifier.flags.i != 0; } diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index be763ed9f0..16d39dc565 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -54,10 +54,7 @@ float real; char *identifier; - union { - struct ast_type_qualifier q; - unsigned i; - } type_qualifier; + struct ast_type_qualifier type_qualifier; ast_node *node; ast_type_specifier *type_specifier; @@ -760,25 +757,25 @@ parameter_declarator: parameter_declaration: parameter_type_qualifier parameter_qualifier parameter_declarator { - $1.i |= $2.i; + $1.flags.i |= $2.flags.i; $$ = $3; - $$->type->qualifier = $1.q; + $$->type->qualifier = $1; } | parameter_qualifier parameter_declarator { $$ = $2; - $$->type->qualifier = $1.q; + $$->type->qualifier = $1; } | parameter_type_qualifier parameter_qualifier parameter_type_specifier { void *ctx = state; - $1.i |= $2.i; + $1.flags.i |= $2.flags.i; $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->qualifier = $1.q; + $$->type->qualifier = $1; $$->type->specifier = $3; } | parameter_qualifier parameter_type_specifier @@ -787,7 +784,7 @@ parameter_declaration: $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); $$->type = new(ctx) ast_fully_specified_type(); - $$->type->qualifier = $1.q; + $$->type->qualifier = $1; $$->type->specifier = $2; } ; @@ -800,17 +797,18 @@ parameter_qualifier: | IN_TOK { memset(& $$, 0, sizeof($$)); - $$.q.in = 1; + $$.flags.q.in = 1; } | OUT_TOK { memset(& $$, 0, sizeof($$)); - $$.q.out = 1; + $$.flags.q.out = 1; } | INOUT_TOK { memset(& $$, 0, sizeof($$)); - $$.q.in = 1; $$.q.out = 1; + $$.flags.q.in = 1; + $$.flags.q.out = 1; } ; @@ -969,7 +967,7 @@ fully_specified_type: void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); $$->set_location(yylloc); - $$->qualifier = $1.q; + $$->qualifier = $1; $$->specifier = $2; } ; @@ -985,7 +983,10 @@ layout_qualifier_id_list: layout_qualifier_id | layout_qualifier_id_list ',' layout_qualifier_id { - $$.i = $1.i | $3.i; + /* FINISHME: Should check for conflicting / duplicate flags here. + */ + $$ = $1; + $$.flags.i |= $3.flags.i; } ; @@ -999,10 +1000,10 @@ layout_qualifier_id: if (state->ARB_fragment_coord_conventions_enable) { if (strcmp($1, "origin_upper_left") == 0) { got_one = true; - $$.q.origin_upper_left = 1; + $$.flags.q.origin_upper_left = 1; } else if (strcmp($1, "pixel_center_integer") == 0) { got_one = true; - $$.q.pixel_center_integer = 1; + $$.flags.q.pixel_center_integer = 1; } } @@ -1025,17 +1026,17 @@ interpolation_qualifier: SMOOTH { memset(& $$, 0, sizeof($$)); - $$.q.smooth = 1; + $$.flags.q.smooth = 1; } | FLAT { memset(& $$, 0, sizeof($$)); - $$.q.flat = 1; + $$.flags.q.flat = 1; } | NOPERSPECTIVE { memset(& $$, 0, sizeof($$)); - $$.q.noperspective = 1; + $$.flags.q.noperspective = 1; } ; @@ -1043,7 +1044,7 @@ parameter_type_qualifier: CONST_TOK { memset(& $$, 0, sizeof($$)); - $$.q.constant = 1; + $$.flags.q.constant = 1; } ; @@ -1052,27 +1053,30 @@ type_qualifier: | layout_qualifier | layout_qualifier storage_qualifier { - $$.i = $1.i | $2.i; + $$ = $1; + $$.flags.i |= $2.flags.i; } | interpolation_qualifier | interpolation_qualifier storage_qualifier { - $$.i = $1.i | $2.i; + $$ = $1; + $$.flags.i |= $2.flags.i; } | INVARIANT storage_qualifier { $$ = $2; - $$.q.invariant = 1; + $$.flags.q.invariant = 1; } | INVARIANT interpolation_qualifier storage_qualifier { - $$.i = $2.i | $3.i; - $$.q.invariant = 1; + $$ = $2; + $$.flags.i |= $3.flags.i; + $$.flags.q.invariant = 1; } | INVARIANT { memset(& $$, 0, sizeof($$)); - $$.q.invariant = 1; + $$.flags.q.invariant = 1; } ; @@ -1080,47 +1084,48 @@ storage_qualifier: CONST_TOK { memset(& $$, 0, sizeof($$)); - $$.q.constant = 1; + $$.flags.q.constant = 1; } | ATTRIBUTE { memset(& $$, 0, sizeof($$)); - $$.q.attribute = 1; + $$.flags.q.attribute = 1; } | VARYING { memset(& $$, 0, sizeof($$)); - $$.q.varying = 1; + $$.flags.q.varying = 1; } | CENTROID VARYING { memset(& $$, 0, sizeof($$)); - $$.q.centroid = 1; $$.q.varying = 1; + $$.flags.q.centroid = 1; + $$.flags.q.varying = 1; } | IN_TOK { memset(& $$, 0, sizeof($$)); - $$.q.in = 1; + $$.flags.q.in = 1; } | OUT_TOK { memset(& $$, 0, sizeof($$)); - $$.q.out = 1; + $$.flags.q.out = 1; } | CENTROID IN_TOK { memset(& $$, 0, sizeof($$)); - $$.q.centroid = 1; $$.q.in = 1; + $$.flags.q.centroid = 1; $$.flags.q.in = 1; } | CENTROID OUT_TOK { memset(& $$, 0, sizeof($$)); - $$.q.centroid = 1; $$.q.out = 1; + $$.flags.q.centroid = 1; $$.flags.q.out = 1; } | UNIFORM { memset(& $$, 0, sizeof($$)); - $$.q.uniform = 1; + $$.flags.q.uniform = 1; } ; diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 33ea664bcd..26e0721ced 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -219,37 +219,37 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, void _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) { - if (q->constant) + if (q->flags.q.constant) printf("const "); - if (q->invariant) + if (q->flags.q.invariant) printf("invariant "); - if (q->attribute) + if (q->flags.q.attribute) printf("attribute "); - if (q->varying) + if (q->flags.q.varying) printf("varying "); - if (q->in && q->out) + if (q->flags.q.in && q->flags.q.out) printf("inout "); else { - if (q->in) + if (q->flags.q.in) printf("in "); - if (q->out) + if (q->flags.q.out) printf("out "); } - if (q->centroid) + if (q->flags.q.centroid) printf("centroid "); - if (q->uniform) + if (q->flags.q.uniform) printf("uniform "); - if (q->smooth) + if (q->flags.q.smooth) printf("smooth "); - if (q->flat) + if (q->flags.q.flat) printf("flat "); - if (q->noperspective) + if (q->flags.q.noperspective) printf("noperspective "); } -- cgit v1.2.3 From 7f68cbdc4d9f602dc2619ac4a90283a4f057a8cb Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Oct 2010 17:00:31 -0700 Subject: glsl: Add parser support for GL_ARB_explicit_attrib_location layouts Only layout(location=#) is supported. Setting the index requires GLSL 1.30 and GL_ARB_blend_func_extended. --- src/glsl/ast.h | 14 +++++++++++ src/glsl/glsl_lexer.lpp | 1 + src/glsl/glsl_parser.ypp | 55 ++++++++++++++++++++++++++++++++++++++--- src/glsl/glsl_parser_extras.cpp | 7 ++++++ src/glsl/glsl_parser_extras.h | 2 ++ 5 files changed, 75 insertions(+), 4 deletions(-) (limited to 'src/glsl/glsl_parser.ypp') diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 5fa932ec80..e5aa5c1b3b 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 ed3cb251a1..8be5c67fc2 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 16d39dc565..ed18179beb 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 26e0721ced..844a746c65 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 ddc2138b76..b573831d5f 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; -- cgit v1.2.3