diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index 767492eb2b27bd8dff56ef2aeb4769c08eed7200..f2a089fd624c02c57db4a65c4a101c4acff371b1 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -1,7 +1,5 @@ #pragma once -#include <vulkan/vulkan.hpp> - #include "vkcv/Handles.hpp" #include "vkcv/ShaderStage.hpp" @@ -41,12 +39,12 @@ namespace vkcv uint32_t bindingID, DescriptorType descriptorType, uint32_t descriptorCount, - ShaderStage shaderStage + ShaderStages shaderStages ) noexcept; uint32_t bindingID; DescriptorType descriptorType; uint32_t descriptorCount; - ShaderStage shaderStage; + ShaderStages shaderStages; }; } diff --git a/include/vkcv/ShaderProgram.hpp b/include/vkcv/ShaderProgram.hpp index 78b1f02169fe630427b9f66150e32078d42b7b3f..c7d67b19148b3c9ec19ce1b539f9661797d1b38f 100644 --- a/include/vkcv/ShaderProgram.hpp +++ b/include/vkcv/ShaderProgram.hpp @@ -13,8 +13,8 @@ #include <vulkan/vulkan.hpp> #include <spirv_cross.hpp> #include "VertexLayout.hpp" -#include "ShaderStage.hpp" #include "DescriptorConfig.hpp" +#include "ShaderStage.hpp" namespace vkcv { diff --git a/include/vkcv/ShaderStage.hpp b/include/vkcv/ShaderStage.hpp index 3893bdf5f73408847ceb2b076abfb7d0902bb2f9..52ba5a7e56ed40efda96c27dfd92734880b88f18 100644 --- a/include/vkcv/ShaderStage.hpp +++ b/include/vkcv/ShaderStage.hpp @@ -1,19 +1,39 @@ #pragma once -namespace vkcv { - - enum class ShaderStage - { - VERTEX, - TESS_CONTROL, - TESS_EVAL, - GEOMETRY, - FRAGMENT, - COMPUTE, - TASK, - MESH - }; - +#include <vulkan/vulkan.hpp> +namespace vkcv { + enum class ShaderStage : VkShaderStageFlags { + VERTEX = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eVertex), + TESS_CONTROL = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eTessellationControl), + TESS_EVAL = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eTessellationEvaluation), + GEOMETRY = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eGeometry), + FRAGMENT = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eFragment), + COMPUTE = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCompute), + TASK = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eTaskNV), + MESH = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMeshNV) + }; + + using ShaderStages = vk::Flags<ShaderStage>; + + constexpr vk::ShaderStageFlags getShaderStageFlags(ShaderStages shaderStages) noexcept { + return vk::ShaderStageFlags(static_cast<VkShaderStageFlags>(shaderStages)); + } + + constexpr ShaderStages operator|(ShaderStage stage0, ShaderStage stage1) noexcept { + return ShaderStages(stage0) | stage1; + } + + constexpr ShaderStages operator&(ShaderStage stage0, ShaderStage stage1) noexcept { + return ShaderStages(stage0) & stage1; + } + + constexpr ShaderStages operator^(ShaderStage stage0, ShaderStage stage1) noexcept { + return ShaderStages(stage0) ^ stage1; + } + + constexpr ShaderStages operator~(ShaderStage stage) noexcept { + return ~(ShaderStages(stage)); + } } diff --git a/modules/shader_compiler/CMakeLists.txt b/modules/shader_compiler/CMakeLists.txt index 6fee42bfb571168cd2371e21e231ce417efa41f0..11c1e460575709dd9c9c16fdd02b6b923cc33045 100644 --- a/modules/shader_compiler/CMakeLists.txt +++ b/modules/shader_compiler/CMakeLists.txt @@ -31,7 +31,7 @@ include(config/GLSLANG.cmake) target_link_libraries(vkcv_shader_compiler ${vkcv_shader_compiler_libraries} vkcv) # including headers of dependencies and the VkCV framework -target_include_directories(vkcv_shader_compiler SYSTEM BEFORE PRIVATE ${vkcv_shader_compiler_includes} ${vkcv_include}) +target_include_directories(vkcv_shader_compiler SYSTEM BEFORE PRIVATE ${vkcv_shader_compiler_includes} ${vkcv_include} ${vkcv_includes}) # add the own include directory for public headers target_include_directories(vkcv_shader_compiler BEFORE PUBLIC ${vkcv_shader_compiler_include}) diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp index 54e879ac7e6ec7825a4c003899e3c264454c547f..a9a127fe608472682c1cbc8d32ca466fba860c72 100644 --- a/src/vkcv/DescriptorConfig.cpp +++ b/src/vkcv/DescriptorConfig.cpp @@ -5,11 +5,11 @@ namespace vkcv { uint32_t bindingID, DescriptorType descriptorType, uint32_t descriptorCount, - ShaderStage shaderStage) noexcept + ShaderStages shaderStages) noexcept : bindingID(bindingID), descriptorType(descriptorType), descriptorCount(descriptorCount), - shaderStage(shaderStage) {} + shaderStages(shaderStages) {} } diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 0df359a15883847c132c429ed2945ac7624fb865..76f2dae74420804c9ce168bea76e7c1bdef0fbc0 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -54,7 +54,7 @@ namespace vkcv binding.bindingID, convertDescriptorTypeFlag(binding.descriptorType), binding.descriptorCount, - convertShaderStageFlag(binding.shaderStage)); + getShaderStageFlags(binding.shaderStages)); setBindings.push_back(descriptorSetLayoutBinding); } @@ -273,26 +273,6 @@ namespace vkcv return vk::DescriptorType::eUniformBuffer; } } - - vk::ShaderStageFlagBits DescriptorManager::convertShaderStageFlag(ShaderStage stage) { - switch (stage) - { - case ShaderStage::VERTEX: - return vk::ShaderStageFlagBits::eVertex; - case ShaderStage::FRAGMENT: - return vk::ShaderStageFlagBits::eFragment; - case ShaderStage::TESS_CONTROL: - return vk::ShaderStageFlagBits::eTessellationControl; - case ShaderStage::TESS_EVAL: - return vk::ShaderStageFlagBits::eTessellationEvaluation; - case ShaderStage::GEOMETRY: - return vk::ShaderStageFlagBits::eGeometry; - case ShaderStage::COMPUTE: - return vk::ShaderStageFlagBits::eCompute; - default: - return vk::ShaderStageFlagBits::eAll; - } - } void DescriptorManager::destroyDescriptorSetById(uint64_t id) { if (id >= m_DescriptorSets.size()) { diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index d18be64f3b069af68cecce68f6fa623c81f8dfa4..df58daa56c26a0432f365a4ed0d9df56adc4cd0e 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -51,12 +51,6 @@ namespace vkcv * @return vk flag of the DescriptorType */ static vk::DescriptorType convertDescriptorTypeFlag(DescriptorType type); - /** - * Converts the flags of the shader stages from VulkanCV (vkcv) to Vulkan (vk). - * @param[in] vkcv flag of the ShaderStage (see ShaderProgram.hpp) - * @return vk flag of the ShaderStage - */ - static vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage); /** * Destroys a specific resource description diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index 971797d9a42d071a1730ebf31a0b554f92fa361f..134ba7afd203d3222b37dfaf627a9d4fd3ede1c7 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -195,7 +195,25 @@ namespace vkcv { if (maxSetID != -1) { if((int32_t)m_DescriptorSets.size() <= maxSetID) m_DescriptorSets.resize(maxSetID + 1); for (const auto &binding : bindings) { - m_DescriptorSets[binding.first].push_back(binding.second); + //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); } }