From a04ecdbe0a844ce046bef473d7cc14c7c2640f8d Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 22 Sep 2017 20:29:12 +0300 Subject: [PATCH] vulkan: Use frameid to determine texture storage to discard --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 4 ++ rpcs3/Emu/RSX/VK/VKHelpers.cpp | 24 +++++++++++ rpcs3/Emu/RSX/VK/VKHelpers.h | 5 +++ rpcs3/Emu/RSX/VK/VKTextureCache.h | 67 +++++++++++++++++++------------ 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index f793746649..db2cc81a40 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1589,6 +1589,8 @@ void VKGSRender::advance_queued_frames() m_current_queue_index = (m_current_queue_index + 1) % VK_MAX_ASYNC_FRAMES; m_current_frame = &frame_context_storage[m_current_queue_index]; + + vk::advance_frame_counter(); } void VKGSRender::present(frame_context_t *ctx) @@ -1606,6 +1608,8 @@ void VKGSRender::present(frame_context_t *ctx) //Presentation image released; reset value ctx->present_image = UINT32_MAX; + + vk::advance_completed_frame_counter(); } void VKGSRender::queue_swap_request() diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 2f0b2f6d81..811a80c77d 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -13,6 +13,9 @@ namespace vk bool g_cb_no_interrupt_flag = false; + u64 g_num_processed_frames = 0; + u64 g_num_total_frames = 0; + VKAPI_ATTR void* VKAPI_CALL mem_realloc(void* pUserData, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) { #ifdef _MSC_VER @@ -348,6 +351,27 @@ namespace vk return g_cb_no_interrupt_flag; } + void advance_completed_frame_counter() + { + g_num_processed_frames++; + } + + void advance_frame_counter() + { + verify(HERE), g_num_processed_frames <= g_num_total_frames; + g_num_total_frames++; + } + + const u64 get_current_frame_id() + { + return g_num_total_frames; + } + + const u64 get_last_completed_frame_id() + { + return (g_num_processed_frames > 0)? g_num_processed_frames - 1: 0; + } + VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void *pUserData) diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index b4daff043b..9f897d49f0 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -89,6 +89,11 @@ namespace vk void leave_uninterruptible(); bool is_uninterruptible(); + void advance_completed_frame_counter(); + void advance_frame_counter(); + const u64 get_current_frame_id(); + const u64 get_last_completed_frame_id(); + struct memory_type_mapping { uint32_t host_visible_coherent; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index a8cf3c1f37..33bcee4c0d 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -272,6 +272,40 @@ namespace vk } }; + struct discarded_storage + { + std::unique_ptr view; + std::unique_ptr img; + + const u64 frame_tag = vk::get_current_frame_id(); + + discarded_storage(std::unique_ptr& _view) + { + view = std::move(_view); + } + + discarded_storage(std::unique_ptr& _img) + { + img = std::move(_img); + } + + discarded_storage(std::unique_ptr& _img, std::unique_ptr& _view) + { + img = std::move(_img); + view = std::move(_view); + } + + discarded_storage(cached_texture_section& tex) + { + view = std::move(tex.get_view()); + img = std::move(tex.get_texture()); + } + + const bool test(u64 ref_frame) const + { + return ref_frame > 0 && frame_tag <= ref_frame; + } + }; class texture_cache : public rsx::texture_cache { @@ -285,12 +319,7 @@ namespace vk vk::buffer* m_texture_upload_buffer; //Stuff that has been dereferenced goes into these - std::vector > m_temporary_image_view; - std::vector> m_dirty_textures; - - //Stuff that has been dereferenced twice goes here. Contents are evicted before new ones are added - std::vector> m_image_views_to_purge; - std::vector> m_images_to_purge; + std::list m_discardable_storage; void purge_cache() { @@ -301,8 +330,7 @@ namespace vk { if (tex.exists()) { - m_dirty_textures.push_back(std::move(tex.get_texture())); - m_temporary_image_view.push_back(std::move(tex.get_view())); + m_discardable_storage.push_back(tex); } if (tex.is_locked()) @@ -314,12 +342,7 @@ namespace vk range_data.data.resize(0); } - m_temporary_image_view.clear(); - m_dirty_textures.clear(); - - m_image_views_to_purge.clear(); - m_images_to_purge.clear(); - + m_discardable_storage.clear(); m_unreleased_texture_objects = 0; } @@ -327,8 +350,7 @@ namespace vk void free_texture_section(cached_texture_section& tex) override { - m_dirty_textures.push_back(std::move(tex.get_texture())); - m_temporary_image_view.push_back(std::move(tex.get_view())); + m_discardable_storage.push_back(tex); tex.release_dma_resources(); } @@ -377,10 +399,8 @@ namespace vk vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresource_range); vk::change_image_layout(cmd, source, old_src_layout, subresource_range); - m_dirty_textures.push_back(std::move(image)); - m_temporary_image_view.push_back(std::move(view)); - - return m_temporary_image_view.back().get(); + m_discardable_storage.push_back({ image, view }); + return m_discardable_storage.back().view.get(); } vk::image_view* create_temporary_subresource_view(vk::command_buffer& cmd, vk::image** source, u32 gcm_format, u16 x, u16 y, u16 w, u16 h) override @@ -642,11 +662,8 @@ namespace vk purge_dirty(); } - m_image_views_to_purge.clear(); - m_images_to_purge.clear(); - - m_image_views_to_purge = std::move(m_temporary_image_view); - m_images_to_purge = std::move(m_dirty_textures); + const u64 last_complete_frame = vk::get_last_completed_frame_id(); + m_discardable_storage.remove_if([&](const discarded_storage& o) {return o.test(last_complete_frame);}); } bool blit(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate, rsx::vk_render_targets& m_rtts, vk::command_buffer& cmd)