summaryrefslogtreecommitdiff
path: root/src/glsl/linker.cpp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-07-28 13:52:23 -0700
committerEric Anholt <eric@anholt.net>2010-07-28 14:04:54 -0700
commitb706283c79de41caf775b0bb15b3c849932f2574 (patch)
tree7bed194fe30c61590154e42a2056ffe3796083b9 /src/glsl/linker.cpp
parenta6c7606ab6e2ba8b4fc253e93a83ca2f18a874b4 (diff)
glsl2: Fail linking where the FS reads a varying that the VS doesn't write.
Fixes: glsl1-varying read but not written glsl1-varying var mismatch
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r--src/glsl/linker.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index ec3cc01d40..fa4fb493f2 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1061,7 +1061,8 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index
void
-assign_varying_locations(gl_shader *producer, gl_shader *consumer)
+assign_varying_locations(struct gl_shader_program *prog,
+ gl_shader *producer, gl_shader *consumer)
{
/* FINISHME: Set dynamically when geometry shader support is added. */
unsigned output_index = VERT_RESULT_VAR0;
@@ -1128,11 +1129,32 @@ assign_varying_locations(gl_shader *producer, gl_shader *consumer)
if ((var == NULL) || (var->mode != ir_var_in))
continue;
- /* An 'in' variable is only really a shader input if its value is written
- * by the previous stage.
- */
- var->shader_in = (var->location != -1);
- var->mode = ir_var_auto;
+ if (var->location == -1) {
+ if (prog->Version <= 120) {
+ /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
+ *
+ * Only those varying variables used (i.e. read) in
+ * the fragment shader executable must be written to
+ * by the vertex shader executable; declaring
+ * superfluous varying variables in a vertex shader is
+ * permissible.
+ *
+ * We interpret this text as meaning that the VS must
+ * write the variable for the FS to read it. See
+ * "glsl1-varying read but not written" in piglit.
+ */
+
+ linker_error_printf(prog, "fragment shader varying %s not written "
+ "by vertex shader\n.", var->name);
+ prog->LinkStatus = false;
+ }
+
+ /* An 'in' variable is only really a shader input if its
+ * value is written by the previous stage.
+ */
+ var->shader_in = false;
+ var->mode = ir_var_auto;
+ }
}
}
@@ -1294,7 +1316,8 @@ link_shaders(struct gl_shader_program *prog)
goto done;
for (unsigned i = 1; i < prog->_NumLinkedShaders; i++)
- assign_varying_locations(prog->_LinkedShaders[i - 1],
+ assign_varying_locations(prog,
+ prog->_LinkedShaders[i - 1],
prog->_LinkedShaders[i]);
/* FINISHME: Assign fragment shader output locations. */