summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
authorVadym Shovkoplias <[email protected]>2018-09-07 15:14:52 +0300
committerTapani Pälli <[email protected]>2018-09-12 11:43:21 +0300
commit9b5c0c520f6e41f19b3568a4e0532c836bc522e4 (patch)
tree461785c1a157f3d016fd4c4ee8c0a0f2281df82a /src/compiler/glsl
parent30580640f2508e935e667e25f0e0cf4ff0ce55af (diff)
glsl/linker: Check the invariance of built-in special variables
From Section 4.6.4 (Invariance and Linkage) of the GLSL ES 1.0 specification "The invariance of varyings that are declared in both the vertex and fragment shaders must match. For the built-in special variables, gl_FragCoord can only be declared invariant if and only if gl_Position is declared invariant. Similarly gl_PointCoord can only be declared invariant if and only if gl_PointSize is declared invariant. It is an error to declare gl_FrontFacing as invariant. The invariance of gl_FrontFacing is the same as the invariance of gl_Position." Fixes: * glsl-pcoord-invariant.shader_test * glsl-fcoord-invariant.shader_test * glsl-fface-invariant.shader_test Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107734 Signed-off-by: Vadym Shovkoplias <[email protected]> Reviewed-by: Tapani Pälli <[email protected]>
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/linker.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 57cf7eb2a8c..3fde7e78d31 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -1287,6 +1287,66 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
return true;
}
+/**
+ * Verifies the invariance of built-in special variables.
+ */
+static bool
+validate_invariant_builtins(struct gl_shader_program *prog,
+ const gl_linked_shader *vert,
+ const gl_linked_shader *frag)
+{
+ const ir_variable *var_vert;
+ const ir_variable *var_frag;
+
+ if (!vert || !frag)
+ return true;
+
+ /*
+ * From OpenGL ES Shading Language 1.0 specification
+ * (4.6.4 Invariance and Linkage):
+ * "The invariance of varyings that are declared in both the vertex and
+ * fragment shaders must match. For the built-in special variables,
+ * gl_FragCoord can only be declared invariant if and only if
+ * gl_Position is declared invariant. Similarly gl_PointCoord can only
+ * be declared invariant if and only if gl_PointSize is declared
+ * invariant. It is an error to declare gl_FrontFacing as invariant.
+ * The invariance of gl_FrontFacing is the same as the invariance of
+ * gl_Position."
+ */
+ var_frag = frag->symbols->get_variable("gl_FragCoord");
+ if (var_frag && var_frag->data.invariant) {
+ var_vert = vert->symbols->get_variable("gl_Position");
+ if (var_vert && !var_vert->data.invariant) {
+ linker_error(prog,
+ "fragment shader built-in `%s' has invariant qualifier, "
+ "but vertex shader built-in `%s' lacks invariant qualifier\n",
+ var_frag->name, var_vert->name);
+ return false;
+ }
+ }
+
+ var_frag = frag->symbols->get_variable("gl_PointCoord");
+ if (var_frag && var_frag->data.invariant) {
+ var_vert = vert->symbols->get_variable("gl_PointSize");
+ if (var_vert && !var_vert->data.invariant) {
+ linker_error(prog,
+ "fragment shader built-in `%s' has invariant qualifier, "
+ "but vertex shader built-in `%s' lacks invariant qualifier\n",
+ var_frag->name, var_vert->name);
+ return false;
+ }
+ }
+
+ var_frag = frag->symbols->get_variable("gl_FrontFacing");
+ if (var_frag && var_frag->data.invariant) {
+ linker_error(prog,
+ "fragment shader built-in `%s' can not be declared as invariant\n",
+ var_frag->name);
+ return false;
+ }
+
+ return true;
+}
/**
* Populates a shaders symbol table with all global declarations
@@ -5012,6 +5072,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
lower_named_interface_blocks(mem_ctx, prog->_LinkedShaders[i]);
}
+ if (prog->IsES && prog->data->Version == 100)
+ if (!validate_invariant_builtins(prog,
+ prog->_LinkedShaders[MESA_SHADER_VERTEX],
+ prog->_LinkedShaders[MESA_SHADER_FRAGMENT]))
+ goto done;
+
/* Implement the GLSL 1.30+ rule for discard vs infinite loops Do
* it before optimization because we want most of the checks to get
* dropped thanks to constant propagation.