diff options
-rw-r--r-- | src/compiler/glsl/nir_linker.cpp | 53 |
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); } |