From 9ee21af524d5816aabcd776c7b52c2d2effc1137 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 22 Sep 2017 18:39:48 +0300 Subject: [PATCH] vulkan: Optimize memory allocation --- rpcs3/Emu/RSX/Common/ring_buffer_helper.h | 13 +++++++ rpcs3/Emu/RSX/VK/VKGSRender.cpp | 46 +++++++++++++++++++---- rpcs3/Emu/RSX/VK/VKGSRender.h | 4 +- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h index 59d1e4b751..9c3beafaac 100644 --- a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h +++ b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h @@ -114,4 +114,17 @@ public: m_largest_allocated_pool = 0; m_get_pos = get_current_put_pos_minus_one(); } + + // Updates the current_allocated_size metrics + void notify() + { + if (m_get_pos == UINT64_MAX) + m_current_allocated_size = 0; + else if (m_get_pos < m_put_pos) + m_current_allocated_size = (m_put_pos - m_get_pos - 1); + else if (m_get_pos > m_put_pos) + m_current_allocated_size = (m_put_pos + (m_size - m_get_pos - 1)); + else + fmt::throw_exception("m_put_pos == m_get_pos!" HERE); + } }; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index b946f87ab3..f793746649 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -878,14 +878,41 @@ void VKGSRender::begin() { std::chrono::time_point submit_start = steady_clock::now(); - flush_command_queue(true); - m_vertex_cache->purge(); + frame_context_t *target_frame = nullptr; + u64 earliest_sync_time = UINT64_MAX; + for (s32 i = 0; i < VK_MAX_ASYNC_FRAMES; ++i) + { + auto ctx = &frame_context_storage[i]; + if (ctx->swap_command_buffer) + { + if (ctx->last_frame_sync_time > m_last_heap_sync_time && + ctx->last_frame_sync_time < earliest_sync_time) + target_frame = ctx; + } + } - m_index_buffer_ring_info.reset_allocation_stats(); - m_uniform_buffer_ring_info.reset_allocation_stats(); - m_attrib_ring_info.reset_allocation_stats(); - m_texture_upload_buffer_ring_info.reset_allocation_stats(); - m_current_frame->reset_heap_ptrs(); + if (target_frame == nullptr) + { + flush_command_queue(true); + m_vertex_cache->purge(); + + m_index_buffer_ring_info.reset_allocation_stats(); + m_uniform_buffer_ring_info.reset_allocation_stats(); + m_attrib_ring_info.reset_allocation_stats(); + m_texture_upload_buffer_ring_info.reset_allocation_stats(); + m_current_frame->reset_heap_ptrs(); + } + else + { + target_frame->swap_command_buffer->poke(); + while (target_frame->swap_command_buffer->pending) + { + if (!target_frame->swap_command_buffer->poke()) + std::this_thread::yield(); + } + + process_swap_request(target_frame, true); + } std::chrono::time_point submit_end = steady_clock::now(); m_flip_time += std::chrono::duration_cast(submit_end - submit_start).count(); @@ -1641,6 +1668,11 @@ void VKGSRender::process_swap_request(frame_context_t *ctx, bool free_resources) m_uniform_buffer_ring_info.m_get_pos = ctx->ubo_heap_ptr; m_index_buffer_ring_info.m_get_pos = ctx->index_heap_ptr; m_texture_upload_buffer_ring_info.m_get_pos = ctx->texture_upload_heap_ptr; + + m_attrib_ring_info.notify(); + m_uniform_buffer_ring_info.notify(); + m_index_buffer_ring_info.notify(); + m_texture_upload_buffer_ring_info.notify(); } } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 4cada0e7fc..149a6b0466 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -80,13 +80,15 @@ struct command_buffer_chunk: public vk::command_buffer vkResetCommandBuffer(commands, 0); } - void poke() + bool poke() { if (vkGetFenceStatus(m_device, submit_fence) == VK_SUCCESS) { vkResetFences(m_device, 1, &submit_fence); pending = false; } + + return !pending; } void wait()