glsl: Support the 'invariant(all)' pragma
authorIan Romanick <ian.d.romanick@intel.com>
Thu, 6 Jan 2011 18:49:56 +0000 (10:49 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 6 Jan 2011 18:49:56 +0000 (10:49 -0800)
Previously the 'STDGL invariant(all)' pragma added in GLSL 1.20 was
simply ignored by the compiler.  This adds support for setting all
variable invariant.

In GLSL 1.10 and GLSL ES 1.00 the pragma is ignored, per the specs,
but a warning is generated.

Fixes piglit test glsl-invariant-pragma and bugzilla #31925.

NOTE: This is a candidate for the 7.9 and 7.10 branches.

src/glsl/ast_to_hir.cpp
src/glsl/glsl_lexer.lpp
src/glsl/glsl_parser.ypp
src/glsl/glsl_parser_extras.h

index 80c4ef4314c0154f8ee6609e420afea6707578ed..a8dcae6e810f6719331fc6541e5ae1aaa9e803b1 100644 (file)
@@ -1852,6 +1852,23 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    else if (qual->flags.q.uniform)
       var->mode = ir_var_uniform;
 
+   if (state->all_invariant && (state->current_function == NULL)) {
+      switch (state->target) {
+      case vertex_shader:
+        if (var->mode == ir_var_out)
+           var->invariant = true;
+        break;
+      case geometry_shader:
+        if ((var->mode == ir_var_in) || (var->mode == ir_var_out))
+           var->invariant = true;
+        break;
+      case fragment_shader:
+        if (var->mode == ir_var_in)
+           var->invariant = true;
+        break;
+      }
+   }
+
    if (qual->flags.q.flat)
       var->interpolation = ir_var_flat;
    else if (qual->flags.q.noperspective)
index 15742ac3636cb813ab1ec2cbed31f0c0a06c099a..d30759be2b808601c37cefa8986d902ae520ba95 100644 (file)
@@ -145,6 +145,10 @@ HASH               ^{SPC}#{SPC}
                                  BEGIN PP;
                                  return PRAGMA_OPTIMIZE_OFF;
                                }
+^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) {
+                                 BEGIN PP;
+                                 return PRAGMA_INVARIANT_ALL;
+                               }
 ^{SPC}#{SPC}pragma{SPCP}       { BEGIN PRAGMA; }
 
 <PRAGMA>\n                     { BEGIN 0; yylineno++; yycolumn = 0; }
index 6d7d148eb04e4a4364f32571e9d04ccdf492d0d3..41b51a7472558739c7be4137172664c20fcee637 100644 (file)
 %token VERSION EXTENSION LINE COLON EOL INTERFACE OUTPUT
 %token PRAGMA_DEBUG_ON PRAGMA_DEBUG_OFF
 %token PRAGMA_OPTIMIZE_ON PRAGMA_OPTIMIZE_OFF
+%token PRAGMA_INVARIANT_ALL
 %token LAYOUT_TOK
 
    /* Reserved words that are not actually used in the grammar.
@@ -241,6 +242,19 @@ pragma_statement:
        | PRAGMA_DEBUG_OFF EOL
        | PRAGMA_OPTIMIZE_ON EOL
        | PRAGMA_OPTIMIZE_OFF EOL
+       | PRAGMA_INVARIANT_ALL EOL
+       {
+          if (state->language_version < 120) {
+             _mesa_glsl_warning(& @1, state,
+                                "pragma `invariant(all)' not supported in "
+                                "GLSL%s %d.%02d",
+                                state->es_shader ? " ES" : "",
+                                state->language_version / 100,
+                                state->language_version % 100);
+          } else {
+             state->all_invariant = true;
+          }
+       }
        ;
 
 extension_statement_list:
index 98c4e70173d74268ea8d95d3518ebdf5d4981cd8..13d3a2979e43c7deb562c55f86281604cd2bb7ec 100644 (file)
@@ -108,6 +108,13 @@ struct _mesa_glsl_parse_state {
    /** Was there an error during compilation? */
    bool error;
 
+   /**
+    * Are all shader inputs / outputs invariant?
+    *
+    * This is set when the 'STDGL invariant(all)' pragma is used.
+    */
+   bool all_invariant;
+
    /** Loop or switch statement containing the current instructions. */
    class ir_instruction *loop_or_switch_nesting;
    class ast_iteration_statement *loop_or_switch_nesting_ast;