[Mesa-dev] [PATCH] [rfc] glsl: allow invariant on fragment shader outputs.

Dave Airlie airlied at gmail.com
Mon May 23 04:18:03 UTC 2016


From: Dave Airlie <airlied at redhat.com>

A CTS test manages to generate this:
GL45-CTS.shading_language_420pack.qualifier_order

I cannot find definitive evidence in the spec that it isn't
allowed. The specs mentions some things can't be used on
fragment shader outputs, but never specifies invariant as
one of them. Chris found GLSL1.20 was more explicit about this
but the language was changed/removed in GLSL 1.30.

This might be a spec bug, I'm not sure.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/compiler/glsl/ast_to_hir.cpp | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index 0ec5b70..69c19e5 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -2586,6 +2586,28 @@ is_varying_var(ir_variable *var, gl_shader_stage target)
    }
 }
 
+static bool
+is_allowed_invariant(ir_variable *var, struct _mesa_glsl_parse_state *state)
+{
+   if (is_varying_var(var, state->stage))
+      return true;
+
+   /* From Section 4.6.1 ("The Invariant Qualifier") GLSL 1.20 spec:
+    * "Only variables output from a vertex shader can be candidates
+    * for invariance".
+    */
+   if (!state->is_version(130, 0))
+      return false;
+
+   /*
+    * Later specs remove this language - so allowed invariant
+    * on fragment shader outputs as well.
+    */
+   if (state->stage == MESA_SHADER_FRAGMENT &&
+       var->data.mode == ir_var_shader_out)
+      return true;
+   return false;
+}
 
 /**
  * Matrix layout qualifiers are only allowed on certain types
@@ -4411,7 +4433,7 @@ ast_declarator_list::hir(exec_list *instructions,
             _mesa_glsl_error(& loc, state,
                              "undeclared variable `%s' cannot be marked "
                              "invariant", decl->identifier);
-         } else if (!is_varying_var(earlier, state->stage)) {
+         } else if (!is_allowed_invariant(earlier, state)) {
             _mesa_glsl_error(&loc, state,
                              "`%s' cannot be marked invariant; interfaces between "
                              "shader stages only.", decl->identifier);
@@ -4700,7 +4722,7 @@ ast_declarator_list::hir(exec_list *instructions,
                                          &loc);
 
       if (this->type->qualifier.flags.q.invariant) {
-         if (!is_varying_var(var, state->stage)) {
+         if (!is_allowed_invariant(var, state)) {
             _mesa_glsl_error(&loc, state,
                              "`%s' cannot be marked invariant; interfaces between "
                              "shader stages only", var->name);
-- 
2.5.5



More information about the mesa-dev mailing list