diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/nir/nir.h | 5 | ||||
-rw-r--r-- | src/compiler/nir/nir_clone.c | 39 |
2 files changed, 42 insertions, 2 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 632cf06c32c..12be397ff19 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2918,6 +2918,8 @@ nir_function_impl *nir_function_impl_clone(nir_shader *shader, nir_constant *nir_constant_clone(const nir_constant *c, nir_variable *var); nir_variable *nir_variable_clone(const nir_variable *c, nir_shader *shader); +void nir_shader_replace(nir_shader *dest, nir_shader *src); + nir_shader *nir_shader_serialize_deserialize(void *mem_ctx, nir_shader *s); #ifndef NDEBUG @@ -2990,8 +2992,7 @@ static inline bool should_print_nir(void) { return false; } nir_validate_shader(nir, "after " #pass); \ if (should_clone_nir()) { \ nir_shader *clone = nir_shader_clone(ralloc_parent(nir), nir); \ - ralloc_free(nir); \ - nir = clone; \ + nir_shader_replace(nir, clone); \ } \ if (should_serialize_deserialize_nir()) { \ void *mem_ctx = ralloc_parent(nir); \ diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index c82ee3c5642..803923e2578 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -769,3 +769,42 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s) return ns; } + +/** Overwrites dst and replaces its contents with src + * + * Everything ralloc parented to dst and src itself (but not its children) + * will be freed. + * + * This should only be used by test code which needs to swap out shaders with + * a cloned or deserialized version. + */ +void +nir_shader_replace(nir_shader *dst, nir_shader *src) +{ + /* Delete all of dest's ralloc children */ + void *dead_ctx = ralloc_context(NULL); + ralloc_adopt(dead_ctx, dst); + ralloc_free(dead_ctx); + + /* Re-parent all of src's ralloc children to dst */ + ralloc_adopt(dst, src); + + memcpy(dst, src, sizeof(*dst)); + + /* We have to move all the linked lists over separately because we need the + * pointers in the list elements to point to the lists in dst and not src. + */ + exec_list_move_nodes_to(&src->uniforms, &dst->uniforms); + exec_list_move_nodes_to(&src->inputs, &dst->inputs); + exec_list_move_nodes_to(&src->outputs, &dst->outputs); + exec_list_move_nodes_to(&src->shared, &dst->shared); + exec_list_move_nodes_to(&src->globals, &dst->globals); + exec_list_move_nodes_to(&src->system_values, &dst->system_values); + + /* Now move the functions over. This takes a tiny bit more work */ + exec_list_move_nodes_to(&src->functions, &dst->functions); + nir_foreach_function(function, dst) + function->shader = dst; + + ralloc_free(src); +} |