summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-09-24 03:30:58 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-09-24 03:30:58 +0000
commitef04580d047c3d4e1b34c76c2af8fd6f333af6ff (patch)
tree8a71c47ef642952e7886bbec5ba4279e0459e215 /Graphics/GraphicsEngineVulkan
parentFixed build - attempt 2 (diff)
downloadDiligentCore-ef04580d047c3d4e1b34c76c2af8fd6f333af6ff.tar.gz
DiligentCore-ef04580d047c3d4e1b34c76c2af8fd6f333af6ff.zip
Reworked dynamic descriptor set allocation/deallocation in Vk backend
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/CMakeLists.txt2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h185
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h8
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h12
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h68
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp202
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp66
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp36
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp87
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp16
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp2
16 files changed, 357 insertions, 346 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
index 0a67939f..e7ab3e44 100644
--- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt
+++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt
@@ -37,7 +37,6 @@ set(VULKAN_UTILS_INCLUDE
include/VulkanUtilities/VulkanCommandBuffer.h
include/VulkanUtilities/VulkanCommandBufferPool.h
include/VulkanUtilities/VulkanDebug.h
- include/VulkanUtilities/VulkanDescriptorPool.h
include/VulkanUtilities/VulkanFencePool.h
include/VulkanUtilities/VulkanInstance.h
include/VulkanUtilities/VulkanLogicalDevice.h
@@ -98,7 +97,6 @@ set(VULKAN_UTILS_SRC
src/VulkanUtilities/VulkanCommandBuffer.cpp
src/VulkanUtilities/VulkanCommandBufferPool.cpp
src/VulkanUtilities/VulkanDebug.cpp
- src/VulkanUtilities/VulkanDescriptorPool.cpp
src/VulkanUtilities/VulkanFencePool.cpp
src/VulkanUtilities/VulkanInstance.cpp
src/VulkanUtilities/VulkanLogicalDevice.cpp
diff --git a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h
index 6b27d2b4..2f597702 100644
--- a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h
+++ b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h
@@ -26,7 +26,7 @@
#include <deque>
#include <mutex>
#include "STDAllocator.h"
-#include "VulkanUtilities/VulkanDescriptorPool.h"
+#include "VulkanUtilities/VulkanLogicalDevice.h"
namespace Diligent
{
diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
index 4df8d9f7..0ea4f7eb 100644
--- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
+++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h
@@ -29,56 +29,54 @@
#include <vector>
#include <deque>
#include <mutex>
-#include "VulkanUtilities/VulkanDescriptorPool.h"
+#include "VulkanUtilities/VulkanObjectWrappers.h"
namespace Diligent
{
-class DescriptorPoolManager;
+class DescriptorSetAllocator;
+class RenderDeviceVkImpl;
-class DescriptorPoolAllocation
+// This class manages descriptor set allocation.
+// The class destructor calls DescriptorSetAllocator::FreeDescriptorSet() that moves
+// the set into the release queue.
+class DescriptorSetAllocation
{
public:
- DescriptorPoolAllocation(VkDescriptorSet _Set,
- Uint64 _CmdQueueMask,
- VulkanUtilities::VulkanDescriptorPool& _ParentPool,
- DescriptorPoolManager& _ParentPoolMgr)noexcept :
- Set (_Set),
- CmdQueueMask(_CmdQueueMask),
- ParentPool (&_ParentPool),
- ParentPoolMgr(&_ParentPoolMgr)
+ DescriptorSetAllocation(VkDescriptorSet _Set,
+ VkDescriptorPool _Pool,
+ Uint64 _CmdQueueMask,
+ DescriptorSetAllocator& _DescrSetAllocator)noexcept :
+ Set (_Set),
+ Pool (_Pool),
+ CmdQueueMask (_CmdQueueMask),
+ DescrSetAllocator(&_DescrSetAllocator)
{}
- DescriptorPoolAllocation()noexcept{}
+ DescriptorSetAllocation()noexcept{}
- DescriptorPoolAllocation (const DescriptorPoolAllocation&) = delete;
- DescriptorPoolAllocation& operator = (const DescriptorPoolAllocation&) = delete;
+ DescriptorSetAllocation (const DescriptorSetAllocation&) = delete;
+ DescriptorSetAllocation& operator = (const DescriptorSetAllocation&) = delete;
- DescriptorPoolAllocation(DescriptorPoolAllocation&& rhs)noexcept :
- Set (rhs.Set),
- CmdQueueMask (rhs.CmdQueueMask),
- ParentPool (rhs.ParentPool),
- ParentPoolMgr(rhs.ParentPoolMgr)
+ DescriptorSetAllocation(DescriptorSetAllocation&& rhs)noexcept :
+ Set (rhs.Set),
+ CmdQueueMask (rhs.CmdQueueMask),
+ Pool (rhs.Pool),
+ DescrSetAllocator(rhs.DescrSetAllocator)
{
- rhs.Set = VK_NULL_HANDLE;
- rhs.CmdQueueMask = 0;
- rhs.ParentPool = nullptr;
- rhs.ParentPoolMgr = nullptr;
+ rhs.Reset();
}
- DescriptorPoolAllocation& operator = (DescriptorPoolAllocation&& rhs)noexcept
+ DescriptorSetAllocation& operator = (DescriptorSetAllocation&& rhs)noexcept
{
Release();
- Set = rhs.Set;
- CmdQueueMask = rhs.CmdQueueMask;
- ParentPool = rhs.ParentPool;
- ParentPoolMgr = rhs.ParentPoolMgr;
+ Set = rhs.Set;
+ CmdQueueMask = rhs.CmdQueueMask;
+ Pool = rhs.Pool;
+ DescrSetAllocator = rhs.DescrSetAllocator;
+
+ rhs.Reset();
- rhs.Set = VK_NULL_HANDLE;
- rhs.CmdQueueMask = 0;
- rhs.ParentPool = nullptr;
- rhs.ParentPoolMgr = nullptr;
-
return *this;
}
@@ -87,9 +85,17 @@ public:
return Set != VK_NULL_HANDLE;
}
+ void Reset()
+ {
+ Set = VK_NULL_HANDLE;
+ Pool = VK_NULL_HANDLE;
+ CmdQueueMask = 0;
+ DescrSetAllocator = nullptr;
+ }
+
void Release();
- ~DescriptorPoolAllocation()
+ ~DescriptorSetAllocation()
{
Release();
}
@@ -97,66 +103,97 @@ public:
VkDescriptorSet GetVkDescriptorSet()const {return Set;}
private:
- VkDescriptorSet Set = VK_NULL_HANDLE;
- Uint64 CmdQueueMask = 0;
- VulkanUtilities::VulkanDescriptorPool* ParentPool = nullptr;
- DescriptorPoolManager* ParentPoolMgr = nullptr;
+ VkDescriptorSet Set = VK_NULL_HANDLE;
+ VkDescriptorPool Pool = VK_NULL_HANDLE;
+ Uint64 CmdQueueMask = 0;
+ DescriptorSetAllocator* DescrSetAllocator = nullptr;
};
+// The class manages pool of descriptor set pools
class DescriptorPoolManager
{
public:
- DescriptorPoolManager(std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
- std::vector<VkDescriptorPoolSize> PoolSizes,
- uint32_t MaxSets) noexcept:
- m_LogicalDevice(std::move(LogicalDevice)),
- m_PoolSizes (std::move(PoolSizes)),
- m_MaxSets (MaxSets)
- {
- CreateNewPool();
- }
-
- // Move constructor must be noexcept, otherwise vector<DescriptorPoolManager> will fail to compile on MSVC
- // So we have to implement it manually. = default also does not work
- DescriptorPoolManager(DescriptorPoolManager&& rhs)noexcept :
- m_PoolSizes (std::move(rhs.m_PoolSizes)),
- m_MaxSets (std::move(rhs.m_MaxSets)),
- //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)),
- m_ReleasedAllocations(std::move(rhs.m_ReleasedAllocations))
+ DescriptorPoolManager(RenderDeviceVkImpl& DeviceVkImpl,
+ std::string PoolName,
+ std::vector<VkDescriptorPoolSize> PoolSizes,
+ uint32_t MaxSets,
+ bool AllowFreeing) noexcept:
+ m_DeviceVkImpl(DeviceVkImpl),
+ m_PoolName (std::move(PoolName)),
+ m_PoolSizes (std::move(PoolSizes)),
+ m_MaxSets (MaxSets),
+ m_AllowFreeing(AllowFreeing)
{
}
+ ~DescriptorPoolManager();
DescriptorPoolManager (const DescriptorPoolManager&) = delete;
DescriptorPoolManager& operator = (const DescriptorPoolManager&) = delete;
+ DescriptorPoolManager (DescriptorPoolManager&&) = delete;
DescriptorPoolManager& operator = (DescriptorPoolManager&&) = delete;
+
+ VulkanUtilities::DescriptorPoolWrapper GetPool(const char* DebugName);
+ void FreePool(VulkanUtilities::DescriptorPoolWrapper&& Pool);
+
+protected:
+ friend class DynamicDescriptorSetAllocator;
+ VulkanUtilities::DescriptorPoolWrapper CreateDescriptorPool(const char* DebugName);
- DescriptorPoolAllocation Allocate(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout);
- void DisposeAllocations(uint64_t FenceValue);
- void ReleaseStaleAllocations(uint64_t LastCompletedFence);
+ RenderDeviceVkImpl& m_DeviceVkImpl;
+ const std::string m_PoolName;
+
+ const std::vector<VkDescriptorPoolSize> m_PoolSizes;
+ const uint32_t m_MaxSets;
+ const bool m_AllowFreeing;
- size_t GetStaleAllocationCount()const
+ std::mutex m_Mutex;
+ std::deque< VulkanUtilities::DescriptorPoolWrapper > m_Pools;
+};
+
+// The class allocates descriptors from the main descriptor pool.
+// Descriptors can be released and returned to the pool
+class DescriptorSetAllocator : public DescriptorPoolManager
+{
+public:
+ friend class DescriptorSetAllocation;
+ DescriptorSetAllocator(RenderDeviceVkImpl& DeviceVkImpl,
+ std::string PoolName,
+ std::vector<VkDescriptorPoolSize> PoolSizes,
+ uint32_t MaxSets,
+ bool AllowFreeing) noexcept:
+ DescriptorPoolManager(DeviceVkImpl, std::move(PoolName), std::move(PoolSizes), MaxSets, AllowFreeing)
{
- return m_ReleasedAllocations.size();
}
- size_t GetPendingReleaseAllocationCount();
-private:
- friend class DescriptorPoolAllocation;
- void FreeAllocation(VkDescriptorSet Set, VulkanUtilities::VulkanDescriptorPool& Pool);
+ DescriptorSetAllocation Allocate(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout);
- void CreateNewPool();
+private:
+ void FreeDescriptorSet(VkDescriptorSet Set, VkDescriptorPool Pool, Uint64 QueueMask);
+};
- const std::vector<VkDescriptorPoolSize> m_PoolSizes;
- const uint32_t m_MaxSets;
+// The class manages dynamic descriptor sets. It first requests descriptor pool from
+// the global manager and performs allocations from this pool. When space in the pool is exhausted,
+// the class requests new pool.
+// The class is not thread-safe as device contexts must not be used in multiple threads at the same time.
+// Entire pools are recycled at the end of every frame.
+class DynamicDescriptorSetAllocator
+{
+public:
+ DynamicDescriptorSetAllocator(DescriptorPoolManager& PoolMgr, std::string Name) :
+ m_PoolMgr(PoolMgr),
+ m_Name(std::move(Name))
+ {}
+ ~DynamicDescriptorSetAllocator();
- 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;
+ VkDescriptorSet Allocate(VkDescriptorSetLayout SetLayout, const char* DebugName);
+ void ReleasePools(Uint64 QueueMask);
+ size_t GetAllocatedPoolCount()const{return m_AllocatedPools.size();}
- // When adding new members, do not forget to update move ctor!
+private:
+ DescriptorPoolManager& m_PoolMgr;
+ const std::string m_Name;
+ std::vector<VulkanUtilities::DescriptorPoolWrapper> m_AllocatedPools;
+ size_t m_PeakPoolCount = 0;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index 1c701a7d..ae443b34 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -166,11 +166,11 @@ public:
virtual void FinishFrame(bool ForceRelease)override final;
void FinishFrame(Uint64 CompletedFenceValue);
- DescriptorPoolAllocation AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout)
+ VkDescriptorSet 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( Uint64{1} << Uint64{m_CommandQueueId}, SetLayout);
+ return m_DynamicDescrSetAllocator.Allocate(SetLayout, "");
}
VulkanDynamicAllocation AllocateDynamicSpace(Uint32 SizeInBytes, Uint32 Alignment);
@@ -291,8 +291,8 @@ private:
- VulkanUploadHeap m_UploadHeap;
- DescriptorPoolManager m_DynamicDescriptorPool;
+ VulkanUploadHeap m_UploadHeap;
+ DynamicDescriptorSetAllocator m_DynamicDescrSetAllocator;
// Number of the command buffer currently being recorded by the context and that will
// be submitted next
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
index a1072089..d326e0f6 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
@@ -101,10 +101,11 @@ public:
void FinishFrame(bool ReleaseAllResources);
virtual void FinishFrame()override final { FinishFrame(false); }
- DescriptorPoolAllocation AllocateDescriptorSet(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout)
+ DescriptorSetAllocation AllocateDescriptorSet(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout)
{
- return m_MainDescriptorPool.Allocate(CommandQueueMask, SetLayout);
+ return m_DescriptorSetAllocator.Allocate(CommandQueueMask, SetLayout);
}
+ DescriptorPoolManager& GetDynamicDescriptorPool(){return m_DynamicDescriptorPool;}
std::shared_ptr<const VulkanUtilities::VulkanInstance> GetVulkanInstance()const{return m_VulkanInstance;}
const VulkanUtilities::VulkanPhysicalDevice& GetPhysicalDevice()const {return *m_PhysicalDevice;}
@@ -137,9 +138,10 @@ private:
EngineVkAttribs m_EngineAttribs;
- FramebufferCache m_FramebufferCache;
- RenderPassCache m_RenderPassCache;
- DescriptorPoolManager m_MainDescriptorPool;
+ FramebufferCache m_FramebufferCache;
+ RenderPassCache m_RenderPassCache;
+ DescriptorSetAllocator m_DescriptorSetAllocator;
+ DescriptorPoolManager m_DynamicDescriptorPool;
// 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/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
index 1531d851..36d58469 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h
@@ -140,7 +140,7 @@ public:
return m_DescriptorSetAllocation.GetVkDescriptorSet();
}
- void AssignDescriptorSetAllocation(DescriptorPoolAllocation&& Allocation)
+ void AssignDescriptorSetAllocation(DescriptorSetAllocation&& Allocation)
{
VERIFY(m_NumResources > 0, "Descriptor set is empty");
m_DescriptorSetAllocation = std::move(Allocation);
@@ -150,7 +150,7 @@ public:
private:
Resource* const m_pResources = nullptr;
- DescriptorPoolAllocation m_DescriptorSetAllocation;
+ DescriptorSetAllocation m_DescriptorSetAllocation;
};
inline DescriptorSet& GetDescriptorSet(Uint32 Index)
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h
deleted file mode 100644
index 7a429147..00000000
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDescriptorPool.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2015-2018 Egor Yusov
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
-*
-* In no event and under no legal theory, whether in tort (including negligence),
-* contract, or otherwise, unless required by applicable law (such as deliberate
-* and grossly negligent acts) or agreed to in writing, shall any Contributor be
-* liable for any damages, including any direct, indirect, special, incidental,
-* or consequential damages of any character arising as a result of this License or
-* out of the use or inability to use the software (including but not limited to damages
-* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
-* all other commercial damages or losses), even if such Contributor has been advised
-* of the possibility of such damages.
-*/
-
-#pragma once
-
-#include <deque>
-#include <memory>
-#include "vulkan.h"
-#include "VulkanLogicalDevice.h"
-#include "VulkanObjectWrappers.h"
-
-namespace VulkanUtilities
-{
- class VulkanDescriptorPool
- {
- public:
- VulkanDescriptorPool(std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
- const VkDescriptorPoolCreateInfo& DescriptorPoolCI);
-
- VulkanDescriptorPool (const VulkanDescriptorPool&) = delete;
- VulkanDescriptorPool& operator = (const VulkanDescriptorPool&) = delete;
- VulkanDescriptorPool (VulkanDescriptorPool&&) = default;
- VulkanDescriptorPool& operator = (VulkanDescriptorPool&&) = default;
- ~VulkanDescriptorPool();
-
- VkDescriptorSet AllocateDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = "");
- void DisposeDescriptorSet(VkDescriptorSet DescrSet, uint64_t FenceValue);
- void ReleaseDiscardedSets(uint64_t LastCompletedFence);
-
- DescriptorPoolWrapper&& Release();
-
- size_t GetDiscardedSetCount()const
- {
- return m_DiscardedSets.size();
- }
-
- private:
- // Shared point to logical device must be defined before the command pool
- std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> m_LogicalDevice;
- DescriptorPoolWrapper m_Pool;
-
- // fist - the fence value associated with the command buffer referencing the set
- // when it was executed
- // second - the descriptor set
- typedef std::pair<uint64_t, VkDescriptorSet > QueueElemType;
- std::deque< QueueElemType > m_DiscardedSets;
- };
-}
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h
index 6fd7e33c..a9cf747d 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h
@@ -123,6 +123,9 @@ namespace VulkanUtilities
VkResult ResetCommandPool(VkCommandPool vkCmdPool,
VkCommandPoolResetFlags flags = 0)const;
+ VkResult ResetDescriptorPool(VkDescriptorPool descriptorPool,
+ VkDescriptorPoolResetFlags flags = 0)const;
+
private:
VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice,
const VkDeviceCreateInfo &DeviceCI,
diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
index fe6e9c9f..f05894e8 100644
--- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp
@@ -28,20 +28,18 @@
namespace Diligent
{
-void DescriptorPoolAllocation::Release()
+void DescriptorSetAllocation::Release()
{
if (Set != VK_NULL_HANDLE)
{
- VERIFY_EXPR(ParentPoolMgr != nullptr && ParentPool != nullptr);
- ParentPoolMgr->FreeAllocation(Set, *ParentPool);
+ VERIFY_EXPR(DescrSetAllocator != nullptr && Pool != nullptr);
+ DescrSetAllocator->FreeDescriptorSet(Set, Pool, CmdQueueMask);
- Set = VK_NULL_HANDLE;
- ParentPoolMgr = nullptr;
- ParentPool = nullptr;
+ Reset();
}
}
-void DescriptorPoolManager::CreateNewPool()
+VulkanUtilities::DescriptorPoolWrapper DescriptorPoolManager::CreateDescriptorPool(const char* DebugName)
{
VkDescriptorPoolCreateInfo PoolCI = {};
PoolCI.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
@@ -49,77 +47,201 @@ void DescriptorPoolManager::CreateNewPool()
// VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT specifies that descriptor sets can
// return their individual allocations to the pool, i.e. all of vkAllocateDescriptorSets,
// vkFreeDescriptorSets, and vkResetDescriptorPool are allowed. (13.2.3)
- PoolCI.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+ PoolCI.flags = m_AllowFreeing ? VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT : 0;
PoolCI.maxSets = m_MaxSets;
PoolCI.poolSizeCount = static_cast<uint32_t>(m_PoolSizes.size());
PoolCI.pPoolSizes = m_PoolSizes.data();
- m_DescriptorPools.emplace_front( new VulkanUtilities::VulkanDescriptorPool(m_LogicalDevice, PoolCI) );
+ return m_DeviceVkImpl.GetLogicalDevice().CreateDescriptorPool(PoolCI, DebugName);
}
-DescriptorPoolAllocation DescriptorPoolManager::Allocate(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout)
+DescriptorPoolManager::~DescriptorPoolManager()
+{
+ LOG_INFO_MESSAGE(m_PoolName, " stats: allocated ", m_Pools.size(), " pool(s)");
+}
+
+VulkanUtilities::DescriptorPoolWrapper DescriptorPoolManager::GetPool(const char* DebugName)
+{
+ std::lock_guard<std::mutex> Lock(m_Mutex);
+ if (m_Pools.empty())
+ return CreateDescriptorPool(DebugName);
+ else
+ {
+ auto& LogicalDevice = m_DeviceVkImpl.GetLogicalDevice();
+ auto Pool = std::move(m_Pools.front());
+ VulkanUtilities::SetDescriptorPoolName(LogicalDevice.GetVkDevice(), Pool, DebugName);
+ m_Pools.pop_front();
+ return Pool;
+ }
+}
+
+void DescriptorPoolManager::FreePool(VulkanUtilities::DescriptorPoolWrapper&& Pool)
+{
+ std::lock_guard<std::mutex> Lock(m_Mutex);
+ m_DeviceVkImpl.GetLogicalDevice().ResetDescriptorPool(Pool);
+ m_Pools.emplace_back(std::move(Pool));
+}
+
+
+static VkDescriptorSet AllocateDescriptorSet(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice,
+ VkDescriptorPool Pool,
+ VkDescriptorSetLayout SetLayout,
+ const char* DebugName)
+{
+ VkDescriptorSetAllocateInfo DescrSetAllocInfo = {};
+ DescrSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ DescrSetAllocInfo.pNext = nullptr;
+ DescrSetAllocInfo.descriptorPool = Pool;
+ DescrSetAllocInfo.descriptorSetCount = 1;
+ DescrSetAllocInfo.pSetLayouts = &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 LogicalDevice.AllocateVkDescriptorSet(DescrSetAllocInfo, DebugName);
+}
+
+
+DescriptorSetAllocation DescriptorSetAllocator::Allocate(Uint64 CommandQueueMask, 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)
std::lock_guard<std::mutex> Lock(m_Mutex);
+ const auto& LogicalDevice = m_DeviceVkImpl.GetLogicalDevice();
// Try all pools starting from the frontmost
- for(auto it = m_DescriptorPools.begin(); it != m_DescriptorPools.end(); ++it)
+ for(auto it = m_Pools.begin(); it != m_Pools.end(); ++it)
{
- auto& Pool = *(*it);
- auto Set = Pool.AllocateDescriptorSet(SetLayout);
- if(Set != VK_NULL_HANDLE)
+ auto& Pool = *it;
+ auto Set = AllocateDescriptorSet(LogicalDevice, Pool, SetLayout, "Descriptor set");
+ if (Set != VK_NULL_HANDLE)
{
// Move the pool to the front
- if(it != m_DescriptorPools.begin())
+ if (it != m_Pools.begin())
{
- std::swap(*it, m_DescriptorPools.front());
+ std::swap(*it, m_Pools.front());
}
- return {Set, CommandQueueMask, Pool, *this};
+ return {Set, Pool, CommandQueueMask, *this};
}
}
// Failed to allocate descriptor from existing pools -> create a new one
- CreateNewPool();
LOG_INFO_MESSAGE("Allocated new descriptor pool");
+ m_Pools.emplace_front(CreateDescriptorPool("Descriptor pool"));
- auto &NewPool = *m_DescriptorPools.front();
- auto Set = NewPool.AllocateDescriptorSet(SetLayout);
+ auto& NewPool = m_Pools.front();
+ auto Set = AllocateDescriptorSet(LogicalDevice, NewPool, SetLayout, "");
VERIFY(Set != VK_NULL_HANDLE, "Failed to allocate descriptor set");
- return {Set, CommandQueueMask, NewPool, *this };
+ return {Set, NewPool, CommandQueueMask, *this };
}
-void DescriptorPoolManager::FreeAllocation(VkDescriptorSet Set, VulkanUtilities::VulkanDescriptorPool& Pool)
+void DescriptorSetAllocator::FreeDescriptorSet(VkDescriptorSet Set, VkDescriptorPool Pool, Uint64 QueueMask)
{
- std::lock_guard<std::mutex> Lock(m_Mutex);
- m_ReleasedAllocations.emplace_back(std::make_pair(Set, &Pool));
+ class DescriptorSetDeleter
+ {
+ public:
+ DescriptorSetDeleter(DescriptorSetAllocator& _Allocator,
+ VkDescriptorSet _Set,
+ VkDescriptorPool _Pool) :
+ Allocator (&_Allocator),
+ Set (_Set),
+ Pool (_Pool)
+ {}
+
+ DescriptorSetDeleter (const DescriptorSetDeleter&) = delete;
+ DescriptorSetDeleter& operator = (const DescriptorSetDeleter&) = delete;
+ DescriptorSetDeleter& operator = ( DescriptorSetDeleter&&)= delete;
+
+ DescriptorSetDeleter(DescriptorSetDeleter&& rhs)noexcept :
+ Allocator (rhs.Allocator),
+ Set (rhs.Set),
+ Pool (rhs.Pool)
+ {
+ rhs.Allocator = nullptr;
+ rhs.Set = nullptr;
+ rhs.Pool = nullptr;
+ }
+
+ ~DescriptorSetDeleter()
+ {
+ if (Allocator!=nullptr)
+ {
+ std::lock_guard<std::mutex> Lock(Allocator->m_Mutex);
+ Allocator->m_DeviceVkImpl.GetLogicalDevice().FreeDescriptorSet(Pool, Set);
+ }
+ }
+
+ private:
+ DescriptorSetAllocator* Allocator;
+ VkDescriptorSet Set;
+ VkDescriptorPool Pool;
+ };
+ m_DeviceVkImpl.SafeReleaseDeviceObject(DescriptorSetDeleter{*this, Set, Pool}, QueueMask);
}
-void DescriptorPoolManager::DisposeAllocations(uint64_t FenceValue)
+
+VkDescriptorSet DynamicDescriptorSetAllocator::Allocate(VkDescriptorSetLayout SetLayout, const char* DebugName)
{
- std::lock_guard<std::mutex> Lock(m_Mutex);
- for(auto &Allocation : m_ReleasedAllocations)
+ VkDescriptorSet set = VK_NULL_HANDLE;
+ const auto& LogicalDevice = m_PoolMgr.m_DeviceVkImpl.GetLogicalDevice();
+ if (!m_AllocatedPools.empty())
{
- Allocation.second->DisposeDescriptorSet(Allocation.first, FenceValue);
+ set = AllocateDescriptorSet(LogicalDevice, m_AllocatedPools.back(), SetLayout, DebugName);
}
- m_ReleasedAllocations.clear();
+
+ if (set == VK_NULL_HANDLE)
+ {
+ m_AllocatedPools.emplace_back(m_PoolMgr.GetPool("Dynamic Descriptor Pool"));
+ set = AllocateDescriptorSet(LogicalDevice, m_AllocatedPools.back(), SetLayout, DebugName);
+ }
+
+ return set;
}
-void DescriptorPoolManager::ReleaseStaleAllocations(uint64_t LastCompletedFence)
+void DynamicDescriptorSetAllocator::ReleasePools(Uint64 QueueMask)
{
- std::lock_guard<std::mutex> Lock(m_Mutex);
- for(auto &Pool : m_DescriptorPools)
- Pool->ReleaseDiscardedSets(LastCompletedFence);
+ class DescriptorPoolDeleter
+ {
+ public:
+ DescriptorPoolDeleter(DescriptorPoolManager& _PoolMgr,
+ VulkanUtilities::DescriptorPoolWrapper&& _Pool) :
+ PoolMgr (&_PoolMgr),
+ Pool (std::move(_Pool))
+ {}
+
+ DescriptorPoolDeleter (const DescriptorPoolDeleter&) = delete;
+ DescriptorPoolDeleter& operator = (const DescriptorPoolDeleter&) = delete;
+ DescriptorPoolDeleter& operator = ( DescriptorPoolDeleter&&)= delete;
+
+ DescriptorPoolDeleter(DescriptorPoolDeleter&& rhs)noexcept :
+ PoolMgr (rhs.PoolMgr),
+ Pool (std::move(rhs.Pool))
+ {
+ rhs.PoolMgr = nullptr;
+ }
+
+ ~DescriptorPoolDeleter()
+ {
+ if (PoolMgr!=nullptr)
+ {
+ PoolMgr->FreePool(std::move(Pool));
+ }
+ }
+
+ private:
+ DescriptorPoolManager* PoolMgr;
+ VulkanUtilities::DescriptorPoolWrapper Pool;
+ };
+
+ for(auto& Pool : m_AllocatedPools)
+ {
+ m_PoolMgr.m_DeviceVkImpl.SafeReleaseDeviceObject(DescriptorPoolDeleter{m_PoolMgr, std::move(Pool)}, QueueMask);
+ }
+ m_PeakPoolCount = std::max(m_PeakPoolCount, m_AllocatedPools.size());
+ m_AllocatedPools.clear();
}
-size_t DescriptorPoolManager::GetPendingReleaseAllocationCount()
+DynamicDescriptorSetAllocator::~DynamicDescriptorSetAllocator()
{
- size_t count = 0;
- std::lock_guard<std::mutex> Lock(m_Mutex);
- for(auto &Pool : m_DescriptorPools)
- count += Pool->GetDiscardedSetCount();
- return count;
+ LOG_INFO_MESSAGE(m_Name, " peak descriptor pool count: ", m_PeakPoolCount);
}
-
}
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 8c6e0b56..c067f768 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -34,28 +34,15 @@
namespace Diligent
{
- static std::string GetUploadHeapName(bool bIsDeferred, Uint32 ContextId)
- {
- if (bIsDeferred)
- {
- std::stringstream ss;
- ss << "Upload heap of deferred context #" << ContextId;
- return ss.str();
- }
- else
- return "Upload heap of immediate context";
- }
-
- static std::string GetDynamicHeapName(bool bIsDeferred, Uint32 ContextId)
+ static std::string GetContextObjectName(const char* Object, bool bIsDeferred, Uint32 ContextId)
{
+ std::stringstream ss;
+ ss << Object;
if (bIsDeferred)
- {
- std::stringstream ss;
- ss << "Dynamic heap of deferred context #" << ContextId;
- return ss.str();
- }
+ ss << " of deferred context #" << ContextId;
else
- return "Dynamic heap of immediate context";
+ ss << " of immediate context";
+ return ss.str();
}
DeviceContextVkImpl::DeviceContextVkImpl( IReferenceCounters* pRefCounters,
@@ -83,36 +70,22 @@ namespace Diligent
m_UploadHeap
{
*pDeviceVkImpl,
- GetUploadHeapName(bIsDeferred, ContextId),
+ GetContextObjectName("Upload heap", bIsDeferred, ContextId),
Attribs.UploadHeapPageSize
},
- // 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),
m_ContextFrameNumber(0),
m_DynamicHeap
{
pDeviceVkImpl->GetDynamicMemoryManager(),
- GetDynamicHeapName(bIsDeferred, ContextId),
+ GetContextObjectName("Dynamic heap", bIsDeferred, ContextId),
Attribs.DynamicHeapPageSize
},
+ m_DynamicDescrSetAllocator
+ {
+ pDeviceVkImpl->GetDynamicDescriptorPool(),
+ GetContextObjectName("Dynamic descriptor set allocator", bIsDeferred, ContextId),
+ },
m_GenerateMipsHelper(std::move(GenerateMipsHelper))
{
m_GenerateMipsHelper->CreateSRB(&m_GenerateMipsSRB);
@@ -153,11 +126,13 @@ namespace Diligent
// moved to the release queue by Flush(). For deferred contexts, this should have happened in the last FinishCommandList()
// call.
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");
+ VERIFY(m_DynamicDescrSetAllocator.GetAllocatedPoolCount() == 0, "All allocated dynamic descriptor set pools must have been released at this point");
+
// TODO: rework
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");
+ // TODO: remove
+ //VERIFY(m_DynamicDescriptorPool.GetPendingReleaseAllocationCount() == 0, "All stale descriptor set allocations must have been destroyed at this point");
auto VkCmdPool = m_CmdPool.Release();
pDeviceVkImpl->SafeReleaseDeviceObject(std::move(VkCmdPool), ~Uint64{0});
@@ -762,8 +737,7 @@ namespace Diligent
// the release queue rightaway when RenderDeviceVkImpl::FlushStaleResources() is called
m_UploadHeap.ReleaseAllocatedPages(m_SubmittedBuffersCmdQueueMask);
m_DynamicHeap.FinishFrame(DeviceVkImpl, m_SubmittedBuffersCmdQueueMask);
-
- m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
+ m_DynamicDescrSetAllocator.ReleasePools(m_SubmittedBuffersCmdQueueMask);
if (m_bIsDeferred)
{
@@ -781,8 +755,8 @@ namespace Diligent
void DeviceContextVkImpl::ReleaseStaleContextResources(Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue)
{
- m_DynamicDescriptorPool.DisposeAllocations(SubmittedFenceValue);
- m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
+ //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 cd5c0c65..dc1085a4 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp
@@ -416,7 +416,7 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, Shader
const auto &StaticAndMutSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_STATIC);
if (StaticAndMutSet.SetIndex >= 0)
{
- DescriptorPoolAllocation SetAllocation = pDeviceVkImpl->AllocateDescriptorSet(~Uint64{0}, StaticAndMutSet.VkLayout);
+ DescriptorSetAllocation SetAllocation = pDeviceVkImpl->AllocateDescriptorSet(~Uint64{0}, StaticAndMutSet.VkLayout);
ResourceCache.GetDescriptorSet(StaticAndMutSet.SetIndex).AssignDescriptorSetAllocation(std::move(SetAllocation));
}
}
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index d41983f0..3161d084 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -551,23 +551,23 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind
#endif
}
- DescriptorPoolAllocation DynamicDescrSetAllocation;
+ VkDescriptorSet DynamicDescrSet = VK_NULL_HANDLE;
auto DynamicDescriptorSetVkLayout = m_PipelineLayout.GetDynamicDescriptorSetVkLayout();
if (DynamicDescriptorSetVkLayout != VK_NULL_HANDLE)
{
// Allocate vulkan descriptor set for dynamic resources
- DynamicDescrSetAllocation = pCtxVkImpl->AllocateDynamicDescriptorSet(DynamicDescriptorSetVkLayout);
+ DynamicDescrSet = pCtxVkImpl->AllocateDynamicDescriptorSet(DynamicDescriptorSetVkLayout);
// Commit all dynamic resource descriptors
for (Uint32 s=0; s < m_NumShaders; ++s)
{
const auto& Layout = m_ShaderResourceLayouts[s];
if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_DYNAMIC) != 0)
- Layout.CommitDynamicResources(ResourceCache, DynamicDescrSetAllocation.GetVkDescriptorSet());
+ Layout.CommitDynamicResources(ResourceCache, DynamicDescrSet);
}
}
// Prepare descriptor sets, and also bind them if there are no dynamic descriptors
VERIFY_EXPR(pDescrSetBindInfo != nullptr);
- m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, m_Desc.IsComputePipeline, ResourceCache, *pDescrSetBindInfo, DynamicDescrSetAllocation.GetVkDescriptorSet());
+ m_PipelineLayout.PrepareDescriptorSets(pCtxVkImpl, m_Desc.IsComputePipeline, ResourceCache, *pDescrSetBindInfo, DynamicDescrSet);
// Dynamic descriptor set allocation automatically goes back to the context's dynamic descriptor pool.
// release queue. It will stay there until the next command list is executed, at which point it will be discarded
// and actually released later
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index f0c8a29e..67729dfc 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -70,9 +70,10 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters*
m_EngineAttribs(CreationAttribs),
m_FramebufferCache(*this),
m_RenderPassCache(*this),
- m_MainDescriptorPool
+ m_DescriptorSetAllocator
{
- m_LogicalVkDevice,
+ *this,
+ "Main descriptor pool",
std::vector<VkDescriptorPoolSize>
{
{VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumSeparateSamplerDescriptors},
@@ -86,7 +87,28 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters*
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumUniformBufferDescriptors},
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumStorageBufferDescriptors},
},
- CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets
+ CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets,
+ true
+ },
+ m_DynamicDescriptorPool
+ {
+ *this,
+ "Dynamic descriptor pool",
+ 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 // Pools can only be reset
},
m_TransientCmdPoolMgr(*m_LogicalVkDevice, CmdQueues[0]->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),
@@ -243,8 +265,8 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo,
SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, pSignalFences);
// TODO: rework this
- auto CompletedFenceValue = m_CommandQueues[0].CmdQueue->GetCompletedFenceValue();
- m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
+ //auto CompletedFenceValue = m_CommandQueues[0].CmdQueue->GetCompletedFenceValue();
+ //m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
m_MemoryMgr.ShrinkMemory();
PurgeReleaseQueues();
@@ -265,7 +287,7 @@ void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects)
// Since GPU has been idled, it it is safe to do so
// SubmittedFenceValue has now been signaled by the GPU since we waited for it
- m_MainDescriptorPool.ReleaseStaleAllocations(m_CommandQueues[0].CmdQueue->GetCompletedFenceValue());
+ //m_MainDescriptorPool.ReleaseStaleAllocations(m_CommandQueues[0].CmdQueue->GetCompletedFenceValue());
m_MemoryMgr.ShrinkMemory();
}
}
@@ -291,7 +313,7 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources)
// TODO: rework this
auto CompletedFenceValue = ReleaseAllResources ? std::numeric_limits<Uint64>::max() : m_CommandQueues[0].CmdQueue->GetCompletedFenceValue();
- m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
+ //m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue);
m_MemoryMgr.ShrinkMemory();
PurgeReleaseQueues();
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp
deleted file mode 100644
index 9113023e..00000000
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDescriptorPool.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright 2015-2018 Egor Yusov
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
-*
-* In no event and under no legal theory, whether in tort (including negligence),
-* contract, or otherwise, unless required by applicable law (such as deliberate
-* and grossly negligent acts) or agreed to in writing, shall any Contributor be
-* liable for any damages, including any direct, indirect, special, incidental,
-* or consequential damages of any character arising as a result of this License or
-* out of the use or inability to use the software (including but not limited to damages
-* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
-* all other commercial damages or losses), even if such Contributor has been advised
-* of the possibility of such damages.
-*/
-#include <sstream>
-
-#include "VulkanUtilities/VulkanDescriptorPool.h"
-#include "VulkanUtilities/VulkanDebug.h"
-#include "Errors.h"
-#include "DebugUtilities.h"
-#include "VulkanErrors.h"
-
-namespace VulkanUtilities
-{
- VulkanDescriptorPool::VulkanDescriptorPool(std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
- const VkDescriptorPoolCreateInfo& DescriptorPoolCI) :
- m_LogicalDevice(LogicalDevice)
- {
- VERIFY_EXPR(DescriptorPoolCI.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO);
- m_Pool = m_LogicalDevice->CreateDescriptorPool(DescriptorPoolCI);
- VERIFY_EXPR(m_Pool != VK_NULL_HANDLE);
- }
-
- VulkanDescriptorPool::~VulkanDescriptorPool()
- {
- m_Pool.Release();
- }
-
- VkDescriptorSet VulkanDescriptorPool::AllocateDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName)
- {
- VkDescriptorSetAllocateInfo DescrSetAllocInfo = {};
- DescrSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- DescrSetAllocInfo.pNext = nullptr;
- DescrSetAllocInfo.descriptorPool = m_Pool;
- DescrSetAllocInfo.descriptorSetCount = 1;
- DescrSetAllocInfo.pSetLayouts = &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_LogicalDevice->AllocateVkDescriptorSet(DescrSetAllocInfo, DebugName);
- }
-
- void VulkanDescriptorPool::ReleaseDiscardedSets(uint64_t LastCompletedFence)
- {
- // Pick the oldest descriptor set at the front of the deque.
- // .first is the fence value that was signaled AFTER the command buffer referencing
- // the set has been submitted. If LastCompletedFence is at least this value, the buffer
- // is now finished, and the set can be safely released
- while (!m_DiscardedSets.empty() && LastCompletedFence >= m_DiscardedSets.front().first )
- {
- m_LogicalDevice->FreeDescriptorSet(m_Pool, m_DiscardedSets.front().second);
- m_DiscardedSets.pop_front();
- }
- }
-
- void VulkanDescriptorPool::DisposeDescriptorSet(VkDescriptorSet DescrSet, uint64_t FenceValue)
- {
- // FenceValue is the value that was signaled by the command queue after it
- // executed the command buffer
- m_DiscardedSets.emplace_back(FenceValue, DescrSet);
- }
-
- DescriptorPoolWrapper&& VulkanDescriptorPool::Release()
- {
- m_LogicalDevice.reset();
- VERIFY(m_DiscardedSets.empty(), "Discarded sets are not released");
- m_DiscardedSets.clear();
- return std::move(m_Pool);
- }
-}
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
index 71329665..490151c5 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp
@@ -71,7 +71,7 @@ namespace VulkanUtilities
void VulkanLogicalDevice::WaitIdle()const
{
auto err = vkDeviceWaitIdle(m_VkDevice);
- VERIFY_EXPR(err == VK_SUCCESS);
+ DEV_CHECK_ERR(err == VK_SUCCESS, "Failed to idle device");
}
template<typename VkObjectType, typename VkCreateObjectFuncType, typename VkObjectCreateInfoType>
@@ -248,7 +248,7 @@ namespace VulkanUtilities
VkCommandBuffer CmdBuff = VK_NULL_HANDLE;
auto err = vkAllocateCommandBuffers(m_VkDevice, &AllocInfo, &CmdBuff);
- VERIFY(err == VK_SUCCESS, "Failed to allocate command buffer '", DebugName, '\'');
+ DEV_CHECK_ERR(err == VK_SUCCESS, "Failed to allocate command buffer '", DebugName, '\'');
if (DebugName != nullptr && *DebugName != 0)
SetCommandBufferName(m_VkDevice, CmdBuff, DebugName);
@@ -423,7 +423,7 @@ namespace VulkanUtilities
VkResult VulkanLogicalDevice::ResetFence(VkFence fence)const
{
auto err = vkResetFences(m_VkDevice, 1, &fence);
- VERIFY(err == VK_SUCCESS, "Failed to reset fence");
+ DEV_CHECK_ERR(err == VK_SUCCESS, "Failed to reset fence");
return err;
}
@@ -439,7 +439,15 @@ namespace VulkanUtilities
VkCommandPoolResetFlags flags)const
{
auto err = vkResetCommandPool(m_VkDevice, vkCmdPool, flags);
- VERIFY(err == VK_SUCCESS, "Failed to reset command pool");
+ DEV_CHECK_ERR(err == VK_SUCCESS, "Failed to reset command pool");
+ return err;
+ }
+
+ VkResult VulkanLogicalDevice::ResetDescriptorPool(VkDescriptorPool vkDescriptorPool,
+ VkDescriptorPoolResetFlags flags)const
+ {
+ auto err = vkResetDescriptorPool(m_VkDevice, vkDescriptorPool, flags);
+ DEV_CHECK_ERR(err == VK_SUCCESS, "Failed to reset descriptor pool");
return err;
}
}
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
index b5dcee74..cad556aa 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp
@@ -151,7 +151,7 @@ namespace VulkanUtilities
// VkPhysicalDeviceMemoryProperties structure for the physical device is
// supported for the resource.
// * requiredProperties - required memory properties (device local, host visible, etc.)
- uint32_t VulkanPhysicalDevice::GetMemoryTypeIndex(uint32_t memoryTypeBitsRequirement,
+ uint32_t VulkanPhysicalDevice::GetMemoryTypeIndex(uint32_t memoryTypeBitsRequirement,
VkMemoryPropertyFlags requiredProperties)const
{
// Iterate over all memory types available for the device