[Mesa-dev] [PATCH] glsl: validate invariance between builtin variables
Tapani Pälli
tapani.palli at intel.com
Fri Nov 7 03:25:49 PST 2014
Patch adds additional validation for GLSL ES 1.00 that specifies
cross stage variance requirements for a set of specified builtins.
Fixes failures in WebGL conformance test 'shaders-with-invariance'.
Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
src/glsl/linker.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index bd2aa3c..57082a4 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -695,10 +695,29 @@ cross_validate_globals(struct gl_shader_program *prog,
* them.
*/
glsl_symbol_table variables;
+
+ ir_variable *gl_fcoord = NULL, *gl_position = NULL,
+ *gl_pcoord = NULL, *gl_psize = NULL,
+ *gl_frontf = NULL;
+
for (unsigned i = 0; i < num_shaders; i++) {
if (shader_list[i] == NULL)
continue;
+ /* For GLSL ES 1.00, store builtin variables that require
+ * cross stage validation.
+ */
+ if (prog->IsES && prog->Version < 300) {
+ if (shader_list[i]->Stage == MESA_SHADER_VERTEX) {
+ gl_position = shader_list[i]->symbols->get_variable("gl_Position");
+ gl_psize = shader_list[i]->symbols->get_variable("gl_PointSize");
+ } else if (shader_list[i]->Stage == MESA_SHADER_FRAGMENT) {
+ gl_fcoord = shader_list[i]->symbols->get_variable("gl_FragCoord");
+ gl_pcoord = shader_list[i]->symbols->get_variable("gl_PointCoord");
+ gl_frontf = shader_list[i]->symbols->get_variable("gl_FrontFacing");
+ }
+ }
+
foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
ir_variable *const var = node->as_variable();
@@ -904,6 +923,30 @@ cross_validate_globals(struct gl_shader_program *prog,
variables.add_variable(var);
}
}
+
+ /* GLSL ES 1.00 specification, Section "Invariance and Linkage" says:
+ *
+ * "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."
+ */
+ if (prog->IsES && prog->Version < 300) {
+ if (gl_fcoord && gl_position)
+ if (gl_fcoord->data.invariant && !gl_position->data.invariant)
+ linker_error(prog, "gl_FragCoord declared invariant "
+ "while gl_Position is declared variant.");
+
+ if (gl_pcoord && gl_psize)
+ if (gl_pcoord->data.invariant && !gl_psize->data.invariant)
+ linker_error(prog, "gl_PointCoord declared invariant "
+ "while gl_PointSize is declared variant.");
+
+ if (gl_frontf && gl_frontf->data.invariant)
+ linker_error(prog, "gl_FrontFacing cannot be declared invariant.");
+ }
}
--
1.9.3
More information about the mesa-dev
mailing list