summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast.h1
-rw-r--r--src/glsl/ast_to_hir.cpp12
-rw-r--r--src/glsl/glsl_lexer.ll3
-rw-r--r--src/glsl/glsl_parser.yy39
-rw-r--r--src/glsl/ir.h1
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?