Draw: Workbench Next: Fix shaders memory leaks

Ensure all shaders are deleted
This commit is contained in:
Miguel Pozo
2023-01-24 20:42:14 +01:00
parent 361ebe98d5
commit 5cc9f07d5c
6 changed files with 75 additions and 17 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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 |

View File

@@ -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);

View File

@@ -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]);
}
}

View File

@@ -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];