From 52d1b5ab7fee4f2c4e63eaf5774d48111becba12 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 8 Sep 2019 14:56:26 -0700 Subject: Added IDeviceContext::Wait() method (updated API version to 240026) --- Graphics/GraphicsEngine/interface/APIInfo.h | 2 +- Graphics/GraphicsEngine/interface/DeviceContext.h | 26 +++++++++++++++++++++- .../include/DeviceContextD3D11Impl.h | 2 ++ .../GraphicsEngineD3D11/include/FenceD3D11Impl.h | 2 ++ .../src/DeviceContextD3D11Impl.cpp | 10 ++++++++- .../GraphicsEngineD3D11/src/FenceD3D11Impl.cpp | 20 +++++++++++++++++ .../include/CommandQueueD3D12Impl.h | 4 +++- .../include/DeviceContextD3D12Impl.h | 2 ++ .../include/RenderDeviceD3D12Impl.h | 4 +++- .../interface/CommandQueueD3D12.h | 3 +++ .../src/CommandQueueD3D12Impl.cpp | 6 +++++ .../src/DeviceContextD3D12Impl.cpp | 10 ++++++++- .../src/RenderDeviceD3D12Impl.cpp | 12 ++++++++++ .../include/DeviceContextMtlImpl.h | 2 ++ .../src/DeviceContextMtlImpl.mm | 10 ++++++++- .../include/DeviceContextGLImpl.h | 2 ++ .../GraphicsEngineOpenGL/include/FenceGLImpl.h | 2 ++ .../src/DeviceContextGLImpl.cpp | 9 +++++++- Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp | 17 ++++++++++++++ .../include/DeviceContextVkImpl.h | 2 ++ .../GraphicsEngineVulkan/include/FenceVkImpl.h | 2 +- .../src/CommandQueueVkImpl.cpp | 2 +- .../src/DeviceContextVkImpl.cpp | 12 +++++++++- Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp | 13 +++++++---- 24 files changed, 161 insertions(+), 15 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h index fd6ef747..59bd261a 100644 --- a/Graphics/GraphicsEngine/interface/APIInfo.h +++ b/Graphics/GraphicsEngine/interface/APIInfo.h @@ -26,7 +26,7 @@ /// \file /// Diligent API information -#define DILIGENT_API_VERSION 240024 +#define DILIGENT_API_VERSION 240026 #include "../../../Primitives/interface/BasicTypes.h" diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index c7dd3d21..62aee8a1 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -799,7 +799,31 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value) = 0; - /// Flushes the command buffer. + /// Waits until the specified fence reaches or exceeds the specified value. + + /// \note The method blocks the execution of the calling thread until the wait is complete. + /// + /// \param [in] pFence - The fence to wait. + /// \param [in] Value - The value that the context is waiting for the fence to reach. + /// + /// \remarks Wait is only allowed for immediate contexts.\n + /// The method flushes the context before initiating the wait (see IDeviceContext::Flush()), + /// so an application must explicitly reset the PSO and bind all required shader + /// resources after waiting for a fence.\n + /// The fence can only be waited for from the same context it has + /// previously been signaled. + virtual void Wait(IFence* pFence, Uint64 Value) = 0; + + + /// Submits all pending commands in the context for execution to the command queue. + + /// \remarks Only immediate contexts can be flushed.\n + /// Internally the method resets the state of the current command list/buffer. + /// When the next draw command is issued, the engine will restore all states + /// (rebind render targets and depth-stencil buffer as well as index and vertex buffers, + /// restore viewports and scissor rects, etc.) except for the pipeline state and shader resource + /// bindings. An application must explicitly reset the PSO and bind all required shader + /// resources after flushing the context. virtual void Flush() = 0; diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index bc5c87a6..ef7124be 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -156,6 +156,8 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void Wait(IFence* pFence, Uint64 Value)override final; + virtual ID3D11DeviceContext* GetD3D11DeviceContext()override final { return m_pd3d11DeviceContext; } void CommitRenderTargets(); diff --git a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h index 9de594cf..bdfc5262 100644 --- a/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/FenceD3D11Impl.h @@ -58,6 +58,8 @@ public: m_PendingQueries.emplace_back(std::move(pCtx), std::move(pQuery), Value); } + void Wait(Uint64 Value); + private: struct PendingFenceData { diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index dc6c3281..1ccdc2e2 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -1764,7 +1764,15 @@ namespace Diligent m_pd3d11DeviceContext->End(pd3d11Query); auto* pFenceD3D11Impl = ValidatedCast(pFence); pFenceD3D11Impl->AddPendingQuery(m_pd3d11DeviceContext, std::move(pd3d11Query), Value); - }; + } + + void DeviceContextD3D11Impl::Wait(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + Flush(); + auto* pFenceD3D11Impl = ValidatedCast(pFence); + pFenceD3D11Impl->Wait(Value); + } void DeviceContextD3D11Impl::ClearStateCache() { diff --git a/Graphics/GraphicsEngineD3D11/src/FenceD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/FenceD3D11Impl.cpp index 73d32f51..e3bd2f4e 100644 --- a/Graphics/GraphicsEngineD3D11/src/FenceD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/FenceD3D11Impl.cpp @@ -64,6 +64,26 @@ Uint64 FenceD3D11Impl :: GetCompletedValue() return m_LastCompletedFenceValue; } +void FenceD3D11Impl :: Wait(Uint64 Value) +{ + while (!m_PendingQueries.empty()) + { + auto& QueryData = m_PendingQueries.front(); + if (QueryData.Value > Value) + break; + + BOOL Data; + while (QueryData.pd3d11Ctx->GetData(QueryData.pd3d11Query, &Data, sizeof(Data), 0) != S_OK) + std::this_thread::yield(); + + VERIFY_EXPR(Data == TRUE); + if (QueryData.Value > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = QueryData.Value; + + m_PendingQueries.pop_front(); + } +} + void FenceD3D11Impl :: Reset(Uint64 Value) { DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")"); diff --git a/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h index 4089663c..e1d29f2e 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandQueueD3D12Impl.h @@ -56,7 +56,9 @@ public: virtual Uint64 GetCompletedFenceValue()override final; - void SignalFence(ID3D12Fence* pFence, Uint64 Value)override final; + virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value)override final; + + virtual void Wait(ID3D12Fence* pFence, Uint64 Value)override final; private: // A value that will be signaled by the command queue next diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h index 7674ed54..a0cea3d2 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -154,6 +154,8 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void Wait(IFence* pFence, Uint64 Value)override final; + virtual void TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State)override final; virtual void TransitionBufferState(IBuffer *pBuffer, D3D12_RESOURCE_STATES State)override final; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h index 0551f7d0..9a70e68d 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h @@ -85,6 +85,8 @@ public: PooledCommandContext AllocateCommandContext(const Char* ID = ""); void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, PooledCommandContext&& Ctx); Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, PooledCommandContext&& Ctx, bool DiscardStaleObjects, std::vector > >* pSignalFences); + + void WaitForFence(Uint32 QueueIndex, IFence* pFence, Uint64 Value); // Disposes an unused command context void DisposeCommandContext(PooledCommandContext&& Ctx); @@ -101,7 +103,7 @@ public: } const GenerateMipsHelper& GetMipsGenerator()const {return m_MipsGenerator;} - + private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; void FreeCommandContext(PooledCommandContext&& Ctx); diff --git a/Graphics/GraphicsEngineD3D12/interface/CommandQueueD3D12.h b/Graphics/GraphicsEngineD3D12/interface/CommandQueueD3D12.h index 81ff9b45..5ad649fa 100644 --- a/Graphics/GraphicsEngineD3D12/interface/CommandQueueD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/CommandQueueD3D12.h @@ -56,6 +56,9 @@ public: /// Signals the given fence virtual void SignalFence(ID3D12Fence* pFence, Uint64 Value) = 0; + + /// Waits until the specified fence reaches or exceeds the specified value. + virtual void Wait(ID3D12Fence* pFence, Uint64 Value) = 0; }; } diff --git a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp index ed41e02a..df423816 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandQueueD3D12Impl.cpp @@ -99,4 +99,10 @@ void CommandQueueD3D12Impl::SignalFence(ID3D12Fence* pFence, Uint64 Value) m_pd3d12CmdQueue->Signal(pFence, Value); } +void CommandQueueD3D12Impl::Wait(ID3D12Fence* pFence, Uint64 Value) +{ + std::lock_guard Lock(m_QueueMtx); + m_pd3d12CmdQueue->Wait(pFence, Value); +} + } diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 01aa8307..7daa6437 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -1562,7 +1562,15 @@ namespace Diligent { VERIFY(!m_bIsDeferred, "Fence can only be signaled from immediate context"); m_PendingFences.emplace_back(Value, pFence); - }; + } + + void DeviceContextD3D12Impl::Wait(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + Flush(); + m_pDevice.RawPtr()->WaitForFence(m_CommandQueueId, pFence, Value); + } + void DeviceContextD3D12Impl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) { diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index a7d2f6c6..e7ee520e 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -197,6 +197,18 @@ Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(Uint32 QueueIndex, P return FenceValue; } +void RenderDeviceD3D12Impl::WaitForFence(Uint32 QueueIndex, IFence* pFence, Uint64 Value) +{ + VERIFY_EXPR(QueueIndex < m_CmdQueueCount); + VERIFY_EXPR(pFence != nullptr); + + auto* pFenceD3D12Impl = ValidatedCast(pFence); + auto* pd3d12Fence = pFenceD3D12Impl->GetD3D12Fence(); + m_CommandQueues[QueueIndex].CmdQueue->Wait(pd3d12Fence, Value); + + PurgeReleaseQueue(QueueIndex); +} + void RenderDeviceD3D12Impl::IdleGPU() { diff --git a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h index f3d711a2..77c88c9b 100644 --- a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h +++ b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h @@ -152,6 +152,8 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void Wait(IFence* pFence, Uint64 Value)override final; + private: }; diff --git a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm index 978fccf7..bd975afe 100644 --- a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm +++ b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm @@ -374,7 +374,15 @@ namespace Diligent VERIFY(!m_bIsDeferred, "Fence can only be signalled from immediate context"); LOG_ERROR_MESSAGE("DeviceContextMtlImpl::SignalFence() is not implemented"); - }; + } + + void DeviceContextD3D11Impl::Wait(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + Flush(); + + LOG_ERROR_MESSAGE("DeviceContextMtlImpl::Wait() is not implemented"); + } void DeviceContextMtlImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) { diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h index 96653441..3d64ad3f 100644 --- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h @@ -150,6 +150,8 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void Wait(IFence* pFence, Uint64 Value)override final; + virtual bool UpdateCurrentGLContext()override final; void BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding); diff --git a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h index ceab0d57..bade8fd1 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/FenceGLImpl.h @@ -59,6 +59,8 @@ public: m_PendingFences.emplace_back(Value, std::move(Fence)); } + void Wait(Uint64 Value); + private: std::deque > m_PendingFences; volatile Uint64 m_LastCompletedFenceValue = 0; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 2b19d5f1..ec77379d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -1073,7 +1073,14 @@ namespace Diligent CHECK_GL_ERROR( "Failed to create gl fence" ); auto* pFenceGLImpl = ValidatedCast(pFence); pFenceGLImpl->AddPendingFence(std::move(GLFence), Value); - }; + } + + void DeviceContextGLImpl::Wait(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + auto* pFenceGLImpl = ValidatedCast(pFence); + pFenceGLImpl->Wait(Value); + } bool DeviceContextGLImpl::UpdateCurrentGLContext() { diff --git a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp index 75983e18..7e39aa2f 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FenceGLImpl.cpp @@ -64,6 +64,23 @@ Uint64 FenceGLImpl :: GetCompletedValue() return m_LastCompletedFenceValue; } +void FenceGLImpl :: Wait(Uint64 Value) +{ + while (!m_PendingFences.empty()) + { + auto& val_fence = m_PendingFences.front(); + if (val_fence.first > Value) + break; + + auto res = glClientWaitSync(val_fence.second, GL_SYNC_FLUSH_COMMANDS_BIT, std::numeric_limits::max()); + VERIFY_EXPR(res == GL_ALREADY_SIGNALED || res == GL_CONDITION_SATISFIED); + + if (val_fence.first > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = val_fence.first; + m_PendingFences.pop_front(); + } +} + void FenceGLImpl :: Reset(Uint64 Value) { DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")"); diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 417f2f5b..bce9f300 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -159,6 +159,8 @@ public: virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + virtual void Wait(IFence* pFence, Uint64 Value)override final; + // Transitions texture subresources from OldState to NewState, and optionally updates // internal texture state. // If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state. diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h index 9816bfb1..a6c80c83 100644 --- a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h @@ -65,7 +65,7 @@ public: m_PendingFences.emplace_back(FenceValue, std::move(vkFence)); } - void Wait(); + void Wait(Uint64 Value); private: VulkanUtilities::VulkanFencePool m_FencePool; diff --git a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp index 8ee3e7b6..2af4e27f 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp @@ -101,7 +101,7 @@ Uint64 CommandQueueVkImpl::WaitForIdle() Atomics::AtomicIncrement(m_NextFenceValue); vkQueueWaitIdle(m_VkQueue); // For some reason after idling the queue not all fences are signaled - m_pFence->Wait(); + m_pFence->Wait(UINT64_MAX); m_pFence->Reset(LastCompletedFenceValue); return LastCompletedFenceValue; } diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 3a3c301a..d2252b4a 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -31,6 +31,7 @@ #include "BufferVkImpl.h" #include "VulkanTypeConversions.h" #include "CommandListVkImpl.h" +#include "FenceVkImpl.h" #include "GraphicsAccessories.h" namespace Diligent @@ -1913,7 +1914,16 @@ namespace Diligent { VERIFY(!m_bIsDeferred, "Fence can only be signaled from immediate context"); m_PendingFences.emplace_back( std::make_pair(Value, pFence) ); - }; + } + + void DeviceContextVkImpl::Wait(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + Flush(); + auto* pFenceVk = ValidatedCast(pFence); + pFenceVk->Wait(Value); + } + void DeviceContextVkImpl::TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout) { diff --git a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp index 3314598a..07f8ba23 100644 --- a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp @@ -48,7 +48,7 @@ FenceVkImpl :: ~FenceVkImpl() // Vulkan spec states that all queue submission commands that refer to // a fence must have completed execution before the fence is destroyed. // (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyFence-fence-01120) - Wait(); + Wait(UINT64_MAX); } } @@ -83,11 +83,15 @@ void FenceVkImpl :: Reset(Uint64 Value) } -void FenceVkImpl :: Wait() +void FenceVkImpl :: Wait(Uint64 Value) { const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); - for (auto& val_fence : m_PendingFences) + while (!m_PendingFences.empty()) { + auto& val_fence = m_PendingFences.front(); + if (val_fence.first > Value) + break; + auto status = LogicalDevice.GetFenceStatus(val_fence.second); if (status == VK_NOT_READY) { @@ -99,8 +103,9 @@ void FenceVkImpl :: Wait() if (val_fence.first > m_LastCompletedFenceValue) m_LastCompletedFenceValue = val_fence.first; m_FencePool.DisposeFence(std::move(val_fence.second)); + + m_PendingFences.pop_front(); } - m_PendingFences.clear(); } } -- cgit v1.2.3