glsl: move disable_varying_optimizations_for_sso() to NIR linker
authorTimothy Arceri <tarceri@itsqueeze.com>
Wed, 5 Apr 2023 04:01:34 +0000 (14:01 +1000)
committerMarge Bot <emma+marge@anholt.net>
Thu, 6 Jul 2023 01:21:06 +0000 (01:21 +0000)
Reviewed-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22846>

src/compiler/glsl/gl_nir_linker.c
src/compiler/glsl/linker.cpp

index f39223c..e874ff8 100644 (file)
@@ -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;
 
index 7706da5..9c75026 100644 (file)
@@ -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;