From 98e50d3064efc77467201e3864037c5ae1c0152b Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 2 Feb 2018 10:04:55 +0300 Subject: [PATCH] gl: Reuse framebuffer textures whenever possible --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 5 +---- rpcs3/Emu/RSX/GL/GLRenderTargets.h | 22 ++++++++++++++++++---- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 11 ++--------- rpcs3/Emu/RSX/rsx_utils.h | 8 ++++++++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 2676a12b35..d05a80ccf2 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1341,10 +1341,7 @@ void GLGSRender::flip(int buffer) // Cleanup m_gl_texture_cache.on_frame_end(); - for (auto &tex : m_rtts.invalidated_resources) - tex->remove(); - - m_rtts.invalidated_resources.clear(); + m_rtts.free_invalidated(); m_vertex_cache->purge(); //If we are skipping the next frame, do not reset perf counters diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index b844fe2cc6..c58022bd28 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -49,7 +49,7 @@ namespace rsx namespace gl { - class render_target : public texture, public rsx::render_target_descriptor + class render_target : public texture, public rsx::ref_counted, public rsx::render_target_descriptor { bool is_cleared = false; @@ -242,10 +242,10 @@ struct gl_render_target_traits info->bpp = static_cast(info->native_pitch / info->surface_width); } - static void prepare_rtt_for_drawing(void *, gl::render_target*) {} + static void prepare_rtt_for_drawing(void *, gl::render_target *rtt) { rtt->reset_refs(); } static void prepare_rtt_for_sampling(void *, gl::render_target*) {} - static void prepare_ds_for_drawing(void *, gl::render_target*) {} + static void prepare_ds_for_drawing(void *, gl::render_target *ds) { ds->reset_refs(); } static void prepare_ds_for_sampling(void *, gl::render_target*) {} static void invalidate_rtt_surface_contents(void *, gl::render_target *rtt, gl::render_target* /*old*/, bool forced) { if (forced) rtt->set_cleared(false); } @@ -318,6 +318,20 @@ struct gl_render_target_traits } }; -class gl_render_targets : public rsx::surface_store +struct gl_render_targets : public rsx::surface_store { + void free_invalidated() + { + invalidated_resources.remove_if([&](auto &rtt) + { + if (rtt->deref_count >= 2) + { + rtt->remove(); + return true; + } + + rtt->deref_count++; + return false; + }); + } }; diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 5ce794bd3b..45f1c49fed 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -8,16 +8,9 @@ #include "VKFormats.h" #include "../rsx_utils.h" -struct ref_counted -{ - u8 deref_count = 0; - - void reset_refs() { deref_count = 0; } -}; - namespace vk { - struct render_target : public image, public ref_counted, public rsx::render_target_descriptor + struct render_target : public image, public rsx::ref_counted, public rsx::render_target_descriptor { bool dirty = false; u16 native_pitch = 0; @@ -90,7 +83,7 @@ namespace vk } }; - struct framebuffer_holder: public vk::framebuffer, public ref_counted + struct framebuffer_holder: public vk::framebuffer, public rsx::ref_counted { framebuffer_holder(VkDevice dev, VkRenderPass pass, diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 7faf46b265..929d0a85c2 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -19,6 +19,14 @@ extern "C" namespace rsx { + //Base for resources with reference counting + struct ref_counted + { + u8 deref_count = 0; + + void reset_refs() { deref_count = 0; } + }; + //Holds information about a framebuffer struct gcm_framebuffer_info {