glsl: add support for `precise` in type_qualifier
authorChris Forbes <chrisf@ijw.co.nz>
Sun, 27 Apr 2014 04:03:53 +0000 (16:03 +1200)
committerChris Forbes <chrisf@ijw.co.nz>
Wed, 4 Jun 2014 06:56:03 +0000 (18:56 +1200)
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/glsl/ast.h
src/glsl/ast_to_hir.cpp
src/glsl/glsl_lexer.ll
src/glsl/glsl_parser.yy
src/glsl/ir.h

index 6b136f518795420a459ffd93a511ae4d23bc17a8..b0430de071ee7305c4b1735c105b2c6ad44ff6d6 100644 (file)
@@ -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;
index f230a70a3ed5a4c1c46af7173853d76331157d4d..0b28b4814c42a7ac73f9f7cb3af918e13edbc6d4 100644 (file)
@@ -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.
index 760235127b89c77bc2158e4d0577adcd0d687e55..6c3f9b692b453a93a0d1738f9e2e2e6dfe3d55f3 100644 (file)
@@ -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);
index b6f614675553c891218faa065f7ac825dcdafa88..83cbb902b5daf08ebc1c3c31276eef61eedd7d5c 100644 (file)
@@ -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");
       }
 
index 2afafe4b5c7c4e6ecabc174181ba0b7baf17f258..b4e52d3d0a51386bef39ea1a329ae26b5a273b89 100644 (file)
@@ -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?