diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-04-20 15:35:07 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-04-28 01:16:18 +0300 |
commit | 9c82c00b32802a88b71c22929e9660f7ba4023a8 (patch) | |
tree | 11a9314e7c51ab3a99212f3d64d58c5496e1a8e5 /source/blender/gpu | |
parent | 676198f57f492ac89d6468119c4146178eb962a8 (diff) |
GPUMaterial: Rework the deferred compilation to not use double locks
This uses refcounter instead of double thread mutexes. This should be
more robust and avoir use after free situation.
Also remove redundant structures and the use of scene as the job owner.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 24 |
3 files changed, 25 insertions, 3 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 49cfad9d89f..042b79565ef 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../nodes ../nodes/intern + ../../../intern/atomic ../../../intern/clog ../../../intern/ghost ../../../intern/glew-mx diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 58bbe11b4d6..fff90e6f8ff 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -215,6 +215,9 @@ GPUMaterial *GPU_material_from_nodetree(struct Scene *scene, void GPU_material_compile(GPUMaterial *mat); void GPU_material_free(struct ListBase *gpumaterial); +void GPU_material_acquire(GPUMaterial *mat); +void GPU_material_release(GPUMaterial *mat); + void GPU_materials_free(struct Main *bmain); struct Scene *GPU_material_scene(GPUMaterial *material); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 3e9cf31e705..e8fb5fb2c45 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -40,6 +40,8 @@ #include "gpu_codegen.h" #include "gpu_node_graph.h" +#include "atomic_ops.h" + /* Structs */ #define MAX_COLOR_BAND 128 @@ -88,6 +90,8 @@ struct GPUMaterial { int sss_samples; bool sss_dirty; + uint32_t refcount; + #ifndef NDEBUG char name[64]; #endif @@ -142,8 +146,10 @@ static void gpu_material_ramp_texture_build(GPUMaterial *mat) static void gpu_material_free_single(GPUMaterial *material) { - /* Cancel / wait any pending lazy compilation. */ - DRW_deferred_shader_remove(material); + bool do_free = atomic_sub_and_fetch_uint32(&material->refcount, 1) == 0; + if (!do_free) { + return; + } gpu_node_graph_free(&material->graph); @@ -168,6 +174,7 @@ void GPU_material_free(ListBase *gpumaterial) { LISTBASE_FOREACH (LinkData *, link, gpumaterial) { GPUMaterial *material = link->data; + DRW_deferred_shader_remove(material); gpu_material_free_single(material); MEM_freeN(material); } @@ -660,6 +667,7 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene, mat->is_volume_shader = is_volume_shader; mat->graph.used_libraries = BLI_gset_new( BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "GPUNodeGraph.used_libraries"); + mat->refcount = 1; #ifndef NDEBUG BLI_snprintf(mat->name, sizeof(mat->name), "%s", name); #else @@ -709,11 +717,21 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene, return mat; } +void GPU_material_acquire(GPUMaterial *mat) +{ + atomic_add_and_fetch_uint32(&mat->refcount, 1); +} + +void GPU_material_release(GPUMaterial *mat) +{ + gpu_material_free_single(mat); +} + void GPU_material_compile(GPUMaterial *mat) { bool success; - BLI_assert(mat->status == GPU_MAT_QUEUED); + BLI_assert(ELEM(mat->status, GPU_MAT_QUEUED, GPU_MAT_CREATED)); BLI_assert(mat->pass); /* NOTE: The shader may have already been compiled here since we are |