|
|
@@ -8,134 +8,27 @@
|
|
|
namespace anki
|
|
|
{
|
|
|
|
|
|
-Error DescriptorSetAllocator::init(VkDevice dev)
|
|
|
-{
|
|
|
- ANKI_ASSERT(dev);
|
|
|
- m_dev = dev;
|
|
|
- ANKI_CHECK(initGlobalDsetLayout());
|
|
|
- ANKI_CHECK(initGlobalDsetPool());
|
|
|
- return ErrorCode::NONE;
|
|
|
-}
|
|
|
-
|
|
|
-void DescriptorSetAllocator::destroy()
|
|
|
-{
|
|
|
- if(m_globalDPool)
|
|
|
- {
|
|
|
- vkDestroyDescriptorPool(m_dev, m_globalDPool, nullptr);
|
|
|
- m_globalDPool = VK_NULL_HANDLE;
|
|
|
- }
|
|
|
-
|
|
|
- if(m_globalDsetLayout)
|
|
|
- {
|
|
|
- vkDestroyDescriptorSetLayout(m_dev, m_globalDsetLayout, nullptr);
|
|
|
- m_globalDsetLayout = VK_NULL_HANDLE;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-Error DescriptorSetAllocator::initGlobalDsetLayout()
|
|
|
+void DescriptorSetLayoutFactory::destroy()
|
|
|
{
|
|
|
- VkDescriptorSetLayoutCreateInfo ci = {};
|
|
|
- ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
|
|
-
|
|
|
- const U BINDING_COUNT =
|
|
|
- MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS + MAX_IMAGE_BINDINGS;
|
|
|
- ci.bindingCount = BINDING_COUNT;
|
|
|
-
|
|
|
- Array<VkDescriptorSetLayoutBinding, BINDING_COUNT> bindings;
|
|
|
- memset(&bindings[0], 0, sizeof(bindings));
|
|
|
- ci.pBindings = &bindings[0];
|
|
|
-
|
|
|
- U count = 0;
|
|
|
-
|
|
|
- // Combined image samplers
|
|
|
- for(U i = 0; i < MAX_TEXTURE_BINDINGS; ++i)
|
|
|
- {
|
|
|
- VkDescriptorSetLayoutBinding& binding = bindings[count];
|
|
|
- binding.binding = count;
|
|
|
- binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
|
- binding.descriptorCount = 1;
|
|
|
- binding.stageFlags = VK_SHADER_STAGE_ALL;
|
|
|
-
|
|
|
- ++count;
|
|
|
- }
|
|
|
-
|
|
|
- // Uniform buffers
|
|
|
- for(U i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
|
|
|
- {
|
|
|
- VkDescriptorSetLayoutBinding& binding = bindings[count];
|
|
|
- binding.binding = count;
|
|
|
- binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
|
|
|
- binding.descriptorCount = 1;
|
|
|
- binding.stageFlags = VK_SHADER_STAGE_ALL;
|
|
|
-
|
|
|
- ++count;
|
|
|
- }
|
|
|
-
|
|
|
- // Storage buffers
|
|
|
- for(U i = 0; i < MAX_STORAGE_BUFFER_BINDINGS; ++i)
|
|
|
- {
|
|
|
- VkDescriptorSetLayoutBinding& binding = bindings[count];
|
|
|
- binding.binding = count;
|
|
|
- binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
|
|
|
- binding.descriptorCount = 1;
|
|
|
- binding.stageFlags = VK_SHADER_STAGE_ALL;
|
|
|
-
|
|
|
- ++count;
|
|
|
- }
|
|
|
-
|
|
|
- // Images
|
|
|
- for(U i = 0; i < MAX_IMAGE_BINDINGS; ++i)
|
|
|
+ for(auto it : m_map)
|
|
|
{
|
|
|
- VkDescriptorSetLayoutBinding& binding = bindings[count];
|
|
|
- binding.binding = count;
|
|
|
- binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
|
- binding.descriptorCount = 1;
|
|
|
- binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
-
|
|
|
- ++count;
|
|
|
+ VkDescriptorSetLayout dset = it;
|
|
|
+ vkDestroyDescriptorSetLayout(m_dev, dset, nullptr);
|
|
|
}
|
|
|
|
|
|
- ANKI_ASSERT(count == BINDING_COUNT);
|
|
|
-
|
|
|
- ANKI_VK_CHECK(vkCreateDescriptorSetLayout(m_dev, &ci, nullptr, &m_globalDsetLayout));
|
|
|
-
|
|
|
- return ErrorCode::NONE;
|
|
|
-}
|
|
|
-
|
|
|
-Error DescriptorSetAllocator::initGlobalDsetPool()
|
|
|
-{
|
|
|
- Array<VkDescriptorPoolSize, 4> pools = {{}};
|
|
|
- pools[0] =
|
|
|
- VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURE_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
- pools[1] = VkDescriptorPoolSize{
|
|
|
- VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, MAX_UNIFORM_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
- pools[2] = VkDescriptorPoolSize{
|
|
|
- VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, MAX_STORAGE_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
- pools[3] = VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MAX_IMAGE_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
-
|
|
|
- VkDescriptorPoolCreateInfo ci = {};
|
|
|
- ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
|
- ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
|
|
- ci.maxSets = MAX_RESOURCE_GROUPS;
|
|
|
- ci.poolSizeCount = pools.getSize();
|
|
|
- ci.pPoolSizes = &pools[0];
|
|
|
-
|
|
|
- ANKI_VK_CHECK(vkCreateDescriptorPool(m_dev, &ci, nullptr, &m_globalDPool));
|
|
|
-
|
|
|
- return ErrorCode::NONE;
|
|
|
+ m_map.destroy(m_alloc);
|
|
|
}
|
|
|
|
|
|
-VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
- U texBindingCount, U uniBindingCount, U storageBindingCount, U imageBindingCount)
|
|
|
+Error DescriptorSetLayoutFactory::getOrCreateLayout(const DescriptorSetLayoutInfo& dsinf, VkDescriptorSetLayout& out)
|
|
|
{
|
|
|
+ out = VK_NULL_HANDLE;
|
|
|
LockGuard<Mutex> lock(m_mtx);
|
|
|
|
|
|
- Key key(texBindingCount, uniBindingCount, storageBindingCount, imageBindingCount);
|
|
|
- auto it = m_map.find(key);
|
|
|
+ auto it = m_map.find(dsinf);
|
|
|
|
|
|
if(it != m_map.getEnd())
|
|
|
{
|
|
|
- return *it;
|
|
|
+ out = *it;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -155,7 +48,7 @@ VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
U bindingIdx = 0;
|
|
|
|
|
|
// Combined image samplers
|
|
|
- for(U i = 0; i < texBindingCount; ++i)
|
|
|
+ for(U i = 0; i < dsinf.m_texCount; ++i)
|
|
|
{
|
|
|
VkDescriptorSetLayoutBinding& binding = bindings[count++];
|
|
|
binding.binding = bindingIdx++;
|
|
|
@@ -166,7 +59,7 @@ VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
|
|
|
// Uniform buffers
|
|
|
bindingIdx = MAX_TEXTURE_BINDINGS;
|
|
|
- for(U i = 0; i < uniBindingCount; ++i)
|
|
|
+ for(U i = 0; i < dsinf.m_uniCount; ++i)
|
|
|
{
|
|
|
VkDescriptorSetLayoutBinding& binding = bindings[count++];
|
|
|
binding.binding = bindingIdx++;
|
|
|
@@ -177,7 +70,7 @@ VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
|
|
|
// Storage buffers
|
|
|
bindingIdx = MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS;
|
|
|
- for(U i = 0; i < storageBindingCount; ++i)
|
|
|
+ for(U i = 0; i < dsinf.m_storageCount; ++i)
|
|
|
{
|
|
|
VkDescriptorSetLayoutBinding& binding = bindings[count++];
|
|
|
binding.binding = bindingIdx++;
|
|
|
@@ -188,7 +81,7 @@ VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
|
|
|
// Images
|
|
|
bindingIdx = MAX_TEXTURE_BINDINGS + MAX_UNIFORM_BUFFER_BINDINGS + MAX_STORAGE_BUFFER_BINDINGS;
|
|
|
- for(U i = 0; i < imageBindingCount; ++i)
|
|
|
+ for(U i = 0; i < dsinf.m_imgCount; ++i)
|
|
|
{
|
|
|
VkDescriptorSetLayoutBinding& binding = bindings[count++];
|
|
|
binding.binding = bindingIdx++;
|
|
|
@@ -200,23 +93,78 @@ VkDescriptorSetLayout DescriptorSetLayoutFactory::createLayout(
|
|
|
ANKI_ASSERT(count <= BINDING_COUNT);
|
|
|
ci.bindingCount = count;
|
|
|
|
|
|
- VkDescriptorSetLayout dset;
|
|
|
- ANKI_VK_CHECKF(vkCreateDescriptorSetLayout(m_dev, &ci, nullptr, &dset));
|
|
|
+ ANKI_VK_CHECK(vkCreateDescriptorSetLayout(m_dev, &ci, nullptr, &out));
|
|
|
|
|
|
- m_map.pushBack(m_alloc, key, dset);
|
|
|
- return dset;
|
|
|
+ m_map.pushBack(m_alloc, dsinf, out);
|
|
|
}
|
|
|
+
|
|
|
+ return ErrorCode::NONE;
|
|
|
}
|
|
|
|
|
|
-void DescriptorSetLayoutFactory::destroy()
|
|
|
+Error DescriptorSetAllocator::init(GrAllocator<U8> alloc, VkDevice dev)
|
|
|
{
|
|
|
- for(auto it : m_map)
|
|
|
+ ANKI_ASSERT(dev);
|
|
|
+ m_dev = dev;
|
|
|
+ ANKI_CHECK(initGlobalDsetPool());
|
|
|
+ m_layoutFactory.init(alloc, dev);
|
|
|
+
|
|
|
+ return ErrorCode::NONE;
|
|
|
+}
|
|
|
+
|
|
|
+void DescriptorSetAllocator::destroy()
|
|
|
+{
|
|
|
+ if(m_globalDPool)
|
|
|
{
|
|
|
- VkDescriptorSetLayout dset = it;
|
|
|
- vkDestroyDescriptorSetLayout(m_dev, dset, nullptr);
|
|
|
+ vkDestroyDescriptorPool(m_dev, m_globalDPool, nullptr);
|
|
|
+ m_globalDPool = VK_NULL_HANDLE;
|
|
|
}
|
|
|
|
|
|
- m_map.destroy(m_alloc);
|
|
|
+ m_layoutFactory.destroy();
|
|
|
+}
|
|
|
+
|
|
|
+Error DescriptorSetAllocator::initGlobalDsetPool()
|
|
|
+{
|
|
|
+ Array<VkDescriptorPoolSize, 4> pools = {{}};
|
|
|
+ pools[0] =
|
|
|
+ VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_TEXTURE_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
+ pools[1] = VkDescriptorPoolSize{
|
|
|
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, MAX_UNIFORM_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
+ pools[2] = VkDescriptorPoolSize{
|
|
|
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, MAX_STORAGE_BUFFER_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
+ pools[3] = VkDescriptorPoolSize{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MAX_IMAGE_BINDINGS * MAX_RESOURCE_GROUPS};
|
|
|
+
|
|
|
+ VkDescriptorPoolCreateInfo ci = {};
|
|
|
+ ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
|
|
+ ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
|
|
+ ci.maxSets = MAX_RESOURCE_GROUPS;
|
|
|
+ ci.poolSizeCount = pools.getSize();
|
|
|
+ ci.pPoolSizes = &pools[0];
|
|
|
+
|
|
|
+ ANKI_VK_CHECK(vkCreateDescriptorPool(m_dev, &ci, nullptr, &m_globalDPool));
|
|
|
+
|
|
|
+ return ErrorCode::NONE;
|
|
|
+}
|
|
|
+
|
|
|
+Error DescriptorSetAllocator::allocate(const DescriptorSetLayoutInfo& dsinf, VkDescriptorSet& out)
|
|
|
+{
|
|
|
+ VkDescriptorSetLayout layout;
|
|
|
+ ANKI_CHECK(m_layoutFactory.getOrCreateLayout(dsinf, layout));
|
|
|
+
|
|
|
+ out = VK_NULL_HANDLE;
|
|
|
+ VkDescriptorSetAllocateInfo ci = {};
|
|
|
+ ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
|
|
+ ci.descriptorPool = m_globalDPool;
|
|
|
+ ci.descriptorSetCount = 1;
|
|
|
+ ci.pSetLayouts = &layout;
|
|
|
+
|
|
|
+ LockGuard<Mutex> lock(m_mtx);
|
|
|
+ if(++m_descriptorSetAllocationCount > MAX_RESOURCE_GROUPS)
|
|
|
+ {
|
|
|
+ ANKI_LOGE("Exceeded the MAX_RESOURCE_GROUPS");
|
|
|
+ return ErrorCode::OUT_OF_MEMORY;
|
|
|
+ }
|
|
|
+ ANKI_VK_CHECK(vkAllocateDescriptorSets(m_dev, &ci, &out));
|
|
|
+ return ErrorCode::NONE;
|
|
|
}
|
|
|
|
|
|
} // end namespace anki
|