From 93da8fc93405700fb95d0f2596fb116f4afc60fa Mon Sep 17 00:00:00 2001 From: Simeon Hermann <shermann04@uni-koblenz.de> Date: Sun, 23 May 2021 22:23:53 +0200 Subject: [PATCH] [#9] implemented first steps for the creation managing of resource descriptions / descriptor sets --- config/Sources.cmake | 4 +- include/vkcv/Core.hpp | 4 +- include/vkcv/DescriptorConfig.hpp | 34 +++++++++++ include/vkcv/DescriptorSet.hpp | 19 +++++++ include/vkcv/ResourcesConfig.hpp | 23 -------- projects/first_triangle/src/main.cpp | 26 +++++++++ src/vkcv/Core.cpp | 5 +- src/vkcv/DescriptorManager.cpp | 85 +++++++++++++++++++++++++++- src/vkcv/DescriptorManager.hpp | 24 ++++++-- src/vkcv/ResourcesConfig.cpp | 0 10 files changed, 189 insertions(+), 35 deletions(-) create mode 100644 include/vkcv/DescriptorConfig.hpp create mode 100644 include/vkcv/DescriptorSet.hpp delete mode 100644 include/vkcv/ResourcesConfig.hpp delete mode 100644 src/vkcv/ResourcesConfig.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index 7646cf6f..3d1120be 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -55,6 +55,6 @@ set(vkcv_sources ${vkcv_source}/vkcv/DescriptorManager.hpp ${vkcv_source}/vkcv/DescriptorManager.cpp - ${vkcv_include}/vkcv/ResourcesConfig.hpp - ${vkcv_source}/vkcv/ResourcesConfig.cpp + ${vkcv_include}/vkcv/DescriptorConfig.hpp + ${vkcv_source}/vkcv/DescriptorConfig.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 79a9d29d..680f0b62 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -17,7 +17,7 @@ #include "CommandResources.hpp" #include "SyncResources.hpp" #include "Result.hpp" -#include "vkcv/ResourcesConfig.hpp" +#include "vkcv/DescriptorConfig.hpp" namespace vkcv { @@ -153,7 +153,7 @@ namespace vkcv * @param setDescriptions * @return */ - ResourcesHandle createResourceDescription(const std::vector<SetDescription> &setDescriptions); + ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> &descriptorSets); /** * @brief start recording command buffers and increment frame index diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp new file mode 100644 index 00000000..c4666b18 --- /dev/null +++ b/include/vkcv/DescriptorConfig.hpp @@ -0,0 +1,34 @@ +#pragma once +#include <vkcv/ShaderProgram.hpp> + +namespace vkcv +{ + enum class DescriptorType + { + // TODO: + // uniform buffers, samplers, images should be supported for now! + UNIFORM_BUFFER, + SAMPLER, + IMAGE + }; + + struct DescriptorBinding + { + // TODO: + // should contain something like the binding ID, + // and the descriptor/resource type + + uint32_t bindingID; + DescriptorType descriptorType; + uint32_t descriptorCount; + ShaderStage shaderStage; + }; + + struct DescriptorSet + { + // TODO: + // should contain a collection of DescriptorBindings and the number of instances to be created from the set + std::vector<DescriptorBinding> bindings; + uint32_t setCount; + }; +} diff --git a/include/vkcv/DescriptorSet.hpp b/include/vkcv/DescriptorSet.hpp new file mode 100644 index 00000000..969f3558 --- /dev/null +++ b/include/vkcv/DescriptorSet.hpp @@ -0,0 +1,19 @@ +#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 diff --git a/include/vkcv/ResourcesConfig.hpp b/include/vkcv/ResourcesConfig.hpp deleted file mode 100644 index d9e9a3f8..00000000 --- a/include/vkcv/ResourcesConfig.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -namespace vkcv -{ - enum class ResourceType - { - // TODO: - // uniform buffers, samplers, images should be supported for now! - }; - - struct BindingDescription - { - // TODO: - // should contain something like the binding ID, - // and the descriptor/resource type - }; - - struct SetDescription - { - // TODO: - // should contain a collection of BindingDescriptions - }; -} diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 3c3f91de..ae0f4f8a 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -2,6 +2,7 @@ #include <vkcv/Core.hpp> #include <vkcv/Window.hpp> #include <vkcv/ShaderProgram.hpp> +#include <vkcv/DescriptorConfig.hpp> int main(int argc, const char** argv) { const char* applicationName = "First Triangle"; @@ -81,6 +82,31 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } +//---------CREATION OF RESOURCES/DESCRIPTORS------------------ + //just an example + //creates 3 descriptor sets with one descriptor each + std::vector<vkcv::DescriptorSet> sets; + vkcv::DescriptorType typeA = vkcv::DescriptorType::UNIFORM_BUFFER; + vkcv::DescriptorType typeB = vkcv::DescriptorType::IMAGE; + vkcv::DescriptorType typeC = vkcv::DescriptorType::SAMPLER; + std::vector<vkcv::DescriptorType> types = { typeA, typeB, typeC }; + for (int i = 0; i < types.size(); i++) + { + vkcv::DescriptorBinding bind{}; + bind.bindingID = i; + bind.descriptorType = types[i]; + bind.descriptorCount = 1; + bind.shaderStage = vkcv::ShaderStage::VERTEX; + + vkcv::DescriptorSet set{}; + std::vector<vkcv::DescriptorBinding> bindings = { bind }; + set.bindings = bindings; + set.setCount = 1; + + sets.push_back(set); + } + core.createResourceDescription(sets); + /* * BufferHandle triangleVertices = core.createBuffer(vertices); * BufferHandle triangleIndices = core.createBuffer(indices); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index cbf5474b..2b544efe 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -215,11 +215,12 @@ namespace vkcv return m_swapchain.getSurfaceFormat().format; } - ResourcesHandle Core::createResourceDescription(const std::vector<SetDescription> &setDescriptions) + ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSet> &descriptorSets) { // TODO: // call DescriptorManager's createResourceDescription // let it do the actual work! No vulkan stuff here. - return ResourcesHandle{0}; + DescriptorManager descriptorManager = DescriptorManager(m_Context.getDevice()); + return descriptorManager.createResourceDescription(descriptorSets); } } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 32e0d031..b19c2e54 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -1,14 +1,95 @@ #include "DescriptorManager.hpp" +#include <vkcv/ShaderProgram.hpp> namespace vkcv { - ResourcesHandle vkcv::DescriptorManager::createResourceDescription(const std::vector<SetDescription> &setDescriptions) + + DescriptorManager::DescriptorManager(vk::Device device) noexcept: + m_Device{ device }, m_NextDescriptorSetID{ 1 } + { + m_DescriptorTypes = { DescriptorType::UNIFORM_BUFFER, DescriptorType::SAMPLER, DescriptorType::IMAGE }; + uint32_t sizesPerType = 1000; + uint32_t maxSetsPerPool = 1000; + + std::vector<vk::DescriptorPoolSize> descriptorPoolSizes; + for (int i = 0; i < m_DescriptorTypes.size(); i++) { + vk::DescriptorType type = convertDescriptorTypeFlag(m_DescriptorTypes[i]); + vk::DescriptorPoolSize poolSize(type, sizesPerType); + descriptorPoolSizes.push_back(poolSize); + } + vk::DescriptorPoolCreateInfo poolInfo({}, maxSetsPerPool, descriptorPoolSizes); + m_Pool = m_Device.createDescriptorPool(poolInfo, nullptr); + } + + ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSet> &p_descriptorSets) { // TODO: create all vk::DescriptorSets and allocate them from the pool // put them into a ResourceDescription struct // push that struct into m_Resources; // return the index into that object as ResourcesHandle; - return ResourcesHandle{0}; + + ResourceDescription resource{}; + + for (int i = 0; i < p_descriptorSets.size(); i++) { + DescriptorSet set = p_descriptorSets[i]; + std::vector<vk::DescriptorSetLayoutBinding> setBindings; + for (int j = 0; j < set.bindings.size(); j++) { + //creates each binding of the set + DescriptorBinding binding = set.bindings[j]; + vk::DescriptorType type = convertDescriptorTypeFlag(binding.descriptorType); + vk::ShaderStageFlagBits stage = convertShaderStageFlag(binding.shaderStage); + vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding(binding.bindingID, type, binding.descriptorCount, stage); + 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) + resource.descriptorSetLayouts.insert(resource.descriptorSetLayouts.begin(), allocLayouts.begin(), allocLayouts.end()); + resource.descriptorSets.insert(resource.descriptorSets.end(), allocSets.begin(), allocSets.end()); + } + m_Resources.push_back(resource); + return ResourcesHandle{m_NextDescriptorSetID++}; + } + + vk::DescriptorType vkcv::DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) { + switch (type) + { + case vkcv::DescriptorType::UNIFORM_BUFFER: + return vk::DescriptorType::eUniformBuffer; + case vkcv::DescriptorType::SAMPLER: + return vk::DescriptorType::eSampler; + case vkcv::DescriptorType::IMAGE: + return vk::DescriptorType::eSampledImage; + } } + + vk::ShaderStageFlagBits vkcv::DescriptorManager::convertShaderStageFlag(ShaderStage stage) { + switch (stage) + { + case vkcv::ShaderStage::VERTEX: + return vk::ShaderStageFlagBits::eVertex; + case vkcv::ShaderStage::FRAGMENT: + return vk::ShaderStageFlagBits::eFragment; + case vkcv::ShaderStage::TESS_CONTROL: + return vk::ShaderStageFlagBits::eTessellationControl; + case vkcv::ShaderStage::TESS_EVAL: + return vk::ShaderStageFlagBits::eTessellationControl; + case vkcv::ShaderStage::GEOMETRY: + return vk::ShaderStageFlagBits::eGeometry; + case vkcv::ShaderStage::COMPUTE: + return vk::ShaderStageFlagBits::eCompute; + } + } + } \ No newline at end of file diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index 5a9d4feb..d906c73a 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -1,24 +1,26 @@ #include <vulkan/vulkan.hpp> #include "vkcv/Handles.hpp" -#include "vkcv/ResourcesConfig.hpp" +#include "vkcv/DescriptorConfig.hpp" namespace vkcv { class DescriptorManager { public: - explicit DescriptorManager(vk::Device) noexcept; - ~DescriptorManager(); + explicit DescriptorManager(vk::Device device) noexcept; + ~DescriptorManager() = default; // TODO: Interface // user wishes to create descriptor sets {X,Y,Z} each with different descriptions {A,B,C} // returns a resource - ResourcesHandle createResourceDescription(const std::vector<SetDescription> &setDescriptions); + ResourcesHandle createResourceDescription(const std::vector<DescriptorSet> & p_descriptorSets); private: + vk::Device m_Device; vk::DescriptorPool m_Pool; + uint64_t m_NextDescriptorSetID; // TODO: container for all resources requested by the user struct ResourceDescription @@ -28,5 +30,19 @@ namespace vkcv }; std::vector<ResourceDescription> m_Resources; + std::vector<DescriptorType> m_DescriptorTypes; + + /** + * converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk) + * @param[in] vkcv flag of the DescriptorType (see DescriptorConfig.hpp) + * @return vk flag of the DescriptorType + */ + vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type); + /** + * converts the flags of the shader stages from VulkanCV (vkcv) to Vulkan (vk) + * @param[in] vkcv flag of the ShaderStage (see ShaderProgram.hpp) + * @return vk flag of the ShaderStage + */ + vk::ShaderStageFlagBits vkcv::DescriptorManager::convertShaderStageFlag(ShaderStage stage); }; } \ No newline at end of file diff --git a/src/vkcv/ResourcesConfig.cpp b/src/vkcv/ResourcesConfig.cpp deleted file mode 100644 index e69de29b..00000000 -- GitLab