diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-07-22 02:46:57 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-07-22 02:46:57 +0000 |
| commit | 2dfbbae491090f3b0f0e622791515c59f3948ee0 (patch) | |
| tree | 898621085fe8253e7e52dc81ff03904931dcb36f /Graphics/GraphicsEngineVulkan | |
| parent | Disabled D3D11 fence for now to fix build (diff) | |
| download | DiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.tar.gz DiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.zip | |
Implemented IFence interface in all backends
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
11 files changed, 145 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h index eab3d101..b1ec606f 100644 --- a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h @@ -32,7 +32,7 @@ #include "CommandQueueVk.h" #include "ObjectBase.h" #include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanFencePool.h" +#include "FenceVkImpl.h" namespace Diligent { @@ -65,23 +65,25 @@ public: virtual void IdleGPU()override final; virtual Uint64 GetCompletedFenceValue()override final; + + virtual void SignalFence(VkFence vkFence)override final; + + void SetFence(RefCntAutoPtr<FenceVkImpl> pFence){m_pFence = std::move(pFence);} + private: // A value that will be signaled by the command queue next Atomics::AtomicInt64 m_NextFenceValue; - // Last fence value that is known to be completed by the GPU - volatile Uint64 m_LastCompletedFenceValue = 0; - std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> m_LogicalDevice; const VkQueue m_VkQueue; const uint32_t m_QueueFamilyIndex; - VulkanUtilities::VulkanFencePool m_FencePool; - // Queue of fences signaled right after a command buffer has been + // Fence is signaled right after a command buffer has been // submitted to the command queue for execution. - // All command buffers with fence value less or equal to the signaled value + // All command buffers with fence value less than or equal to the signaled value // are guaranteed to be finished by the GPU - std::deque<std::pair<Uint64, VulkanUtilities::FenceWrapper>> m_PendingFences; + RefCntAutoPtr<FenceVkImpl> m_pFence; + std::mutex m_QueueMutex; }; diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 0e40553c..26e74a25 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -93,6 +93,8 @@ public: virtual void ExecuteCommandList(class ICommandList* pCommandList)override final; + virtual void SignalFence(IFence* pFence, Uint64 Value)override final; + void TransitionImageLayout(class TextureVkImpl &TextureVk, VkImageLayout NewLayout); void TransitionImageLayout(class TextureVkImpl &TextureVk, VkImageLayout OldLayout, VkImageLayout NewLayout, const VkImageSubresourceRange& SubresRange); virtual void TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout)override final; @@ -199,9 +201,12 @@ private: VulkanUtilities::VulkanCommandBufferPool m_CmdPool; // Semaphores are not owned by the command context - std::vector<VkSemaphore> m_WaitSemaphores; - std::vector<VkPipelineStageFlags> m_WaitDstStageMasks; - std::vector<VkSemaphore> m_SignalSemaphores; + std::vector<VkSemaphore> m_WaitSemaphores; + std::vector<VkPipelineStageFlags> m_WaitDstStageMasks; + std::vector<VkSemaphore> m_SignalSemaphores; + + // List of fences to signal next time the command context is flushed + std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > > m_PendingFences; std::unordered_map<BufferVkImpl*, VulkanUtilities::VulkanUploadAllocation> m_UploadAllocations; ResourceReleaseQueue<DynamicStaleResourceWrapper> m_ReleaseQueue; diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h index 6d1a9267..fcb5f979 100644 --- a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h @@ -26,14 +26,16 @@ /// \file /// Declaration of Diligent::FenceVkImpl class +#include <deque> #include "FenceVk.h" -#include "RenderDeviceVk.h" #include "FenceBase.h" +#include "VulkanUtilities/VulkanFencePool.h" namespace Diligent { class FixedBlockMemoryAllocator; +class RenderDeviceVkImpl; /// Implementation of the Diligent::IFenceVk interface class FenceVkImpl : public FenceBase<IFenceVk> @@ -42,17 +44,28 @@ public: using TFenceBase = FenceBase<IFenceVk>; FenceVkImpl(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - const FenceDesc& Desc); + RenderDeviceVkImpl* pRendeDeviceVkImpl, + const FenceDesc& Desc, + bool IsDeviceInternal = false); ~FenceVkImpl(); virtual Uint64 GetCompletedValue()override final; /// Resets the fence to the specified value. virtual void Reset(Uint64 Value)override final; + + VulkanUtilities::FenceWrapper GetVkFence() { return m_FencePool.GetFence(); } + void AddPendingFence(VulkanUtilities::FenceWrapper&& vkFence, Uint64 FenceValue) + { + m_PendingFences.emplace_back(FenceValue, std::move(vkFence)); + } -private: + void Wait(); +private: + VulkanUtilities::VulkanFencePool m_FencePool; + std::deque<std::pair<Uint64, VulkanUtilities::FenceWrapper>> m_PendingFences; + volatile Uint64 m_LastCompletedFenceValue = 0; }; } diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h index e2edd52b..612854f7 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h @@ -103,7 +103,7 @@ public: Uint64 IdleGPU(bool ReleaseStaleObjects); // pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context // The method returns fence value associated with the submitted command buffer - Uint64 ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo, class DeviceContextVkImpl* pImmediateCtx); + Uint64 ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo, class DeviceContextVkImpl* pImmediateCtx, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences); void AllocateTransientCmdPool(VulkanUtilities::CommandPoolWrapper& CmdPool, VkCommandBuffer& vkCmdBuff, const Char* DebugPoolName = nullptr); void ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmdBuff, VulkanUtilities::CommandPoolWrapper&& CmdPool); @@ -144,7 +144,7 @@ private: // Parameters: // * SubmittedCmdBuffNumber - submitted command buffer number // * SubmittedFenceValue - fence value associated with the submitted command buffer - void SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue); + void SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pFences); std::shared_ptr<VulkanUtilities::VulkanInstance> m_VulkanInstance; std::unique_ptr<VulkanUtilities::VulkanPhysicalDevice> m_PhysicalDevice; diff --git a/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h b/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h index ca1a4acc..a7c58096 100644 --- a/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h @@ -64,6 +64,9 @@ public: /// Blocks execution until all pending GPU commands are complete virtual void IdleGPU() = 0; + + /// Signals the given fence + virtual void SignalFence(VkFence vkFence) = 0; }; } diff --git a/Graphics/GraphicsEngineVulkan/interface/FenceVk.h b/Graphics/GraphicsEngineVulkan/interface/FenceVk.h index 4fa22e51..25bf1475 100644 --- a/Graphics/GraphicsEngineVulkan/interface/FenceVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/FenceVk.h @@ -40,8 +40,7 @@ static constexpr INTERFACE_ID IID_FenceVk = class IFenceVk : public IFence { public: - /// Returns OpenGL sync object - //virtual IGLFence* GetGLFence() = 0; + }; } diff --git a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp index 92fd5f85..e75d4aaf 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp @@ -35,8 +35,7 @@ CommandQueueVkImpl::CommandQueueVkImpl(IReferenceCounters* m_LogicalDevice (LogicalDevice), m_VkQueue (LogicalDevice->GetQueue(QueueFamilyIndex, 0)), m_QueueFamilyIndex (QueueFamilyIndex), - m_NextFenceValue (1), - m_FencePool (LogicalDevice) + m_NextFenceValue (1) { } @@ -46,11 +45,6 @@ CommandQueueVkImpl::~CommandQueueVkImpl() // All queues associated with a logical device are destroyed when vkDestroyDevice // is called on that device. - while (!m_PendingFences.empty()) - { - m_FencePool.DisposeFence(std::move(m_PendingFences.front().second)); - m_PendingFences.pop_front(); - } } IMPLEMENT_QUERY_INTERFACE( CommandQueueVkImpl, IID_CommandQueueVk, TBase ) @@ -59,18 +53,18 @@ IMPLEMENT_QUERY_INTERFACE( CommandQueueVkImpl, IID_CommandQueueVk, TBase ) Uint64 CommandQueueVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo) { std::lock_guard<std::mutex> Lock(m_QueueMutex); - auto Fence = m_FencePool.GetFence(); + auto vkFence = m_pFence->GetVkFence(); bool SubmitCount = (SubmitInfo.waitSemaphoreCount != 0 || SubmitInfo.commandBufferCount != 0 || SubmitInfo.signalSemaphoreCount != 0) ? 1 : 0; - auto err = vkQueueSubmit(m_VkQueue, SubmitCount, &SubmitInfo, Fence); + auto err = vkQueueSubmit(m_VkQueue, SubmitCount, &SubmitInfo, vkFence); VERIFY(err == VK_SUCCESS, "Failed to submit command buffer to the command queue"); // We must atomically place the (value, fence) pair into the deque auto FenceValue = m_NextFenceValue; - m_PendingFences.emplace_back(FenceValue, std::move(Fence)); + m_pFence->AddPendingFence(std::move(vkFence), FenceValue); // Increment the value Atomics::AtomicIncrement(m_NextFenceValue); @@ -105,47 +99,21 @@ void CommandQueueVkImpl::IdleGPU() // Increment fence before idling the queue Atomics::AtomicIncrement(m_NextFenceValue); vkQueueWaitIdle(m_VkQueue); - if (LastCompletedFenceValue > m_LastCompletedFenceValue) - m_LastCompletedFenceValue = LastCompletedFenceValue; - for (auto& val_fence : m_PendingFences) - { - // For some reason after idling the queue not all fences are signaled - while (m_LogicalDevice->GetFenceStatus(val_fence.second) != VK_SUCCESS) - { - VkFence FenceToWait = val_fence.second; - auto res = vkWaitForFences(m_LogicalDevice->GetVkDevice(), 1, &FenceToWait, VK_TRUE, UINT64_MAX); - VERIFY_EXPR(res == VK_SUCCESS); - } - - auto status = m_LogicalDevice->GetFenceStatus(val_fence.second); - VERIFY(status == VK_SUCCESS, "All pending fences must now be complete!"); - m_FencePool.DisposeFence(std::move(val_fence.second)); - } - m_PendingFences.clear(); + // For some reason after idling the queue not all fences are signaled + m_pFence->Wait(); + m_pFence->Reset(LastCompletedFenceValue); } Uint64 CommandQueueVkImpl::GetCompletedFenceValue() { std::lock_guard<std::mutex> Lock(m_QueueMutex); + return m_pFence->GetCompletedValue(); +} - while (!m_PendingFences.empty()) - { - auto &Value_Fence = m_PendingFences.front(); - auto status = m_LogicalDevice->GetFenceStatus(Value_Fence.second); - if(status == VK_SUCCESS) - { - if (Value_Fence.first > m_LastCompletedFenceValue) - m_LastCompletedFenceValue = Value_Fence.first; - m_FencePool.DisposeFence(std::move(Value_Fence.second)); - m_PendingFences.pop_front(); - } - else - { - break; - } - } - - return m_LastCompletedFenceValue; +void CommandQueueVkImpl::SignalFence(VkFence vkFence) +{ + auto err = vkQueueSubmit(m_VkQueue, 0, nullptr, vkFence); + VERIFY(err == VK_SUCCESS, "Failed to submit command buffer to the command queue"); } } diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index febcc1d7..bb7acaf7 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -811,11 +811,12 @@ namespace Diligent // Submit command buffer even if there are no commands to release stale resources. //if (SubmitInfo.commandBufferCount != 0 || SubmitInfo.waitSemaphoreCount !=0 || SubmitInfo.signalSemaphoreCount != 0) - auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this); + auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this, &m_PendingFences); m_WaitSemaphores.clear(); m_WaitDstStageMasks.clear(); m_SignalSemaphores.clear(); + m_PendingFences.clear(); if (vkCmdBuff != VK_NULL_HANDLE) { @@ -1269,8 +1270,9 @@ namespace Diligent SubmitInfo.commandBufferCount = 1; SubmitInfo.pCommandBuffers = &vkCmdBuff; auto pDeviceVkImpl = m_pDevice.RawPtr<RenderDeviceVkImpl>(); - auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this); - + VERIFY_EXPR(m_PendingFences.empty()); + auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this, nullptr); + auto pDeferredCtxVkImpl = pDeferredCtx.RawPtr<DeviceContextVkImpl>(); // It is OK to dispose command buffer from another thread. We are not going to // record any commands and only need to add the buffer to the queue @@ -1282,6 +1284,12 @@ namespace Diligent m_ReleaseQueue.Purge(CompletedFenceValue); } + void DeviceContextVkImpl::SignalFence(IFence* pFence, Uint64 Value) + { + VERIFY(!m_bIsDeferred, "Fence can only be signalled from immediate context"); + m_PendingFences.emplace_back( std::make_pair(Value, pFence) ); + }; + void DeviceContextVkImpl::TransitionImageLayout(ITexture *pTexture, VkImageLayout NewLayout) { VERIFY_EXPR(pTexture != nullptr); diff --git a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp index bde0fe89..bbd872fc 100644 --- a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp @@ -25,30 +25,79 @@ #include "FenceVkImpl.h" #include "EngineMemory.h" +#include "RenderDeviceVkImpl.h" namespace Diligent { FenceVkImpl :: FenceVkImpl(IReferenceCounters* pRefCounters, - IRenderDevice* pDevice, - const FenceDesc& Desc) : - TFenceBase(pRefCounters, pDevice, Desc) + RenderDeviceVkImpl* pRendeDeviceVkImpl, + const FenceDesc& Desc, + bool IsDeviceInternal) : + TFenceBase(pRefCounters, pRendeDeviceVkImpl, Desc, IsDeviceInternal), + m_FencePool(pRendeDeviceVkImpl->GetLogicalDevice().GetSharedPtr()) { } FenceVkImpl :: ~FenceVkImpl() { + while (!m_PendingFences.empty()) + { + m_FencePool.DisposeFence(std::move(m_PendingFences.front().second)); + m_PendingFences.pop_front(); + } } Uint64 FenceVkImpl :: GetCompletedValue() { - UNSUPPORTED("Not yet implemented"); - return 0; + const auto& LogicalDevice = GetDevice<RenderDeviceVkImpl>()->GetLogicalDevice(); + while (!m_PendingFences.empty()) + { + auto& Value_Fence = m_PendingFences.front(); + auto status = LogicalDevice.GetFenceStatus(Value_Fence.second); + if(status == VK_SUCCESS) + { + if (Value_Fence.first > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = Value_Fence.first; + m_FencePool.DisposeFence(std::move(Value_Fence.second)); + m_PendingFences.pop_front(); + } + else + { + break; + } + } + + return m_LastCompletedFenceValue; } void FenceVkImpl :: Reset(Uint64 Value) { - UNSUPPORTED("Not yet implemented"); + 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, ")"); + if (Value > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = Value; +} + + +void FenceVkImpl :: Wait() +{ + const auto& LogicalDevice = GetDevice<RenderDeviceVkImpl>()->GetLogicalDevice(); + for (auto& val_fence : m_PendingFences) + { + while (LogicalDevice.GetFenceStatus(val_fence.second) != VK_SUCCESS) + { + VkFence FenceToWait = val_fence.second; + auto res = vkWaitForFences(LogicalDevice.GetVkDevice(), 1, &FenceToWait, VK_TRUE, UINT64_MAX); + VERIFY_EXPR(res == VK_SUCCESS); + } + + auto status = LogicalDevice.GetFenceStatus(val_fence.second); + VERIFY(status == VK_SUCCESS, "All pending fences must now be complete!"); + if (val_fence.first > m_LastCompletedFenceValue) + m_LastCompletedFenceValue = val_fence.first; + m_FencePool.DisposeFence(std::move(val_fence.second)); + } + m_PendingFences.clear(); } } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp index 4508a9ce..08ddd8bf 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp @@ -195,6 +195,14 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& Crea pCmdQueueVk = NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(LogicalDevice, QueueInfo.queueFamilyIndex); AttachToVulkanDevice(Instance, std::move(PhysicalDevice), LogicalDevice, pCmdQueueVk, CreationAttribs, ppDevice, ppContexts, NumDeferredContexts); + + FenceDesc Desc; + Desc.Name = "Command queue fence"; + // Render device owns command queue that in turn owns the fence, so it is an internal device object + bool IsDeviceInternal = true; + auto* pRenderDeviceVk = ValidatedCast<RenderDeviceVkImpl>(*ppDevice); + RefCntAutoPtr<FenceVkImpl> pFenceVk( NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal) ); + pCmdQueueVk->SetFence(std::move(pFenceVk)); } catch(std::runtime_error& ) { diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 762acebd..6095b2e8 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -172,7 +172,7 @@ void RenderDeviceVkImpl::ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmd Uint64 SubmittedFenceValue = 0; Uint64 SubmittedCmdBuffNumber = 0; - SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue); + SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, nullptr); // We MUST NOT discard stale objects when executing transient command buffer, @@ -204,8 +204,9 @@ void RenderDeviceVkImpl::ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmd } void RenderDeviceVkImpl::SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, - Uint64& SubmittedCmdBuffNumber, // Number of the submitted command buffer - Uint64& SubmittedFenceValue // Fence value associated with the submitted command buffer + Uint64& SubmittedCmdBuffNumber, // Number of the submitted command buffer + Uint64& SubmittedFenceValue, // Fence value associated with the submitted command buffer + std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pFences // List of fences to signal ) { std::lock_guard<std::mutex> LockGuard(m_CmdQueueMutex); @@ -216,9 +217,19 @@ void RenderDeviceVkImpl::SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, SubmittedFenceValue = std::max(SubmittedFenceValue, NextFenceValue); SubmittedCmdBuffNumber = m_NextCmdBuffNumber; Atomics::AtomicIncrement(m_NextCmdBuffNumber); + if (pFences != nullptr) + { + for (auto& val_fence : *pFences) + { + auto* pFenceVkImpl = val_fence.second.RawPtr<FenceVkImpl>(); + auto vkFence = pFenceVkImpl->GetVkFence(); + m_pCommandQueue->SignalFence(vkFence); + pFenceVkImpl->AddPendingFence(std::move(vkFence), val_fence.first); + } + } } -Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo, DeviceContextVkImpl* pImmediateCtx) +Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo, DeviceContextVkImpl* pImmediateCtx, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences) { // pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context // Stale objects MUST only be discarded when submitting cmd list from the immediate context @@ -226,7 +237,7 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo, Uint64 SubmittedFenceValue = 0; Uint64 SubmittedCmdBuffNumber = 0; - SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue); + SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, pSignalFences); // The following basic requirement guarantees correctness of resource deallocation: // @@ -325,7 +336,7 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources) Uint64 SubmittedCmdBuffNumber = 0; VkSubmitInfo DummySubmitInfo = {}; // Submit empty command buffer to set a fence on the GPU - SubmitCommandBuffer(DummySubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue); + SubmitCommandBuffer(DummySubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, nullptr); // Discard all remaining objects. This is important to do if there were // no command lists submitted during the frame. All stale resources will |
