[Bf-blender-cvs] [5cc9f07d5c5] master: Draw: Workbench Next: Fix shaders memory leaks

Miguel Pozo noreply at git.blender.org
Tue Jan 24 20:53:04 CET 2023


Commit: 5cc9f07d5c56e7201f17a40659c3f4c4c5a83002
Author: Miguel Pozo
Date:   Tue Jan 24 20:42:14 2023 +0100
Branches: master
https://developer.blender.org/rB5cc9f07d5c56e7201f17a40659c3f4c4c5a83002

Draw: Workbench Next: Fix shaders memory leaks

Ensure all shaders are deleted

===================================================================

M	source/blender/draw/engines/workbench/workbench_effect_dof.cc
M	source/blender/draw/engines/workbench/workbench_effect_outline.cc
M	source/blender/draw/engines/workbench/workbench_mesh_passes.cc
M	source/blender/draw/engines/workbench/workbench_private.hh
M	source/blender/draw/engines/workbench/workbench_shader_cache.cc
M	source/blender/draw/engines/workbench/workbench_shadow.cc

===================================================================

diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.cc b/source/blender/draw/engines/workbench/workbench_effect_dof.cc
index 7d46703ad35..d7f2edb3e90 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.cc
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.cc
@@ -53,6 +53,15 @@ static void square_to_circle(float x, float y, float &r, float &T)
   }
 }
 
