diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 53d8e4bf536..88b05d80f30 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1692,6 +1692,23 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else if (qual->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->flat) var->interpolation = ir_var_flat; else if (qual->noperspective) diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp index 786fc68c625..eba5e728df1 100644 --- a/src/glsl/glsl_lexer.lpp +++ b/src/glsl/glsl_lexer.lpp @@ -137,6 +137,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; } \n { BEGIN 0; yylineno++; yycolumn = 0; } diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 0df1e480ce3..209e1802020 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -111,6 +111,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. @@ -243,6 +244,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 ddc2138b765..10de53683ee 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -109,6 +109,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;