From 82bac4173e2158c94f4251a125286dd11849b1e7 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 17 Jul 2022 19:05:00 +0300 Subject: [PATCH] gl: Reuse scratch images --- rpcs3/Emu/RSX/GL/GLTexture.cpp | 4 +-- rpcs3/Emu/RSX/GL/GLTextureCache.cpp | 54 ++++++++++++++++++++--------- rpcs3/Emu/RSX/GL/GLTextureCache.h | 41 +++++++--------------- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 14a2245b94..38af26c3b7 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -740,7 +740,7 @@ namespace gl void fill_texture(gl::command_context& cmd, texture* dst, int format, const std::vector &input_layouts, - bool is_swizzled, GLenum gl_format, GLenum gl_type, std::vector& staging_buffer) + bool is_swizzled, GLenum gl_format, GLenum gl_type, rsx::simple_array& staging_buffer) { const auto driver_caps = gl::get_driver_caps(); rsx::texture_uploader_capabilities caps @@ -1000,7 +1000,7 @@ namespace gl void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout) { // Calculate staging buffer size - std::vector data_upload_buf; + rsx::simple_array data_upload_buf; if (rsx::is_compressed_host_format(gcm_format)) { diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index 6aff3fa0d7..39954b6192 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -91,7 +91,38 @@ namespace gl sized_internal_fmt = gl::get_sized_internal_format(gcm_format); } - std::unique_ptr dst = std::make_unique(dst_type, width, height, depth, mipmaps, sized_internal_fmt, rsx::classify_format(gcm_format)); + temporary_image_t* dst = nullptr; + const u64 match_key = + (static_cast(width) << 0) | + (static_cast(height) << 16) | + (static_cast(depth) << 32) | + (static_cast(mipmaps) << 40) | + (static_cast(sized_internal_fmt) << 48); + + // Search image cache + for (auto& e : m_temporary_surfaces) + { + if (e->has_refs()) + { + continue; + } + + if (e->properties_encoding == match_key) + { + dst = e.get(); + break; + } + } + + if (!dst) + { + std::unique_ptr data = std::make_unique(dst_type, width, height, depth, mipmaps, sized_internal_fmt, rsx::classify_format(gcm_format)); + dst = data.get(); + dst->properties_encoding = match_key; + m_temporary_surfaces.emplace_back(std::move(data)); + } + + dst->add_ref(); if (copy) { @@ -104,29 +135,18 @@ namespace gl width, height, width, height }}; - copy_transfer_regions_impl(cmd, dst.get(), region); + copy_transfer_regions_impl(cmd, dst, region); } - std::array swizzle; if (!src || static_cast(src->get_internal_format()) != sized_internal_fmt) { // Apply base component map onto the new texture if a data cast has been done - swizzle = get_component_mapping(gcm_format, rsx::component_order::default_); - } - else - { - swizzle = src->get_native_component_layout(); + auto components = get_component_mapping(gcm_format, rsx::component_order::default_); + dst->set_native_component_layout(components); } - if (memcmp(remap.first.data(), rsx::default_remap_vector.first.data(), 4) || - memcmp(remap.second.data(), rsx::default_remap_vector.second.data(), 4)) - swizzle = apply_swizzle_remap(swizzle, remap); - - auto view = std::make_unique(dst.get(), dst_type, sized_internal_fmt, swizzle.data()); - auto result = view.get(); - - m_temporary_surfaces.emplace_back(dst, view); - return result; + const auto encoding = rsx::get_remap_encoding(remap); + return dst->get_view(encoding, remap); } void texture_cache::copy_transfer_regions_impl(gl::command_context& cmd, gl::texture* dst_image, const std::vector& sources) const diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 1cff596b93..4f4b640978 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -441,36 +441,19 @@ namespace gl using baseclass = rsx::texture_cache; friend baseclass; - private: - struct discardable_storage + struct temporary_image_t : public gl::viewable_image, public rsx::ref_counted { - std::unique_ptr image; - std::unique_ptr view; + u64 properties_encoding = 0; - discardable_storage() = default; - - discardable_storage(std::unique_ptr& tex) - { - image = std::move(tex); - } - - discardable_storage(std::unique_ptr& _view) - { - view = std::move(_view); - } - - discardable_storage(std::unique_ptr& tex, std::unique_ptr& _view) - { - image = std::move(tex); - view = std::move(_view); - } + using gl::viewable_image::viewable_image; }; - private: - blitter m_hw_blitter; - std::vector m_temporary_surfaces; + std::vector> m_temporary_surfaces; + const u32 max_cached_image_pool_size = 256; + + private: void clear() { baseclass::clear(); @@ -615,10 +598,9 @@ namespace gl { for (auto& e : m_temporary_surfaces) { - if (e.image.get() == view->image()) + if (e.get() == view->image()) { - e.view.reset(); - e.image.reset(); + e->release(); return; } } @@ -889,7 +871,10 @@ namespace gl purge_unreleased_sections(); } - clear_temporary_subresources(); + if (m_temporary_surfaces.size() > max_cached_image_pool_size) + { + m_temporary_surfaces.resize(max_cached_image_pool_size / 2); + } baseclass::on_frame_end(); }