diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index fedc8742437..a5c4dfaebd4 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -324,10 +324,6 @@ CopyEffects::~CopyEffects() { copy.pipelines[i].free(); } - for (int i = 0; i < FILTER_MODE_MAX; i++) { - filter.compute_pipelines[i].free(); - } - if (raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR)) { blur_raster.shader.version_free(blur_raster.shader_version); RD::get_singleton()->free_rid(blur_raster.glow_sampler); @@ -338,8 +334,19 @@ CopyEffects::~CopyEffects() { filter.raster_shader.version_free(filter.shader_version); roughness.raster_shader.version_free(roughness.shader_version); } else { + // PipelineDeferredRD always needs to be freed before its corresponding shader since the pipeline may not have finished compiling before the shader is freed. This + // ensures that we wait on the pipeline compilation before we free it. + for (int i = 0; i < DOWNSAMPLER_MODE_MAX; i++) { + octmap_downsampler.compute_pipelines[i].free(); + } octmap_downsampler.compute_shader.version_free(octmap_downsampler.shader_version); + + for (int i = 0; i < FILTER_MODE_MAX; i++) { + filter.compute_pipelines[i].free(); + } filter.compute_shader.version_free(filter.shader_version); + + roughness.compute_pipeline.free(); roughness.compute_shader.version_free(roughness.shader_version); } diff --git a/servers/rendering/renderer_rd/pipeline_deferred_rd.h b/servers/rendering/renderer_rd/pipeline_deferred_rd.h index 020d756aac8..54e512986eb 100644 --- a/servers/rendering/renderer_rd/pipeline_deferred_rd.h +++ b/servers/rendering/renderer_rd/pipeline_deferred_rd.h @@ -82,7 +82,9 @@ public: } ~PipelineDeferredRD() { - free(); +#ifdef DEV_ENABLED + ERR_FAIL_COND_MSG(pipeline.is_valid(), "'free()' must be called manually before deconstruction and before the corresponding shader is freed."); +#endif } void create_render_pipeline(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::VertexFormatID p_vertex_format, RD::RenderPrimitive p_render_primitive, const RD::PipelineRasterizationState &p_rasterization_state, const RD::PipelineMultisampleState &p_multisample_state, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, BitField p_dynamic_state_flags = 0, uint32_t p_for_render_pass = 0, const Vector &p_specialization_constants = Vector()) { @@ -119,6 +121,9 @@ public: _wait(); if (pipeline.is_valid()) { +#ifdef DEV_ENABLED + ERR_FAIL_COND_MSG(!(RD::get_singleton()->render_pipeline_is_valid(pipeline) || RD::get_singleton()->compute_pipeline_is_valid(pipeline)), "`free()` must be called manually before the dependent shader is freed."); +#endif RD::get_singleton()->free_rid(pipeline); pipeline = RID(); }