summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/nir_linker.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/compiler/glsl/nir_linker.cpp b/src/compiler/glsl/nir_linker.cpp
index 22204c1d54..c197c3c21f 100644
--- a/src/compiler/glsl/nir_linker.cpp
+++ b/src/compiler/glsl/nir_linker.cpp
@@ -163,6 +163,50 @@ nir_to_ir_variable(void *mem_ctx, gl_shader_program *prog,
ir_var->data.explicit_location = 1;
}
+static ir_variable *
+find_ir_variable(gl_linked_shader *sh, nir_variable *nir_var)
+{
+ ir_variable_mode mode = ir_from_nir_variable_mode(nir_var->data.mode);
+
+ foreach_in_list(ir_instruction, node, sh->ir) {
+ ir_variable *ir_var = node->as_variable();
+ if (!ir_var)
+ continue;
+
+ if (ir_var->data.mode != mode)
+ continue;
+
+ if (nir_var->data.location >= 0) {
+ if (ir_var->data.location == nir_var->data.location)
+ return ir_var;
+ } else if (nir_var->name) {
+ if (!strcmp(nir_var->name, ir_var->name))
+ return ir_var;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+ir_to_nir_variable(gl_linked_shader *sh, nir_variable *nir_var)
+{
+ const ir_variable *ir_var = find_ir_variable(sh, nir_var);
+
+ if (!ir_var) {
+ /* Variable was removed during linking. Remove it from NIR interfaces
+ * as well.
+ */
+ nir_var->data.mode = nir_var_global;
+ exec_node_remove(&nir_var->node);
+ exec_list_push_tail(&sh->nir->globals, &nir_var->node);
+ return;
+ }
+
+ assert(nir_var->data.location < 0 || nir_var->data.location == ir_var->data.location);
+ nir_var->data.location = ir_var->data.location;
+}
+
/**
* Create and fill in a gl_linked_shader for a given shader which has already
* been converted to NIR.
@@ -229,5 +273,14 @@ void
finalize_linked_nir_shader(struct gl_shader_program *prog,
struct gl_linked_shader *sh)
{
+ nir_foreach_variable_safe(var, &sh->nir->inputs)
+ ir_to_nir_variable(sh, var);
+
+ nir_foreach_variable_safe(var, &sh->nir->outputs)
+ ir_to_nir_variable(sh, var);
+
+ nir_foreach_variable_safe(var, &sh->nir->uniforms)
+ ir_to_nir_variable(sh, var);
+
nir_print_shader(sh->nir, stdout);
}