diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 486d36fd05..a7e89b796c 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -989,14 +989,14 @@ void VKGSRender::end() if (m_current_command_buffer->flags & vk::command_buffer::cb_load_occluson_task) { - u32 occlusion_id = m_occlusion_query_pool.find_free_slot(); + u32 occlusion_id = m_occlusion_query_pool.find_free_slot(*m_current_command_buffer); if (occlusion_id == UINT32_MAX) { // Force flush rsx_log.error("[Performance Warning] Out of free occlusion slots. Forcing hard sync."); ZCULL_control::sync(this); - occlusion_id = m_occlusion_query_pool.find_free_slot(); + occlusion_id = m_occlusion_query_pool.find_free_slot(*m_current_command_buffer); if (occlusion_id == UINT32_MAX) { //rsx_log.error("Occlusion pool overflow"); diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index f7f5ba01aa..423665b8f1 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -156,6 +156,9 @@ namespace vk void release_global_submit_lock(); void queue_submit(VkQueue queue, const VkSubmitInfo* info, fence* pfence, VkBool32 flush = VK_FALSE); + bool is_renderpass_open(VkCommandBuffer cmd); + void end_renderpass(VkCommandBuffer cmd); + template T* get_compute_task(); void reset_compute_tasks(); @@ -3211,12 +3214,7 @@ public: void begin_query(vk::command_buffer &cmd, u32 index) { - if (query_slot_status[index].active) - { - //Synchronization must be done externally - vkCmdResetQueryPool(cmd, query_pool, index, 1); - query_slot_status[index] = {}; - } + verify(HERE), query_slot_status[index].active == false; vkCmdBeginQuery(cmd, query_pool, index, 0);//VK_QUERY_CONTROL_PRECISE_BIT); query_slot_status[index].active = true; @@ -3250,13 +3248,11 @@ public: vkCmdCopyQueryPoolResults(cmd, query_pool, index, 1, dst, dst_offset, 4, VK_QUERY_RESULT_WAIT_BIT); } - void reset_query(vk::command_buffer &cmd, u32 index) + void reset_query(vk::command_buffer &/*cmd*/, u32 index) { if (query_slot_status[index].active) { - vkCmdResetQueryPool(cmd, query_pool, index, 1); - - query_slot_status[index] = {}; + // Actual reset is handled later on demand available_slots.push_back(index); } } @@ -3277,17 +3273,32 @@ public: } } - u32 find_free_slot() + u32 find_free_slot(vk::command_buffer& cmd) { if (available_slots.empty()) { return ~0u; } - u32 result = available_slots.front(); - available_slots.pop_front(); + const u32 result = available_slots.front(); + if (query_slot_status[result].active) + { + // Trigger reset if round robin allocation has gone back to the first item + if (vk::is_renderpass_open(cmd)) + { + vk::end_renderpass(cmd); + } - verify(HERE), !query_slot_status[result].active; + // At this point, the first available slot is not reset which means they're all active + for (auto It = available_slots.cbegin(); It != available_slots.cend(); ++It) + { + const auto index = *It; + vkCmdResetQueryPool(cmd, query_pool, index, 1); + query_slot_status[index] = {}; + } + } + + available_slots.pop_front(); return result; } };