diff --git a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp index 242d5db72e..d702760285 100644 --- a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp +++ b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.cpp @@ -67,18 +67,11 @@ namespace vk AsyncTaskScheduler::~AsyncTaskScheduler() { - *g_fxo->get() = thread_state::aborting; - while (has_refs()) _mm_pause(); - - for (auto& cb : m_async_command_queue) + if (!m_async_command_queue.empty()) { - cb.destroy(); + // Driver resources should be destroyed before driver is detached or you get crashes. RAII won't save you here. + rsx_log.error("Async task scheduler resources were not freed correctly!"); } - - m_async_command_queue.clear(); - m_next_cb_index = 0; - m_command_pool.destroy(); - m_events_pool.clear(); } command_buffer* AsyncTaskScheduler::get_current() @@ -158,4 +151,20 @@ namespace vk m_current_cb = nullptr; m_sync_required = false; } + + void AsyncTaskScheduler::kill() + { + *g_fxo->get() = thread_state::aborting; + while (has_refs()) _mm_pause(); + + for (auto& cb : m_async_command_queue) + { + cb.destroy(); + } + + m_async_command_queue.clear(); + m_next_cb_index = 0; + m_command_pool.destroy(); + m_events_pool.clear(); + } } diff --git a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h index 3a3fa65bbe..cc9a6f374d 100644 --- a/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h +++ b/rpcs3/Emu/RSX/VK/VKAsyncScheduler.h @@ -49,6 +49,7 @@ namespace vk event* get_primary_sync_label(); void flush(VkSemaphore wait_semaphore = VK_NULL_HANDLE, VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + void kill(); // Thread entry-point void operator()(); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index edfd9e78f6..b84b30fe44 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -558,6 +558,9 @@ VKGSRender::~VKGSRender() return; } + // Globals. TODO: Refactor lifetime management + g_fxo->get()->kill(); + //Wait for device to finish up with resources vkDeviceWaitIdle(*m_device);