summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-09-23 02:03:07 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-09-23 02:03:07 +0000
commit396c5eddcf80630a79b5174c070321080f2fa27c (patch)
tree852eec4f1be727f8479ec75e77c42fac6d506206 /Graphics/GraphicsEngineVulkan
parentReworked upload allocation release process in Vk backend (diff)
downloadDiligentCore-396c5eddcf80630a79b5174c070321080f2fa27c.tar.gz
DiligentCore-396c5eddcf80630a79b5174c070321080f2fa27c.zip
Reworked vulkan dynamic heap deallocation to use main release queue
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp29
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp10
5 files changed, 28 insertions, 21 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index ed3d2645..1c701a7d 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -188,7 +188,7 @@ private:
inline void EnsureVkCmdBuffer();
inline void DisposeVkCmdBuffer(VkCommandBuffer vkCmdBuff, Uint64 FenceValue);
inline void DisposeCurrentCmdBuffer(Uint64 FenceValue);
- void ReleaseStaleContextResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue);
+ void ReleaseStaleContextResources(Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue);
struct BufferToTextureCopyInfo
{
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h b/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h
index 31f291de..10ccad1c 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h
@@ -154,7 +154,9 @@ public:
~VulkanDynamicHeap();
VulkanDynamicAllocation Allocate(Uint32 SizeInBytes, Uint32 Alignment);
- void FinishFrame(Uint64 FenceValue);
+ // CmdQueueMask indicates which command queues the allocations from this heap were used
+ // with during the last frame
+ void FinishFrame(RenderDeviceVkImpl& DeviceVkImpl, Uint64 CmdQueueMask);
using OffsetType = VulkanDynamicMemoryManager::OffsetType;
using MasterBlock = VulkanDynamicMemoryManager::MasterBlock;
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index d3aba87d..8c6e0b56 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -143,6 +143,8 @@ namespace Diligent
// We must now wait for GPU to finish so that we can safely destroy all context resources.
// We need to idle when destroying deferred contexts as well since some resources may still be in use.
+ // Also, upload allocation for instance reference the upload heap, so it must be alive when these
+ // allocations are destroyed by the release queue.
pDeviceVkImpl->IdleGPU(true);
DisposeCurrentCmdBuffer(m_LastSubmittedFenceValue);
@@ -153,7 +155,7 @@ namespace Diligent
VERIFY(m_UploadHeap.GetStalePagesCount() == 0, "All stale pages must have been discarded at this point");
VERIFY(m_DynamicDescriptorPool.GetStaleAllocationCount() == 0, "All stale dynamic descriptor set allocations must have been discarded at this point");
// TODO: rework
- ReleaseStaleContextResources(m_NextCmdBuffNumber, m_LastSubmittedFenceValue, pDeviceVkImpl->GetCompletedFenceValue(0));
+ ReleaseStaleContextResources(m_LastSubmittedFenceValue, pDeviceVkImpl->GetCompletedFenceValue(0));
// Since we idled the GPU, all stale resources must have been destroyed now
VERIFY(m_DynamicDescriptorPool.GetPendingReleaseAllocationCount() == 0, "All stale descriptor set allocations must have been destroyed at this point");
@@ -753,24 +755,31 @@ namespace Diligent
"There are outstanding commands in the deferred device context when finishing the frame. This is an error and may cause unpredicted behaviour. Close all deferred contexts and execute them before finishing the frame" :
"There are outstanding commands in the immediate device context when finishing the frame. This is an error and may cause unpredicted behaviour. Call Flush() to submit all commands for execution before finishing the frame");
+ auto& DeviceVkImpl = *m_pDevice.RawPtr<RenderDeviceVkImpl>();
+
VERIFY_EXPR(m_bIsDeferred || m_SubmittedBuffersCmdQueueMask == (Uint64{1}<<m_CommandQueueId));
+ // The released resources will go into the stale resources queue first, however they will move into
+ // the release queue rightaway when RenderDeviceVkImpl::FlushStaleResources() is called
m_UploadHeap.ReleaseAllocatedPages(m_SubmittedBuffersCmdQueueMask);
- if (m_bIsDeferred)
- m_SubmittedBuffersCmdQueueMask = 0;
-
+ m_DynamicHeap.FinishFrame(DeviceVkImpl, m_SubmittedBuffersCmdQueueMask);
+
m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
- m_DynamicHeap.FinishFrame(m_LastSubmittedFenceValue);
- if (!m_bIsDeferred)
+ if (m_bIsDeferred)
+ {
+ // For deferred context, reset submitted cmd queue mask
+ m_SubmittedBuffersCmdQueueMask = 0;
+ }
+ else
{
// Make all stale resource move into the release queue
- m_pDevice.RawPtr<RenderDeviceVkImpl>()->FlushStaleResources(m_CommandQueueId);
+ DeviceVkImpl.FlushStaleResources(m_CommandQueueId);
}
Atomics::AtomicIncrement(m_ContextFrameNumber);
}
- void DeviceContextVkImpl::ReleaseStaleContextResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue)
+ void DeviceContextVkImpl::ReleaseStaleContextResources(Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue)
{
m_DynamicDescriptorPool.DisposeAllocations(SubmittedFenceValue);
m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
@@ -836,7 +845,7 @@ namespace Diligent
Atomics::AtomicIncrement(m_NextCmdBuffNumber);
// TODO: rework
auto CompletedFenceValue = pDeviceVkImpl->GetCompletedFenceValue(0);
- ReleaseStaleContextResources(SubmittedCmdBuffNumber, m_LastSubmittedFenceValue, CompletedFenceValue);
+ ReleaseStaleContextResources(m_LastSubmittedFenceValue, CompletedFenceValue);
m_State = ContextState{};
m_DescrSetBindInfo.Reset();
@@ -1460,7 +1469,7 @@ namespace Diligent
// We can now release all temporary resources in the deferred context associated with the submitted command list
// TODO: rework
auto CompletedFenceValue = pDeviceVkImpl->GetCompletedFenceValue(0);
- pDeferredCtxVkImpl->ReleaseStaleContextResources(DeferredCtxCmdBuffNumber, SubmittedFenceValue, CompletedFenceValue);
+ pDeferredCtxVkImpl->ReleaseStaleContextResources(SubmittedFenceValue, CompletedFenceValue);
}
void DeviceContextVkImpl::SignalFence(IFence* pFence, Uint64 Value)
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index a313b44b..f0c8a29e 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -291,12 +291,10 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources)
// TODO: rework this
auto CompletedFenceValue = ReleaseAllResources ? std::numeric_limits<Uint64>::max() : m_CommandQueues[0].CmdQueue->GetCompletedFenceValue();
- PurgeReleaseQueues();
-
m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
m_MemoryMgr.ShrinkMemory();
- m_DynamicMemoryManager.ReleaseStaleBlocks(CompletedFenceValue);
+ PurgeReleaseQueues();
}
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp
index 90e585ba..22ee9227 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp
@@ -146,10 +146,8 @@ VulkanDynamicMemoryManager::MasterBlock VulkanDynamicMemoryManager::AllocateMast
Uint32 SleepIterations = 0;
while (Block.UnalignedOffset == InvalidOffset && IdleDuration < MaxIdleDuration)
{
- // TODO: rework
- auto LastCompletedFenceValue = m_DeviceVk.GetCompletedFenceValue(0);
- ReleaseStaleBlocks(LastCompletedFenceValue);
- Block = AllocateMasterBlock(SizeInBytes, Alignment);
+ m_DeviceVk.PurgeReleaseQueues();
+ Block = TBase::AllocateMasterBlock(SizeInBytes, Alignment);
if (Block.UnalignedOffset == InvalidOffset)
{
std::this_thread::sleep_for(SleepPeriod);
@@ -259,9 +257,9 @@ VulkanDynamicAllocation VulkanDynamicHeap::Allocate(Uint32 SizeInBytes, Uint32 A
return VulkanDynamicAllocation{};
}
-void VulkanDynamicHeap::FinishFrame(Uint64 FenceValue)
+void VulkanDynamicHeap::FinishFrame(RenderDeviceVkImpl& DeviceVkImpl, Uint64 CmdQueueMask)
{
- m_DynamicMemMgr.DiscardMasterBlocks(m_MasterBlocks, FenceValue);
+ m_DynamicMemMgr.ReleaseMasterBlocks(m_MasterBlocks, DeviceVkImpl, CmdQueueMask);
m_MasterBlocks.clear();
m_CurrOffset = InvalidOffset;