Skip to content
Snippets Groups Projects
Commit 53310dfd authored by Artur Wasmut's avatar Artur Wasmut
Browse files

refactor and finalize descriptor manager.

parent 0d06ff1c
No related branches found
No related tags found
1 merge request!3Resolve "Descriptor Set Managment"
Pipeline #25089 passed
...@@ -55,6 +55,7 @@ set(vkcv_sources ...@@ -55,6 +55,7 @@ set(vkcv_sources
${vkcv_source}/vkcv/Framebuffer.cpp ${vkcv_source}/vkcv/Framebuffer.cpp
${vkcv_include}/vkcv/Event.hpp ${vkcv_include}/vkcv/Event.hpp
${vkcv_source}/vkcv/DescriptorManager.hpp ${vkcv_source}/vkcv/DescriptorManager.hpp
${vkcv_source}/vkcv/DescriptorManager.cpp ${vkcv_source}/vkcv/DescriptorManager.cpp
......
...@@ -61,7 +61,9 @@ namespace vkcv ...@@ -61,7 +61,9 @@ namespace vkcv
std::unique_ptr<PassManager> m_PassManager; std::unique_ptr<PassManager> m_PassManager;
std::unique_ptr<PipelineManager> m_PipelineManager; std::unique_ptr<PipelineManager> m_PipelineManager;
std::unique_ptr<DescriptorManager> m_DescriptorManager;
std::unique_ptr<BufferManager> m_BufferManager; std::unique_ptr<BufferManager> m_BufferManager;
CommandResources m_CommandResources; CommandResources m_CommandResources;
SyncResources m_SyncResources; SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex; uint32_t m_currentSwapchainImageIndex;
...@@ -173,6 +175,7 @@ namespace vkcv ...@@ -173,6 +175,7 @@ namespace vkcv
* @param setDescriptions * @param setDescriptions
* @return * @return
*/ */
[[nodiscard]]
ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets); ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets);
/** /**
......
...@@ -9,6 +9,7 @@ namespace vkcv ...@@ -9,6 +9,7 @@ namespace vkcv
enum class DescriptorType enum class DescriptorType
{ {
UNIFORM_BUFFER, UNIFORM_BUFFER,
STORAGE_BUFFER,
SAMPLER, SAMPLER,
IMAGE IMAGE
}; };
...@@ -23,15 +24,12 @@ namespace vkcv ...@@ -23,15 +24,12 @@ namespace vkcv
struct DescriptorBinding struct DescriptorBinding
{ {
DescriptorBinding() = delete; DescriptorBinding() = delete;
DescriptorBinding( DescriptorBinding(
uint32_t p_bindingID, DescriptorType descriptorType,
DescriptorType p_descriptorType, uint32_t descriptorCount,
uint32_t p_descriptorCount, ShaderStage shaderStage
ShaderStage p_shaderStage
) noexcept; ) noexcept;
uint32_t bindingID;
DescriptorType descriptorType; DescriptorType descriptorType;
uint32_t descriptorCount; uint32_t descriptorCount;
ShaderStage shaderStage; ShaderStage shaderStage;
...@@ -45,12 +43,8 @@ namespace vkcv ...@@ -45,12 +43,8 @@ namespace vkcv
struct DescriptorSet struct DescriptorSet
{ {
DescriptorSet() = delete; DescriptorSet() = delete;
explicit DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept;
DescriptorSet(
std::vector<DescriptorBinding> p_bindings,
uint32_t p_setCount) noexcept;
std::vector<DescriptorBinding> bindings; std::vector<DescriptorBinding> bindings;
uint32_t setCount;
}; };
} }
#pragma once
#include <vulkan/vulkan.hpp>
namespace vkcv {
class DescriptorSet
{
public:
DescriptorSet::DescriptorSet();
void createDescriptorSets(vk::Device device);
private:
//std::vector<vk::DescriptorPoolSize> descriptorPoolSizes;
//std::vector<vk::DescriptorSetLayoutBinding> descriptorSetLayoutBinding;
//vk::DescriptorSetLayout descriptorSetLayout;
//vk::DescriptorPool descriptorPool;
};
}
\ No newline at end of file
...@@ -95,26 +95,23 @@ int main(int argc, const char** argv) { ...@@ -95,26 +95,23 @@ int main(int argc, const char** argv) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
//---------CREATION OF RESOURCES/DESCRIPTORS------------------
//just an example //just an example
//creates 3 descriptor sets with one descriptor each //creates 20 descriptor sets, each containing bindings for 50 uniform buffers, images, and samplers
std::vector<vkcv::DescriptorSet> sets; std::vector<vkcv::DescriptorSet> sets;
vkcv::DescriptorType typeA = vkcv::DescriptorType::UNIFORM_BUFFER;
vkcv::DescriptorType typeB = vkcv::DescriptorType::IMAGE; for (uint32_t i = 0; i < 20; i++)
vkcv::DescriptorType typeC = vkcv::DescriptorType::SAMPLER;
std::vector<vkcv::DescriptorType> types = { typeA, typeB, typeC };
for (uint32_t i = 0; i < types.size(); i++)
{ {
vkcv::DescriptorBinding bind(i, types[i], static_cast<uint32_t>(1), vkcv::ShaderStage::VERTEX); vkcv::DescriptorBinding uniformBufBinding(vkcv::DescriptorType::UNIFORM_BUFFER, 50, vkcv::ShaderStage::VERTEX);
vkcv::DescriptorBinding storageBufBinding(vkcv::DescriptorType::STORAGE_BUFFER, 50, vkcv::ShaderStage::VERTEX);
vkcv::DescriptorBinding imageBinding(vkcv::DescriptorType::IMAGE, 50, vkcv::ShaderStage::VERTEX);
vkcv::DescriptorBinding samplerBinding(vkcv::DescriptorType::SAMPLER, 50, vkcv::ShaderStage::VERTEX);
std::vector<vkcv::DescriptorBinding> bindings = { bind }; vkcv::DescriptorSet set({uniformBufBinding, storageBufBinding, imageBinding, samplerBinding});
vkcv::DescriptorSet set(bindings, static_cast<uint32_t>(1));
sets.push_back(set); sets.push_back(set);
auto resourceHandle = core.createResourceDescription(sets);
std::cout << "Resource " << resourceHandle.id << " created." << std::endl;
} }
core.createResourceDescription(sets);
//------------END CREATION OF RESOURCES/DESCRIPTORS------------------
/* /*
* BufferHandle triangleVertices = core.createBuffer(vertices); * BufferHandle triangleVertices = core.createBuffer(vertices);
......
...@@ -93,6 +93,7 @@ namespace vkcv ...@@ -93,6 +93,7 @@ namespace vkcv
m_swapchainImageViews(imageViews), m_swapchainImageViews(imageViews),
m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)),
m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())}, m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager())},
m_CommandResources(commandResources), m_CommandResources(commandResources),
m_SyncResources(syncResources) m_SyncResources(syncResources)
...@@ -253,13 +254,8 @@ namespace vkcv ...@@ -253,13 +254,8 @@ namespace vkcv
} }
} }
ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets) ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets)
{ {
// TODO: return m_DescriptorManager->createResourceDescription(descriptorSets);
// call DescriptorManager's createResourceDescription
// let it do the actual work! No vulkan stuff here.
DescriptorManager descriptorManager = DescriptorManager(m_Context.getDevice());
return descriptorManager.createResourceDescription(descriptorSets);
} }
} }
#include "vkcv/DescriptorConfig.hpp" #include "vkcv/DescriptorConfig.hpp"
#include <utility>
namespace vkcv { namespace vkcv {
DescriptorBinding::DescriptorBinding( DescriptorBinding::DescriptorBinding(
uint32_t p_bindingID, DescriptorType descriptorType,
DescriptorType p_descriptorType, uint32_t descriptorCount,
uint32_t p_descriptorCount, ShaderStage shaderStage
ShaderStage p_shaderStage
) noexcept : ) noexcept :
bindingID{ p_bindingID }, descriptorType{descriptorType},
descriptorType{ p_descriptorType }, descriptorCount{descriptorCount},
descriptorCount{ p_descriptorCount }, shaderStage{shaderStage}
shaderStage{ p_shaderStage }
{}; {};
DescriptorSet::DescriptorSet( DescriptorSet::DescriptorSet(std::vector<DescriptorBinding> bindings) noexcept :
std::vector<DescriptorBinding> p_bindings, bindings{std::move(bindings)}
uint32_t p_setCount
) noexcept :
bindings{ p_bindings },
setCount{ p_setCount }
{}; {};
}
}
\ No newline at end of file
#include "DescriptorManager.hpp" #include "DescriptorManager.hpp"
#include <vkcv/ShaderProgram.hpp>
namespace vkcv namespace vkcv
{ {
DescriptorManager::ResourceDescription::ResourceDescription(std::vector<vk::DescriptorSet> sets,
std::vector<vk::DescriptorSetLayout> layouts) noexcept :
descriptorSets{std::move(sets)},
descriptorSetLayouts{std::move(layouts)}
{}
DescriptorManager::DescriptorManager(vk::Device device) noexcept: DescriptorManager::DescriptorManager(vk::Device device) noexcept:
m_Device{ device }, m_NextDescriptorSetID{ 1 } m_Device{ device }, m_NextResourceDescriptionID{ 1 }
{ {
m_DescriptorTypes = { DescriptorType::UNIFORM_BUFFER, DescriptorType::SAMPLER, DescriptorType::IMAGE }; /**
uint32_t sizesPerType = 1000; * Allocate a set size for the initial pool, namely 1000 units of each descriptor type below.
uint32_t maxSetsPerPool = 1000; */
const std::vector<vk::DescriptorPoolSize> poolSizes = {vk::DescriptorPoolSize(vk::DescriptorType::eSampler, 1000),
vk::DescriptorPoolSize(vk::DescriptorType::eSampledImage, 1000),
vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1000),
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 1000)};
vk::DescriptorPoolCreateInfo poolInfo({},
1000,
static_cast<uint32_t>(poolSizes.size()),
poolSizes.data());
if(m_Device.createDescriptorPool(&poolInfo, nullptr, &m_Pool) != vk::Result::eSuccess)
{
std::cout << "FAILED TO ALLOCATED DESCRIPTOR POOL." << std::endl;
m_Pool = nullptr;
};
}
std::vector<vk::DescriptorPoolSize> descriptorPoolSizes; DescriptorManager::~DescriptorManager() noexcept
for (int i = 0; i < m_DescriptorTypes.size(); i++) { {
vk::DescriptorType type = convertDescriptorTypeFlag(m_DescriptorTypes[i]); for(const auto &resource : m_ResourceDescriptions)
vk::DescriptorPoolSize poolSize(type, sizesPerType); {
descriptorPoolSizes.push_back(poolSize); for(const auto &layout : resource.descriptorSetLayouts)
m_Device.destroyDescriptorSetLayout(layout);
} }
vk::DescriptorPoolCreateInfo poolInfo({}, maxSetsPerPool, descriptorPoolSizes); m_Device.destroy(m_Pool);
m_Pool = m_Device.createDescriptorPool(poolInfo, nullptr);
} }
ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &p_descriptorSets) ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets)
{ {
ResourceDescription resource{}; std::vector<vk::DescriptorSet> vk_sets;
std::vector<vk::DescriptorSetLayout> vk_setLayouts;
for (const auto &set : descriptorSets) {
std::vector<vk::DescriptorSetLayoutBinding> setBindings = {};
for (int i = 0; i < p_descriptorSets.size(); i++) { //create each set's binding
DescriptorSet set = p_descriptorSets[i]; for (uint32_t j = 0; j < set.bindings.size(); j++) {
std::vector<vk::DescriptorSetLayoutBinding> setBindings; vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(
for (int j = 0; j < set.bindings.size(); j++) { j,
//creates each binding of the set convertDescriptorTypeFlag(set.bindings[j].descriptorType),
DescriptorBinding binding = set.bindings[j]; set.bindings[j].descriptorCount,
vk::DescriptorType type = convertDescriptorTypeFlag(binding.descriptorType); convertShaderStageFlag(set.bindings[j].shaderStage));
vk::ShaderStageFlagBits stage = convertShaderStageFlag(binding.shaderStage);
vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(binding.bindingID, type, binding.descriptorCount, stage);
setBindings.push_back(descriptorSetLayoutBinding); setBindings.push_back(descriptorSetLayoutBinding);
} }
//creates the descriptor set layouts
vk::DescriptorSetLayoutCreateInfo descriptorSetLayoutInfo({}, setBindings);
vk::DescriptorSetLayout allocLayout = m_Device.createDescriptorSetLayout(descriptorSetLayoutInfo, nullptr);
std::vector<vk::DescriptorSetLayout> allocLayouts(set.setCount, allocLayout);
//binds the layout to the pool
vk::DescriptorSetAllocateInfo allocInfo(m_Pool, allocLayout);
//creates and allocates the set(s) based on the layout
vk::DescriptorSet allocSet;
std::vector<vk::DescriptorSet> allocSets(set.setCount, allocSet);
m_Device.allocateDescriptorSets(&allocInfo, allocSets.data());
//inserts the descriptor sets and layouts into the resources (also considers copies of the same sets) //create the descriptor set's layout from the bindings gathered above
resource.descriptorSetLayouts.insert(resource.descriptorSetLayouts.begin(), allocLayouts.begin(), allocLayouts.end()); vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings);
resource.descriptorSets.insert(resource.descriptorSets.end(), allocSets.begin(), allocSets.end()); vk::DescriptorSetLayout layout = nullptr;
if(m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &layout) != vk::Result::eSuccess)
{
std::cout << "FAILED TO CREATE DESCRIPTOR SET LAYOUT" << std::endl;
return ResourcesHandle{0};
};
vk_setLayouts.push_back(layout);
} }
m_ResourceDescriptions.push_back(resource); //create and allocate the set(s) based on the layouts that have been gathered above
return ResourcesHandle{m_NextDescriptorSetID++}; vk_sets.resize(vk_setLayouts.size());
vk::DescriptorSetAllocateInfo allocInfo(m_Pool, vk_sets.size(), vk_setLayouts.data());
auto result = m_Device.allocateDescriptorSets(&allocInfo, vk_sets.data());
if(result != vk::Result::eSuccess)
{
std::cout << "FAILED TO ALLOCATE DESCRIPTOR SET" << std::endl;
std::cout << vk::to_string(result) << std::endl;
for(const auto &layout : vk_setLayouts)
m_Device.destroy(layout);
return ResourcesHandle{0};
};
m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts);
return ResourcesHandle{m_NextResourceDescriptionID++};
} }
vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) { vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) {
switch (type) switch (type)
{ {
case DescriptorType::UNIFORM_BUFFER: case DescriptorType::UNIFORM_BUFFER:
return vk::DescriptorType::eUniformBuffer; return vk::DescriptorType::eUniformBuffer;
case DescriptorType::SAMPLER: case DescriptorType::STORAGE_BUFFER:
return vk::DescriptorType::eSampler; return vk::DescriptorType::eStorageBuffer;
case DescriptorType::IMAGE: case DescriptorType::SAMPLER:
return vk::DescriptorType::eSampledImage; return vk::DescriptorType::eSampler;
case DescriptorType::IMAGE:
return vk::DescriptorType::eSampledImage;
default:
return vk::DescriptorType::eUniformBuffer;
} }
} }
vk::ShaderStageFlagBits DescriptorManager::convertShaderStageFlag(ShaderStage stage) { vk::ShaderStageFlagBits DescriptorManager::convertShaderStageFlag(ShaderStage stage) {
switch (stage) switch (stage)
{ {
case ShaderStage::VERTEX: case ShaderStage::VERTEX:
return vk::ShaderStageFlagBits::eVertex; return vk::ShaderStageFlagBits::eVertex;
case ShaderStage::FRAGMENT: case ShaderStage::FRAGMENT:
return vk::ShaderStageFlagBits::eFragment; return vk::ShaderStageFlagBits::eFragment;
case ShaderStage::TESS_CONTROL: case ShaderStage::TESS_CONTROL:
return vk::ShaderStageFlagBits::eTessellationControl; return vk::ShaderStageFlagBits::eTessellationControl;
case ShaderStage::TESS_EVAL: case ShaderStage::TESS_EVAL:
return vk::ShaderStageFlagBits::eTessellationControl; return vk::ShaderStageFlagBits::eTessellationEvaluation;
case ShaderStage::GEOMETRY: case ShaderStage::GEOMETRY:
return vk::ShaderStageFlagBits::eGeometry; return vk::ShaderStageFlagBits::eGeometry;
case ShaderStage::COMPUTE: case ShaderStage::COMPUTE:
return vk::ShaderStageFlagBits::eCompute; return vk::ShaderStageFlagBits::eCompute;
default:
return vk::ShaderStageFlagBits::eAll;
} }
} }
......
...@@ -9,7 +9,7 @@ namespace vkcv ...@@ -9,7 +9,7 @@ namespace vkcv
{ {
public: public:
explicit DescriptorManager(vk::Device device) noexcept; explicit DescriptorManager(vk::Device device) noexcept;
~DescriptorManager() = default; ~DescriptorManager() noexcept;
/** /**
* Creates all vk::DescriptorSets and allocates them from the pool. * Creates all vk::DescriptorSets and allocates them from the pool.
...@@ -18,12 +18,12 @@ namespace vkcv ...@@ -18,12 +18,12 @@ namespace vkcv
* @param[in] vector of filled vkcv::DescriptorSet structs * @param[in] vector of filled vkcv::DescriptorSet structs
* @return index into that objects a resource handle * @return index into that objects a resource handle
*/ */
ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & p_descriptorSets); ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & descriptorSets);
private: private:
vk::Device m_Device; vk::Device m_Device;
vk::DescriptorPool m_Pool; vk::DescriptorPool m_Pool;
uint64_t m_NextDescriptorSetID;
/** /**
* Container for all resources requested by the user in one call of createResourceDescription. * Container for all resources requested by the user in one call of createResourceDescription.
...@@ -31,6 +31,9 @@ namespace vkcv ...@@ -31,6 +31,9 @@ namespace vkcv
*/ */
struct ResourceDescription struct ResourceDescription
{ {
ResourceDescription() = delete;
ResourceDescription(std::vector<vk::DescriptorSet> sets, std::vector<vk::DescriptorSetLayout> layouts) noexcept;
std::vector<vk::DescriptorSet> descriptorSets; std::vector<vk::DescriptorSet> descriptorSets;
std::vector<vk::DescriptorSetLayout> descriptorSetLayouts; std::vector<vk::DescriptorSetLayout> descriptorSetLayouts;
}; };
...@@ -39,24 +42,20 @@ namespace vkcv ...@@ -39,24 +42,20 @@ namespace vkcv
* Contains all the resource descriptions that were requested by the user in calls of createResourceDescription. * Contains all the resource descriptions that were requested by the user in calls of createResourceDescription.
*/ */
std::vector<ResourceDescription> m_ResourceDescriptions; std::vector<ResourceDescription> m_ResourceDescriptions;
// Counter for the vector above
/** uint64_t m_NextResourceDescriptionID;
* Contains all the allowed vkcv::DescriptorTypes that were also pre-defined in the DescriptorConfig class.
* Allowed types are defined in the constructor of DescriptorManager.
*/
std::vector<DescriptorType> m_DescriptorTypes;
/** /**
* Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk). * Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk).
* @param[in] vkcv flag of the DescriptorType (see DescriptorConfig.hpp) * @param[in] vkcv flag of the DescriptorType (see DescriptorConfig.hpp)
* @return vk flag of the DescriptorType * @return vk flag of the DescriptorType
*/ */
vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type); static vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type);
/** /**
* Converts the flags of the shader stages from VulkanCV (vkcv) to Vulkan (vk). * Converts the flags of the shader stages from VulkanCV (vkcv) to Vulkan (vk).
* @param[in] vkcv flag of the ShaderStage (see ShaderProgram.hpp) * @param[in] vkcv flag of the ShaderStage (see ShaderProgram.hpp)
* @return vk flag of the ShaderStage * @return vk flag of the ShaderStage
*/ */
vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage); static vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage);
}; };
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment