From 9dee005580dc227b7f64ae3eb739902ddb01f187 Mon Sep 17 00:00:00 2001 From: Eugene Golushkov Date: Wed, 18 Dec 2024 11:51:45 +0100 Subject: [PATCH] [Vk] fixed recovering from real rather than simulated device lost --- .../Vulkan/include/OgreVulkanQueue.h | 2 +- .../Vulkan/include/Vao/OgreVulkanVaoManager.h | 2 +- RenderSystems/Vulkan/src/OgreVulkanQueue.cpp | 60 ++++++++----------- .../Vulkan/src/OgreVulkanRenderSystem.cpp | 1 + .../Vulkan/src/Vao/OgreVulkanVaoManager.cpp | 2 +- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/RenderSystems/Vulkan/include/OgreVulkanQueue.h b/RenderSystems/Vulkan/include/OgreVulkanQueue.h index a7dfa0a45f..47ef5c32b9 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanQueue.h +++ b/RenderSystems/Vulkan/include/OgreVulkanQueue.h @@ -100,7 +100,7 @@ namespace Ogre VkSemaphoreArray mGpuWaitSemaphForCurrCmdBuff; FastArray mGpuWaitFlags; /// Collection of semaphore we will signal when our queue - /// submitted in commitAndNextCommandBuffer is done + /// submitted in commitAndNextCommandBuffer is done. Semaphores are owned. VkSemaphoreArray mGpuSignalSemaphForCurrCmdBuff; // clang-format on diff --git a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h index d80c3eefbf..cc788a3c2a 100644 --- a/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h +++ b/RenderSystems/Vulkan/include/Vao/OgreVulkanVaoManager.h @@ -540,7 +540,7 @@ namespace Ogre VulkanDevice *getDevice() const { return mDevice; } /// Insert into the end of semaphoreArray 'numSemaphores' - /// number of semaphores that are safe for use. + /// number of semaphores that are safe for use. Transfers ownership. void getAvailableSemaphores( VkSemaphoreArray &semaphoreArray, size_t numSemaphores ); VkSemaphore getAvailableSemaphore(); diff --git a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp index d39ee343df..1bc8dcb972 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanQueue.cpp @@ -76,49 +76,35 @@ namespace Ogre { vkDeviceWaitIdle( mDevice ); - { - FastArray::iterator itor = mPerFrameData.begin(); - FastArray::iterator endt = mPerFrameData.end(); - - while( itor != endt ) - { - VkFenceArray::const_iterator itFence = itor->mProtectingFences.begin(); - VkFenceArray::const_iterator enFence = itor->mProtectingFences.end(); - - while( itFence != enFence ) - vkDestroyFence( mDevice, *itFence++, 0 ); - itor->mProtectingFences.clear(); - - vkDestroyCommandPool( mDevice, itor->mCmdPool, 0 ); - itor->mCommands.clear(); - itor->mCurrentCmdIdx = 0; + mWindowsPendingSwap.clear(); - ++itor; - } - } + for( PerFrameData &perFrameData : mPerFrameData ) { - RefCountedFenceMap::const_iterator itor = mRefCountedFences.begin(); - RefCountedFenceMap::const_iterator endt = mRefCountedFences.end(); - - while( itor != endt ) - { - // If recycleAfterRelease == false, then they were destroyed with mProtectingFences - if( itor->second.recycleAfterRelease ) - vkDestroyFence( mDevice, itor->first, 0 ); - ++itor; - } + for( VkFence fence : perFrameData.mProtectingFences ) + vkDestroyFence( mDevice, fence, 0 ); + perFrameData.mProtectingFences.clear(); - mRefCountedFences.clear(); + vkDestroyCommandPool( mDevice, perFrameData.mCmdPool, 0 ); + perFrameData.mCommands.clear(); + perFrameData.mCurrentCmdIdx = 0; } - VkFenceArray::const_iterator itor = mAvailableFences.begin(); - VkFenceArray::const_iterator endt = mAvailableFences.end(); - - while( itor != endt ) - vkDestroyFence( mDevice, *itor++, 0 ); + for( RefCountedFenceMap::value_type &elem : mRefCountedFences ) + { + // If recycleAfterRelease == false, then they were destroyed with mProtectingFences + if( elem.second.recycleAfterRelease ) + vkDestroyFence( mDevice, elem.first, 0 ); + } + mRefCountedFences.clear(); + for( VkFence fence : mAvailableFences ) + vkDestroyFence( mDevice, fence, 0 ); mAvailableFences.clear(); + for( VkSemaphore sem : mGpuSignalSemaphForCurrCmdBuff ) + vkDestroySemaphore( mDevice, sem, 0 ); + mGpuSignalSemaphForCurrCmdBuff.clear(); + mDevice = 0; } } @@ -1256,7 +1242,7 @@ namespace Ogre VkResult result = vkQueueSubmit( mQueue, 1u, &submitInfo, fence ); if( result != VK_SUCCESS ) mOwnerDevice->mIsDeviceLost = true; - checkVkResult( result, "vkQueueSubmit" ); + // we need some cleanup before checking result mGpuWaitSemaphForCurrCmdBuff.clear(); @@ -1274,6 +1260,8 @@ namespace Ogre mPendingCmds.clear(); + checkVkResult( result, "vkQueueSubmit" ); + if( submissionType >= SubmissionType::EndFrameAndSwap ) { for( size_t windowIdx = 0u; windowIdx < numWindowsPendingSwap; ++windowIdx ) diff --git a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp index ee18a0d1ad..68f295117a 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp @@ -1343,6 +1343,7 @@ namespace Ogre // recreate device mDevice->setPhysicalDevice( mInstance, mActiveDevice, nullptr ); + mDevice->mIsDeviceLost = false; static_cast( mVaoManager )->createVkResources(); static_cast( mTextureGpuManager )->createVkResources(); diff --git a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp index c837597d29..703f55db0f 100644 --- a/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp +++ b/RenderSystems/Vulkan/src/Vao/OgreVulkanVaoManager.cpp @@ -476,7 +476,7 @@ namespace Ogre //----------------------------------------------------------------------------------- bool VulkanVaoManager::flushAllGpuDelayedBlocks( const bool bIssueBarrier ) { - if( bIssueBarrier ) + if( bIssueBarrier && !mDevice->mIsDeviceLost ) { if( mDevice->mGraphicsQueue.getEncoderState() == VulkanQueue::EncoderGraphicsOpen ) {