diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index a0b6d6f21c..51652814c4 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -308,6 +308,7 @@ namespace rsx */ virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_resource_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0; virtual image_view_type create_temporary_subresource_view(commandbuffer_type&, image_storage_type* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const texture_channel_remap_t& remap_vector) = 0; + virtual void release_temporary_subresource(image_view_type rsc) = 0; virtual section_storage_type* create_new_texture(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, texture_create_flags flags) = 0; virtual section_storage_type* upload_image_from_cpu(commandbuffer_type&, const address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u16 pitch, u32 gcm_format, texture_upload_context context, @@ -1432,6 +1433,7 @@ namespace rsx const auto& desc = It->second.first; if (range.overlaps(desc.cache_range)) { + release_temporary_subresource(It->second.second); It = m_temporary_subresource_cache.erase(It); } else diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 8b41206fdb..a822c20d54 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -781,6 +781,19 @@ namespace gl return view; } + void release_temporary_subresource(gl::texture_view* view) override + { + for (auto& e : m_temporary_surfaces) + { + if (e.image.get() == view->image()) + { + e.view.reset(); + e.image.reset(); + return; + } + } + } + void update_image_contents(gl::command_context& cmd, gl::texture_view* dst, gl::texture* src, u16 width, u16 height) override { std::vector region = diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 984273d2b0..4d9e1eddc6 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -443,6 +443,7 @@ namespace vk struct temporary_storage { std::unique_ptr combined_image; + bool can_reuse = false; // Memory held by this temp storage object u32 block_size = 0; @@ -777,7 +778,7 @@ namespace vk const auto current_frame = vk::get_current_frame_id(); for (auto &e : m_temporary_storage) { - if (e.frame_tag != current_frame && e.matches(format, w, h, d, mipmaps, 0)) + if (e.can_reuse && e.matches(format, w, h, d, mipmaps, 0)) { m_temporary_memory_size -= e.block_size; e.block_size = 0; @@ -793,7 +794,7 @@ namespace vk const auto current_frame = vk::get_current_frame_id(); for (auto &e : m_temporary_storage) { - if (e.frame_tag != current_frame && e.matches(format, size, size, 1, 1, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) + if (e.can_reuse && e.matches(format, size, size, 1, 1, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) { m_temporary_memory_size -= e.block_size; e.block_size = 0; @@ -1055,6 +1056,19 @@ namespace vk return view; } + void release_temporary_subresource(vk::image_view* view) override + { + auto handle = dynamic_cast(view->image()); + for (auto& e : m_temporary_storage) + { + if (e.combined_image.get() == handle) + { + e.can_reuse = true; + return; + } + } + } + void update_image_contents(vk::command_buffer& cmd, vk::image_view* dst_view, vk::image* src, u16 width, u16 height) override { std::vector region =