diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 817c3f5840895158f621ae0c022df07c3c97978a..e20a34446d5d23ad0fa79946d2fdfa74a8177eba 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -233,16 +233,26 @@ namespace vkcv [[nodiscard]] vk::Format getImageFormat(const ImageHandle& image); + /** TODO: + * @param bindings + * @return + */ + [[nodiscard]] + DescriptorSetLayoutHandle createDescriptorSetLayout(const std::unordered_map<uint32_t, DescriptorBinding> &bindingsMap); + DescriptorSetLayout getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const; + + // TODO: existsDescriptorSetLayout function that checks and returns fitting layout upon existence. + /** TODO: * @param setDescriptions * @return */ [[nodiscard]] - DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &bindings); + DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &layoutHandle); void writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites& writes); - DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; + /** * @brief start recording command buffers and increment frame index */ diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index f2a089fd624c02c57db4a65c4a101c4acff371b1..2fac0a24e24260fee9b5936243535110cb228dbe 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -1,17 +1,13 @@ #pragma once +#include <unordered_map> + #include "vkcv/Handles.hpp" #include "vkcv/ShaderStage.hpp" +#include "vkcv/Logger.hpp" namespace vkcv { - struct DescriptorSet - { - vk::DescriptorSet vulkanHandle; - vk::DescriptorSetLayout layout; - size_t poolIndex; - }; - /* * All the types of descriptors (resources) that can be retrieved by the shaders */ @@ -25,7 +21,34 @@ namespace vkcv UNIFORM_BUFFER_DYNAMIC, STORAGE_BUFFER_DYNAMIC }; - + + /** + * Converts the descriptor types from VulkanCV (vkcv) to native Vulkan (vk). + * @param[in] vkcv DescriptorType + * @return vk DescriptorType + */ + constexpr vk::DescriptorType getVkDescriptorType(DescriptorType type) noexcept { + switch (type) + { + case DescriptorType::UNIFORM_BUFFER: + return vk::DescriptorType::eUniformBuffer; + case DescriptorType::UNIFORM_BUFFER_DYNAMIC: + return vk::DescriptorType::eUniformBufferDynamic; + case DescriptorType::STORAGE_BUFFER: + return vk::DescriptorType::eStorageBuffer; + case DescriptorType::STORAGE_BUFFER_DYNAMIC: + return vk::DescriptorType::eStorageBufferDynamic; + case DescriptorType::SAMPLER: + return vk::DescriptorType::eSampler; + case DescriptorType::IMAGE_SAMPLED: + return vk::DescriptorType::eSampledImage; + case DescriptorType::IMAGE_STORAGE: + return vk::DescriptorType::eStorageImage; + default: + return vk::DescriptorType::eMutableVALVE; + } + } + /* * One binding for a descriptor set * @param[in] a unique binding ID @@ -42,9 +65,26 @@ namespace vkcv ShaderStages shaderStages ) noexcept; - uint32_t bindingID; - DescriptorType descriptorType; - uint32_t descriptorCount; - ShaderStages shaderStages; + uint32_t bindingID; + DescriptorType descriptorType; + uint32_t descriptorCount; + ShaderStages shaderStages; + + bool operator ==(const DescriptorBinding &other) const; + }; + + typedef std::unordered_map<uint32_t, DescriptorBinding> DescriptorBindings; + + struct DescriptorSetLayout + { + vk::DescriptorSetLayout vulkanHandle; + DescriptorBindings descriptorBindings; + }; + + struct DescriptorSet + { + vk::DescriptorSet vulkanHandle; + DescriptorSetLayoutHandle setLayoutHandle; + size_t poolIndex; }; } diff --git a/include/vkcv/Handles.hpp b/include/vkcv/Handles.hpp index ea05bd212dd9314957e4771070bedb3963b1b2dc..1a88a85ee379c8e1999d13a0ec0f4c91a6abf420 100644 --- a/include/vkcv/Handles.hpp +++ b/include/vkcv/Handles.hpp @@ -84,6 +84,12 @@ namespace vkcv private: using Handle::Handle; }; + + class DescriptorSetLayoutHandle : public Handle { + friend class DescriptorManager; + private: + using Handle::Handle; + }; class SamplerHandle : public Handle { friend class SamplerManager; diff --git a/include/vkcv/ShaderProgram.hpp b/include/vkcv/ShaderProgram.hpp index c7d67b19148b3c9ec19ce1b539f9661797d1b38f..d39f0da436089830fc90e5178b056d0be2cae910 100644 --- a/include/vkcv/ShaderProgram.hpp +++ b/include/vkcv/ShaderProgram.hpp @@ -51,7 +51,13 @@ namespace vkcv { const std::vector<VertexAttachment> &getVertexAttachments() const; size_t getPushConstantSize() const; - const std::vector<std::vector<DescriptorBinding>>& getReflectedDescriptors() const; + /** + * Returns the reflected descriptor sets/layouts/bindings in a map of maps. + * First uint32_t serves as descriptor SET id. + * Second uint32_t serves as the descriptor set's BINDING id. + * @return + */ + const std::unordered_map<uint32_t, std::unordered_map<uint32_t, DescriptorBinding>>& getReflectedDescriptors() const; private: /** @@ -65,7 +71,7 @@ namespace vkcv { // contains all vertex input attachments used in the vertex buffer std::vector<VertexAttachment> m_VertexAttachments; - std::vector<std::vector<DescriptorBinding>> m_DescriptorSets; + std::unordered_map<uint32_t, std::unordered_map<uint32_t, DescriptorBinding>> m_DescriptorSets; size_t m_pushConstantSize = 0; }; } diff --git a/modules/material/include/vkcv/material/Material.hpp b/modules/material/include/vkcv/material/Material.hpp index 9b54d99828eca3738fed9ff1c4078ca9f87eaefa..41ee8aecce98072981be80ccf9803c43c6464746 100644 --- a/modules/material/include/vkcv/material/Material.hpp +++ b/modules/material/include/vkcv/material/Material.hpp @@ -23,6 +23,7 @@ namespace vkcv::material { MaterialType m_Type; DescriptorSetHandle m_DescriptorSet; + DescriptorSetLayoutHandle m_DescriptorSetLayout; std::vector<Texture> m_Textures; public: @@ -40,12 +41,15 @@ namespace vkcv::material { [[nodiscard]] const DescriptorSetHandle& getDescriptorSet() const; + + [[nodiscard]] + const DescriptorSetLayoutHandle& getDescriptorSetLayout() const; explicit operator bool() const; bool operator!() const; - static const std::vector<DescriptorBinding>& getDescriptorBindings(MaterialType type); + static const std::unordered_map<uint32_t ,DescriptorBinding>& getDescriptorBindings(MaterialType type); static Material createPBR(Core &core, const ImageHandle &colorImg, diff --git a/modules/material/src/vkcv/material/Material.cpp b/modules/material/src/vkcv/material/Material.cpp index 409db0b9dd83f91b6a2afbb48d74933ab1a483fc..43a72e4cb6c936457f3723e32dc2715d9788ce08 100644 --- a/modules/material/src/vkcv/material/Material.cpp +++ b/modules/material/src/vkcv/material/Material.cpp @@ -14,6 +14,10 @@ namespace vkcv::material { const DescriptorSetHandle & Material::getDescriptorSet() const { return m_DescriptorSet; } + + const DescriptorSetLayoutHandle & Material::getDescriptorSetLayout() const { + return m_DescriptorSetLayout; + } Material::operator bool() const { return (m_Type != MaterialType::UNKNOWN); @@ -23,24 +27,25 @@ namespace vkcv::material { return (m_Type == MaterialType::UNKNOWN); } - const std::vector<DescriptorBinding>& Material::getDescriptorBindings(MaterialType type) + const DescriptorBindings& Material::getDescriptorBindings(MaterialType type) { - static std::vector<DescriptorBinding> pbr_bindings; - static std::vector<DescriptorBinding> default_bindings; + static DescriptorBindings pbr_bindings = {}; + static DescriptorBindings default_bindings = {}; switch (type) { case MaterialType::PBR_MATERIAL: - if (pbr_bindings.empty()) { - pbr_bindings.emplace_back(0, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(1, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(2, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(3, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(4, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(5, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(6, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(7, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(8, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT); - pbr_bindings.emplace_back(9, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT); + if (pbr_bindings.empty()) + { + pbr_bindings.insert(std::make_pair(0, DescriptorBinding(0, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(1, DescriptorBinding(1, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(2, DescriptorBinding(2, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(3, DescriptorBinding(3, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(4, DescriptorBinding(4, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(5, DescriptorBinding(5, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(6, DescriptorBinding(6, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(7, DescriptorBinding(7, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(8, DescriptorBinding(8, DescriptorType::IMAGE_SAMPLED, 1, ShaderStage::FRAGMENT))); + pbr_bindings.insert(std::make_pair(9, DescriptorBinding(9, DescriptorType::SAMPLER, 1, ShaderStage::FRAGMENT))); } return pbr_bindings; @@ -163,7 +168,8 @@ namespace vkcv::material { material.m_Type = MaterialType::PBR_MATERIAL; const auto& bindings = getDescriptorBindings(material.m_Type); - material.m_DescriptorSet = core.createDescriptorSet(bindings);; + material.m_DescriptorSetLayout = core.createDescriptorSetLayout(bindings); + material.m_DescriptorSet = core.createDescriptorSet(material.m_DescriptorSetLayout);; material.m_Textures.reserve(bindings.size()); material.m_Textures.push_back({ images[0], samplers[0], std::vector<float>(baseColorFactor, baseColorFactor+4) }); diff --git a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp index 2a1338b85e3ee60a33215157aaaa15817f2db97f..241544c79545384d14a2599fb718cd3992455705 100644 --- a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp +++ b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp @@ -32,8 +32,11 @@ namespace vkcv::upscaling { private: PipelineHandle m_easuPipeline; PipelineHandle m_rcasPipeline; - + + DescriptorSetLayoutHandle m_easuDescriptorSetLayout; DescriptorSetHandle m_easuDescriptorSet; + + DescriptorSetLayoutHandle m_rcasDescriptorSetLayout; DescriptorSetHandle m_rcasDescriptorSet; Buffer<FSRConstants> m_easuConstants; diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index b11051273ba6f9e56d3a537931f9d33fff657e43..88436c148d711638554f82a0cfb7be2dc81c998e 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -65,25 +65,44 @@ namespace vkcv::upscaling { } } - static std::vector<DescriptorBinding> getDescriptorBindings() { - return std::vector<DescriptorBinding>({ - DescriptorBinding( - 0, DescriptorType::UNIFORM_BUFFER_DYNAMIC, - 1, ShaderStage::COMPUTE - ), - DescriptorBinding( - 1, DescriptorType::IMAGE_SAMPLED, - 1, ShaderStage::COMPUTE - ), - DescriptorBinding( - 2, DescriptorType::IMAGE_STORAGE, - 1, ShaderStage::COMPUTE - ), - DescriptorBinding( - 3, DescriptorType::SAMPLER, - 1, ShaderStage::COMPUTE - ) - }); + static DescriptorBindings getDescriptorBindings() { + DescriptorBindings descriptorBindings = {}; + + auto binding_0 = DescriptorBinding( + 0, + DescriptorType::UNIFORM_BUFFER_DYNAMIC, + 1, + ShaderStage::COMPUTE + ); + + auto binding_1 = DescriptorBinding( + 1, + DescriptorType::IMAGE_SAMPLED, + 1, + ShaderStage::COMPUTE + ); + + auto binding_2 = DescriptorBinding( + 2, + DescriptorType::IMAGE_STORAGE, + 1, + ShaderStage::COMPUTE + ); + + auto binding_3 = DescriptorBinding( + 3, + DescriptorType::SAMPLER, + 1, + ShaderStage::COMPUTE + ); + + descriptorBindings.insert(std::make_pair(0, binding_0)); + descriptorBindings.insert(std::make_pair(1, binding_1)); + descriptorBindings.insert(std::make_pair(2, binding_2)); + descriptorBindings.insert(std::make_pair(3, binding_3)); + + return descriptorBindings; + } template<typename T> @@ -155,8 +174,13 @@ namespace vkcv::upscaling { Upscaling(core), m_easuPipeline(), m_rcasPipeline(), - m_easuDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), - m_rcasDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), + + m_easuDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings())), + m_easuDescriptorSet(m_core.createDescriptorSet(m_easuDescriptorSetLayout)), + + m_rcasDescriptorSetLayout(m_core.createDescriptorSetLayout(getDescriptorBindings())), + m_rcasDescriptorSet(m_core.createDescriptorSet(m_rcasDescriptorSetLayout)), + m_easuConstants(m_core.createBuffer<FSRConstants>( BufferType::UNIFORM,1, BufferMemoryType::HOST_VISIBLE @@ -207,7 +231,7 @@ namespace vkcv::upscaling { }); m_easuPipeline = m_core.createComputePipeline(program, { - m_core.getDescriptorSet(m_easuDescriptorSet).layout + m_core.getDescriptorSetLayout(m_easuDescriptorSetLayout).vulkanHandle }); DescriptorWrites writes; @@ -228,7 +252,7 @@ namespace vkcv::upscaling { }); m_rcasPipeline = m_core.createComputePipeline(program, { - m_core.getDescriptorSet(m_rcasDescriptorSet).layout + m_core.getDescriptorSetLayout(m_rcasDescriptorSetLayout).vulkanHandle }); DescriptorWrites writes; diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 2ad76e8f78c5870f6b582a1970caac306026166f..0649bdd12ae50d34c4c9b37119a022ac9b59bafa 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -105,9 +105,16 @@ int main(int argc, const char** argv) { const vkcv::VertexLayout firstMeshLayout (bindings); - uint32_t setID = 0; - std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[setID] }; - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings); + + // since we only use one descriptor set (namely, desc set 0), directly address it + // recreate copies of the bindings and the handles (to check whether they are properly reused instead of actually recreated) + std::unordered_map<uint32_t, vkcv::DescriptorBinding> set0Bindings = firstMeshProgram.getReflectedDescriptors().at(0); + auto set0BindingsExplicitCopy = set0Bindings; + + vkcv::DescriptorSetLayoutHandle setLayoutHandle = core.createDescriptorSetLayout(set0Bindings); + vkcv::DescriptorSetLayoutHandle setLayoutHandleCopy = core.createDescriptorSetLayout(set0BindingsExplicitCopy); + + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(setLayoutHandle); const vkcv::PipelineConfig firstMeshPipelineConfig { firstMeshProgram, @@ -115,7 +122,7 @@ int main(int argc, const char** argv) { UINT32_MAX, firstMeshPass, {firstMeshLayout}, - { core.getDescriptorSet(descriptorSet).layout }, + { core.getDescriptorSetLayout(setLayoutHandle).vulkanHandle }, true }; vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig); diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index 21f8deacdb3f81fcd29c5f14cbe74485f36d13cd..cc026e4302e9970be58fc698e9148ea3c6602806 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -84,15 +84,15 @@ int main(int argc, const char** argv) { const auto& material0 = scene.getMaterial(0); - const vkcv::PipelineConfig scenePipelineDefsinition{ + const vkcv::PipelineConfig scenePipelineDefinition{ sceneShaderProgram, UINT32_MAX, UINT32_MAX, scenePass, {sceneLayout}, - { core.getDescriptorSet(material0.getDescriptorSet()).layout }, + { core.getDescriptorSetLayout(material0.getDescriptorSetLayout()).vulkanHandle }, true }; - vkcv::PipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefsinition); + vkcv::PipelineHandle scenePipeline = core.createGraphicsPipeline(scenePipelineDefinition); if (!scenePipeline) { std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; diff --git a/projects/indirect_dispatch/src/AppSetup.cpp b/projects/indirect_dispatch/src/AppSetup.cpp index 267ac6bd8ef44dcee9b3a05d7204e8d33fbe86a7..659ceffd55570db64cf26ed1597d8256c3b8efa0 100644 --- a/projects/indirect_dispatch/src/AppSetup.cpp +++ b/projects/indirect_dispatch/src/AppSetup.cpp @@ -122,12 +122,14 @@ bool loadGraphicPass( const auto descriptorBindings = shaderProgram.getReflectedDescriptors(); const bool hasDescriptor = descriptorBindings.size() > 0; + std::vector<vk::DescriptorSetLayout> descriptorSetLayouts = {}; if (hasDescriptor) - outPassHandles->descriptorSet = core.createDescriptorSet(descriptorBindings[0]); + { + outPassHandles->descriptorSetLayout = core.createDescriptorSetLayout(descriptorBindings.at(0)); + outPassHandles->descriptorSet = core.createDescriptorSet(outPassHandles->descriptorSetLayout); + descriptorSetLayouts.push_back(core.getDescriptorSetLayout(outPassHandles->descriptorSetLayout).vulkanHandle); + } - std::vector<vk::DescriptorSetLayout> descriptorLayouts; - if (hasDescriptor) - descriptorLayouts.push_back(core.getDescriptorSet(outPassHandles->descriptorSet).layout); vkcv::PipelineConfig pipelineConfig{ shaderProgram, @@ -135,7 +137,7 @@ bool loadGraphicPass( UINT32_MAX, outPassHandles->renderPass, { vertexLayout }, - descriptorLayouts, + descriptorSetLayouts, true }; pipelineConfig.m_depthTest = depthTest; outPassHandles->pipeline = core.createGraphicsPipeline(pipelineConfig); @@ -254,11 +256,11 @@ bool loadComputePass(vkcv::Core& core, const std::filesystem::path& path, Comput return false; } - outComputePass->descriptorSet = core.createDescriptorSet(shaderProgram.getReflectedDescriptors()[0]); - + outComputePass->descriptorSetLayout = core.createDescriptorSetLayout(shaderProgram.getReflectedDescriptors().at(0)); + outComputePass->descriptorSet = core.createDescriptorSet(outComputePass->descriptorSetLayout); outComputePass->pipeline = core.createComputePipeline( shaderProgram, - { core.getDescriptorSet(outComputePass->descriptorSet).layout }); + { core.getDescriptorSetLayout(outComputePass->descriptorSetLayout).vulkanHandle }); if (!outComputePass->pipeline) { vkcv_log(vkcv::LogLevel::ERROR, "Compute shader pipeline creation failed"); diff --git a/projects/indirect_dispatch/src/AppSetup.hpp b/projects/indirect_dispatch/src/AppSetup.hpp index 3125bc516b553de715d6e51bbda259e3e16f758f..162a6c6126f39adb85da7e419ef4e5b9793dc5ad 100644 --- a/projects/indirect_dispatch/src/AppSetup.hpp +++ b/projects/indirect_dispatch/src/AppSetup.hpp @@ -8,14 +8,16 @@ struct AppRenderTargets { }; struct GraphicPassHandles { - vkcv::PipelineHandle pipeline; - vkcv::PassHandle renderPass; - vkcv::DescriptorSetHandle descriptorSet; + vkcv::PipelineHandle pipeline; + vkcv::PassHandle renderPass; + vkcv::DescriptorSetLayoutHandle descriptorSetLayout; + vkcv::DescriptorSetHandle descriptorSet; }; struct ComputePassHandles { - vkcv::PipelineHandle pipeline; - vkcv::DescriptorSetHandle descriptorSet; + vkcv::PipelineHandle pipeline; + vkcv::DescriptorSetLayoutHandle descriptorSetLayout; + vkcv::DescriptorSetHandle descriptorSet; }; struct MeshResources { diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index 15aaf527619b4fb06d89bccc78cffe843cc723b7..600de22a8f94b37ee8fdf74256acc51aea2e07a9 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -205,7 +205,8 @@ int main(int argc, const char** argv) { } const vkcv::VertexLayout bunnyLayout (bindings); - vkcv::DescriptorSetHandle vertexShaderDescriptorSet = core.createDescriptorSet(bunnyShaderProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle vertexShaderDescriptorSetLayout = core.createDescriptorSetLayout(bunnyShaderProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle vertexShaderDescriptorSet = core.createDescriptorSet(vertexShaderDescriptorSetLayout); const vkcv::PipelineConfig bunnyPipelineDefinition { bunnyShaderProgram, @@ -213,7 +214,7 @@ int main(int argc, const char** argv) { (uint32_t)windowHeight, renderPass, { bunnyLayout }, - { core.getDescriptorSet(vertexShaderDescriptorSet).layout }, + { core.getDescriptorSetLayout(vertexShaderDescriptorSetLayout).vulkanHandle }, false }; @@ -253,8 +254,8 @@ int main(int argc, const char** argv) { meshShaderProgram.addShader(shaderStage, path); }); - uint32_t setID = 0; - vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet( meshShaderProgram.getReflectedDescriptors()[setID]); + vkcv::DescriptorSetLayoutHandle meshShaderDescriptorSetLayout = core.createDescriptorSetLayout(meshShaderProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle meshShaderDescriptorSet = core.createDescriptorSet(meshShaderDescriptorSetLayout); const vkcv::VertexLayout meshShaderLayout(bindings); const vkcv::PipelineConfig meshShaderPipelineDefinition{ @@ -263,7 +264,7 @@ int main(int argc, const char** argv) { (uint32_t)windowHeight, renderPass, {meshShaderLayout}, - {core.getDescriptorSet(meshShaderDescriptorSet).layout}, + {core.getDescriptorSetLayout(meshShaderDescriptorSetLayout).vulkanHandle}, false }; diff --git a/projects/particle_simulation/src/BloomAndFlares.cpp b/projects/particle_simulation/src/BloomAndFlares.cpp index 5961aae664a39dfb9bd597ffa7648c9b67999af4..68a553574eddd668f7c0360b91d4da448c5b8cf8 100644 --- a/projects/particle_simulation/src/BloomAndFlares.cpp +++ b/projects/particle_simulation/src/BloomAndFlares.cpp @@ -30,11 +30,14 @@ BloomAndFlares::BloomAndFlares( }); for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++) { + m_DownsampleDescSetLayouts.push_back( + p_Core->createDescriptorSetLayout(dsProg.getReflectedDescriptors().at(0))); + m_DownsampleDescSets.push_back( - p_Core->createDescriptorSet(dsProg.getReflectedDescriptors()[0])); + p_Core->createDescriptorSet(m_DownsampleDescSetLayouts.back())); } m_DownsamplePipe = p_Core->createComputePipeline( - dsProg, { p_Core->getDescriptorSet(m_DownsampleDescSets[0]).layout }); + dsProg, { p_Core->getDescriptorSetLayout(m_DownsampleDescSetLayouts[0]).vulkanHandle }); // UPSAMPLE vkcv::ShaderProgram usProg; @@ -46,11 +49,13 @@ BloomAndFlares::BloomAndFlares( }); for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++) { + m_UpsampleDescSetLayouts.push_back( + p_Core->createDescriptorSetLayout(usProg.getReflectedDescriptors().at(0))); m_UpsampleDescSets.push_back( - p_Core->createDescriptorSet(usProg.getReflectedDescriptors()[0])); + p_Core->createDescriptorSet(m_UpsampleDescSetLayouts.back())); } m_UpsamplePipe = p_Core->createComputePipeline( - usProg, { p_Core->getDescriptorSet(m_UpsampleDescSets[0]).layout }); + usProg, { p_Core->getDescriptorSetLayout(m_UpsampleDescSetLayouts[0]).vulkanHandle }); // LENS FEATURES vkcv::ShaderProgram lensProg; @@ -60,9 +65,10 @@ BloomAndFlares::BloomAndFlares( { lensProg.addShader(shaderStage, path); }); - m_LensFlareDescSet = p_Core->createDescriptorSet(lensProg.getReflectedDescriptors()[0]); + m_LensFlareDescSetLayout = p_Core->createDescriptorSetLayout(lensProg.getReflectedDescriptors().at(0)); + m_LensFlareDescSet = p_Core->createDescriptorSet(m_LensFlareDescSetLayout); m_LensFlarePipe = p_Core->createComputePipeline( - lensProg, { p_Core->getDescriptorSet(m_LensFlareDescSet).layout }); + lensProg, { p_Core->getDescriptorSetLayout(m_LensFlareDescSetLayout).vulkanHandle }); // COMPOSITE vkcv::ShaderProgram compProg; @@ -72,9 +78,10 @@ BloomAndFlares::BloomAndFlares( { compProg.addShader(shaderStage, path); }); - m_CompositeDescSet = p_Core->createDescriptorSet(compProg.getReflectedDescriptors()[0]); + m_CompositeDescSetLayout = p_Core->createDescriptorSetLayout(compProg.getReflectedDescriptors().at(0)); + m_CompositeDescSet = p_Core->createDescriptorSet(m_CompositeDescSetLayout); m_CompositePipe = p_Core->createComputePipeline( - compProg, { p_Core->getDescriptorSet(m_CompositeDescSet).layout }); + compProg, { p_Core->getDescriptorSetLayout(m_CompositeDescSetLayout).vulkanHandle }); } void BloomAndFlares::execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream, diff --git a/projects/particle_simulation/src/BloomAndFlares.hpp b/projects/particle_simulation/src/BloomAndFlares.hpp index 756b1ca154ea5232df04eb09a88bb743c5bd28aa..21f69f43511fabb920fd85c9e07f3fd0e5a355f3 100644 --- a/projects/particle_simulation/src/BloomAndFlares.hpp +++ b/projects/particle_simulation/src/BloomAndFlares.hpp @@ -25,17 +25,21 @@ private: vkcv::Image m_LensFeatures; - vkcv::PipelineHandle m_DownsamplePipe; - std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set + vkcv::PipelineHandle m_DownsamplePipe; + std::vector<vkcv::DescriptorSetLayoutHandle> m_DownsampleDescSetLayouts; + std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set - vkcv::PipelineHandle m_UpsamplePipe; - std::vector<vkcv::DescriptorSetHandle> m_UpsampleDescSets; // per mip desc set + vkcv::PipelineHandle m_UpsamplePipe; + std::vector<vkcv::DescriptorSetLayoutHandle> m_UpsampleDescSetLayouts; + std::vector<vkcv::DescriptorSetHandle> m_UpsampleDescSets; // per mip desc set - vkcv::PipelineHandle m_LensFlarePipe; - vkcv::DescriptorSetHandle m_LensFlareDescSet; + vkcv::PipelineHandle m_LensFlarePipe; + vkcv::DescriptorSetLayoutHandle m_LensFlareDescSetLayout; + vkcv::DescriptorSetHandle m_LensFlareDescSet; - vkcv::PipelineHandle m_CompositePipe; - vkcv::DescriptorSetHandle m_CompositeDescSet; + vkcv::PipelineHandle m_CompositePipe; + vkcv::DescriptorSetLayoutHandle m_CompositeDescSetLayout; + vkcv::DescriptorSetHandle m_CompositeDescSet; void execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment); void execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream); diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index 4de016aefd345a4231ea2dae0818b0839b163729..4027ce7b2d6aabd72653efd35d76db971b90d0ae 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -82,7 +82,8 @@ int main(int argc, const char **argv) { computeShaderProgram.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeShaderProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle computeDescriptorSetLayout = core.createDescriptorSetLayout(computeShaderProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle computeDescriptorSet = core.createDescriptorSet(computeDescriptorSetLayout); const std::vector<vkcv::VertexAttachment> computeVertexAttachments = computeShaderProgram.getVertexAttachments(); @@ -100,8 +101,9 @@ int main(int argc, const char **argv) { particleShaderProgram.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet( - particleShaderProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle descriptorSetLayout = core.createDescriptorSetLayout( + particleShaderProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorSetLayout); vkcv::Buffer<glm::vec3> vertexBuffer = core.createBuffer<glm::vec3>( vkcv::BufferType::VERTEX, @@ -125,7 +127,7 @@ int main(int argc, const char **argv) { UINT32_MAX, particlePass, {particleLayout}, - {core.getDescriptorSet(descriptorSet).layout}, + {core.getDescriptorSetLayout(descriptorSetLayout).vulkanHandle}, true}; particlePipelineDefinition.m_blendMode = vkcv::BlendMode::Additive; @@ -137,7 +139,7 @@ int main(int argc, const char **argv) { vkcv::PipelineHandle particlePipeline = core.createGraphicsPipeline(particlePipelineDefinition); - vkcv::PipelineHandle computePipeline = core.createComputePipeline(computeShaderProgram, {core.getDescriptorSet(computeDescriptorSet).layout} ); + vkcv::PipelineHandle computePipeline = core.createComputePipeline(computeShaderProgram, {core.getDescriptorSetLayout(computeDescriptorSetLayout).vulkanHandle} ); vkcv::Buffer<glm::vec4> color = core.createBuffer<glm::vec4>( vkcv::BufferType::UNIFORM, @@ -227,10 +229,11 @@ int main(int argc, const char **argv) { tonemappingShader.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingShader.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle tonemappingDescriptorLayout = core.createDescriptorSetLayout(tonemappingShader.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle tonemappingDescriptor = core.createDescriptorSet(tonemappingDescriptorLayout); vkcv::PipelineHandle tonemappingPipe = core.createComputePipeline( tonemappingShader, - { core.getDescriptorSet(tonemappingDescriptor).layout }); + { core.getDescriptorSetLayout(tonemappingDescriptorLayout).vulkanHandle }); std::uniform_real_distribution<float> rdm = std::uniform_real_distribution<float>(0.95f, 1.05f); std::default_random_engine rdmEngine; diff --git a/projects/voxelization/src/BloomAndFlares.cpp b/projects/voxelization/src/BloomAndFlares.cpp index 6cb02e9035daf7abebc047d26137d0ba973bb4f1..1837ffe0f16500e18e2c013c5c74ac0e10ef6221 100644 --- a/projects/voxelization/src/BloomAndFlares.cpp +++ b/projects/voxelization/src/BloomAndFlares.cpp @@ -44,11 +44,13 @@ BloomAndFlares::BloomAndFlares( }); for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++) { - m_DownsampleDescSets.push_back( - p_Core->createDescriptorSet(dsProg.getReflectedDescriptors()[0])); + m_DownsampleDescSetLayouts.push_back( + p_Core->createDescriptorSetLayout(dsProg.getReflectedDescriptors().at(0)) + ); + m_DownsampleDescSets.push_back(p_Core->createDescriptorSet(m_DownsampleDescSetLayouts.back())); } m_DownsamplePipe = p_Core->createComputePipeline( - dsProg, { p_Core->getDescriptorSet(m_DownsampleDescSets[0]).layout }); + dsProg, { p_Core->getDescriptorSetLayout(m_DownsampleDescSetLayouts[0]).vulkanHandle }); // UPSAMPLE vkcv::ShaderProgram usProg; @@ -60,16 +62,20 @@ BloomAndFlares::BloomAndFlares( }); for(uint32_t mipLevel = 0; mipLevel < m_Blur.getMipCount(); mipLevel++) { + m_UpsampleDescSetLayouts.push_back( + p_Core->createDescriptorSetLayout(usProg.getReflectedDescriptors().at(0))); m_UpsampleDescSets.push_back( - p_Core->createDescriptorSet(usProg.getReflectedDescriptors()[0])); + p_Core->createDescriptorSet(m_UpsampleDescSetLayouts.back())); } for (uint32_t mipLevel = 0; mipLevel < m_LensFeatures.getMipCount(); mipLevel++) { + m_UpsampleLensFlareDescSetLayouts.push_back( + p_Core->createDescriptorSetLayout(usProg.getReflectedDescriptors().at(0))); m_UpsampleLensFlareDescSets.push_back( - p_Core->createDescriptorSet(usProg.getReflectedDescriptors()[0])); + p_Core->createDescriptorSet(m_UpsampleLensFlareDescSetLayouts.back())); } m_UpsamplePipe = p_Core->createComputePipeline( - usProg, { p_Core->getDescriptorSet(m_UpsampleDescSets[0]).layout }); + usProg, { p_Core->getDescriptorSetLayout(m_UpsampleDescSetLayouts[0]).vulkanHandle }); // LENS FEATURES vkcv::ShaderProgram lensProg; @@ -79,9 +85,10 @@ BloomAndFlares::BloomAndFlares( { lensProg.addShader(shaderStage, path); }); - m_LensFlareDescSet = p_Core->createDescriptorSet(lensProg.getReflectedDescriptors()[0]); + m_LensFlareDescSetLayout = p_Core->createDescriptorSetLayout(lensProg.getReflectedDescriptors().at(0)); + m_LensFlareDescSet = p_Core->createDescriptorSet(m_LensFlareDescSetLayout); m_LensFlarePipe = p_Core->createComputePipeline( - lensProg, { p_Core->getDescriptorSet(m_LensFlareDescSet).layout }); + lensProg, { p_Core->getDescriptorSetLayout(m_LensFlareDescSetLayout).vulkanHandle }); // COMPOSITE vkcv::ShaderProgram compProg; @@ -91,9 +98,11 @@ BloomAndFlares::BloomAndFlares( { compProg.addShader(shaderStage, path); }); - m_CompositeDescSet = p_Core->createDescriptorSet(compProg.getReflectedDescriptors()[0]); + + m_CompositeDescSetLayout = p_Core->createDescriptorSetLayout(compProg.getReflectedDescriptors().at(0)); + m_CompositeDescSet = p_Core->createDescriptorSet(m_CompositeDescSetLayout); m_CompositePipe = p_Core->createComputePipeline( - compProg, { p_Core->getDescriptorSet(m_CompositeDescSet).layout }); + compProg, { p_Core->getDescriptorSetLayout(m_CompositeDescSetLayout).vulkanHandle }); // radial LUT const auto texture = vkcv::asset::loadTexture("resources/RadialLUT.png"); diff --git a/projects/voxelization/src/BloomAndFlares.hpp b/projects/voxelization/src/BloomAndFlares.hpp index 2b410e5b256c5820d908372d2e23fd495853274a..133a82cbe85a2fd4fd9965874a36faa5369013b9 100644 --- a/projects/voxelization/src/BloomAndFlares.hpp +++ b/projects/voxelization/src/BloomAndFlares.hpp @@ -29,18 +29,24 @@ private: vkcv::Image m_radialLut; vkcv::Image m_lensDirt; - vkcv::PipelineHandle m_DownsamplePipe; - std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set - std::vector<vkcv::DescriptorSetHandle> m_UpsampleLensFlareDescSets; // per mip desc set + vkcv::PipelineHandle m_DownsamplePipe; + std::vector<vkcv::DescriptorSetLayoutHandle> m_DownsampleDescSetLayouts; + std::vector<vkcv::DescriptorSetHandle> m_DownsampleDescSets; // per mip desc set - vkcv::PipelineHandle m_UpsamplePipe; - std::vector<vkcv::DescriptorSetHandle> m_UpsampleDescSets; // per mip desc set + std::vector<vkcv::DescriptorSetLayoutHandle> m_UpsampleLensFlareDescSetLayouts; + std::vector<vkcv::DescriptorSetHandle> m_UpsampleLensFlareDescSets; // per mip desc set - vkcv::PipelineHandle m_LensFlarePipe; - vkcv::DescriptorSetHandle m_LensFlareDescSet; + vkcv::PipelineHandle m_UpsamplePipe; + std::vector<vkcv::DescriptorSetLayoutHandle> m_UpsampleDescSetLayouts; + std::vector<vkcv::DescriptorSetHandle> m_UpsampleDescSets; // per mip desc set - vkcv::PipelineHandle m_CompositePipe; - vkcv::DescriptorSetHandle m_CompositeDescSet; + vkcv::PipelineHandle m_LensFlarePipe; + vkcv::DescriptorSetLayoutHandle m_LensFlareDescSetLayout; + vkcv::DescriptorSetHandle m_LensFlareDescSet; + + vkcv::PipelineHandle m_CompositePipe; + vkcv::DescriptorSetLayoutHandle m_CompositeDescSetLayout; + vkcv::DescriptorSetHandle m_CompositeDescSet; void execDownsamplePipe(const vkcv::CommandStreamHandle &cmdStream, const vkcv::ImageHandle &colorAttachment); void execUpsamplePipe(const vkcv::CommandStreamHandle &cmdStream); diff --git a/projects/voxelization/src/ShadowMapping.cpp b/projects/voxelization/src/ShadowMapping.cpp index 32dd5457541f8f09f4d2711ea831e3c78de2303a..109da9a3b11023e9ba3734b09030d1b910050173 100644 --- a/projects/voxelization/src/ShadowMapping.cpp +++ b/projects/voxelization/src/ShadowMapping.cpp @@ -189,8 +189,9 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert // depth to moments vkcv::ShaderProgram depthToMomentsShader = loadDepthToMomentsShader(); - m_depthToMomentsDescriptorSet = corePtr->createDescriptorSet(depthToMomentsShader.getReflectedDescriptors()[0]); - m_depthToMomentsPipe = corePtr->createComputePipeline(depthToMomentsShader, { corePtr->getDescriptorSet(m_depthToMomentsDescriptorSet).layout }); + m_depthToMomentsDescriptorSetLayout = corePtr->createDescriptorSetLayout(depthToMomentsShader.getReflectedDescriptors().at(0)); + m_depthToMomentsDescriptorSet = corePtr->createDescriptorSet(m_depthToMomentsDescriptorSetLayout); + m_depthToMomentsPipe = corePtr->createComputePipeline(depthToMomentsShader, { corePtr->getDescriptorSetLayout(m_depthToMomentsDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites depthToMomentDescriptorWrites; depthToMomentDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapDepth.getHandle()) }; @@ -199,9 +200,10 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert corePtr->writeDescriptorSet(m_depthToMomentsDescriptorSet, depthToMomentDescriptorWrites); // shadow blur X - vkcv::ShaderProgram shadowBlurXShader = loadShadowBlurXShader(); - m_shadowBlurXDescriptorSet = corePtr->createDescriptorSet(shadowBlurXShader.getReflectedDescriptors()[0]); - m_shadowBlurXPipe = corePtr->createComputePipeline(shadowBlurXShader, { corePtr->getDescriptorSet(m_shadowBlurXDescriptorSet).layout }); + vkcv::ShaderProgram shadowBlurXShader = loadShadowBlurXShader(); + m_shadowBlurXDescriptorSetLayout = corePtr->createDescriptorSetLayout(shadowBlurXShader.getReflectedDescriptors().at(0)); + m_shadowBlurXDescriptorSet = corePtr->createDescriptorSet(m_shadowBlurXDescriptorSetLayout); + m_shadowBlurXPipe = corePtr->createComputePipeline(shadowBlurXShader, { corePtr->getDescriptorSetLayout(m_shadowBlurXDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites shadowBlurXDescriptorWrites; shadowBlurXDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, m_shadowMap.getHandle()) }; @@ -210,9 +212,10 @@ ShadowMapping::ShadowMapping(vkcv::Core* corePtr, const vkcv::VertexLayout& vert corePtr->writeDescriptorSet(m_shadowBlurXDescriptorSet, shadowBlurXDescriptorWrites); // shadow blur Y - vkcv::ShaderProgram shadowBlurYShader = loadShadowBlurYShader(); - m_shadowBlurYDescriptorSet = corePtr->createDescriptorSet(shadowBlurYShader.getReflectedDescriptors()[0]); - m_shadowBlurYPipe = corePtr->createComputePipeline(shadowBlurYShader, { corePtr->getDescriptorSet(m_shadowBlurYDescriptorSet).layout }); + vkcv::ShaderProgram shadowBlurYShader = loadShadowBlurYShader(); + m_shadowBlurYDescriptorSetLayout = corePtr->createDescriptorSetLayout(shadowBlurYShader.getReflectedDescriptors().at(0)); + m_shadowBlurYDescriptorSet = corePtr->createDescriptorSet(m_shadowBlurYDescriptorSetLayout); + m_shadowBlurYPipe = corePtr->createComputePipeline(shadowBlurYShader, { corePtr->getDescriptorSetLayout(m_shadowBlurYDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites shadowBlurYDescriptorWrites; shadowBlurYDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(0, m_shadowMapIntermediate.getHandle()) }; diff --git a/projects/voxelization/src/ShadowMapping.hpp b/projects/voxelization/src/ShadowMapping.hpp index 8066d5bdc90a66c0823be4dc23cf6a12729e32c7..3bd72581357510ae4ae9a581daeb23b60bb80e1c 100644 --- a/projects/voxelization/src/ShadowMapping.hpp +++ b/projects/voxelization/src/ShadowMapping.hpp @@ -36,21 +36,24 @@ public: private: vkcv::Core* m_corePtr; - vkcv::Image m_shadowMap; - vkcv::Image m_shadowMapIntermediate; - vkcv::Image m_shadowMapDepth; - vkcv::SamplerHandle m_shadowSampler; - vkcv::Buffer<LightInfo> m_lightInfoBuffer; - - vkcv::PassHandle m_shadowMapPass; - vkcv::PipelineHandle m_shadowMapPipe; - - vkcv::PipelineHandle m_depthToMomentsPipe; - vkcv::DescriptorSetHandle m_depthToMomentsDescriptorSet; - - vkcv::PipelineHandle m_shadowBlurXPipe; - vkcv::DescriptorSetHandle m_shadowBlurXDescriptorSet; - - vkcv::PipelineHandle m_shadowBlurYPipe; - vkcv::DescriptorSetHandle m_shadowBlurYDescriptorSet; + vkcv::Image m_shadowMap; + vkcv::Image m_shadowMapIntermediate; + vkcv::Image m_shadowMapDepth; + vkcv::SamplerHandle m_shadowSampler; + vkcv::Buffer<LightInfo> m_lightInfoBuffer; + + vkcv::PassHandle m_shadowMapPass; + vkcv::PipelineHandle m_shadowMapPipe; + + vkcv::PipelineHandle m_depthToMomentsPipe; + vkcv::DescriptorSetLayoutHandle m_depthToMomentsDescriptorSetLayout; + vkcv::DescriptorSetHandle m_depthToMomentsDescriptorSet; + + vkcv::PipelineHandle m_shadowBlurXPipe; + vkcv::DescriptorSetLayoutHandle m_shadowBlurXDescriptorSetLayout; + vkcv::DescriptorSetHandle m_shadowBlurXDescriptorSet; + + vkcv::PipelineHandle m_shadowBlurYPipe; + vkcv::DescriptorSetLayoutHandle m_shadowBlurYDescriptorSetLayout; + vkcv::DescriptorSetHandle m_shadowBlurYDescriptorSet; }; \ No newline at end of file diff --git a/projects/voxelization/src/Voxelization.cpp b/projects/voxelization/src/Voxelization.cpp index f7e03709c6423ef0e3c43251afb28e887b9be61f..139851870a6dc3bb7a5aca9f926504cdfc571f40 100644 --- a/projects/voxelization/src/Voxelization.cpp +++ b/projects/voxelization/src/Voxelization.cpp @@ -98,12 +98,11 @@ Voxelization::Voxelization( voxelizationDummyFormat) }); m_voxelizationPass = m_corePtr->createPass(voxelizationPassConfig); - std::vector<vkcv::DescriptorBinding> voxelizationDescriptorBindings = - { voxelizationShader.getReflectedDescriptors()[0] }; - m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(voxelizationDescriptorBindings); + m_voxelizationDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelizationShader.getReflectedDescriptors().at(0)); + m_voxelizationDescriptorSet = m_corePtr->createDescriptorSet(m_voxelizationDescriptorSetLayout); - vkcv::DescriptorSetHandle dummyPerMeshDescriptorSet = - m_corePtr->createDescriptorSet({ voxelizationShader.getReflectedDescriptors()[1] }); + vkcv::DescriptorSetLayoutHandle dummyPerMeshDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelizationShader.getReflectedDescriptors().at(1)); + vkcv::DescriptorSetHandle dummyPerMeshDescriptorSet = m_corePtr->createDescriptorSet(dummyPerMeshDescriptorSetLayout); const vkcv::PipelineConfig voxelizationPipeConfig{ voxelizationShader, @@ -112,8 +111,8 @@ Voxelization::Voxelization( m_voxelizationPass, dependencies.vertexLayout, { - m_corePtr->getDescriptorSet(m_voxelizationDescriptorSet).layout, - m_corePtr->getDescriptorSet(dummyPerMeshDescriptorSet).layout}, + m_corePtr->getDescriptorSetLayout(m_voxelizationDescriptorSetLayout).vulkanHandle, + m_corePtr->getDescriptorSetLayout(dummyPerMeshDescriptorSetLayout).vulkanHandle}, false, true }; m_voxelizationPipe = m_corePtr->createGraphicsPipeline(voxelizationPipeConfig); @@ -131,9 +130,8 @@ Voxelization::Voxelization( vkcv::ShaderProgram voxelVisualisationShader = loadVoxelVisualisationShader(); - const std::vector<vkcv::DescriptorBinding> voxelVisualisationDescriptorBindings = - { voxelVisualisationShader.getReflectedDescriptors()[0] }; - m_visualisationDescriptorSet = m_corePtr->createDescriptorSet(voxelVisualisationDescriptorBindings); + m_visualisationDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(voxelVisualisationShader.getReflectedDescriptors().at(0)); + m_visualisationDescriptorSet = m_corePtr->createDescriptorSet(m_visualisationDescriptorSetLayout); const vkcv::AttachmentDescription voxelVisualisationColorAttachments( vkcv::AttachmentOperation::STORE, @@ -158,7 +156,7 @@ Voxelization::Voxelization( 0, m_visualisationPass, {}, - { m_corePtr->getDescriptorSet(m_visualisationDescriptorSet).layout }, + { m_corePtr->getDescriptorSetLayout(m_visualisationDescriptorSetLayout).vulkanHandle }, true, false, vkcv::PrimitiveTopology::PointList }; // points are extended to cubes in the geometry shader @@ -174,10 +172,11 @@ Voxelization::Voxelization( vkcv::ShaderProgram resetVoxelShader = loadVoxelResetShader(); - m_voxelResetDescriptorSet = m_corePtr->createDescriptorSet(resetVoxelShader.getReflectedDescriptors()[0]); + m_voxelResetDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(resetVoxelShader.getReflectedDescriptors().at(0)); + m_voxelResetDescriptorSet = m_corePtr->createDescriptorSet(m_voxelResetDescriptorSetLayout); m_voxelResetPipe = m_corePtr->createComputePipeline( resetVoxelShader, - { m_corePtr->getDescriptorSet(m_voxelResetDescriptorSet).layout }); + { m_corePtr->getDescriptorSetLayout(m_voxelResetDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites resetVoxelWrites; resetVoxelWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; @@ -186,10 +185,11 @@ Voxelization::Voxelization( // buffer to image vkcv::ShaderProgram bufferToImageShader = loadVoxelBufferToImageShader(); - m_bufferToImageDescriptorSet = m_corePtr->createDescriptorSet(bufferToImageShader.getReflectedDescriptors()[0]); + m_bufferToImageDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(bufferToImageShader.getReflectedDescriptors().at(0)); + m_bufferToImageDescriptorSet = m_corePtr->createDescriptorSet(m_bufferToImageDescriptorSetLayout); m_bufferToImagePipe = m_corePtr->createComputePipeline( bufferToImageShader, - { m_corePtr->getDescriptorSet(m_bufferToImageDescriptorSet).layout }); + { m_corePtr->getDescriptorSetLayout(m_bufferToImageDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites bufferToImageDescriptorWrites; bufferToImageDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; @@ -199,10 +199,11 @@ Voxelization::Voxelization( // secondary bounce vkcv::ShaderProgram secondaryBounceShader = loadSecondaryBounceShader(); - m_secondaryBounceDescriptorSet = m_corePtr->createDescriptorSet(secondaryBounceShader.getReflectedDescriptors()[0]); + m_secondaryBounceDescriptorSetLayout = m_corePtr->createDescriptorSetLayout(secondaryBounceShader.getReflectedDescriptors().at(0)); + m_secondaryBounceDescriptorSet = m_corePtr->createDescriptorSet(m_secondaryBounceDescriptorSetLayout); m_secondaryBouncePipe = m_corePtr->createComputePipeline( secondaryBounceShader, - { m_corePtr->getDescriptorSet(m_secondaryBounceDescriptorSet).layout }); + { m_corePtr->getDescriptorSetLayout(m_secondaryBounceDescriptorSetLayout).vulkanHandle }); vkcv::DescriptorWrites secondaryBounceDescriptorWrites; secondaryBounceDescriptorWrites.storageBufferWrites = { vkcv::BufferDescriptorWrite(0, m_voxelBuffer.getHandle()) }; diff --git a/projects/voxelization/src/Voxelization.hpp b/projects/voxelization/src/Voxelization.hpp index 66c87acb3c13c0d950a28dc33e4084d728da5947..1ca25703361d11b0f3e43b8ce252a3cf21367b5f 100644 --- a/projects/voxelization/src/Voxelization.hpp +++ b/projects/voxelization/src/Voxelization.hpp @@ -53,24 +53,29 @@ private: vkcv::Image m_voxelImage; vkcv::Buffer<VoxelBufferContent> m_voxelBuffer; - vkcv::Image m_dummyRenderTarget; - vkcv::PassHandle m_voxelizationPass; - vkcv::PipelineHandle m_voxelizationPipe; - vkcv::DescriptorSetHandle m_voxelizationDescriptorSet; + vkcv::Image m_dummyRenderTarget; + vkcv::PassHandle m_voxelizationPass; + vkcv::PipelineHandle m_voxelizationPipe; + vkcv::DescriptorSetLayoutHandle m_voxelizationDescriptorSetLayout; + vkcv::DescriptorSetHandle m_voxelizationDescriptorSet; - vkcv::PipelineHandle m_voxelResetPipe; - vkcv::DescriptorSetHandle m_voxelResetDescriptorSet; + vkcv::PipelineHandle m_voxelResetPipe; + vkcv::DescriptorSetLayoutHandle m_voxelResetDescriptorSetLayout; + vkcv::DescriptorSetHandle m_voxelResetDescriptorSet; - vkcv::PipelineHandle m_bufferToImagePipe; - vkcv::DescriptorSetHandle m_bufferToImageDescriptorSet; + vkcv::PipelineHandle m_bufferToImagePipe; + vkcv::DescriptorSetLayoutHandle m_bufferToImageDescriptorSetLayout; + vkcv::DescriptorSetHandle m_bufferToImageDescriptorSet; - vkcv::PassHandle m_visualisationPass; - vkcv::PipelineHandle m_visualisationPipe; + vkcv::PassHandle m_visualisationPass; + vkcv::PipelineHandle m_visualisationPipe; - vkcv::PipelineHandle m_secondaryBouncePipe; - vkcv::DescriptorSetHandle m_secondaryBounceDescriptorSet; + vkcv::PipelineHandle m_secondaryBouncePipe; + vkcv::DescriptorSetLayoutHandle m_secondaryBounceDescriptorSetLayout; + vkcv::DescriptorSetHandle m_secondaryBounceDescriptorSet; - vkcv::DescriptorSetHandle m_visualisationDescriptorSet; + vkcv::DescriptorSetLayoutHandle m_visualisationDescriptorSetLayout; + vkcv::DescriptorSetHandle m_visualisationDescriptorSet; struct VoxelizationInfo { glm::vec3 offset; diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 3c23c7eabbbdc5d83d37bde79b43a2730b1f28b2..fe962ff3036c12734ab6d82e034499ab89312b37 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -5,9 +5,7 @@ #include <chrono> #include <vkcv/asset/asset_loader.hpp> #include <vkcv/shader/GLSLCompiler.hpp> -#include <vkcv/Logger.hpp> #include "Voxelization.hpp" -#include <glm/glm.hpp> #include "vkcv/gui/GUI.hpp" #include "ShadowMapping.hpp" #include "BloomAndFlares.hpp" @@ -194,8 +192,8 @@ int main(int argc, const char** argv) { } const vkcv::VertexLayout vertexLayout (vertexBindings); - vkcv::DescriptorSetHandle forwardShadingDescriptorSet = - core.createDescriptorSet({ forwardProgram.getReflectedDescriptors()[0] }); + vkcv::DescriptorSetLayoutHandle forwardShadingDescriptorSetLayout = core.createDescriptorSetLayout(forwardProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle forwardShadingDescriptorSet = core.createDescriptorSet(forwardShadingDescriptorSetLayout); // depth prepass config vkcv::ShaderProgram depthPrepassShader; @@ -232,6 +230,7 @@ int main(int argc, const char** argv) { vkcv::SamplerAddressMode::REPEAT ); + std::vector<vkcv::DescriptorSetLayoutHandle> materialDescriptorSetLayouts; std::vector<vkcv::DescriptorSetHandle> materialDescriptorSets; std::vector<vkcv::Image> sceneImages; @@ -253,7 +252,8 @@ int main(int argc, const char** argv) { specularIndex = 0; } - materialDescriptorSets.push_back(core.createDescriptorSet(forwardProgram.getReflectedDescriptors()[1])); + materialDescriptorSetLayouts.push_back(core.createDescriptorSetLayout(forwardProgram.getReflectedDescriptors().at(1))); + materialDescriptorSets.push_back(core.createDescriptorSet(materialDescriptorSetLayouts.back())); vkcv::asset::Texture& albedoTexture = scene.textures[albedoIndex]; vkcv::asset::Texture& normalTexture = scene.textures[normalIndex]; @@ -292,13 +292,16 @@ int main(int argc, const char** argv) { core.writeDescriptorSet(materialDescriptorSets.back(), setWrites); } + std::vector<vkcv::DescriptorSetLayoutHandle> perMeshDescriptorSetLayouts; std::vector<vkcv::DescriptorSetHandle> perMeshDescriptorSets; for (const auto& vertexGroup : scene.vertexGroups) { + perMeshDescriptorSetLayouts.push_back(materialDescriptorSetLayouts[vertexGroup.materialIndex]); perMeshDescriptorSets.push_back(materialDescriptorSets[vertexGroup.materialIndex]); } // prepass pipeline - vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(std::vector<vkcv::DescriptorBinding>()); + vkcv::DescriptorSetLayoutHandle prepassDescriptorSetLayout = core.createDescriptorSetLayout({}); + vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(prepassDescriptorSetLayout); vkcv::PipelineConfig prepassPipelineConfig{ depthPrepassShader, @@ -307,8 +310,8 @@ int main(int argc, const char** argv) { prepassPass, vertexLayout, { - core.getDescriptorSet(prepassDescriptorSet).layout, - core.getDescriptorSet(perMeshDescriptorSets[0]).layout }, + core.getDescriptorSetLayout(prepassDescriptorSetLayout).vulkanHandle, + core.getDescriptorSetLayout(perMeshDescriptorSetLayouts[0]).vulkanHandle }, true }; prepassPipelineConfig.m_culling = vkcv::CullMode::Back; prepassPipelineConfig.m_multisampling = msaa; @@ -325,8 +328,8 @@ int main(int argc, const char** argv) { forwardPass, vertexLayout, { - core.getDescriptorSet(forwardShadingDescriptorSet).layout, - core.getDescriptorSet(perMeshDescriptorSets[0]).layout }, + core.getDescriptorSetLayout(forwardShadingDescriptorSetLayout).vulkanHandle, + core.getDescriptorSetLayout(perMeshDescriptorSetLayouts[0]).vulkanHandle }, true }; forwardPipelineConfig.m_culling = vkcv::CullMode::Back; @@ -425,11 +428,12 @@ int main(int argc, const char** argv) { [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { tonemappingProgram.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle tonemappingDescriptorSet = core.createDescriptorSet( - tonemappingProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle tonemappingDescriptorSetLayout = core.createDescriptorSetLayout( + tonemappingProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle tonemappingDescriptorSet = core.createDescriptorSet(tonemappingDescriptorSetLayout); vkcv::PipelineHandle tonemappingPipeline = core.createComputePipeline( tonemappingProgram, - { core.getDescriptorSet(tonemappingDescriptorSet).layout }); + { core.getDescriptorSetLayout(tonemappingDescriptorSetLayout).vulkanHandle }); // tonemapping compute shader vkcv::ShaderProgram postEffectsProgram; @@ -437,11 +441,12 @@ int main(int argc, const char** argv) { [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { postEffectsProgram.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle postEffectsDescriptorSet = core.createDescriptorSet( - postEffectsProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle postEffectsDescriptorSetLayout = core.createDescriptorSetLayout( + postEffectsProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle postEffectsDescriptorSet = core.createDescriptorSet(postEffectsDescriptorSetLayout); vkcv::PipelineHandle postEffectsPipeline = core.createComputePipeline( postEffectsProgram, - { core.getDescriptorSet(postEffectsDescriptorSet).layout }); + { core.getDescriptorSetLayout(postEffectsDescriptorSetLayout).vulkanHandle }); // resolve compute shader vkcv::ShaderProgram resolveProgram; @@ -449,11 +454,12 @@ int main(int argc, const char** argv) { [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { resolveProgram.addShader(shaderStage, path); }); - vkcv::DescriptorSetHandle resolveDescriptorSet = core.createDescriptorSet( - resolveProgram.getReflectedDescriptors()[0]); + vkcv::DescriptorSetLayoutHandle resolveDescriptorSetLayout = core.createDescriptorSetLayout( + resolveProgram.getReflectedDescriptors().at(0)); + vkcv::DescriptorSetHandle resolveDescriptorSet = core.createDescriptorSet(resolveDescriptorSetLayout); vkcv::PipelineHandle resolvePipeline = core.createComputePipeline( resolveProgram, - { core.getDescriptorSet(resolveDescriptorSet).layout }); + { core.getDescriptorSetLayout(resolveDescriptorSetLayout).vulkanHandle }); vkcv::SamplerHandle resolveSampler = core.createSampler( vkcv::SamplerFilterType::NEAREST, @@ -941,7 +947,7 @@ int main(int argc, const char** argv) { }); vkcv::PipelineHandle newPipeline = core.createComputePipeline( newProgram, - { core.getDescriptorSet(tonemappingDescriptorSet).layout }); + { core.getDescriptorSetLayout(tonemappingDescriptorSetLayout).vulkanHandle }); if (newPipeline) { tonemappingPipeline = newPipeline; diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 095fdd2e98e7f48a14c3426c89e3f336b848b463..5413d1133f0348a97616d1001bcd4a763364bfb7 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -721,9 +721,19 @@ namespace vkcv return m_ImageManager->getImageFormat(image); } - DescriptorSetHandle Core::createDescriptorSet(const std::vector<DescriptorBinding>& bindings) + DescriptorSetLayoutHandle Core::createDescriptorSetLayout(const DescriptorBindings &bindingsMap) + { + return m_DescriptorManager->createDescriptorSetLayout(bindingsMap); + } + + DescriptorSetLayout Core::getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const + { + return m_DescriptorManager->getDescriptorSetLayout(handle); + } + + DescriptorSetHandle Core::createDescriptorSet(const DescriptorSetLayoutHandle &layoutHandle) { - return m_DescriptorManager->createDescriptorSet(bindings); + return m_DescriptorManager->createDescriptorSet(layoutHandle); } void Core::writeDescriptorSet(DescriptorSetHandle handle, const DescriptorWrites &writes) { diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp index a9a127fe608472682c1cbc8d32ca466fba860c72..91a9c24dc1819b69223b6befa9b6d64409698c35 100644 --- a/src/vkcv/DescriptorConfig.cpp +++ b/src/vkcv/DescriptorConfig.cpp @@ -1,15 +1,23 @@ #include "vkcv/DescriptorConfig.hpp" -namespace vkcv { +namespace vkcv +{ DescriptorBinding::DescriptorBinding( uint32_t bindingID, DescriptorType descriptorType, uint32_t descriptorCount, - ShaderStages shaderStages) noexcept - : + ShaderStages shaderStages) noexcept: bindingID(bindingID), descriptorType(descriptorType), descriptorCount(descriptorCount), - shaderStages(shaderStages) {} - + shaderStages(shaderStages) + {} + + bool DescriptorBinding::operator==(const DescriptorBinding &other) const + { + return (this->bindingID == other.bindingID) && + (this->descriptorType == other.descriptorType) && + (this->descriptorCount == other.descriptorCount) && + (this->shaderStages == other.shaderStages); + } } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 76f2dae74420804c9ce168bea76e7c1bdef0fbc0..e7ae9ea2bda1164f5425e4324b3ff3969ff45847 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -1,7 +1,5 @@ #include "DescriptorManager.hpp" -#include "vkcv/Logger.hpp" - namespace vkcv { DescriptorManager::DescriptorManager(vk::Device device) noexcept: @@ -34,8 +32,13 @@ namespace vkcv for (uint64_t id = 0; id < m_DescriptorSets.size(); id++) { destroyDescriptorSetById(id); } + + for (uint64_t id = 0; id < m_DescriptorSetLayouts.size(); id++) { + destroyDescriptorSetLayoutById(id); + } m_DescriptorSets.clear(); + m_DescriptorSetLayouts.clear(); for (const auto &pool : m_Pools) { if (pool) { @@ -44,55 +47,77 @@ namespace vkcv } } - DescriptorSetHandle DescriptorManager::createDescriptorSet(const std::vector<DescriptorBinding>& bindings) + DescriptorSetLayoutHandle DescriptorManager::createDescriptorSetLayout(const DescriptorBindings &setBindingsMap) { - std::vector<vk::DescriptorSetLayoutBinding> setBindings = {}; + for (auto i = 0; i < m_DescriptorSetLayouts.size(); i++) + { + if(m_DescriptorSetLayouts[i].descriptorBindings.size() != setBindingsMap.size()) + continue; - //create each set's binding - for (auto binding : bindings) { - vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( - binding.bindingID, - convertDescriptorTypeFlag(binding.descriptorType), - binding.descriptorCount, - getShaderStageFlags(binding.shaderStages)); - setBindings.push_back(descriptorSetLayoutBinding); + if (m_DescriptorSetLayouts[i].descriptorBindings == setBindingsMap) + { + return DescriptorSetLayoutHandle(i, [&](uint64_t id) { destroyDescriptorSetLayoutById(id); }); + } } + + //create the descriptor set's layout by iterating over its bindings + std::vector<vk::DescriptorSetLayoutBinding> bindingsVector = {}; + for (auto bindingElem : setBindingsMap) + { + DescriptorBinding binding = bindingElem.second; + uint32_t bindingID = bindingElem.first; - DescriptorSet set; + vk::DescriptorSetLayoutBinding descriptorSetLayoutBinding( + bindingID, + getVkDescriptorType(binding.descriptorType), + binding.descriptorCount, + getShaderStageFlags(binding.shaderStages), + nullptr + ); + + bindingsVector.push_back(descriptorSetLayoutBinding); + } - //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) { - vkcv_log(LogLevel::ERROR, "Failed to create descriptor set layout"); - return DescriptorSetHandle(); + //create the descriptor set's layout from the binding data gathered above + vk::DescriptorSetLayout vulkanHandle = VK_NULL_HANDLE; + vk::DescriptorSetLayoutCreateInfo layoutInfo({}, bindingsVector); + auto result = m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &vulkanHandle); + if (result != vk::Result::eSuccess) { + vkcv_log(LogLevel::ERROR, "Failed to create descriptor set layout"); + return DescriptorSetLayoutHandle(); }; - - //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); + + const uint64_t id = m_DescriptorSetLayouts.size(); + m_DescriptorSetLayouts.push_back({vulkanHandle, setBindingsMap}); + return DescriptorSetLayoutHandle(id, [&](uint64_t id) { destroyDescriptorSetLayoutById(id); }); + } + + DescriptorSetHandle DescriptorManager::createDescriptorSet(const DescriptorSetLayoutHandle &setLayoutHandle) + { + //create and allocate the set based on the layout provided + DescriptorSetLayout setLayout = m_DescriptorSetLayouts[setLayoutHandle.getId()]; + vk::DescriptorSet vulkanHandle = VK_NULL_HANDLE; + vk::DescriptorSetAllocateInfo allocInfo(m_Pools.back(), 1, &setLayout.vulkanHandle); + auto result = m_Device.allocateDescriptorSets(&allocInfo, &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, &set.vulkanHandle); + result = m_Device.allocateDescriptorSets(&allocInfo, &vulkanHandle); } if (result != vk::Result::eSuccess) { vkcv_log(LogLevel::ERROR, "Failed to create descriptor set (%s)", vk::to_string(result).c_str()); - - m_Device.destroy(set.layout); return DescriptorSetHandle(); } }; - set.poolIndex = (m_Pools.size() - 1); - + size_t poolIndex = (m_Pools.size() - 1); const uint64_t id = m_DescriptorSets.size(); - - m_DescriptorSets.push_back(set); + m_DescriptorSets.push_back({vulkanHandle, setLayoutHandle, poolIndex}); return DescriptorSetHandle(id, [&](uint64_t id) { destroyDescriptorSetById(id); }); } @@ -247,33 +272,15 @@ namespace vkcv m_Device.updateDescriptorSets(vulkanWrites, nullptr); } + DescriptorSetLayout DescriptorManager::getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const + { + return m_DescriptorSetLayouts[handle.getId()]; + } + DescriptorSet DescriptorManager::getDescriptorSet(const DescriptorSetHandle handle) const { return m_DescriptorSets[handle.getId()]; } - vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) { - switch (type) - { - case DescriptorType::UNIFORM_BUFFER: - return vk::DescriptorType::eUniformBuffer; - case DescriptorType::UNIFORM_BUFFER_DYNAMIC: - return vk::DescriptorType::eUniformBufferDynamic; - case DescriptorType::STORAGE_BUFFER: - return vk::DescriptorType::eStorageBuffer; - case DescriptorType::STORAGE_BUFFER_DYNAMIC: - return vk::DescriptorType::eStorageBufferDynamic; - case DescriptorType::SAMPLER: - return vk::DescriptorType::eSampler; - case DescriptorType::IMAGE_SAMPLED: - return vk::DescriptorType::eSampledImage; - case DescriptorType::IMAGE_STORAGE: - return vk::DescriptorType::eStorageImage; - default: - vkcv_log(LogLevel::ERROR, "Unknown DescriptorType"); - return vk::DescriptorType::eUniformBuffer; - } - } - void DescriptorManager::destroyDescriptorSetById(uint64_t id) { if (id >= m_DescriptorSets.size()) { vkcv_log(LogLevel::ERROR, "Invalid id"); @@ -281,17 +288,26 @@ namespace vkcv } auto& set = m_DescriptorSets[id]; - if (set.layout) { - m_Device.destroyDescriptorSetLayout(set.layout); - set.layout = nullptr; - } - if (set.vulkanHandle) { m_Device.freeDescriptorSets(m_Pools[set.poolIndex], 1, &(set.vulkanHandle)); + set.setLayoutHandle = DescriptorSetLayoutHandle(); set.vulkanHandle = nullptr; } } + void DescriptorManager::destroyDescriptorSetLayoutById(uint64_t id) { + if (id >= m_DescriptorSets.size()) { + vkcv_log(LogLevel::ERROR, "Invalid id"); + return; + } + + auto layout = m_DescriptorSetLayouts[id]; + if (layout.vulkanHandle){ + m_Device.destroy(layout.vulkanHandle); + layout.vulkanHandle = nullptr; + } + } + vk::DescriptorPool DescriptorManager::allocateDescriptorPool() { vk::DescriptorPool pool; if (m_Device.createDescriptorPool(&m_PoolInfo, nullptr, &pool) != vk::Result::eSuccess) { diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index df58daa56c26a0432f365a4ed0d9df56adc4cd0e..acc6edd9b704c377480e7acbbc40b3e763003d5f 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -21,7 +21,8 @@ namespace vkcv explicit DescriptorManager(vk::Device device) noexcept; ~DescriptorManager() noexcept; - DescriptorSetHandle createDescriptorSet(const std::vector<DescriptorBinding> &descriptorBindings); + DescriptorSetLayoutHandle createDescriptorSetLayout(const std::unordered_map<uint32_t, DescriptorBinding> &setBindingsMap); + DescriptorSetHandle createDescriptorSet(const DescriptorSetLayoutHandle &setLayoutHandle); void writeDescriptorSet( const DescriptorSetHandle &handle, @@ -30,6 +31,8 @@ namespace vkcv const BufferManager &bufferManager, const SamplerManager &samplerManager); + [[nodiscard]] + DescriptorSetLayout getDescriptorSetLayout(const DescriptorSetLayoutHandle handle) const; [[nodiscard]] DescriptorSet getDescriptorSet(const DescriptorSetHandle handle) const; @@ -39,25 +42,29 @@ namespace vkcv std::vector<vk::DescriptorPoolSize> m_PoolSizes; vk::DescriptorPoolCreateInfo m_PoolInfo; - /** - * Contains all the resource descriptions that were requested by the user in calls of createResourceDescription. + * Contains all the descriptor set layout descriptions + * that were requested by the user in calls of createDescriptorSetLayout. + */ + std::vector<DescriptorSetLayout> m_DescriptorSetLayouts; + + /** + * Contains all the descriptor sets that were created by the user in calls of createDescriptorSet. */ std::vector<DescriptorSet> m_DescriptorSets; - - /** - * 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 - */ - static vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type); - + /** - * Destroys a specific resource description - * @param[in] the handle id of the respective resource description + * Destroys a specific descriptor set + * @param[in] the DescriptorSetHandle */ void destroyDescriptorSetById(uint64_t id); + /** + * Destroys a specific descriptor set LAYOUT (not the set) + * @param[in] the DescriptorSetLayoutHandle + */ + void destroyDescriptorSetLayoutById(uint64_t id); + /** * creates a descriptor pool based on the poolSizes and poolInfo defined in the constructor * is called initially in the constructor and then every time the pool runs out memory diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index 134ba7afd203d3222b37dfaf627a9d4fd3ede1c7..a1634c230907ffa741101710613aff73e1fb7b06 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -141,85 +141,124 @@ namespace vkcv { //reflect descriptor sets (uniform buffer, storage buffer, sampler, sampled image, storage image) std::vector<std::pair<uint32_t, DescriptorBinding>> bindings; - int32_t maxSetID = -1; - for (uint32_t i = 0; i < resources.uniform_buffers.size(); i++) { + + for (uint32_t i = 0; i < resources.uniform_buffers.size(); i++) + { auto& u = resources.uniform_buffers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); - std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), - DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::UNIFORM_BUFFER, base_type.vecsize, shaderStage)); - bindings.push_back(descriptor); - if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) - maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + + uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + auto binding = DescriptorBinding( + bindingID, + DescriptorType::UNIFORM_BUFFER, + base_type.vecsize, + shaderStage); + + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); + if(!insertionResult.second) + { + vkcv_log(LogLevel::WARNING, + "Attempting to overwrite already existing binding %u at set ID %u.", + bindingID, + setID); + } } - for (uint32_t i = 0; i < resources.storage_buffers.size(); i++) { + for (uint32_t i = 0; i < resources.storage_buffers.size(); i++) + { auto& u = resources.storage_buffers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); - std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), - DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::STORAGE_BUFFER, base_type.vecsize, shaderStage)); - bindings.push_back(descriptor); - if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) - maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + + uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + auto binding = DescriptorBinding( + bindingID, + DescriptorType::STORAGE_BUFFER, + base_type.vecsize, + shaderStage); + + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); + if(!insertionResult.second) + { + vkcv_log(LogLevel::WARNING, + "Attempting to overwrite already existing binding %u at set ID %u.", + bindingID, + setID); + } } for (uint32_t i = 0; i < resources.separate_samplers.size(); i++) { auto& u = resources.separate_samplers[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); - std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), - DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::SAMPLER, base_type.vecsize, shaderStage)); - bindings.push_back(descriptor); - if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) - maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + + uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + auto binding = DescriptorBinding( + bindingID, + DescriptorType::SAMPLER, + base_type.vecsize, + shaderStage); + + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); + if(!insertionResult.second) + { + vkcv_log(LogLevel::WARNING, + "Attempting to overwrite already existing binding %u at set ID %u.", + bindingID, + setID); + } } for (uint32_t i = 0; i < resources.separate_images.size(); i++) { auto& u = resources.separate_images[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); - std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), - DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::IMAGE_SAMPLED, base_type.vecsize, shaderStage)); - bindings.push_back(descriptor); - if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) - maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + auto binding = DescriptorBinding( + bindingID, + DescriptorType::IMAGE_SAMPLED, + base_type.vecsize, + shaderStage); + + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); + if(!insertionResult.second) + { + vkcv_log(LogLevel::WARNING, + "Attempting to overwrite already existing binding %u at set ID %u.", + bindingID, + setID); + } } for (uint32_t i = 0; i < resources.storage_images.size(); i++) { auto& u = resources.storage_images[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); - std::pair descriptor(comp.get_decoration(u.id, spv::DecorationDescriptorSet), - DescriptorBinding(comp.get_decoration(u.id, spv::DecorationBinding), DescriptorType::IMAGE_STORAGE, base_type.vecsize, shaderStage)); - bindings.push_back(descriptor); - if ((int32_t)comp.get_decoration(u.id, spv::DecorationDescriptorSet) > maxSetID) - maxSetID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); - } - if (maxSetID != -1) { - if((int32_t)m_DescriptorSets.size() <= maxSetID) m_DescriptorSets.resize(maxSetID + 1); - for (const auto &binding : bindings) { - //checking if descriptor has already been reflected in another shader stage - bool bindingFound = false; - uint32_t pos = 0; - for (const auto& descriptor : m_DescriptorSets[binding.first]) { - if (binding.second.bindingID == descriptor.bindingID) { - if (binding.second.descriptorType == descriptor.descriptorType && binding.second.descriptorCount == descriptor.descriptorCount) { - //updating descriptor binding with another shader stage - ShaderStages updatedShaders = descriptor.shaderStages | shaderStage; - DescriptorBinding newBinding = DescriptorBinding(binding.second.bindingID, binding.second.descriptorType, binding.second.descriptorCount, updatedShaders); - m_DescriptorSets[binding.first][pos] = newBinding; - bindingFound = true; - break; - } - else vkcv_log(LogLevel::ERROR, "Included shaders contain resources with same identifier but different type or count"); - } - pos++; - } - //append new descriptor if it has not been reflected yet - if(!bindingFound) m_DescriptorSets[binding.first].push_back(binding.second); + + uint32_t setID = comp.get_decoration(u.id, spv::DecorationDescriptorSet); + uint32_t bindingID = comp.get_decoration(u.id, spv::DecorationBinding); + auto binding = DescriptorBinding( + bindingID, + DescriptorType::IMAGE_STORAGE, + base_type.vecsize, + shaderStage); + + auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding)); + if(!insertionResult.second) + { + vkcv_log(LogLevel::WARNING, + "Attempting to overwrite already existing binding %u at set ID %u.", + bindingID, + setID); } } //reflect push constants - for (const auto &pushConstantBuffer : resources.push_constant_buffers) { - for (const auto &range : comp.get_active_buffer_ranges(pushConstantBuffer.id)) { + for (const auto &pushConstantBuffer : resources.push_constant_buffers) + { + for (const auto &range : comp.get_active_buffer_ranges(pushConstantBuffer.id)) + { const size_t size = range.range + range.offset; m_pushConstantSize = std::max(m_pushConstantSize, size); } @@ -231,7 +270,8 @@ namespace vkcv { return m_VertexAttachments; } - const std::vector<std::vector<DescriptorBinding>>& ShaderProgram::getReflectedDescriptors() const { + const std::unordered_map<uint32_t, DescriptorBindings>& ShaderProgram::getReflectedDescriptors() const + { return m_DescriptorSets; }