summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ast_to_hir.cpp17
-rw-r--r--src/glsl/glsl_lexer.lpp4
-rw-r--r--src/glsl/glsl_parser.ypp14
-rw-r--r--src/glsl/glsl_parser_extras.h7
4 files changed, 42 insertions, 0 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 80c4ef4314c..a8dcae6e810 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -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)
diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp
index 15742ac3636..d30759be2b8 100644
--- a/src/glsl/glsl_lexer.lpp
+++ b/src/glsl/glsl_lexer.lpp
@@ -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; }
diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp
index 6d7d148eb04..41b51a74725 100644
--- a/src/glsl/glsl_parser.ypp
+++ b/src/glsl/glsl_parser.ypp
@@ -108,6 +108,7 @@
%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:
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 98c4e70173d..13d3a2979e4 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -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;