diff options
author | Bastiaan Olij <mux213@gmail.com> | 2022-08-09 15:18:03 +1000 |
---|---|---|
committer | Bastiaan Olij <mux213@gmail.com> | 2022-08-09 15:18:03 +1000 |
commit | f50f0844e9e8018e4663f2b5fddcb317bf17888a (patch) | |
tree | 6abd455ae02baa427c272f2717e2342dee2d1a43 | |
parent | 7355dfb502dbae6f13fbe42a9feeadb57affac0e (diff) |
Fix resource leaks in VoxelGI
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.cpp | 51 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/environment/gi.h | 7 | ||||
-rw-r--r-- | servers/rendering/renderer_rd/renderer_scene_render_rd.cpp | 15 |
3 files changed, 48 insertions, 25 deletions
diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index feafcc42c9..eaef5ba39c 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -1140,6 +1140,7 @@ void GI::SDFGI::erase() { RD::get_singleton()->free(lightprobe_data); RD::get_singleton()->free(lightprobe_history_scroll); + RD::get_singleton()->free(lightprobe_average_scroll); RD::get_singleton()->free(occlusion_data); RD::get_singleton()->free(ambient_texture); @@ -2427,18 +2428,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID if (last_probe_data_version != data_version) { //need to re-create everything - if (texture.is_valid()) { - RD::get_singleton()->free(texture); - RD::get_singleton()->free(write_buffer); - mipmaps.clear(); - } - - for (int i = 0; i < dynamic_maps.size(); i++) { - RD::get_singleton()->free(dynamic_maps[i].texture); - RD::get_singleton()->free(dynamic_maps[i].depth); - } - - dynamic_maps.clear(); + free_resources(); Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); @@ -3130,6 +3120,37 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID last_probe_version = gi->voxel_gi_get_version(probe); } +void GI::VoxelGIInstance::free_resources() { + if (texture.is_valid()) { + RD::get_singleton()->free(texture); + RD::get_singleton()->free(write_buffer); + + texture = RID(); + write_buffer = RID(); + mipmaps.clear(); + } + + for (int i = 0; i < dynamic_maps.size(); i++) { + RD::get_singleton()->free(dynamic_maps[i].texture); + RD::get_singleton()->free(dynamic_maps[i].depth); + + // these only exist on the first level... + if (dynamic_maps[i].fb_depth.is_valid()) { + RD::get_singleton()->free(dynamic_maps[i].fb_depth); + } + if (dynamic_maps[i].albedo.is_valid()) { + RD::get_singleton()->free(dynamic_maps[i].albedo); + } + if (dynamic_maps[i].normal.is_valid()) { + RD::get_singleton()->free(dynamic_maps[i].normal); + } + if (dynamic_maps[i].orm.is_valid()) { + RD::get_singleton()->free(dynamic_maps[i].orm); + } + } + dynamic_maps.clear(); +} + void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3936,6 +3957,12 @@ RID GI::voxel_gi_instance_create(RID p_base) { return rid; } +void GI::voxel_gi_instance_free(RID p_rid) { + GI::VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_rid); + voxel_gi->free_resources(); + voxel_gi_instance_owner.free(p_rid); +} + void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index 304df1605b..8860445c3b 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -469,6 +469,7 @@ public: void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + void free_resources(); }; mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; @@ -483,6 +484,12 @@ public: return voxel_gi->texture; }; + bool voxel_gi_instance_owns(RID p_rid) const { + return voxel_gi_instance_owner.owns(p_rid); + } + + void voxel_gi_instance_free(RID p_rid); + RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_LOW; /* SDFGI */ diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 8b3b7050d2..13f8d1ab75 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -4086,19 +4086,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { decal_instance_owner.free(p_rid); } else if (lightmap_instance_owner.owns(p_rid)) { lightmap_instance_owner.free(p_rid); - } else if (gi.voxel_gi_instance_owner.owns(p_rid)) { - RendererRD::GI::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid); - if (voxel_gi->texture.is_valid()) { - RD::get_singleton()->free(voxel_gi->texture); - RD::get_singleton()->free(voxel_gi->write_buffer); - } - - for (int i = 0; i < voxel_gi->dynamic_maps.size(); i++) { - RD::get_singleton()->free(voxel_gi->dynamic_maps[i].texture); - RD::get_singleton()->free(voxel_gi->dynamic_maps[i].depth); - } - - gi.voxel_gi_instance_owner.free(p_rid); + } else if (gi.voxel_gi_instance_owns(p_rid)) { + gi.voxel_gi_instance_free(p_rid); } else if (sky.sky_owner.owns(p_rid)) { sky.update_dirty_skys(); sky.free_sky(p_rid); |