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.pa...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev