From bbb4f1b040684d1d2a0b9b3db6cba0ff9ce0ca5c Mon Sep 17 00:00:00 2001 From: emufan Date: Sun, 3 Jul 2022 23:51:19 +0300 Subject: [PATCH] renderer_vulkan: Fix broken synchronization * The GPU was always 1 tick ahead, making all wait operations nops. --- .../renderer_vulkan/vk_task_scheduler.cpp | 25 +++++++------------ .../renderer_vulkan/vk_task_scheduler.h | 4 +-- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp index 5950e114a..8604365b1 100644 --- a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp @@ -118,8 +118,6 @@ void TaskScheduler::SyncToGPU(u64 task_index) { return; } - auto last_completed_task_id = GetGPUTick(); - // Wait for the task to complete vk::SemaphoreWaitInfo wait_info{{}, timeline, tasks[task_index].task_id}; auto result = g_vk_instace->GetDevice().waitSemaphores(wait_info, UINT64_MAX); @@ -127,18 +125,6 @@ void TaskScheduler::SyncToGPU(u64 task_index) { if (result != vk::Result::eSuccess) { LOG_CRITICAL(Render_Vulkan, "Failed waiting for timeline semaphore!"); } - - auto completed_task_id = GetGPUTick(); - - // Delete all resources that can be freed now - for (auto& task : tasks) { - if (task.task_id > last_completed_task_id && task.task_id <= completed_task_id) { - for (auto& func : task.cleanups) { - func(); - } - task.cleanups.clear(); - } - } } void TaskScheduler::SyncToGPU() { @@ -165,11 +151,11 @@ void TaskScheduler::Submit(bool wait_completion, bool present, Swapchain* swapch } const u32 num_signal_semaphores = present ? 2U : 1U; - const std::array signal_values{task.task_id + 1, u64(0)}; + const std::array signal_values{task.task_id, u64(0)}; std::array signal_semaphores{timeline, vk::Semaphore{}}; const u32 num_wait_semaphores = present ? 2U : 1U; - const std::array wait_values{task.task_id, u64(1)}; + const std::array wait_values{task.task_id - 1, u64(1)}; std::array wait_semaphores{timeline, vk::Semaphore{}}; // When the task completes the timeline will increment to the task id @@ -222,6 +208,12 @@ void TaskScheduler::BeginTask() { // Wait for the GPU to finish with all resources for this task. SyncToGPU(next_task_index); + + // Delete all resources that can be freed now + for (auto& func : task.cleanups) { + func(); + } + device.resetDescriptorPool(task.pool); task.command_buffers[1].begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit}); @@ -230,6 +222,7 @@ void TaskScheduler::BeginTask() { task.task_id = ++current_task_id; task.current_offset = 0; task.use_upload_buffer = false; + task.cleanups.clear(); auto& state = VulkanState::Get(); state.InitDescriptorSets(); diff --git a/src/video_core/renderer_vulkan/vk_task_scheduler.h b/src/video_core/renderer_vulkan/vk_task_scheduler.h index b1436559e..77634b8f0 100644 --- a/src/video_core/renderer_vulkan/vk_task_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_task_scheduler.h @@ -59,11 +59,11 @@ private: vk::Semaphore timeline; vk::CommandPool command_pool; - u64 current_task_id = -1; + u64 current_task_id = 0; // Each task contains unique resources std::array tasks; - u64 current_task = TASK_COUNT - 1; + u64 current_task = -1; }; extern std::unique_ptr g_vk_task_scheduler;