diff options
-rw-r--r-- | src/glsl/ast.h | 1 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 12 | ||||
-rw-r--r-- | src/glsl/glsl_lexer.ll | 3 | ||||
-rw-r--r-- | src/glsl/glsl_parser.yy | 39 | ||||
-rw-r--r-- | src/glsl/ir.h | 1 |
5 files changed, 48 insertions, 8 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 6b136f51879..b0430de071e 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -424,6 +424,7 @@ struct ast_type_qualifier { union { struct { unsigned invariant:1; + unsigned precise:1; unsigned constant:1; unsigned attribute:1; unsigned varying:1; diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f230a70a3ed..0b28b4814c4 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2393,6 +2393,17 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } } + if (qual->flags.q.precise) { + if (var->data.used) { + _mesa_glsl_error(loc, state, + "variable `%s' may not be redeclared " + "`precise' after being used", + var->name); + } else { + var->data.precise = 1; + } + } + if (qual->flags.q.constant || qual->flags.q.attribute || qual->flags.q.uniform || (qual->flags.q.varying && (state->stage == MESA_SHADER_FRAGMENT))) @@ -3165,6 +3176,7 @@ ast_declarator_list::hir(exec_list *instructions, assert(this->type != NULL); assert(!this->invariant); + assert(!this->precise); /* The type specifier may contain a structure definition. Process that * before any of the variable declarations. diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll index 760235127b8..6c3f9b692b4 100644 --- a/src/glsl/glsl_lexer.ll +++ b/src/glsl/glsl_lexer.ll @@ -338,6 +338,9 @@ samplerExternalOES { return IDENTIFIER; } + /* keywords available with ARB_gpu_shader5 */ +precise KEYWORD_WITH_ALT(400, 0, 400, 0, yyextra->ARB_gpu_shader5_enable, PRECISE); + /* keywords available with ARB_shader_image_load_store */ image1D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE1D); image2D KEYWORD_WITH_ALT(130, 300, 420, 0, yyextra->ARB_shader_image_load_store_enable, IMAGE2D); diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy index b6f61467555..83cbb902b5d 100644 --- a/src/glsl/glsl_parser.yy +++ b/src/glsl/glsl_parser.yy @@ -166,7 +166,7 @@ static bool match_layout_qualifier(const char *s1, const char *s2, %token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN %token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN %token SUB_ASSIGN -%token INVARIANT +%token INVARIANT PRECISE %token LOWP MEDIUMP HIGHP SUPERP PRECISION %token VERSION_TOK EXTENSION LINE COLON EOL INTERFACE OUTPUT @@ -1498,6 +1498,11 @@ type_qualifier: memset(& $$, 0, sizeof($$)); $$.flags.q.invariant = 1; } + | PRECISE + { + memset(& $$, 0, sizeof($$)); + $$.flags.q.precise = 1; + } | auxiliary_storage_qualifier | storage_qualifier | interpolation_qualifier @@ -1518,8 +1523,16 @@ type_qualifier: * Each qualifier's rule ensures that the accumulated qualifiers on the right * side don't contain any that must appear on the left hand side. * For example, when processing a storage qualifier, we check that there are - * no auxiliary, interpolation, layout, or invariant qualifiers to the right. + * no auxiliary, interpolation, layout, invariant, or precise qualifiers to the right. */ + | PRECISE type_qualifier + { + if ($2.flags.q.precise) + _mesa_glsl_error(&@1, state, "duplicate \"precise\" qualifier"); + + $$ = $2; + $$.flags.q.precise = 1; + } | INVARIANT type_qualifier { if ($2.flags.q.invariant) @@ -1530,6 +1543,10 @@ type_qualifier: "\"invariant\" cannot be used with layout(...)"); } + if (!state->ARB_shading_language_420pack_enable && $2.flags.q.precise) + _mesa_glsl_error(&@1, state, + "\"invariant\" must come after \"precise\""); + $$ = $2; $$.flags.q.invariant = 1; } @@ -1553,9 +1570,10 @@ type_qualifier: "with layout(...)"); } - if (!state->ARB_shading_language_420pack_enable && $2.flags.q.invariant) { + if (!state->ARB_shading_language_420pack_enable && + ($2.flags.q.precise || $2.flags.q.invariant)) { _mesa_glsl_error(&@1, state, "interpolation qualifiers must come " - "after \"invariant\""); + "after \"precise\" or \"invariant\""); } $$ = $1; @@ -1576,6 +1594,10 @@ type_qualifier: _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " "the \"invariant\" qualifier"); + if ($2.flags.q.precise) + _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " + "the \"precise\" qualifier"); + if ($2.has_interpolation()) { _mesa_glsl_error(&@1, state, "layout(...) cannot be used with " "interpolation qualifiers"); @@ -1592,7 +1614,8 @@ type_qualifier: } if (!state->ARB_shading_language_420pack_enable && - ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout())) { + ($2.flags.q.precise || $2.flags.q.invariant || + $2.has_interpolation() || $2.has_layout())) { _mesa_glsl_error(&@1, state, "auxiliary storage qualifiers must come " "just before storage qualifiers"); } @@ -1609,10 +1632,10 @@ type_qualifier: _mesa_glsl_error(&@1, state, "duplicate storage qualifier"); if (!state->ARB_shading_language_420pack_enable && - ($2.flags.q.invariant || $2.has_interpolation() || $2.has_layout() || - $2.has_auxiliary_storage())) { + ($2.flags.q.precise || $2.flags.q.invariant || $2.has_interpolation() || + $2.has_layout() || $2.has_auxiliary_storage())) { _mesa_glsl_error(&@1, state, "storage qualifiers must come after " - "invariant, interpolation, layout and auxiliary " + "precise, invariant, interpolation, layout and auxiliary " "storage qualifiers"); } diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 2afafe4b5c7..b4e52d3d0a5 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -561,6 +561,7 @@ public: unsigned centroid:1; unsigned sample:1; unsigned invariant:1; + unsigned precise:1; /** * Has this variable been used for reading or writing? |