From 47983e30c503ffa4dc05c53fac15752f90c9b339 Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Thu, 16 Nov 2023 13:24:04 +1100 Subject: [PATCH] Ensure 2D MSAA resolve is performed when 3D content but no 2D content in scene --- drivers/gles3/storage/texture_storage.h | 3 +++ .../rendering/dummy/storage/texture_storage.h | 3 +++ .../forward_mobile/render_forward_mobile.cpp | 1 + .../renderer_rd/renderer_canvas_render_rd.cpp | 1 + .../renderer_rd/renderer_scene_render_rd.cpp | 3 +++ .../storage_rd/texture_storage.cpp | 26 +++++++++++++++++++ .../renderer_rd/storage_rd/texture_storage.h | 8 ++++-- servers/rendering/renderer_viewport.cpp | 5 ++++ servers/rendering/storage/texture_storage.h | 3 +++ 9 files changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 87a07ebb3682..27e358ec31c7 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -619,6 +619,9 @@ public: void render_target_clear_used(RID p_render_target); virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override; virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override; + virtual void render_target_set_msaa_needs_resolve(RID p_render_target, bool p_needs_resolve) override {} + virtual bool render_target_get_msaa_needs_resolve(RID p_render_target) const override { return false; } + virtual void render_target_do_msaa_resolve(RID p_render_target) override {} virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) override {} virtual bool render_target_is_using_hdr(RID p_render_target) const override { return false; } diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index 2a72547810f9..b3a5323e66ff 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -177,6 +177,9 @@ public: virtual void render_target_set_as_unused(RID p_render_target) override {} virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override {} virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override { return RS::VIEWPORT_MSAA_DISABLED; } + virtual void render_target_set_msaa_needs_resolve(RID p_render_target, bool p_needs_resolve) override {} + virtual bool render_target_get_msaa_needs_resolve(RID p_render_target) const override { return false; } + virtual void render_target_do_msaa_resolve(RID p_render_target) override {} virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) override {} virtual bool render_target_is_using_hdr(RID p_render_target) const override { return false; } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 462fc4b524fa..b1413a52e8f5 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -268,6 +268,7 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe target_buffer = texture_storage->render_target_get_rd_texture(render_target); } else { target_buffer = texture_storage->render_target_get_rd_texture_msaa(render_target); + texture_storage->render_target_set_msaa_needs_resolve(render_target, true); // Make sure this gets resolved. } ERR_FAIL_COND_V(target_buffer.is_null(), RID()); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 0b1561939e15..6ec9f0768a8d 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1116,6 +1116,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co fb_uniform_set = texture_storage->render_target_get_backbuffer_uniform_set(p_to_render_target); } else { framebuffer = texture_storage->render_target_get_rd_framebuffer(p_to_render_target); + texture_storage->render_target_set_msaa_needs_resolve(p_to_render_target, false); // If MSAA is enabled, our framebuffer will be resolved! if (texture_storage->render_target_is_clear_requested(p_to_render_target)) { clear = true; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 1a33f1d6e048..d4ed64024706 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -586,6 +586,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (dest_is_msaa_2d) { dest_fb = FramebufferCacheRD::get_singleton()->get_cache(texture_storage->render_target_get_rd_texture_msaa(render_target)); + texture_storage->render_target_set_msaa_needs_resolve(render_target, true); // Make sure this gets resolved. } else { dest_fb = texture_storage->render_target_get_rd_framebuffer(render_target); } @@ -611,6 +612,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RID source_texture = texture_storage->render_target_get_rd_texture(render_target); RID dest_fb = FramebufferCacheRD::get_singleton()->get_cache(texture_storage->render_target_get_rd_texture_msaa(render_target)); copy_effects->copy_to_fb_rect(source_texture, dest_fb, Rect2i(Point2i(), rb->get_target_size())); + + texture_storage->render_target_set_msaa_needs_resolve(render_target, true); // Make sure this gets resolved. } RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 678564a0e42d..307cbd703aa3 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3364,6 +3364,31 @@ RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) con return rt->msaa; } +void TextureStorage::render_target_set_msaa_needs_resolve(RID p_render_target, bool p_needs_resolve) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_NULL(rt); + + rt->msaa_needs_resolve = p_needs_resolve; +} + +bool TextureStorage::render_target_get_msaa_needs_resolve(RID p_render_target) const { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_NULL_V(rt, false); + + return rt->msaa_needs_resolve; +} + +void TextureStorage::render_target_do_msaa_resolve(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_NULL(rt); + if (!rt->msaa_needs_resolve) { + return; + } + RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_end(); + rt->msaa_needs_resolve = false; +} + void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_NULL(rt); @@ -3479,6 +3504,7 @@ void TextureStorage::render_target_do_clear_request(RID p_render_target) { RD::get_singleton()->draw_list_begin(rt->get_framebuffer(), RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors); RD::get_singleton()->draw_list_end(); rt->clear_requested = false; + rt->msaa_needs_resolve = false; } void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 276c8c4ce2b2..c665b02e14b3 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -331,9 +331,10 @@ private: uint32_t view_count; RID color; Vector color_slices; - RID color_multisample; // Needed when MSAA is enabled. + RID color_multisample; // Needed when 2D MSAA is enabled. - RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; // 2D MSAA mode + bool msaa_needs_resolve = false; // 2D MSAA needs resolved //used for retrieving from CPU RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8; @@ -718,6 +719,9 @@ public: virtual void render_target_set_as_unused(RID p_render_target) override; virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) override; virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const override; + virtual void render_target_set_msaa_needs_resolve(RID p_render_target, bool p_needs_resolve) override; + virtual bool render_target_get_msaa_needs_resolve(RID p_render_target) const override; + virtual void render_target_do_msaa_resolve(RID p_render_target) override; virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) override; virtual bool render_target_is_using_hdr(RID p_render_target) const override; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 6b47c29382ad..8e9b2229b44f 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -622,6 +622,11 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target); } + if (RSG::texture_storage->render_target_get_msaa_needs_resolve(p_viewport->render_target)) { + WARN_PRINT_ONCE("2D MSAA is enabled while there is no 2D content. Disable 2D MSAA for better performance."); + RSG::texture_storage->render_target_do_msaa_resolve(p_viewport->render_target); + } + if (p_viewport->measure_render_time) { String rt_id = "vp_end_" + itos(p_viewport->self.get_id()); RSG::utilities->capture_timestamp(rt_id); diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 6332dd578ef7..cf37fbfb4a05 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -151,6 +151,9 @@ public: virtual void render_target_set_as_unused(RID p_render_target) = 0; virtual void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) = 0; virtual RS::ViewportMSAA render_target_get_msaa(RID p_render_target) const = 0; + virtual void render_target_set_msaa_needs_resolve(RID p_render_target, bool p_needs_resolve) = 0; + virtual bool render_target_get_msaa_needs_resolve(RID p_render_target) const = 0; + virtual void render_target_do_msaa_resolve(RID p_render_target) = 0; virtual void render_target_set_use_hdr(RID p_render_target, bool p_use_hdr) = 0; virtual bool render_target_is_using_hdr(RID p_render_target) const = 0;