From 06f3988c582b8761a5eebe13d9c252d03955c03d Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 5 Apr 2023 14:01:34 +1000 Subject: [PATCH] glsl: move disable_varying_optimizations_for_sso() to NIR linker MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Emma Anholt Reviewed-by: Marek Olšák Part-of: --- src/compiler/glsl/gl_nir_linker.c | 66 +++++++++++++++++++++++++++++++++++++ src/compiler/glsl/linker.cpp | 68 --------------------------------------- 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index f39223c..e874ff8 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -236,6 +236,69 @@ can_remove_var(nir_variable *var, UNUSED void *data) return true; } +static void +set_always_active_io(nir_shader *shader, nir_variable_mode io_mode) +{ + assert(io_mode == nir_var_shader_in || io_mode == nir_var_shader_out); + + nir_foreach_variable_with_modes(var, shader, io_mode) { + /* Don't set always active on builtins that haven't been redeclared */ + if (var->data.how_declared == nir_var_declared_implicitly) + continue; + + var->data.always_active_io = true; + } +} + +/** + * When separate shader programs are enabled, only input/outputs between + * the stages of a multi-stage separate program can be safely removed + * from the shader interface. Other inputs/outputs must remain active. + */ +static void +disable_varying_optimizations_for_sso(struct gl_shader_program *prog) +{ + unsigned first, last; + assert(prog->SeparateShader); + + first = MESA_SHADER_STAGES; + last = 0; + + /* Determine first and last stage. Excluding the compute stage */ + for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) { + if (!prog->_LinkedShaders[i]) + continue; + if (first == MESA_SHADER_STAGES) + first = i; + last = i; + } + + if (first == MESA_SHADER_STAGES) + return; + + for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { + if (!prog->_LinkedShaders[stage]) + continue; + + /* Prevent the removal of inputs to the first and outputs from the last + * stage, unless they are the initial pipeline inputs or final pipeline + * outputs, respectively. + * + * The removal of IO between shaders in the same program is always + * allowed. + */ + if (stage == first && stage != MESA_SHADER_VERTEX) { + set_always_active_io(prog->_LinkedShaders[stage]->Program->nir, + nir_var_shader_in); + } + + if (stage == last && stage != MESA_SHADER_FRAGMENT) { + set_always_active_io(prog->_LinkedShaders[stage]->Program->nir, + nir_var_shader_out); + } + } +} + static bool inout_has_same_location(const nir_variable *var, unsigned stage) { @@ -1239,6 +1302,9 @@ gl_nir_link_glsl(const struct gl_constants *consts, MESA_TRACE_FUNC(); + if (prog->SeparateShader) + disable_varying_optimizations_for_sso(prog); + struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES]; unsigned num_shaders = 0; diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 7706da5..9c75026 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -3447,71 +3447,6 @@ verify_subroutine_associated_funcs(struct gl_shader_program *prog) } } - -static void -set_always_active_io(exec_list *ir, ir_variable_mode io_mode) -{ - assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out); - - foreach_in_list(ir_instruction, node, ir) { - ir_variable *const var = node->as_variable(); - - if (var == NULL || var->data.mode != io_mode) - continue; - - /* Don't set always active on builtins that haven't been redeclared */ - if (var->data.how_declared == ir_var_declared_implicitly) - continue; - - var->data.always_active_io = true; - } -} - -/** - * When separate shader programs are enabled, only input/outputs between - * the stages of a multi-stage separate program can be safely removed - * from the shader interface. Other inputs/outputs must remain active. - */ -static void -disable_varying_optimizations_for_sso(struct gl_shader_program *prog) -{ - unsigned first, last; - assert(prog->SeparateShader); - - first = MESA_SHADER_STAGES; - last = 0; - - /* Determine first and last stage. Excluding the compute stage */ - for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) { - if (!prog->_LinkedShaders[i]) - continue; - if (first == MESA_SHADER_STAGES) - first = i; - last = i; - } - - if (first == MESA_SHADER_STAGES) - return; - - for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { - gl_linked_shader *sh = prog->_LinkedShaders[stage]; - if (!sh) - continue; - - /* Prevent the removal of inputs to the first and outputs from the last - * stage, unless they are the initial pipeline inputs or final pipeline - * outputs, respectively. - * - * The removal of IO between shaders in the same program is always - * allowed. - */ - if (stage == first && stage != MESA_SHADER_VERTEX) - set_always_active_io(sh->ir, ir_var_shader_in); - if (stage == last && stage != MESA_SHADER_FRAGMENT) - set_always_active_io(sh->ir, ir_var_shader_out); - } -} - static bool link_varyings(const struct gl_constants *consts, struct gl_shader_program *prog, void *mem_ctx) @@ -3827,9 +3762,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } } - if (prog->SeparateShader) - disable_varying_optimizations_for_sso(prog); - /* Process UBOs */ if (!interstage_cross_validate_uniform_blocks(prog, false)) goto done; -- 2.7.4