From 1a96447d2d0a1df8089a3ed6778ee6c94bd2a611 Mon Sep 17 00:00:00 2001 From: Michael Parkin-White Date: Tue, 14 Mar 2023 14:17:25 +0000 Subject: [PATCH] Fix: Uncached materials not being released Optimized node graphs do not get cached and were not correctly freed once their reference count reached zero, due to being excluded from the GPUPass garbage collection. Also suppress Metal shader warnings, which are prevalent during material optimization. Authored by Apple: Michael Parkin-White --- source/blender/gpu/intern/gpu_codegen.cc | 24 ++++++++++++------- .../gpu/shaders/metal/mtl_shader_defines.msl | 4 ++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 78cddc6d272..d9d8031c0ab 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -99,6 +99,8 @@ struct GPUPass { /** Hint that an optimized variant of this pass should be created based on a complexity heuristic * during pass code generation. */ bool should_optimize; + /** Whether pass is in the GPUPass cache. */ + bool cached; }; /* -------------------------------------------------------------------- */ @@ -132,6 +134,7 @@ static GPUPass *gpu_pass_cache_lookup(uint32_t hash) static void gpu_pass_cache_insert_after(GPUPass *node, GPUPass *pass) { BLI_spin_lock(&pass_cache_spin); + pass->cached = true; if (node != nullptr) { /* Add after the first pass having the same hash. */ pass->next = node->next; @@ -775,6 +778,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, pass->create_info = codegen.create_info; pass->hash = codegen.hash_get(); pass->compiled = false; + pass->cached = false; /* Only flag pass optimization hint if this is the first generated pass for a material. * Optimized passes cannot be optimized further, even if the heuristic is still not * favorable. */ @@ -881,14 +885,6 @@ GPUShader *GPU_pass_shader_get(GPUPass *pass) return pass->shader; } -void GPU_pass_release(GPUPass *pass) -{ - BLI_spin_lock(&pass_cache_spin); - BLI_assert(pass->refcount > 0); - pass->refcount--; - BLI_spin_unlock(&pass_cache_spin); -} - static void gpu_pass_free(GPUPass *pass) { BLI_assert(pass->refcount == 0); @@ -899,6 +895,18 @@ static void gpu_pass_free(GPUPass *pass) MEM_freeN(pass); } +void GPU_pass_release(GPUPass *pass) +{ + BLI_spin_lock(&pass_cache_spin); + BLI_assert(pass->refcount > 0); + pass->refcount--; + /* Un-cached passes will not be filtered by garbage collection, so release here. */ + if (pass->refcount == 0 && !pass->cached) { + gpu_pass_free(pass); + } + BLI_spin_unlock(&pass_cache_spin); +} + void GPU_pass_cache_garbage_collect(void) { static int lasttime = 0; diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index 5cb9c47f36f..a192e51a0ec 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -7,6 +7,10 @@ * and texture2d types in metal). */ +/* Suppress unhelpful shader compiler warnings. */ +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wcomment" + /* Base instance with offsets. */ #define gpu_BaseInstance gl_BaseInstanceARB #define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance) -- 2.30.2