summaryrefslogtreecommitdiffstats
path: root/src/glsl/linker.cpp
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2015-03-17 13:58:57 +0200
committerTapani Pälli <tapani.palli@intel.com>2015-04-16 07:30:12 +0300
commit993b9b6adbd2c97ccb58b7cbc46382d1ae87b9ab (patch)
treef2023c10d2a2d9ea2da398caf3d09867bc55b552 /src/glsl/linker.cpp
parent17d69862a9232e2bcdfa032c5a65c27557dd9275 (diff)
downloadexternal_mesa3d-993b9b6adbd2c97ccb58b7cbc46382d1ae87b9ab.zip
external_mesa3d-993b9b6adbd2c97ccb58b7cbc46382d1ae87b9ab.tar.gz
external_mesa3d-993b9b6adbd2c97ccb58b7cbc46382d1ae87b9ab.tar.bz2
linker: fix varying linking if SSO program has only gs and fs
Previously linker did not take in to account case where one would have only gs and fs (with SSO), patch adds the case by refactoring code around assign_varying_locations. This makes sure locations for gs get populated correctly. This was found with some of the SSO subtests of Martin's upcoming GetProgramInterfaceiv Piglit test which passes with the patch, no Piglit regressions. v2: code cleanups (Martin Peres) Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r--src/glsl/linker.cpp29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 85830e6..118614b 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2726,10 +2726,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
- unsigned first;
- for (first = 0; first <= MESA_SHADER_FRAGMENT; first++) {
- if (prog->_LinkedShaders[first] != NULL)
- break;
+ unsigned first, last;
+
+ first = MESA_SHADER_STAGES;
+ last = 0;
+
+ /* Determine first and last stage. */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (!prog->_LinkedShaders[i])
+ continue;
+ if (first == MESA_SHADER_STAGES)
+ first = i;
+ last = i;
}
if (num_tfeedback_decls != 0) {
@@ -2758,13 +2766,9 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* ensures that inter-shader outputs written to in an earlier stage are
* eliminated if they are (transitively) not used in a later stage.
*/
- int last, next;
- for (last = MESA_SHADER_FRAGMENT; last >= 0; last--) {
- if (prog->_LinkedShaders[last] != NULL)
- break;
- }
+ int next;
- if (last >= 0 && last < MESA_SHADER_FRAGMENT) {
+ if (first < MESA_SHADER_FRAGMENT) {
gl_shader *const sh = prog->_LinkedShaders[last];
if (first == MESA_SHADER_GEOMETRY) {
@@ -2776,13 +2780,14 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
* MESA_SHADER_GEOMETRY.
*/
if (!assign_varying_locations(ctx, mem_ctx, prog,
- NULL, sh,
+ NULL, prog->_LinkedShaders[first],
num_tfeedback_decls, tfeedback_decls,
prog->Geom.VerticesIn))
goto done;
}
- if (num_tfeedback_decls != 0 || prog->SeparateShader) {
+ if (last != MESA_SHADER_FRAGMENT &&
+ (num_tfeedback_decls != 0 || prog->SeparateShader)) {
/* There was no fragment shader, but we still have to assign varying
* locations for use by transform feedback.
*/