diff --git a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp index 36eacccf9..737c147d9 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp @@ -136,6 +136,15 @@ void CmdBufferVulkan::EndEvent() #endif +void CmdBufferVulkan::Wait(float timeoutSeconds) +{ + PROFILE_CPU(); + ASSERT(IsSubmitted()); + const bool failed = _device->FenceManager.WaitForFence(GetFence(), timeoutSeconds); + ASSERT(!failed); + RefreshFenceStatus(); +} + void CmdBufferVulkan::RefreshFenceStatus() { if (_state == State::Submitted) @@ -186,9 +195,8 @@ CmdBufferVulkan::~CmdBufferVulkan() auto& fenceManager = _device->FenceManager; if (_state == State::Submitted) { - // Wait 60ms - const uint64 waitForCmdBufferInNanoSeconds = 60 * 1000 * 1000LL; - fenceManager.WaitAndReleaseFence(_fence, waitForCmdBufferInNanoSeconds); + // Wait + fenceManager.WaitAndReleaseFence(_fence); } else { @@ -281,15 +289,6 @@ void CmdBufferManagerVulkan::SubmitActiveCmdBuffer(SemaphoreVulkan* signalSemaph _activeCmdBuffer = nullptr; } -void CmdBufferManagerVulkan::WaitForCmdBuffer(CmdBufferVulkan* cmdBuffer, float timeInSecondsToWait) -{ - PROFILE_CPU(); - ASSERT(cmdBuffer->IsSubmitted()); - const bool failed = _device->FenceManager.WaitForFence(cmdBuffer->GetFence(), (uint64)(timeInSecondsToWait * 1e9)); - ASSERT(!failed); - cmdBuffer->RefreshFenceStatus(); -} - void CmdBufferManagerVulkan::PrepareForNewActiveCommandBuffer() { PROFILE_CPU(); diff --git a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h index 7cb3ee104..c8e096cdd 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h @@ -136,6 +136,7 @@ public: void EndEvent(); #endif + void Wait(float timeoutSeconds = VULKAN_WAIT_TIMEOUT); void RefreshFenceStatus(); }; @@ -206,7 +207,6 @@ public: public: void SubmitActiveCmdBuffer(SemaphoreVulkan* signalSemaphore = nullptr); - void WaitForCmdBuffer(CmdBufferVulkan* cmdBuffer, float timeInSecondsToWait = 1.0f); void RefreshFenceStatus(CmdBufferVulkan* skipCmdBuffer = nullptr) { _pool.RefreshFenceStatus(skipCmdBuffer); diff --git a/Source/Engine/GraphicsDevice/Vulkan/Config.h b/Source/Engine/GraphicsDevice/Vulkan/Config.h index 1f30c301a..7b4e54137 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/Config.h +++ b/Source/Engine/GraphicsDevice/Vulkan/Config.h @@ -49,4 +49,9 @@ #define VULKAN_USE_QUERIES 1 #endif +// Fence wait operation timeout in seconds +#ifndef VULKAN_WAIT_TIMEOUT +#define VULKAN_WAIT_TIMEOUT 5.0f +#endif + #endif diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index e96f7b3b3..71ef42005 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -2184,11 +2184,12 @@ FenceVulkan* FenceManagerVulkan::AllocateFence(bool createSignaled) return fence; } -bool FenceManagerVulkan::WaitForFence(FenceVulkan* fence, uint64 timeInNanoseconds) const +bool FenceManagerVulkan::WaitForFence(FenceVulkan* fence, float timeoutSeconds) const { ASSERT(_usedFences.Contains(fence)); ASSERT(!fence->IsSignaled); - const VkResult result = vkWaitForFences(_device->Device, 1, &fence->Handle, true, timeInNanoseconds); + uint64 timeNanoseconds = (uint64)((double)timeoutSeconds * 1000000000.0); + const VkResult result = vkWaitForFences(_device->Device, 1, &fence->Handle, true, timeNanoseconds); LOG_VULKAN_RESULT(result); if (result == VK_SUCCESS) { @@ -2216,11 +2217,11 @@ void FenceManagerVulkan::ReleaseFence(FenceVulkan*& fence) fence = nullptr; } -void FenceManagerVulkan::WaitAndReleaseFence(FenceVulkan*& fence, uint64 timeInNanoseconds) +void FenceManagerVulkan::WaitAndReleaseFence(FenceVulkan*& fence, float timeoutSeconds) { ScopeLock lock(_device->_fenceLock); if (!fence->IsSignaled) - WaitForFence(fence, timeInNanoseconds); + WaitForFence(fence, timeoutSeconds); ResetFence(fence); _usedFences.Remove(fence); _freeFences.Add(fence); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h index 09fa93f3e..a22cd9cc6 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h @@ -88,7 +88,7 @@ public: } // Returns true if waiting timed out or failed, false otherwise. - bool WaitForFence(FenceVulkan* fence, uint64 timeInNanoseconds) const; + bool WaitForFence(FenceVulkan* fence, float timeoutSeconds = VULKAN_WAIT_TIMEOUT) const; void ResetFence(FenceVulkan* fence) const; @@ -96,7 +96,7 @@ public: void ReleaseFence(FenceVulkan*& fence); // Sets the fence handle to null - void WaitAndReleaseFence(FenceVulkan*& fence, uint64 timeInNanoseconds); + void WaitAndReleaseFence(FenceVulkan*& fence, float timeoutSeconds = VULKAN_WAIT_TIMEOUT); private: // Returns true if fence was signaled, otherwise false. diff --git a/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp index f2d2521d0..39b0d2691 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp @@ -62,11 +62,7 @@ void QueueVulkan::Submit(CmdBufferVulkan* cmdBuffer, uint32 signalSemaphoresCoun const bool WaitForIdleOnSubmit = false; if (WaitForIdleOnSubmit) { - // Use 200ms timeout - bool success = _device->FenceManager.WaitForFence(fence, 200 * 1000 * 1000); - ASSERT(success); - ASSERT(_device->FenceManager.IsFenceSignaled(fence)); - cmdBuffer->GetOwner()->RefreshFenceStatus(); + cmdBuffer->Wait(); } #endif