+DofPass::~DofPass()
+{
+  DRW_SHADER_FREE_SAFE(prepare_sh_);
+  DRW_SHADER_FREE_SAFE(downsample_sh_);
+  DRW_SHADER_FREE_SAFE(blur1_sh_);
+  DRW_SHADER_FREE_SAFE(blur2_sh_);
+  DRW_SHADER_FREE_SAFE(resolve_sh_);
+}
+
 void DofPass::setup_samples()
 {
   float4 *sample = samples_buf_.begin();
diff --git a/source/blender/draw/engines/workbench/workbench_effect_outline.cc b/source/blender/draw/engines/workbench/workbench_effect_outline.cc
index a1826d5ecf8..a4b321c44b5 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_outline.cc
+++ b/source/blender/draw/engines/workbench/workbench_effect_outline.cc
@@ -12,6 +12,11 @@
 
 namespace blender::workbench {
 
+OutlinePass::~OutlinePass()
+{
+  DRW_SHADER_FREE_SAFE(sh_);
+}
+
 void OutlinePass::init(const SceneState &scene_state)
 {
   enabled_ = scene_state.draw_outline;
diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc
index a32127d66b0..2f4d785216d 100644
--- a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc
+++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc
@@ -245,6 +245,11 @@ bool OpaquePass::is_empty() const
 /** \name TransparentPass
  * \{ */
 
+TransparentPass::~TransparentPass()
+{
+  DRW_SHADER_FREE_SAFE(resolve_sh_);
+}
+
 void TransparentPass::sync(const SceneState &scene_state, SceneResources &resources)
 {
   DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT |
@@ -324,6 +329,11 @@ bool TransparentPass::is_empty() const
 /** \name TransparentDepthPass
  * \{ */
 
+TransparentDepthPass::~TransparentDepthPass()
+{
+  DRW_SHADER_FREE_SAFE(merge_sh_);
+}
+
 void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &resources)
 {
   DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh
index 5d9de764d56..20c07061b06 100644
--- a/source/blender/draw/engines/workbench/workbench_private.hh
+++ b/source/blender/draw/engines/workbench/workbench_private.hh
@@ -226,6 +226,8 @@ class TransparentPass {
   PassSimple resolve_ps_ = {"Transparent.Resolve"};
   Framebuffer resolve_fb = {};
 
+  ~TransparentPass();
+
   void sync(const SceneState &scene_state, SceneResources &resources);
   void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
   bool is_empty() const;
@@ -243,6 +245,8 @@ class TransparentDepthPass {
   PassSimple merge_ps_ = {"TransparentDepth.Merge"};
   Framebuffer merge_fb = {"TransparentDepth.Merge"};
 
+  ~TransparentDepthPass();
+
   void sync(const SceneState &scene_state, SceneResources &resources);
   void draw(Manager &manager, View &view, SceneResources &resources);
   bool is_empty() const;
@@ -261,13 +265,17 @@ class ShadowPass {
     VisibilityBuf pass_visibility_buf_ = {};
     VisibilityBuf fail_visibility_buf_ = {};
 
+    GPUShader *dynamic_pass_type_shader_;
+    GPUShader *static_pass_type_shader_;
+
    public:
+    ShadowView();
+    ~ShadowView();
+
     void setup(View &view, float3 light_direction, bool force_fail_method);
     bool debug_object_culling(Object *ob);
     void set_mode(PassType type);
 
-    ShadowView();
-
    protected:
     virtual void compute_visibility(ObjectBoundsBuf &bounds,
                                     uint resource_len,
@@ -298,6 +306,8 @@ class ShadowPass {
   Framebuffer fb_ = {};
 
  public:
+  ~ShadowPass();
+
   void init(const SceneState &scene_state, SceneResources &resources);
   void update();
   void sync();
@@ -322,6 +332,8 @@ class OutlinePass {
   Framebuffer fb_ = Framebuffer("Workbench.Outline");
 
  public:
+  ~OutlinePass();
+
   void init(const SceneState &scene_state);
   void sync(SceneResources &resources);
   void draw(Manager &manager, SceneResources &resources);
@@ -369,6 +381,8 @@ class DofPass {
   float ratio_ = 0;
 
  public:
+  ~DofPass();
+
   void init(const SceneState &scene_state);
   void sync(SceneResources &resources);
   void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
diff --git a/source/blender/draw/engines/workbench/workbench_shader_cache.cc b/source/blender/draw/engines/workbench/workbench_shader_cache.cc
index 6720fc1702b..d544535d146 100644
--- a/source/blender/draw/engines/workbench/workbench_shader_cache.cc
+++ b/source/blender/draw/engines/workbench/workbench_shader_cache.cc
@@ -6,21 +6,21 @@ namespace blender::workbench {
 
 ShaderCache::~ShaderCache()
 {
-  for (auto i : IndexRange(lighting_type_len)) {
-    for (auto j : IndexRange(shader_type_len)) {
-      for (auto k : IndexRange(geometry_type_len)) {
-        for (auto l : IndexRange(pipeline_type_len)) {
-          for (auto m : IndexRange(2)) {
+  for (auto i : IndexRange(pipeline_type_len)) {
+    for (auto j : IndexRange(geometry_type_len)) {
+      for (auto k : IndexRange(shader_type_len)) {
+        for (auto l : IndexRange(lighting_type_len)) {
+          for (auto m : IndexRange(2) /*clip*/) {
             DRW_SHADER_FREE_SAFE(prepass_shader_cache_[i][j][k][l][m]);
           }
         }
       }
     }
   }
-  for (auto i : IndexRange(lighting_type_len)) {
-    for (auto j : IndexRange(pipeline_type_len)) {
-      for (auto k : IndexRange(2)) {
-        for (auto l : IndexRange(2)) {
+  for (auto i : IndexRange(pipeline_type_len)) {
+    for (auto j : IndexRange(lighting_type_len)) {
+      for (auto k : IndexRange(2) /*cavity*/) {
+        for (auto l : IndexRange(2) /*curvature*/) {
           DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l]);
         }
       }
diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc
index d13d717832e..15c18ffef9d 100644
--- a/source/blender/draw/engines/workbench/workbench_shadow.cc
+++ b/source/blender/draw/engines/workbench/workbench_shadow.cc
@@ -25,6 +25,11 @@
 namespace blender::workbench {
 
 ShadowPass::ShadowView::ShadowView() : View("ShadowPass.View"){};
+ShadowPass::ShadowView::~ShadowView()
+{
+  DRW_SHADER_FREE_SAFE(dynamic_pass_type_shader_);
+  DRW_SHADER_FREE_SAFE(static_pass_type_shader_);
+}
 
 void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool force_fail_method)
 {
@@ -237,13 +242,17 @@ void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds,
   if (do_visibility_) {
     /* TODO(Miguel Pozo): Use regular culling for the caps pass */
 
-    static GPUShader *dynamic_pass_type_shader = GPU_shader_create_from_info_name(
-        "workbench_next_shadow_visibility_compute_dynamic_pass_type");
-    static GPUShader *static_pass_type_shader = GPU_shader_create_from_info_name(
-        "workbench_next_shadow_visibility_compute_static_pass_type");
+    if (dynamic_pass_type_shader_ == nullptr) {
+      dynamic_pass_type_shader_ = GPU_shader_create_from_info_name(
+          "workbench_next_shadow_visibility_compute_dynamic_pass_type");
+    }
+    if (static_pass_type_shader_ == nullptr) {
+      static_pass_type_shader_ = GPU_shader_create_from_info_name(
+          "workbench_next_shadow_visibility_compute_static_pass_type");
+    }
 
-    GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader :
-                                                                        dynamic_pass_type_shader;
+    GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader_ :
+                                                                        dynamic_pass_type_shader_;
     GPU_shader_bind(shader);
     GPU_shader_uniform_1i(shader, "resource_len", resource_len);
     GPU_shader_uniform_1i(shader, "view_len", view_len_);
@@ -285,6 +294,17 @@ VisibilityBuf &ShadowPass::ShadowView::get_visibility_buffer()
   return visibility_buf_;
 }
 
+ShadowPass::~ShadowPass()
+{
+  for (int depth_pass : IndexRange(2)) {
+    for (int manifold : IndexRange(2)) {
+      for (int cap : IndexRange(2)) {
+        DRW_SHADER_FREE_SAFE(shaders_[depth_pass][manifold][cap]);
+      }
+    }
+  }
+}
+
 PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type, bool manifold, bool cap /*= false*/)
 {
   return passes_[type][manifold][cap];



More information about the Bf-blender-cvs mailing list