diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 6b26b9c1042..e0b36a224d1 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -117,7 +117,7 @@ gl_nir_opts(nir_shader *nir) } while (progress); } -void +static void gl_nir_link_opts(nir_shader *producer, nir_shader *consumer) { if (producer->options->lower_to_scalar) { @@ -756,6 +756,24 @@ gl_nir_link_spirv(const struct gl_constants *consts, struct gl_shader_program *prog, const struct gl_nir_linker_options *options) { + struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES]; + unsigned num_shaders = 0; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog->_LinkedShaders[i]) + linked_shader[num_shaders++] = prog->_LinkedShaders[i]; + } + + /* Linking the stages in the opposite order (from fragment to vertex) + * ensures that inter-shader outputs written to in an earlier stage + * are eliminated if they are (transitively) not used in a later + * stage. + */ + for (int i = num_shaders - 2; i >= 0; i--) { + gl_nir_link_opts(linked_shader[i]->Program->nir, + linked_shader[i + 1]->Program->nir); + } + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_linked_shader *shader = prog->_LinkedShaders[i]; if (shader) { @@ -919,6 +937,34 @@ gl_nir_link_glsl(const struct gl_constants *consts, return false; } + if (prog->data->LinkStatus == LINKING_FAILURE) + return false; + + struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES]; + unsigned num_shaders = 0; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog->_LinkedShaders[i]) + linked_shader[num_shaders++] = prog->_LinkedShaders[i]; + } + + /* Linking the stages in the opposite order (from fragment to vertex) + * ensures that inter-shader outputs written to in an earlier stage + * are eliminated if they are (transitively) not used in a later + * stage. + */ + for (int i = num_shaders - 2; i >= 0; i--) { + gl_nir_link_opts(linked_shader[i]->Program->nir, + linked_shader[i + 1]->Program->nir); + } + + /* Tidy up any left overs from the linking process for single shaders. + * For example varying arrays that get packed may have dead elements that + * can be now be eliminated now that array access has been lowered. + */ + if (num_shaders == 1) + gl_nir_opts(linked_shader[0]->Program->nir); + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_linked_shader *shader = prog->_LinkedShaders[i]; if (shader) { diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 892f4d7660b..4454c110f6d 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -54,8 +54,6 @@ struct gl_nir_linker_options { void gl_nir_opts(nir_shader *nir); -void gl_nir_link_opts(nir_shader *producer, nir_shader *consumer); - bool gl_nir_link_spirv(const struct gl_constants *consts, struct gl_shader_program *prog, const struct gl_nir_linker_options *options); diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 23c6e8f88a5..fa5bfc31f86 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -712,16 +712,6 @@ st_link_nir(struct gl_context *ctx, gl_nir_opts(linked_shader[0]->Program->nir); if (shader_program->data->spirv) { - /* Linking the stages in the opposite order (from fragment to vertex) - * ensures that inter-shader outputs written to in an earlier stage - * are eliminated if they are (transitively) not used in a later - * stage. - */ - for (int i = num_shaders - 2; i >= 0; i--) { - gl_nir_link_opts(linked_shader[i]->Program->nir, - linked_shader[i + 1]->Program->nir); - } - static const gl_nir_linker_options opts = { true /*fill_parameters */ }; @@ -731,23 +721,6 @@ st_link_nir(struct gl_context *ctx, if (!gl_nir_link_glsl(&ctx->Const, &ctx->Extensions, ctx->API, shader_program)) return GL_FALSE; - - /* Linking the stages in the opposite order (from fragment to vertex) - * ensures that inter-shader outputs written to in an earlier stage - * are eliminated if they are (transitively) not used in a later - * stage. - */ - for (int i = num_shaders - 2; i >= 0; i--) { - gl_nir_link_opts(linked_shader[i]->Program->nir, - linked_shader[i + 1]->Program->nir); - } - - /* Tidy up any left overs from the linking process for single shaders. - * For example varying arrays that get packed may have dead elements that - * can be now be eliminated now that array access has been lowered. - */ - if (num_shaders == 1) - gl_nir_opts(linked_shader[0]->Program->nir); } for (unsigned i = 0; i < num_shaders; i++) {