diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index cb0e819dc8..14c7a4666d 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -500,14 +500,20 @@ void VulkanRenderManager::CompileThreadFunc() { } } -void VulkanRenderManager::DrainCompileQueue() { +void VulkanRenderManager::DrainAndBlockCompileQueue() { std::unique_lock lock(compileMutex_); + compileBlocked_ = true; compileCond_.notify_all(); while (!compileQueue_.empty()) { queueRunner_.WaitForCompileNotification(); } } +void VulkanRenderManager::ReleaseCompileQueue() { + std::unique_lock lock(compileMutex_); + compileBlocked_ = false; +} + void VulkanRenderManager::ThreadFunc() { SetCurrentThreadName("RenderMan"); while (true) { @@ -709,14 +715,12 @@ VkCommandBuffer VulkanRenderManager::GetInitCmd() { } VKRGraphicsPipeline *VulkanRenderManager::CreateGraphicsPipeline(VKRGraphicsPipelineDesc *desc, PipelineFlags pipelineFlags, uint32_t variantBitmask, VkSampleCountFlagBits sampleCount, bool cacheLoad, const char *tag) { - VKRGraphicsPipeline *pipeline = new VKRGraphicsPipeline(pipelineFlags, tag); - if (!desc->vertexShader || !desc->fragmentShader) { ERROR_LOG(G3D, "Can't create graphics pipeline with missing vs/ps: %p %p", desc->vertexShader, desc->fragmentShader); - delete pipeline; return nullptr; } + VKRGraphicsPipeline *pipeline = new VKRGraphicsPipeline(pipelineFlags, tag); pipeline->desc = desc; pipeline->desc->AddRef(); if (curRenderStep_ && !cacheLoad) { @@ -733,7 +737,11 @@ VKRGraphicsPipeline *VulkanRenderManager::CreateGraphicsPipeline(VKRGraphicsPipe VKRRenderPassStoreAction::STORE, VKRRenderPassStoreAction::DONT_CARE, VKRRenderPassStoreAction::DONT_CARE, }; VKRRenderPass *compatibleRenderPass = queueRunner_.GetRenderPass(key); - compileMutex_.lock(); + std::lock_guard lock(compileMutex_); + if (compileBlocked_) { + delete pipeline; + return nullptr; + } bool needsCompile = false; for (size_t i = 0; i < (size_t)RenderPassType::TYPE_COUNT; i++) { if (!(variantBitmask & (1 << i))) @@ -757,18 +765,19 @@ VKRGraphicsPipeline *VulkanRenderManager::CreateGraphicsPipeline(VKRGraphicsPipe } if (needsCompile) compileCond_.notify_one(); - compileMutex_.unlock(); } return pipeline; } VKRComputePipeline *VulkanRenderManager::CreateComputePipeline(VKRComputePipelineDesc *desc) { + std::lock_guard lock(compileMutex_); + if (compileBlocked_) { + return nullptr; + } VKRComputePipeline *pipeline = new VKRComputePipeline(); pipeline->desc = desc; - compileMutex_.lock(); compileQueue_.push_back(CompileQueueEntry(pipeline)); compileCond_.notify_one(); - compileMutex_.unlock(); return pipeline; } @@ -814,7 +823,7 @@ void VulkanRenderManager::EndCurRenderStep() { compileMutex_.lock(); bool needsCompile = false; for (VKRGraphicsPipeline *pipeline : pipelinesToCheck_) { - if (!pipeline) { + if (!pipeline || compileBlocked_) { // Not good, but let's try not to crash. continue; } diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index 80270eb378..1c912cd0fe 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -455,7 +455,8 @@ public: } void ResetStats(); - void DrainCompileQueue(); + void DrainAndBlockCompileQueue(); + void ReleaseCompileQueue(); private: void EndCurRenderStep(); @@ -527,6 +528,7 @@ private: std::condition_variable compileCond_; std::mutex compileMutex_; std::vector compileQueue_; + bool compileBlocked_ = false; // Thread for measuring presentation delay. std::thread presentWaitThread_; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 9d62212092..6846a1d52e 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -182,7 +182,7 @@ void GPU_Vulkan::SaveCache(const Path &filename) { GPU_Vulkan::~GPU_Vulkan() { if (draw_) { VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - rm->DrainCompileQueue(); + rm->DrainAndBlockCompileQueue(); } SaveCache(shaderCachePath_); @@ -193,6 +193,11 @@ GPU_Vulkan::~GPU_Vulkan() { delete pipelineManager_; // other managers are deleted in ~GPUCommonHW. + + if (draw_) { + VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->ReleaseCompileQueue(); + } } u32 GPU_Vulkan::CheckGPUFeatures() const {