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)
{
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;
}
}
-
-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)
}
}
- if (prog->SeparateShader)
- disable_varying_optimizations_for_sso(prog);
-
/* Process UBOs */
if (!interstage_cross_validate_uniform_blocks(prog, false))
goto done;