diff --git a/config/Sources.cmake b/config/Sources.cmake index 7646cf6f07e172341fcdda4a2f56f4a19955b901..3d1120be5301f835f93215023d5a83a54e0c686c 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 79a9d29d636540fe069b192322472c9e641a9039..680f0b628c5e1f48acc5e2c070863da05b7ffea7 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 0000000000000000000000000000000000000000..c4666b18798d5b71393d9b37e74b3187cc96583f --- /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 0000000000000000000000000000000000000000..969f3558f7ec2842f26920c0a8c59be86f5d6fc2 --- /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 d9e9a3f8864afa3e78d68bb5896d09edf97fda56..0000000000000000000000000000000000000000 --- 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 3c3f91de9ac1c4490859559db2bca5bdd089ecfa..ae0f4f8abb900bec54f70b222b837cfb6246ff15 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 cbf5474b6a25f7598c8c5bc74df50f1a2145a69a..2b544efe826a6da5fa3bd166191a16696d6d5931 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 32e0d031bb789af5aed9d51ad1bd14b52c4d2b9f..b19c2e54f44cd79c04bc81bf58767d74bc27d3ce 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 5a9d4feb30ce6e69e32eba461cba182afbe88b4c..d906c73ae987d4d1fc460f7b08509f20a03060e2 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 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000