Fix Vulkan timeout to be larger (5s)

#3967
This commit is contained in:
Wojtek Figat
2026-03-03 23:29:10 +01:00
parent ff81d339ef
commit 10bcf9c9a3
6 changed files with 25 additions and 24 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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.

View File

@@ -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