summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-06-07 06:44:42 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-06-07 06:44:42 +0000
commit0095c62420fdc1f7a966863b5ea1f06bfb001353 (patch)
treea672183bb053cbaee2c7050b4a2c24580c73692f /Graphics/GraphicsEngineVulkan
parentReworked dynamic upload heap to be managed by every context and to release re... (diff)
downloadDiligentCore-0095c62420fdc1f7a966863b5ea1f06bfb001353.tar.gz
DiligentCore-0095c62420fdc1f7a966863b5ea1f06bfb001353.zip
Reworked dynamic descriptor pools to be owned by device contexts
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h12
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h9
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineLayout.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h19
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp19
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp22
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp124
9 files changed, 84 insertions, 132 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
index 907f369c..822768e0 100644
--- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
+++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
@@ -96,12 +96,10 @@ class DescriptorPoolManager
public:
DescriptorPoolManager(std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
std::vector<VkDescriptorPoolSize> PoolSizes,
- uint32_t MaxSets,
- bool IsThreadSafe)noexcept:
+ uint32_t MaxSets)noexcept:
m_LogicalDevice(std::move(LogicalDevice)),
m_PoolSizes(std::move(PoolSizes)),
- m_MaxSets(MaxSets),
- m_IsThreadSafe(IsThreadSafe)
+ m_MaxSets(MaxSets)
{
CreateNewPool();
}
@@ -111,7 +109,6 @@ public:
DescriptorPoolManager(DescriptorPoolManager&& rhs)noexcept :
m_PoolSizes(std::move(rhs.m_PoolSizes)),
m_MaxSets(std::move(rhs.m_MaxSets)),
- m_IsThreadSafe(std::move(rhs.m_IsThreadSafe)),
//m_Mutex(std::move(rhs.m_Mutex)), mutex is not movable
m_LogicalDevice(std::move(rhs.m_LogicalDevice)),
m_DescriptorPools(std::move(rhs.m_DescriptorPools)),
@@ -119,7 +116,7 @@ public:
{
}
- DescriptorPoolManager(const DescriptorPoolManager&) = delete;
+ DescriptorPoolManager (const DescriptorPoolManager&) = delete;
DescriptorPoolManager& operator = (const DescriptorPoolManager&) = delete;
DescriptorPoolManager& operator = (DescriptorPoolManager&&) = delete;
@@ -135,12 +132,13 @@ private:
const std::vector<VkDescriptorPoolSize> m_PoolSizes;
const uint32_t m_MaxSets;
- const bool m_IsThreadSafe;
std::mutex m_Mutex;
std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> m_LogicalDevice;
std::deque< std::unique_ptr<VulkanUtilities::VulkanDescriptorPool> > m_DescriptorPools;
std::vector< std::pair<VkDescriptorSet, VulkanUtilities::VulkanDescriptorPool*> > m_ReleasedAllocations;
+
+ // When adding new members, do not forget to update move ctor!
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index ccdc62ee..f2c1b0a5 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -35,6 +35,7 @@
#include "VulkanUtilities/VulkanUploadHeap.h"
#include "VulkanDynamicHeap.h"
#include "ResourceReleaseQueue.h"
+#include "DescriptorPoolManager.h"
#ifdef _DEBUG
# define VERIFY_CONTEXT_BINDINGS
@@ -139,6 +140,13 @@ public:
void FinishFrame(Uint64 CompletedFenceValue);
+ DescriptorPoolAllocation AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout)
+ {
+ // Descriptor pools are externally synchronized, meaning that the application must not allocate
+ // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3)
+ return m_DynamicDescriptorPool.Allocate(SetLayout);
+ }
+
private:
void CommitRenderPassAndFramebuffer(class PipelineStateVkImpl *pPipelineStateVk);
void CommitVkVertexBuffers();
@@ -186,6 +194,7 @@ private:
ResourceReleaseQueue<DynamicStaleResourceWrapper> m_ReleaseQueue;
VulkanUtilities::VulkanUploadHeap m_UploadHeap;
+ DescriptorPoolManager m_DynamicDescriptorPool;
// Number of the command buffer currently being recorded by the context and that will
// be submitted next
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
index 7f26427f..b8bdddfc 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h
@@ -78,8 +78,7 @@ public:
// Allocates Vulkan descriptor set for dynamic resources and assigns the
// set to the resource cache
- void AllocateDynamicDescriptorSet(RenderDeviceVkImpl* pDevicVkImpl,
- DeviceContextVkImpl* pCtxVkImpl,
+ void AllocateDynamicDescriptorSet(DeviceContextVkImpl* pCtxVkImpl,
ShaderResourceCacheVk& ResourceCache)const;
// Binds Vulkan descriptor sets to the command buffer in the cmd context
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
index 331e64bf..7aa33423 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
@@ -115,18 +115,12 @@ public:
DescriptorPoolAllocation AllocateDescriptorSet(VkDescriptorSetLayout SetLayout)
{
- return m_DescriptorPools[0].Allocate(SetLayout);
- }
- DescriptorPoolAllocation AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, Uint32 CtxId)
- {
- // Descriptor pools are externally synchronized, meaning that the application must not allocate
- // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3)
- return m_DescriptorPools[1 + CtxId].Allocate(SetLayout);
+ return m_MainDescriptorPool.Allocate(SetLayout);
}
std::shared_ptr<const VulkanUtilities::VulkanInstance> GetVulkanInstance()const{return m_VulkanInstance;}
- const VulkanUtilities::VulkanPhysicalDevice &GetPhysicalDevice(){return *m_PhysicalDevice;}
- const auto &GetLogicalDevice(){return *m_LogicalVkDevice;}
+ const VulkanUtilities::VulkanPhysicalDevice& GetPhysicalDevice(){return *m_PhysicalDevice;}
+ const VulkanUtilities::VulkanLogicalDevice& GetLogicalDevice(){return *m_LogicalVkDevice;}
FramebufferCache& GetFramebufferCache(){return m_FramebufferCache;}
VulkanUtilities::VulkanMemoryAllocation AllocateMemory(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProperties)
@@ -136,7 +130,7 @@ public:
private:
virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final;
- void ProcessReleaseQueue(Uint64 CompletedFenceValue);
+ void ProcessStaleResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue);
// Submits command buffer for execution to the command queue
// Returns the submitted command buffer number and the fence value that has been set to signal by GPU
@@ -186,10 +180,7 @@ private:
FramebufferCache m_FramebufferCache;
- // [0] - Main descriptor pool
- // [1] - Immediate context dynamic descriptor pool
- // [2+] - Deferred context dynamic descriptor pool
- std::vector<DescriptorPoolManager, STDAllocatorRawMem<DescriptorPoolManager> > m_DescriptorPools;
+ DescriptorPoolManager m_MainDescriptorPool;
// These one-time command pools are used by buffer and texture constructors to
// issue copy commands. Vulkan requires that every command pool is used by one thread
diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
index bca37fff..d6c22d8a 100644
--- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
@@ -60,9 +60,7 @@ DescriptorPoolAllocation DescriptorPoolManager::Allocate(VkDescriptorSetLayout S
{
// Descriptor pools are externally synchronized, meaning that the application must not allocate
// and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3)
- std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock);
- if (m_IsThreadSafe)
- Lock.lock();
+ std::lock_guard<std::mutex> Lock(m_Mutex);
// Try all pools starting from the frontmost
for(auto it = m_DescriptorPools.begin(); it != m_DescriptorPools.end(); ++it)
@@ -93,19 +91,13 @@ DescriptorPoolAllocation DescriptorPoolManager::Allocate(VkDescriptorSetLayout S
void DescriptorPoolManager::FreeAllocation(VkDescriptorSet Set, VulkanUtilities::VulkanDescriptorPool& Pool)
{
- std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock);
- if (m_IsThreadSafe)
- Lock.lock();
-
+ std::lock_guard<std::mutex> Lock(m_Mutex);
m_ReleasedAllocations.emplace_back(std::make_pair(Set, &Pool));
}
void DescriptorPoolManager::DisposeAllocations(uint64_t FenceValue)
{
- std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock);
- if (m_IsThreadSafe)
- Lock.lock();
-
+ std::lock_guard<std::mutex> Lock(m_Mutex);
for(auto &Allocation : m_ReleasedAllocations)
{
Allocation.second->DisposeDescriptorSet(Allocation.first, FenceValue);
@@ -115,10 +107,7 @@ void DescriptorPoolManager::DisposeAllocations(uint64_t FenceValue)
void DescriptorPoolManager::ReleaseStaleAllocations(uint64_t LastCompletedFence)
{
- std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock);
- if (m_IsThreadSafe)
- Lock.lock();
-
+ std::lock_guard<std::mutex> Lock(m_Mutex);
for(auto &Pool : m_DescriptorPools)
Pool->ReleaseDiscardedSets(LastCompletedFence);
}
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 8e54e049..84779d77 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -64,6 +64,25 @@ namespace Diligent
bIsDeferred ? Attribs.DeferredCtxUploadHeapPageSize : Attribs.ImmediateCtxUploadHeapPageSize,
bIsDeferred ? Attribs.DeferredCtxUploadHeapReserveSize : Attribs.ImmediateCtxUploadHeapReserveSize
},
+ // Descriptor pools must always be thread-safe as for a deferred context, Finish() may be called from another thread
+ m_DynamicDescriptorPool
+ {
+ pDeviceVkImpl->GetLogicalDevice().GetSharedPtr(),
+ std::vector<VkDescriptorPoolSize>
+ {
+ {VK_DESCRIPTOR_TYPE_SAMPLER, Attribs.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors},
+ {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Attribs.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors},
+ {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, Attribs.DynamicDescriptorPoolSize.NumSampledImageDescriptors},
+ {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, Attribs.DynamicDescriptorPoolSize.NumStorageImageDescriptors},
+ {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, Attribs.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors},
+ {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, Attribs.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors},
+ {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, Attribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors },
+ {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Attribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors },
+ //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, Attribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors },
+ //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, Attribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors },
+ },
+ Attribs.DynamicDescriptorPoolSize.MaxDescriptorSets,
+ },
m_NextCmdBuffNumber(0)
{
#if 0
@@ -752,6 +771,7 @@ namespace Diligent
{
m_ReleaseQueue.Purge(CompletedFenceValue);
m_UploadHeap.ShrinkMemory();
+ m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
}
void DeviceContextVkImpl::ReleaseStaleContextResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue)
@@ -759,6 +779,8 @@ namespace Diligent
m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBufferNumber, SubmittedFenceValue);
m_ReleaseQueue.Purge(CompletedFenceValue);
m_UploadHeap.ShrinkMemory();
+ m_DynamicDescriptorPool.DisposeAllocations(SubmittedFenceValue);
+ m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
}
void DeviceContextVkImpl::Flush()
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
index c5bac746..e5d356f9 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
@@ -406,14 +406,13 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl *pDeviceVkImpl, Shader
}
}
-void PipelineLayout::AllocateDynamicDescriptorSet(RenderDeviceVkImpl* pDevicVkImpl,
- DeviceContextVkImpl* pCtxVkImpl,
+void PipelineLayout::AllocateDynamicDescriptorSet(DeviceContextVkImpl* pCtxVkImpl,
ShaderResourceCacheVk& ResourceCache)const
{
const auto &DynSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_DYNAMIC);
if (DynSet.SetIndex >= 0)
{
- auto DynamicSetAllocation = pDevicVkImpl->AllocateDynamicDescriptorSet(DynSet.VkLayout, pCtxVkImpl->GetContextId());
+ auto DynamicSetAllocation = pCtxVkImpl->AllocateDynamicDescriptorSet(DynSet.VkLayout);
auto &DynamicSetCache = ResourceCache.GetDescriptorSet(DynSet.SetIndex);
DynamicSetCache.AssignDescriptorSetAllocation(std::move(DynamicSetAllocation));
}
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 3cdd2b62..8874b0b7 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -557,9 +557,8 @@ ShaderResourceCacheVk* PipelineStateVkImpl::CommitAndTransitionShaderResources(I
#endif
}
- auto *pDeviceVkImpl = ValidatedCast<RenderDeviceVkImpl>(GetDevice());
// Allocate vulkan descriptor set for dynamic resources
- m_PipelineLayout.AllocateDynamicDescriptorSet(pDeviceVkImpl, pCtxVkImpl, ResourceCache);
+ m_PipelineLayout.AllocateDynamicDescriptorSet(pCtxVkImpl, ResourceCache);
// Commit all dynamic resource descriptors
for(Uint32 s=0; s < m_NumShaders; ++s)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 104089a7..6e98bd1b 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -66,27 +66,12 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters*
m_EngineAttribs(CreationAttribs),
m_FrameNumber(0),
m_NextCmdBuffNumber(0),
- /*m_CmdListManager(this),
- m_ContextPool(STD_ALLOCATOR_RAW_MEM(ContextPoolElemType, GetRawAllocator(), "Allocator for vector<unique_ptr<CommandContext>>")),
- m_AvailableContexts(STD_ALLOCATOR_RAW_MEM(CommandContext*, GetRawAllocator(), "Allocator for vector<CommandContext*>")),*/
- m_DescriptorPools(STD_ALLOCATOR_RAW_MEM(DescriptorPoolManager, GetRawAllocator(), "Allocator for vector<DescriptorPoolManager>")),
m_FramebufferCache(*this),
- m_TransientCmdPoolMgr(*m_LogicalVkDevice, pCmdQueue->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT),
- m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), CreationAttribs.DeviceLocalMemoryPageSize, CreationAttribs.HostVisibleMemoryPageSize, CreationAttribs.DeviceLocalMemoryReserveSize, CreationAttribs.HostVisibleMemoryReserveSize),
- m_ReleaseQueue(GetRawAllocator())
-{
- m_DeviceCaps.DevType = DeviceType::Vulkan;
- m_DeviceCaps.MajorVersion = 1;
- m_DeviceCaps.MinorVersion = 0;
- m_DeviceCaps.bSeparableProgramSupported = True;
- m_DeviceCaps.bMultithreadedResourceCreationSupported = True;
- for(int fmt = 1; fmt < m_TextureFormatsInfo.size(); ++fmt)
- m_TextureFormatsInfo[fmt].Supported = true; // We will test every format on a specific hardware device
-
- m_DescriptorPools.reserve(2 + NumDeferredContexts);
- m_DescriptorPools.emplace_back(
+ m_MainDescriptorPool
+ {
m_LogicalVkDevice,
- std::vector<VkDescriptorPoolSize>{
+ std::vector<VkDescriptorPoolSize>
+ {
{VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumSeparateSamplerDescriptors},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumCombinedSamplerDescriptors},
{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.MainDescriptorPoolSize.NumSampledImageDescriptors},
@@ -98,30 +83,19 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters*
//{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumUniformBufferDescriptors },
//{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumStorageBufferDescriptors },
},
- CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets,
- true // Thread-safe
- );
-
- for(Uint32 ctx = 0; ctx < 1 + NumDeferredContexts; ++ctx)
- {
- m_DescriptorPools.emplace_back(
- m_LogicalVkDevice,
- std::vector<VkDescriptorPoolSize>{
- {VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors},
- {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors},
- {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumSampledImageDescriptors},
- {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumStorageImageDescriptors},
- {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors},
- {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors},
- {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors },
- {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors },
- //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors },
- //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors },
- },
- CreationAttribs.DynamicDescriptorPoolSize.MaxDescriptorSets,
- false // Dynamic descriptor pools need not to be thread-safe
- );
- }
+ CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets
+ },
+ m_TransientCmdPoolMgr(*m_LogicalVkDevice, pCmdQueue->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT),
+ m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), CreationAttribs.DeviceLocalMemoryPageSize, CreationAttribs.HostVisibleMemoryPageSize, CreationAttribs.DeviceLocalMemoryReserveSize, CreationAttribs.HostVisibleMemoryReserveSize),
+ m_ReleaseQueue(GetRawAllocator())
+{
+ m_DeviceCaps.DevType = DeviceType::Vulkan;
+ m_DeviceCaps.MajorVersion = 1;
+ m_DeviceCaps.MinorVersion = 0;
+ m_DeviceCaps.bSeparableProgramSupported = True;
+ m_DeviceCaps.bMultithreadedResourceCreationSupported = True;
+ for(int fmt = 1; fmt < m_TextureFormatsInfo.size(); ++fmt)
+ m_TextureFormatsInfo[fmt].Supported = true; // We will test every format on a specific hardware device
}
RenderDeviceVkImpl::~RenderDeviceVkImpl()
@@ -136,10 +110,6 @@ RenderDeviceVkImpl::~RenderDeviceVkImpl()
// release queues
FinishFrame(true);
-#if 0
- m_ContextPool.clear();
-#endif
-
m_TransientCmdPoolMgr.DestroyPools(m_pCommandQueue->GetCompletedFenceValue());
//if(m_PhysicalDevice)
@@ -260,35 +230,22 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo,
// As long as resources used by deferred contexts are not released until the command list
// is executed through immediate context, this stategy always works.
- m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue);
auto CompletedFenceValue = GetCompletedFenceValue();
- ProcessReleaseQueue(CompletedFenceValue);
- m_MemoryMgr.ShrinkMemory();
+ ProcessStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue, CompletedFenceValue);
-#if 0
- // DiscardAllocator() is thread-safe
- m_CmdListManager.DiscardAllocator(FenceValue, pAllocator);
-
- pCtx->DiscardDynamicDescriptors(FenceValue);
-
- {
- std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex);
- m_AvailableContexts.push_back(pCtx);
- }
-#endif
return SubmittedFenceValue;
}
void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects)
{
- Uint64 FenceValue = 0;
- Uint64 CmdBuffNumber = 0;
+ Uint64 SubmittedFenceValue = 0;
+ Uint64 SubmittedCmdBuffNumber = 0;
{
// Lock the command queue to avoid other threads interfering with the GPU
std::lock_guard<std::mutex> LockGuard(m_CmdQueueMutex);
- FenceValue = m_pCommandQueue->GetNextFenceValue();
+ SubmittedFenceValue = m_pCommandQueue->GetNextFenceValue();
m_pCommandQueue->IdleGPU();
m_LogicalVkDevice->WaitIdle();
@@ -296,7 +253,7 @@ void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects)
// Increment cmd list number while keeping queue locked.
// This guarantees that any Vk object released after the lock
// is released, will be associated with the incremented cmd list number
- CmdBuffNumber = m_NextCmdBuffNumber;
+ SubmittedCmdBuffNumber = m_NextCmdBuffNumber;
Atomics::AtomicIncrement(m_NextCmdBuffNumber);
}
@@ -306,11 +263,10 @@ void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects)
// This is necessary to release outstanding references to the
// swap chain buffers when it is resized in the middle of the frame.
// Since GPU has been idled, it it is safe to do so
- m_ReleaseQueue.DiscardStaleResources(CmdBuffNumber, FenceValue);
- // FenceValue has now been signaled by the GPU since we waited for it
- auto CompletedFenceValue = FenceValue;
- ProcessReleaseQueue(CompletedFenceValue);
- m_MemoryMgr.ShrinkMemory();
+
+ // SubmittedFenceValue has now been signaled by the GPU since we waited for it
+ auto CompletedFenceValue = SubmittedFenceValue;
+ ProcessStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue, CompletedFenceValue);
}
}
@@ -368,33 +324,23 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources)
Atomics::AtomicIncrement(m_NextCmdBuffNumber);
}
- {
- // This is OK if other thread disposes descriptor heap allocation at this time
- // The allocation will be registered as part of the current frame
- for(auto &Pool : m_DescriptorPools)
- Pool.DisposeAllocations(NextFenceValue);
- }
-
// Discard all remaining objects. This is important to do if there were
- // no command lists submitted during the frame
- m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBuffNumber, NextFenceValue);
- ProcessReleaseQueue(CompletedFenceValue);
- m_MemoryMgr.ShrinkMemory();
+ // no command lists submitted during the frame. All stale resources will
+ // be associated with the next fence value and thus will not be released
+ // until the next command list is finished by the GPU
+ ProcessStaleResources(SubmittedCmdBuffNumber, NextFenceValue, CompletedFenceValue);
+
Atomics::AtomicIncrement(m_FrameNumber);
}
-void RenderDeviceVkImpl::ProcessReleaseQueue(Uint64 CompletedFenceValue)
+void RenderDeviceVkImpl::ProcessStaleResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue)
{
+ m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBufferNumber, SubmittedFenceValue);
m_ReleaseQueue.Purge(CompletedFenceValue);
-
- {
- // This is OK if other thread disposes descriptor heap allocation at this time
- // The allocation will be registered as part of the current frame
- for(auto &Pool : m_DescriptorPools)
- Pool.ReleaseStaleAllocations(CompletedFenceValue);
- }
+ m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
+ m_MemoryMgr.ShrinkMemory();
}