From c4acea6c822d3c6d4264cf449409c61fd5e5d7bb Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 30 Jun 2023 02:38:08 +0300 Subject: [PATCH] vk: Fix some regressions in synchronization2 behavior --- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 2 +- rpcs3/Emu/RSX/VK/vkutils/sync.cpp | 50 +++++++++++++++++++++++++---- rpcs3/Emu/RSX/VK/vkutils/sync.h | 6 +++- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index 7a0189b193..55635389da 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -217,7 +217,7 @@ namespace vk }; // Create event object for this transfer and queue signal op - dma_fence = std::make_unique(*m_device, sync_domain::any); + dma_fence = std::make_unique(*m_device, sync_domain::host); dma_fence->signal(cmd, { .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, diff --git a/rpcs3/Emu/RSX/VK/vkutils/sync.cpp b/rpcs3/Emu/RSX/VK/vkutils/sync.cpp index ce75784dbe..7facc1eca3 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sync.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/sync.cpp @@ -209,13 +209,13 @@ namespace vk } event::event(const render_device& dev, sync_domain domain) - : m_device(&dev) + : m_device(&dev), m_domain(domain) { m_backend = dev.get_synchronization2_support() ? sync_backend::events_v2 : sync_backend::events_v1; - if (domain != sync_domain::gpu && + if (domain == sync_domain::host && vk::get_driver_vendor() == vk::driver_vendor::AMD && vk::get_chip_family() < vk::chip_class::AMD_navi1x) { @@ -280,10 +280,30 @@ namespace vk return; } - // Resolve the actual dependencies on a pipeline barrier + ensure(m_vk_event); + + if (m_domain != sync_domain::host) + { + // As long as host is not involved, keep things consistent. + // The expectation is that this will be awaited using the gpu_wait function. + if (m_backend == sync_backend::events_v2) [[ likely ]] + { + m_device->_vkCmdSetEvent2KHR(cmd, m_vk_event, &dependency); + } + else + { + const auto dst_stages = v1_utils::gather_dst_stages(dependency); + vkCmdSetEvent(cmd, m_vk_event, dst_stages); + } + + return; + } + + // Host sync doesn't behave intuitively with events, so we use some workarounds. + // 1. Resolve the actual dependencies on a pipeline barrier. resolve_dependencies(cmd, dependency); - // Signalling won't wait. The caller is responsible for setting up the dependencies correctly. + // 2. Signalling won't wait. The caller is responsible for setting up the dependencies correctly. if (m_backend == sync_backend::events_v2) { // We need a memory barrier to keep AMDVLK from hanging @@ -293,6 +313,7 @@ namespace vk .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR, .srcAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT }; + // Empty dependency that does nothing VkDependencyInfoKHR empty_dependency { @@ -310,13 +331,19 @@ namespace vk void event::host_signal() const { - ensure(m_vk_event); - vkSetEvent(*m_device, m_vk_event); + if (m_backend != sync_backend::gpu_label) [[ likely ]] + { + ensure(m_vk_event); + vkSetEvent(*m_device, m_vk_event); + return; + } + + m_label->set(); } void event::gpu_wait(const command_buffer& cmd, const VkDependencyInfoKHR& dependency) const { - ensure(m_vk_event); + ensure(m_vk_event && m_domain != sync_domain::host); if (m_backend == sync_backend::events_v2) [[ likely ]] { @@ -363,6 +390,15 @@ namespace vk : pdev(&dev), m_count(count) {} + gpu_label_pool::~gpu_label_pool() + { + if (m_mapped) + { + ensure(m_buffer); + m_buffer->unmap(); + } + } + std::tuple gpu_label_pool::allocate() { if (!m_buffer || m_offset >= m_count) diff --git a/rpcs3/Emu/RSX/VK/vkutils/sync.h b/rpcs3/Emu/RSX/VK/vkutils/sync.h index 4272218e9a..152582a98e 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sync.h +++ b/rpcs3/Emu/RSX/VK/vkutils/sync.h @@ -14,7 +14,7 @@ namespace vk enum class sync_domain { - any = 0, + host = 0, gpu = 1 }; @@ -64,6 +64,7 @@ namespace vk }; const vk::render_device* m_device = nullptr; + sync_domain m_domain = sync_domain::any; sync_backend m_backend = sync_backend::events_v1; // For events_v1 and events_v2 @@ -106,6 +107,8 @@ namespace vk { public: gpu_label_pool(const vk::render_device& dev, u32 count); + virtual ~gpu_label_pool(); + std::tuple allocate(); private: @@ -137,6 +140,7 @@ namespace vk void signal(const vk::command_buffer& cmd, const VkDependencyInfoKHR& dependency); void reset() { *m_ptr = label_constants::reset_; } + void set() { *m_ptr = label_constants::set_; } bool signaled() const { return label_constants::set_ == *m_ptr; } };