glsl: Only allow invariant on shader in/out between stages.

Previously this was special-cased for VS and FS; it never got updated
when geometry shaders came along. Generalize using is_varying_var() so
this won't be broken again with tessellation.

Note that there are two copies of the logic for `invariant`: It can be
present as part of a new declaration, and also as a redeclaration of an
existing variable or block member.

Fixes the four new piglits:
   spec/glsl-1.50/compiler/invariant-qualifier-*.geom

Note for stable: This won't quite pick cleanly due to whitespace and
state->target -> state->stage renames. Should be straightforward
adjustments though.

Cc: "10.0 10.1" <mesa-stable@lists.freedesktop.org>
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Chris Forbes
2014-04-21 15:45:32 +12:00
parent 0a0075666c
commit 0dfa6e7cf5
+8 -23
View File
@@ -3065,16 +3065,10 @@ ast_declarator_list::hir(exec_list *instructions,
_mesa_glsl_error(& loc, state,
"undeclared variable `%s' cannot be marked "
"invariant", decl->identifier);
} else if ((state->stage == MESA_SHADER_VERTEX)
&& (earlier->data.mode != ir_var_shader_out)) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, vertex shader "
"outputs only", decl->identifier);
} else if ((state->stage == MESA_SHADER_FRAGMENT)
&& (earlier->data.mode != ir_var_shader_in)) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, fragment shader "
"inputs only", decl->identifier);
} else if (!is_varying_var(earlier, state->stage)) {
_mesa_glsl_error(&loc, state,
"`%s' cannot be marked invariant; interfaces between "
"shader stages only.", decl->identifier);
} else if (earlier->data.used) {
_mesa_glsl_error(& loc, state,
"variable `%s' may not be redeclared "
@@ -3250,19 +3244,10 @@ ast_declarator_list::hir(exec_list *instructions,
& loc, false);
if (this->type->qualifier.flags.q.invariant) {
if ((state->stage == MESA_SHADER_VERTEX) &&
var->data.mode != ir_var_shader_out) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, vertex shader "
"outputs only", var->name);
} else if ((state->stage == MESA_SHADER_FRAGMENT) &&
var->data.mode != ir_var_shader_in) {
/* FINISHME: Note that this doesn't work for invariant on
* a function signature inval
*/
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, fragment shader "
"inputs only", var->name);
if (!is_varying_var(var, state->stage)) {
_mesa_glsl_error(&loc, state,
"`%s' cannot be marked invariant; interfaces between "
"shader stages only", var->name);
}
}