From 2e8036d756121e4331678184bbbaf9f6feb2692d Mon Sep 17 00:00:00 2001 From: Nolan Kramer Date: Wed, 1 Oct 2025 17:30:50 -0700 Subject: [PATCH] Increase extensibility of DescriptorSetLayout --- include/vsg/state/DescriptorSetLayout.h | 11 ++++- src/vsg/state/DescriptorSetLayout.cpp | 55 ++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/include/vsg/state/DescriptorSetLayout.h b/include/vsg/state/DescriptorSetLayout.h index c9e31f49b3..bff22dd1e0 100644 --- a/include/vsg/state/DescriptorSetLayout.h +++ b/include/vsg/state/DescriptorSetLayout.h @@ -21,6 +21,7 @@ namespace vsg class Context; using DescriptorSetLayoutBindings = std::vector; + using DescriptorSetLayoutBindingFlags = std::vector; using DescriptorPoolSizes = std::vector; /// DescriptorSetLayout encapsulates VkDescriptorSetLayout and VkDescriptorSetLayoutCreateInfo settings used to set it up. @@ -34,9 +35,17 @@ namespace vsg /// Vulkan VkDescriptorSetLayout handle virtual VkDescriptorSetLayout vk(uint32_t deviceID) const { return _implementation[deviceID]->_descriptorSetLayout; } + /// VkDescriptorSetLayoutCreateFlags flags + VkDescriptorSetLayoutCreateFlags createFlags; + + void addBinding(uint32_t binding, VkDescriptorType descriptorType, uint32_t descriptorCount, VkShaderStageFlags stageFlags, VkDescriptorBindingFlags flags = 0); + /// VkDescriptorSetLayoutCreateInfo settings DescriptorSetLayoutBindings bindings; + /// VkDescriptorSetLayoutBindingFlagsCreateInfo settings + DescriptorSetLayoutBindingFlags bindingFlags; + /// map the descriptor bindings to the descriptor pool sizes that will be required to represent them. void getDescriptorPoolSizes(DescriptorPoolSizes& descriptorPoolSizes); @@ -59,7 +68,7 @@ namespace vsg struct Implementation : public Inherit { - Implementation(Device* device, const DescriptorSetLayoutBindings& descriptorSetLayoutBindings); + Implementation(Device* device, VkDescriptorSetLayoutCreateFlags createFlags, const DescriptorSetLayoutBindings& descriptorSetLayoutBindings, const DescriptorSetLayoutBindingFlags& descriptorSetLayoutBindingFlags); virtual ~Implementation(); diff --git a/src/vsg/state/DescriptorSetLayout.cpp b/src/vsg/state/DescriptorSetLayout.cpp index 787956fefc..dbc499b1fc 100644 --- a/src/vsg/state/DescriptorSetLayout.cpp +++ b/src/vsg/state/DescriptorSetLayout.cpp @@ -23,24 +23,47 @@ using namespace vsg; // DescriptorSetLayout // DescriptorSetLayout::DescriptorSetLayout() + : createFlags(0) { } DescriptorSetLayout::DescriptorSetLayout(const DescriptorSetLayout& rhs, const CopyOp& copyop) : Inherit(rhs, copyop), - bindings(rhs.bindings) + bindings(rhs.bindings), + bindingFlags(rhs.bindingFlags), + createFlags(rhs.createFlags) { } DescriptorSetLayout::DescriptorSetLayout(const DescriptorSetLayoutBindings& descriptorSetLayoutBindings) : - bindings(descriptorSetLayoutBindings) + bindings(descriptorSetLayoutBindings), + createFlags(0) { + bindingFlags.resize(bindings.size(), 0); } DescriptorSetLayout::~DescriptorSetLayout() { } +void DescriptorSetLayout::addBinding(uint32_t binding, VkDescriptorType descriptorType, uint32_t descriptorCount, VkShaderStageFlags stageFlags, VkDescriptorBindingFlags flags) +{ + VkDescriptorSetLayoutBinding layoutBinding = {}; + layoutBinding.binding = binding; + layoutBinding.descriptorType = descriptorType; + layoutBinding.descriptorCount = descriptorCount; + layoutBinding.stageFlags = stageFlags; + layoutBinding.pImmutableSamplers = nullptr; + bindings.push_back(layoutBinding); + + if (flags != 0) + { + if (binding >= bindingFlags.size()) + bindingFlags.resize(binding + 1, 0); + bindingFlags[binding] = flags; + } +} + void DescriptorSetLayout::getDescriptorPoolSizes(DescriptorPoolSizes& descriptorPoolSizes) { for (auto& binding : bindings) @@ -67,21 +90,26 @@ int DescriptorSetLayout::compare(const Object& rhs_object) const if (result != 0) return result; const auto& rhs = static_cast(rhs_object); - return compare_value_container(bindings, rhs.bindings); + return (createFlags == rhs.createFlags) && compare_value_container(bindings, rhs.bindings) && compare_value_container(bindingFlags, rhs.bindingFlags); } void DescriptorSetLayout::read(Input& input) { Object::read(input); + createFlags = input.readValue("createFlags"); bindings.resize(input.readValue("bindings")); + size_t i = 0; for (auto& dslb : bindings) { input.read("binding", dslb.binding); input.readValue("descriptorType", dslb.descriptorType); input.read("descriptorCount", dslb.descriptorCount); input.readValue("stageFlags", dslb.stageFlags); + if (i >= bindingFlags.size()) bindingFlags.resize(i + 1); + input.readValue("flags", bindingFlags[i]); + ++i; } } @@ -89,34 +117,49 @@ void DescriptorSetLayout::write(Output& output) const { Object::write(output); + output.writeValue("createFlags", createFlags); output.writeValue("bindings", bindings.size()); + size_t i = 0; for (auto& dslb : bindings) { output.write("binding", dslb.binding); output.writeValue("descriptorType", dslb.descriptorType); output.write("descriptorCount", dslb.descriptorCount); output.writeValue("stageFlags", dslb.stageFlags); + output.writeValue("flags", (i < bindingFlags.size()) ? static_cast(bindingFlags[i]) : 0); + ++i; } } void DescriptorSetLayout::compile(Context& context) { - if (!_implementation[context.deviceID]) _implementation[context.deviceID] = DescriptorSetLayout::Implementation::create(context.device, bindings); + if (!_implementation[context.deviceID]) _implementation[context.deviceID] = DescriptorSetLayout::Implementation::create(context.device, createFlags, bindings, bindingFlags); } ////////////////////////////////////// // // DescriptorSetLayout::Implementation // -DescriptorSetLayout::Implementation::Implementation(Device* device, const DescriptorSetLayoutBindings& descriptorSetLayoutBindings) : +DescriptorSetLayout::Implementation::Implementation(Device* device, VkDescriptorSetLayoutCreateFlags createFlags, const DescriptorSetLayoutBindings& descriptorSetLayoutBindings, const DescriptorSetLayoutBindingFlags& descriptorSetLayoutBindingFlags) : _device(device) { VkDescriptorSetLayoutCreateInfo layoutInfo = {}; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.bindingCount = static_cast(descriptorSetLayoutBindings.size()); layoutInfo.pBindings = descriptorSetLayoutBindings.data(); - layoutInfo.pNext = nullptr; + layoutInfo.flags = createFlags; + + if (!descriptorSetLayoutBindingFlags.empty()) + { + VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsCreateInfo = {}; + bindingFlagsCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; + bindingFlagsCreateInfo.bindingCount = static_cast(descriptorSetLayoutBindingFlags.size()); + bindingFlagsCreateInfo.pBindingFlags = descriptorSetLayoutBindingFlags.data(); + layoutInfo.pNext = &bindingFlagsCreateInfo; + } else { + layoutInfo.pNext = nullptr; + } if (VkResult result = vkCreateDescriptorSetLayout(*device, &layoutInfo, _device->getAllocationCallbacks(), &_descriptorSetLayout); result != VK_SUCCESS) {