diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index e69177c63e..dbe70dee19 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -217,14 +217,15 @@ void VulkanRenderManager::StopThread(bool shutdown) { thread_.join(); VLOG("thread joined."); - // Resignal fences for next time around - must be done after join. + // Wait for any fences to finish and be resignaled, so we don't have sync issues. for (int i = 0; i < vulkan_->GetInflightFrames(); i++) { auto &frameData = frameData_[i]; frameData.readyForRun = false; - if (!shutdown && !frameData.readyForFence) { - vkDestroyFence(vulkan_->GetDevice(), frameData.fence, nullptr); - frameData.fence = vulkan_->CreateFence(true); - frameData.readyForFence = true; + + std::unique_lock lock(frameData.push_mutex); + while (!frameData.readyForFence) { + VLOG("PUSH: Waiting for frame[%d].readyForFence = 1 (stop)", i); + frameData.push_condVar.wait(lock); } } } @@ -273,7 +274,7 @@ void VulkanRenderManager::ThreadFunc() { setCurrentThreadName("RenderMan"); int threadFrame = threadInitFrame_; bool nextFrame = false; - while (run_) { + while (true) { { if (nextFrame) { threadFrame++; @@ -286,6 +287,10 @@ void VulkanRenderManager::ThreadFunc() { VLOG("PULL: Waiting for frame[%d].readyForRun", threadFrame); frameData.pull_condVar.wait(lock); } + if (!frameData.readyForRun && !run_) { + // This means we're out of frames to render and run_ is false, so bail. + break; + } VLOG("PULL: frame[%d].readyForRun = false", threadFrame); frameData.readyForRun = false; // Previously we had a quick exit here that avoided calling Run() if run_ was suddenly false, @@ -656,7 +661,6 @@ void VulkanRenderManager::Finish() { } void VulkanRenderManager::Wipe() { - int curFrame = vulkan_->GetCurFrame(); for (auto step : steps_) { // Need to release held framebuffers. switch (step->stepType) {