diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index c11cdf32db944a1603af8699f760233acb000da3..e7d098812c1f7397b2bdd9a5d745376a397b415b 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -25,6 +25,7 @@ namespace vkcv { + struct VertexBufferBinding { vk::DeviceSize offset; BufferHandle buffer; @@ -215,10 +216,10 @@ namespace vkcv * @return */ [[nodiscard]] - ResourcesHandle createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets); - void writeResourceDescription(ResourcesHandle handle, size_t setIndex, const DescriptorWrites& writes); + DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &bindings); + void writeResourceDescription(DescriptorSetHandle handle, size_t setIndex, const DescriptorWrites& writes); - vk::DescriptorSetLayout getDescriptorSetLayout(ResourcesHandle handle, size_t setIndex); + DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; /** * @brief start recording command buffers and increment frame index @@ -229,14 +230,13 @@ namespace vkcv * @brief render a beautiful triangle */ void renderMesh( - const PassHandle renderpassHandle, - const PipelineHandle pipelineHandle, - const size_t pushConstantSize, - const void* pushConstantData, - const Mesh &mesh, - const vkcv::ResourcesHandle resourceHandle, - const size_t resourceDescriptorSetIndex, - const std::vector<ImageHandle> &renderTargets); + const PassHandle renderpassHandle, + const PipelineHandle pipelineHandle, + const size_t pushConstantSize, + const void* pushConstantData, + const Mesh &mesh, + const std::vector<DescriptorSetUsage> &descriptorSets, + const std::vector<ImageHandle> &renderTargets); /** * @brief end recording and present image diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index 161273db1ec3bd0be290ecdd1042d12d181d303e..15083e8c9863ac2e8d44bbe174e0d7f40bf27dfc 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -1,8 +1,23 @@ #pragma once #include <vkcv/ShaderProgram.hpp> +#include <vkcv/Handles.hpp> +#include <vulkan/vulkan.hpp> namespace vkcv { + struct DescriptorSet + { + vk::DescriptorSet vulkanHandle; + vk::DescriptorSetLayout layout; + }; + + struct DescriptorSetUsage { + DescriptorSetUsage(uint32_t setLocation, DescriptorSetHandle handle) noexcept; + + const uint32_t setLocation; + const DescriptorSetHandle handle; + }; + /* * All the types of descriptors (resources) that can be retrieved by the shaders */ @@ -24,7 +39,6 @@ namespace vkcv */ struct DescriptorBinding { - DescriptorBinding() = delete; DescriptorBinding( DescriptorType descriptorType, uint32_t descriptorCount, @@ -35,16 +49,4 @@ namespace vkcv uint32_t descriptorCount; ShaderStage shaderStage; }; - - /* - * One descriptor set struct that contains all the necessary information for the actual creation. - * @param[in] a number of bindings that were created beforehand - * @param[in] the number of (identical) sets that should be created from the attached bindings - */ - struct DescriptorSetConfig - { - explicit DescriptorSetConfig(std::vector<DescriptorBinding> bindings) noexcept; - - std::vector<DescriptorBinding> bindings; - }; } diff --git a/include/vkcv/Handles.hpp b/include/vkcv/Handles.hpp index bd80630808c03ea731a445209062a98e761849de..f2a0da0a6d9650ad22fff9a1e5ec2071eebf53e3 100644 --- a/include/vkcv/Handles.hpp +++ b/include/vkcv/Handles.hpp @@ -79,7 +79,7 @@ namespace vkcv using Handle::Handle; }; - class ResourcesHandle : public Handle { + class DescriptorSetHandle : public Handle { friend class DescriptorManager; private: using Handle::Handle; diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp index 64c08943ca89a5a07bf41aced7a79d4838c4bf37..01eec2fc2bf95e616739e0a84a35add13865cdd4 100644 --- a/projects/cmd_sync_test/src/main.cpp +++ b/projects/cmd_sync_test/src/main.cpp @@ -108,17 +108,10 @@ int main(int argc, const char** argv) { return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); }); - vkcv::DescriptorSetConfig setConfig({ + std::vector<vkcv::DescriptorBinding> descriptorBindings = { vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_SAMPLED, 1, vkcv::ShaderStage::FRAGMENT), - vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER, 1, vkcv::ShaderStage::FRAGMENT) - }); - vkcv::ResourcesHandle set = core.createResourceDescription({ setConfig }); - - //only exemplary code for testing - for (int i = 0; i < 1001; i++) { - vkcv::ResourcesHandle furtherSets = core.createResourceDescription({ setConfig }); - } - //end of exemplary code + vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER, 1, vkcv::ShaderStage::FRAGMENT)}; + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); const vkcv::PipelineConfig trianglePipelineDefinition( triangleShaderProgram, @@ -126,7 +119,7 @@ int main(int argc, const char** argv) { windowHeight, trianglePass, mesh.vertexGroups[0].vertexBuffer.attributes, - { core.getDescriptorSetLayout(set, 0) }, + { core.getDescriptorSet(descriptorSet).layout }, true); vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); @@ -148,7 +141,7 @@ int main(int argc, const char** argv) { vkcv::DescriptorWrites setWrites; setWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, texture.getHandle()) }; setWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(1, sampler) }; - core.writeResourceDescription(set, 0, setWrites); + core.writeResourceDescription(descriptorSet, 0, setWrites); vkcv::ImageHandle depthBuffer = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle(); @@ -174,8 +167,7 @@ int main(int argc, const char** argv) { sizeof(mvp), &mvp, boxMesh, - set, - 0, + { vkcv::DescriptorSetUsage(0, descriptorSet) }, { swapchainInput, depthBuffer }); core.endFrame(); diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 44cb9c7433089f6863e04dabbb0f33d52878a093..bc832b91df1a4b2cf65bdcb11d771abc4a6bf3c1 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -104,11 +104,11 @@ int main(int argc, const char** argv) { vkcv::DescriptorBinding(vkcv::DescriptorType::IMAGE_SAMPLED, 1, vkcv::ShaderStage::FRAGMENT), vkcv::DescriptorBinding(vkcv::DescriptorType::SAMPLER, 1, vkcv::ShaderStage::FRAGMENT) }); - vkcv::ResourcesHandle set = core.createResourceDescription({ setConfig }); + vkcv::DescriptorSetHandle set = core.createDescriptorSet({ setConfig }); //only exemplary code for testing for (int i = 0; i < 1001; i++) { - vkcv::ResourcesHandle furtherSets = core.createResourceDescription({ setConfig }); + vkcv::DescriptorSetHandle furtherSets = core.createDescriptorSet({ setConfig }); } //end of exemplary code @@ -118,7 +118,7 @@ int main(int argc, const char** argv) { UINT32_MAX, trianglePass, mesh.vertexGroups[0].vertexBuffer.attributes, - { core.getDescriptorSetLayout(set, 0) }, + { core.getDescriptorSet(set, 0) }, true); vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition); diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 41a35c780ae0ec2e1b5c9f6faeb5db0883974bb1..24aaa9ef45713e1a1d24e079d29f9279f49386d1 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -155,7 +155,7 @@ int main(int argc, const char** argv) { vertexBufferBindings, triangleIndexBuffer.getHandle(), 3, - vkcv::ResourcesHandle(), + vkcv::DescriptorSetHandle(), 0, {swapchainImageHandle}); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index d72f87d6cb5c47b9f8fe9db174177c0ee8aca106..472f3766de22edbc96776499566ed5c53c02a41f 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -142,14 +142,13 @@ namespace vkcv } void Core::renderMesh( - const PassHandle renderpassHandle, - const PipelineHandle pipelineHandle, - const size_t pushConstantSize, - const void *pushConstantData, - const Mesh &mesh, - const vkcv::ResourcesHandle resourceHandle, - const size_t resourceDescriptorSetIndex, - const std::vector<ImageHandle>& renderTargets) { + const PassHandle renderpassHandle, + const PipelineHandle pipelineHandle, + const size_t pushConstantSize, + const void *pushConstantData, + const Mesh &mesh, + const std::vector<DescriptorSetUsage> &descriptorSets, + const std::vector<ImageHandle> &renderTargets) { if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; @@ -262,9 +261,13 @@ namespace vkcv cmdBuffer.bindVertexBuffers(i, (vertexBuffer), (vertexBinding.offset)); } - if (resourceHandle) { - const vk::DescriptorSet descriptorSet = m_DescriptorManager->getDescriptorSet(resourceHandle, resourceDescriptorSetIndex); - cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSet, nullptr); + for (const auto &descriptorUsage : descriptorSets) { + cmdBuffer.bindDescriptorSets( + vk::PipelineBindPoint::eGraphics, + pipelineLayout, + descriptorUsage.setLocation, + m_DescriptorManager->getDescriptorSet(descriptorUsage.handle).vulkanHandle, + nullptr); } const vk::Buffer indexBuffer = m_BufferManager->getBuffer(mesh.indexBuffer); @@ -346,12 +349,12 @@ namespace vkcv return Image::create(m_ImageManager.get(), format, width, height, depth); } - ResourcesHandle Core::createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets) + DescriptorSetHandle Core::createDescriptorSet(const std::vector<DescriptorBinding>& bindings) { - return m_DescriptorManager->createResourceDescription(descriptorSets); + return m_DescriptorManager->createDescriptorSet(bindings); } - void Core::writeResourceDescription(ResourcesHandle handle, size_t setIndex, const DescriptorWrites &writes) { + void Core::writeResourceDescription(DescriptorSetHandle handle, size_t setIndex, const DescriptorWrites &writes) { m_DescriptorManager->writeResourceDescription( handle, setIndex, @@ -361,8 +364,8 @@ namespace vkcv *m_SamplerManager); } - vk::DescriptorSetLayout Core::getDescriptorSetLayout(ResourcesHandle handle, size_t setIndex) { - return m_DescriptorManager->getDescriptorSetLayout(handle, setIndex); + DescriptorSet Core::getDescriptorSet(const DescriptorSetHandle handle) const { + return m_DescriptorManager->getDescriptorSet(handle); } std::vector<vk::ImageView> Core::createImageViews( Context &context, SwapChain& swapChain){ diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp index c4f6e326560e91747d206fecc983525a5b7bb6dc..122d29fe76a6c9a1c933e40c21486f975fd286ce 100644 --- a/src/vkcv/DescriptorConfig.cpp +++ b/src/vkcv/DescriptorConfig.cpp @@ -1,20 +1,17 @@ #include "vkcv/DescriptorConfig.hpp" -#include <utility> - namespace vkcv { - DescriptorBinding::DescriptorBinding( - DescriptorType descriptorType, - uint32_t descriptorCount, - ShaderStage shaderStage - ) noexcept : - descriptorType{descriptorType}, - descriptorCount{descriptorCount}, - shaderStage{shaderStage} - {}; + DescriptorSetUsage::DescriptorSetUsage(uint32_t setLocation, DescriptorSetHandle handle) noexcept + : setLocation(setLocation), handle(handle) {} - DescriptorSetConfig::DescriptorSetConfig(std::vector<DescriptorBinding> bindings) noexcept : - bindings{std::move(bindings)} - {}; + DescriptorBinding::DescriptorBinding( + DescriptorType descriptorType, + uint32_t descriptorCount, + ShaderStage shaderStage) noexcept + : + descriptorType(descriptorType), + descriptorCount(descriptorCount), + shaderStage(shaderStage) {} + } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 2ecb23bd39cd4656c12d1816ece3db404ecdc248..a2efecbe7055122d28a864b7c722a5998be460e4 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -2,11 +2,6 @@ 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: m_Device{ device } { @@ -29,67 +24,63 @@ namespace vkcv DescriptorManager::~DescriptorManager() noexcept { - for (uint64_t id = 0; id < m_ResourceDescriptions.size(); id++) { - destroyResourceDescriptionById(id); + for (uint64_t id = 0; id < m_DescriptorSets.size(); id++) { + destroyDescriptorSetById(id); } + m_DescriptorSets.clear(); for (const auto &pool : m_Pools) { m_Device.destroy(pool); } } - ResourcesHandle DescriptorManager::createResourceDescription(const std::vector<DescriptorSetConfig> &descriptorSets) + DescriptorSetHandle DescriptorManager::createDescriptorSet(const std::vector<DescriptorBinding>& bindings) { - std::vector<vk::DescriptorSet> vk_sets; - std::vector<vk::DescriptorSetLayout> vk_setLayouts; + std::vector<vk::DescriptorSetLayoutBinding> setBindings = {}; - for (const auto &set : descriptorSets) { - std::vector<vk::DescriptorSetLayoutBinding> setBindings = {}; + //create each set's binding + for (uint32_t i = 0; i < bindings.size(); i++) { + vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( + i, + convertDescriptorTypeFlag(bindings[i].descriptorType), + bindings[i].descriptorCount, + convertShaderStageFlag(bindings[i].shaderStage)); + setBindings.push_back(descriptorSetLayoutBinding); + } - //create each set's binding - for (uint32_t j = 0; j < set.bindings.size(); j++) { - vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( - j, - convertDescriptorTypeFlag(set.bindings[j].descriptorType), - set.bindings[j].descriptorCount, - convertShaderStageFlag(set.bindings[j].shaderStage)); - setBindings.push_back(descriptorSetLayoutBinding); - } + DescriptorSet set; - //create the descriptor set's layout from the bindings gathered above - vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings); - 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(); - }; - vk_setLayouts.push_back(layout); - } - //create and allocate the set(s) based on the layouts that have been gathered above - vk_sets.resize(vk_setLayouts.size()); - vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), vk_sets.size(), vk_setLayouts.data()); - auto result = m_Device.allocateDescriptorSets(&allocInfo, vk_sets.data()); + //create the descriptor set's layout from the bindings gathered above + vk::DescriptorSetLayoutCreateInfo layoutInfo({}, setBindings); + if(m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &set.layout) != vk::Result::eSuccess) + { + std::cout << "FAILED TO CREATE DESCRIPTOR SET LAYOUT" << std::endl; + return DescriptorSetHandle(); + }; + + //create and allocate the set based on the layout that have been gathered above + vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &set.layout); + auto result = m_Device.allocateDescriptorSets(&allocInfo, &set.vulkanHandle); if(result != vk::Result::eSuccess) { //create a new descriptor pool if the previous one ran out of memory if (result == vk::Result::eErrorOutOfPoolMemory) { allocateDescriptorPool(); allocInfo.setDescriptorPool(m_Pools.back()); - result = m_Device.allocateDescriptorSets(&allocInfo, vk_sets.data()); + result = m_Device.allocateDescriptorSets(&allocInfo, &set.vulkanHandle); } 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); + m_Device.destroy(set.layout); - return ResourcesHandle(); + return DescriptorSetHandle(); } }; - const uint64_t id = m_ResourceDescriptions.size(); - m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts); - return ResourcesHandle(id, [&](uint64_t id) { destroyResourceDescriptionById(id); }); + const uint64_t id = m_DescriptorSets.size(); + + m_DescriptorSets.push_back(set); + return DescriptorSetHandle(id, [&](uint64_t id) { destroyDescriptorSetById(id); }); } struct WriteDescriptorSetInfo { @@ -100,14 +91,14 @@ namespace vkcv }; void DescriptorManager::writeResourceDescription( - const ResourcesHandle &handle, + const DescriptorSetHandle &handle, size_t setIndex, const DescriptorWrites &writes, const ImageManager &imageManager, const BufferManager &bufferManager, const SamplerManager &samplerManager) { - vk::DescriptorSet set = m_ResourceDescriptions[handle.getId()].descriptorSets[setIndex]; + vk::DescriptorSet set = m_DescriptorSets[handle.getId()].vulkanHandle; std::vector<vk::DescriptorImageInfo> imageInfos; std::vector<vk::DescriptorBufferInfo> bufferInfos; @@ -230,12 +221,8 @@ namespace vkcv m_Device.updateDescriptorSets(vulkanWrites, nullptr); } - vk::DescriptorSet DescriptorManager::getDescriptorSet(const ResourcesHandle &handle, size_t index) const { - return m_ResourceDescriptions[handle.getId()].descriptorSets[index]; - } - - vk::DescriptorSetLayout DescriptorManager::getDescriptorSetLayout(const ResourcesHandle &handle, size_t index) const { - return m_ResourceDescriptions[handle.getId()].descriptorSetLayouts[index]; + DescriptorSet DescriptorManager::getDescriptorSet(const DescriptorSetHandle handle) const { + return m_DescriptorSets[handle.getId()]; } vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) { @@ -277,18 +264,18 @@ namespace vkcv } } - void DescriptorManager::destroyResourceDescriptionById(uint64_t id) { - if (id >= m_ResourceDescriptions.size()) { + void DescriptorManager::destroyDescriptorSetById(uint64_t id) { + if (id >= m_DescriptorSets.size()) { + std::cerr << "Error: DescriptorManager::destroyResourceDescriptionById invalid id" << std::endl; return; } - auto& resourceDescription = m_ResourceDescriptions[id]; - - for(const auto &layout : resourceDescription.descriptorSetLayouts) { - m_Device.destroyDescriptorSetLayout(layout); + auto& set = m_DescriptorSets[id]; + if (set.layout) { + m_Device.destroyDescriptorSetLayout(set.layout); + set.layout = nullptr; } - - resourceDescription.descriptorSetLayouts.clear(); + // FIXME: descriptor set itself not destroyed } vk::DescriptorPool DescriptorManager::allocateDescriptorPool() { diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index 22042c703256055e3852b7a4729faad39b5d0dbb..d8607b9312b25e71c7eb4af009efd92b834b40ec 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -21,17 +21,10 @@ namespace vkcv explicit DescriptorManager(vk::Device device) noexcept; ~DescriptorManager() noexcept; - /** - * Creates all vk::DescriptorSets and allocates them from the pool. - * DescriptorSets are put inside a ResourceDescription struct. - * Structs are then put into m_ResourceDescriptions. - * @param[in] vector of filled vkcv::DescriptorSet structs - * @return index into that objects a resource handle - */ - ResourcesHandle createResourceDescription(const std::vector<DescriptorSetConfig> & descriptorSets); + DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &descriptorBindings); void writeResourceDescription( - const ResourcesHandle &handle, + const DescriptorSetHandle &handle, size_t setIndex, const DescriptorWrites &writes, const ImageManager &imageManager, @@ -39,34 +32,19 @@ namespace vkcv const SamplerManager &samplerManager); [[nodiscard]] - vk::DescriptorSet getDescriptorSet(const ResourcesHandle &handle, size_t index) const; - [[nodiscard]] - vk::DescriptorSetLayout getDescriptorSetLayout(const ResourcesHandle &handle, size_t index) const; + DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; private: - vk::Device m_Device; + vk::Device m_Device; std::vector<vk::DescriptorPool> m_Pools; std::vector<vk::DescriptorPoolSize> m_PoolSizes; vk::DescriptorPoolCreateInfo m_PoolInfo; - /** - * Container for all resources requested by the user in one call of createResourceDescription. - * Includes descriptor sets and the respective descriptor set layouts. - */ - struct ResourceDescription - { - ResourceDescription() = delete; - ResourceDescription(std::vector<vk::DescriptorSet> sets, std::vector<vk::DescriptorSetLayout> layouts) noexcept; - - std::vector<vk::DescriptorSet> descriptorSets; - std::vector<vk::DescriptorSetLayout> descriptorSetLayouts; - }; - /** * Contains all the resource descriptions that were requested by the user in calls of createResourceDescription. */ - std::vector<ResourceDescription> m_ResourceDescriptions; + std::vector<DescriptorSet> m_DescriptorSets; /** * Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk). @@ -85,7 +63,7 @@ namespace vkcv * Destroys a specific resource description * @param[in] the handle id of the respective resource description */ - void destroyResourceDescriptionById(uint64_t id); + void destroyDescriptorSetById(uint64_t id); /** * creates a descriptor pool based on the poolSizes and poolInfo defined in the constructor