diff --git a/README.md b/README.md index 46c6794..6dabff4 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,15 @@ vk::MemoryAllocateInfo &allocInfo = c.get(); vk::ImportMemoryFdInfoKHR &fdInfo = c.get(); ``` +Vulkan-Hpp provides a constructor for these chains similar to the CreateInfo objects which accepts a list of all structures part of the chain. The `pNext` field is automatically set to the correct value: + +```c++ +vk::StructureChain c = { + vk::MemoryAllocateInfo(size, type), + vk::MemoryDedicatedAllocateInfo(image) +}; +``` + Sometimes the user has to pass a preallocated structure chain to query information. In those cases the corresponding query functions are variadic templates and do accept a structure chain to construct the return value: ``` diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 2884d06..362871d 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -398,6 +398,11 @@ const std::string structureChainHeader = R"( linkAndCopy(rhs); } + StructureChain(StructureElements const &... elems) + { + linkAndCopyElements(elems...); + } + StructureChain& operator=(StructureChain const &rhs) { linkAndCopy(rhs); @@ -439,7 +444,24 @@ const std::string structureChainHeader = R"( linkAndCopy(rhs); } -}; + template + void linkAndCopyElements(X const &xelem) + { + static_cast(*this) = xelem; + } + + template + void linkAndCopyElements(X const &xelem, Y const &yelem, Z const &... zelem) + { + static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x = xelem; + x.pNext = &y; + linkAndCopyElements(yelem, zelem...); + } + }; + )"; const std::string versionCheckHeader = R"( diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 249da81..bf96c05 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -471,6 +471,11 @@ namespace VULKAN_HPP_NAMESPACE linkAndCopy(rhs); } + StructureChain(StructureElements const &... elems) + { + linkAndCopyElements(elems...); + } + StructureChain& operator=(StructureChain const &rhs) { linkAndCopy(rhs); @@ -512,7 +517,24 @@ namespace VULKAN_HPP_NAMESPACE linkAndCopy(rhs); } -}; + template + void linkAndCopyElements(X const &xelem) + { + static_cast(*this) = xelem; + } + + template + void linkAndCopyElements(X const &xelem, Y const &yelem, Z const &... zelem) + { + static_assert(isStructureChainValid::value, "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x = xelem; + x.pNext = &y; + linkAndCopyElements(yelem, zelem...); + } + }; + enum class Result { eSuccess = VK_SUCCESS,