From bca6564dac806ea8d30bad792066a3ba963fdbf1 Mon Sep 17 00:00:00 2001 From: Markus Tavenrath Date: Wed, 16 Aug 2017 11:46:45 +0200 Subject: [PATCH] Add support for structure pointer chains & bump version to 1.0.57 (#119) --- README.md | 26 ++++ Vulkan-Docs | 2 +- VulkanHppGenerator.cpp | 261 +++++++++++++++++++++++++++++++++-------- vulkan/vulkan.hpp | 215 ++++++++++++++++++++++++++++++++- 4 files changed, 454 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index ca5ec0b..06dfddf 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,32 @@ vkSubresourceLayout layout = vkGetImageSubResourceLayout(image, subresource); auto layout = device.getImageSubResourceLayout(image, { {} /* flags*/, 0 /* miplevel */, 0 /* layout */ }); ``` +# Structure Pointer Chains +Vulkan allows chaining of structures through the pNext pointer. Vulkan-Hpp has a variadic template class which allows constructing of such structure chains with minimal efforts. +In addition to this it checks at compile time if the spec allows the construction of such a pNext chain. + +``` +// This will compile successfully. +vk::StructureChain c; +vk::MemoryAllocateInfo &allocInfo = c.get(); +vk::ImportMemoryFdInfoKHR &fdInfo = c.get(); + +// This will fail compilation since it's not valid according to the spec. +vk::StructureChain c; +vk::MemoryAllocateInfo &allocInfo = c.get(); +vk::ImportMemoryFdInfoKHR &fdInfo = c.get(); +``` + +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: + +``` +// Query vk::MemoryRequirements2KHR and vk::MemoryDedicatedRequirementsKHR when calling Device::getBufferMemoryRequirements2KHR: +auto result = device.getBufferMemoryRequirements2KHR({}); +vk::MemoryRequirements2KHR &memReqs = result.get(); +vk::MemoryDedicatedRequirementsKHR &dedMemReqs = result.get(); +``` + + # Return values, Error Codes & Exceptions By default Vulkan-Hpp has exceptions enabled. This means that Vulkan-Hpp checks the return code of each function call which returns a Vk::Result. If Vk::Result is a failure a std::runtime_error will be thrown. Since there is no need to return the error code anymore the C++ bindings can now return the actual desired return value, i.e. a vulkan handle. In those cases ResultValue ::type is defined as the returned type. diff --git a/Vulkan-Docs b/Vulkan-Docs index 8e6dc96..a9231ec 160000 --- a/Vulkan-Docs +++ b/Vulkan-Docs @@ -1 +1 @@ -Subproject commit 8e6dc96ef04a12dc4018ca682146d953733f105b +Subproject commit a9231ec465ec08eb367fc990ca160fe45d545470 diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 3d17e89..a22e6d8 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -352,6 +352,77 @@ const std::string arrayProxyHeader = R"( #endif )"; +const std::string structureChainHeader = R"( + template constexpr bool isStructureChainValid() { return false; } + + template + class StructureChainElement + { + public: + explicit operator Element&() { return value; } + explicit operator const Element&() const { return value; } + private: + Element value; + }; + + template + class StructureChain : private StructureChainElement... + { + public: + StructureChain() + { + link(); + } + + StructureChain(StructureChain const &rhs) + { + linkAndCopy(rhs); + } + + StructureChain& operator=(StructureChain const &rhs) + { + linkAndCopy(rhs); + return this; + } + + template ClassType& get() { return static_cast(*this);} + + private: + template + void link() + { + } + + template + void link() + { + static_assert(isStructureChainValid(), "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x.pNext = &y; + link(); + } + + template + void linkAndCopy(StructureChain const &rhs) + { + static_cast(*this) = static_cast(rhs); + } + + template + void linkAndCopy(StructureChain const &rhs) + { + static_assert(isStructureChainValid(), "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x = static_cast(rhs); + x.pNext = &y; + linkAndCopy(rhs); + } + +}; +)"; + const std::string versionCheckHeader = R"( #if !defined(VULKAN_HPP_HAS_UNRESTRICTED_UNIONS) # if defined(__clang__) @@ -748,10 +819,11 @@ struct StructData : returnedOnly(false) {} - bool returnedOnly; - bool isUnion; - std::vector members; - std::string protect; + bool returnedOnly; + bool isUnion; + std::vector members; + std::string protect; + std::vector structExtends; }; struct DeleterData @@ -771,6 +843,7 @@ struct VkData std::map handles; std::map scalars; std::map structs; + std::set extendedStructs; // structs which are referenced by the structextends tag std::set tags; std::string typesafeCheck; std::string version; @@ -817,7 +890,7 @@ void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ); void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ); void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData); void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData, bool isUnion ); -void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); +void readTypeStructMember( tinyxml2::XMLElement * element, VkData & vkData, StructData & structData ); void readTags(tinyxml2::XMLElement * element, std::set & tags); void readTypes(tinyxml2::XMLElement * element, VkData & vkData); std::string reduceName(std::string const& name, bool singular = false); @@ -841,15 +914,15 @@ void writeDeleterClasses(std::ostream & os, std::pair> const& deleterTypes, std::map const& deleterData); void writeEnumsToString(std::ostream & os, EnumData const& enumData); void writeFlagsToString(std::ostream & os, std::string const& flagsName, EnumData const &enumData); -void writeFunction(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique); -void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool singular); +void writeFunction(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain); +void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool singular, bool isStructureChain); void writeFunctionBodyEnhancedCall(std::ostream &os, std::string const& indentation, std::set const& vkTypes, CommandData const& commandData, bool singular); void writeFunctionBodyEnhancedCallResult(std::ostream &os, std::string const& indentation, std::set const& vkTypes, CommandData const& commandData, bool singular); void writeFunctionBodyEnhancedCallTwoStep(std::ostream & os, std::string const& indentation, std::set const& vkTypes, std::string const& returnName, std::string const& sizeName, CommandData const& commandData); void writeFunctionBodyEnhancedCallTwoStepChecked(std::ostream & os, std::string const& indentation, std::set const& vkTypes, std::string const& returnName, std::string const& sizeName, CommandData const& commandData); void writeFunctionBodyEnhancedCallTwoStepIterate(std::ostream & os, std::string const& indentation, std::set const& vkTypes, std::string const& returnName, std::string const& sizeName, CommandData const& commandData); void writeFunctionBodyEnhancedLocalCountVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData); -std::string writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool singular); +std::string writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool singular, bool isStructureChain); void writeFunctionBodyEnhancedMultiVectorSizeCheck(std::ostream & os, std::string const& indentation, CommandData const& commandData); void writeFunctionBodyEnhancedReturnResultValue(std::ostream & os, std::string const& indentation, std::string const& returnName, CommandData const& commandData, bool singular); void writeFunctionBodyStandard(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData); @@ -858,8 +931,8 @@ void writeFunctionHeaderArguments(std::ostream & os, VkData const& vkData, Comma void writeFunctionHeaderArgumentsEnhanced(std::ostream & os, VkData const& vkData, CommandData const& commandData, bool singular, bool withDefaults); void writeFunctionHeaderArgumentsStandard(std::ostream & os, CommandData const& commandData); void writeFunctionHeaderName(std::ostream & os, std::string const& name, bool singular, bool unique); -void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique); -void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault); +void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain); +void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault, bool isStructureChain); void writeReinterpretCast(std::ostream & os, bool leadingConst, bool vulkanType, std::string const& type, bool trailingPointerToConst); void writeStandardOrEnhanced(std::ostream & os, std::string const& standard, std::string const& enhanced); void writeStructConstructor( std::ostream & os, std::string const& name, StructData const& structData, std::set const& vkTypes, std::map const& defaultValues ); @@ -1826,6 +1899,23 @@ void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData, bool isUni it->second.returnedOnly = !!element->Attribute( "returnedonly" ); it->second.isUnion = isUnion; + if (element->Attribute("structextends")) + { + std::string structextends = element->Attribute("structextends"); + std::vector structs; + size_t endPos = -1; + do + { + size_t startPos = endPos + 1; + endPos = structextends.find(',', startPos); + assert(structextends.substr(startPos, 2) == "Vk"); + std::string structExtendName = structextends.substr(startPos + 2, endPos - startPos - 2); + it->second.structExtends.push_back(structExtendName); + vkData.extendedStructs.insert(structExtendName); + } while (endPos != std::string::npos); + assert(!it->second.structExtends.empty()); + } + for (tinyxml2::XMLElement * child = element->FirstChildElement(); child; child = child->NextSiblingElement()) { assert( child->Value() ); @@ -1833,7 +1923,7 @@ void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData, bool isUni assert((value == "comment") || (value == "member")); if (value == "member") { - readTypeStructMember(child, it->second.members, vkData.dependencies.back().dependencies); + readTypeStructMember(child, vkData, it->second); } } @@ -1841,13 +1931,14 @@ void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData, bool isUni vkData.vkTypes.insert( name ); } -void readTypeStructMember(tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies) +void readTypeStructMember(tinyxml2::XMLElement * element, VkData & vkData, StructData & structData) { - members.push_back(MemberData()); - MemberData & member = members.back(); + + structData.members.push_back(MemberData()); + MemberData & member = structData.members.back(); tinyxml2::XMLNode* child = readType(element->FirstChild(), member.type, member.pureType); - dependencies.insert(member.pureType); + vkData.dependencies.back().dependencies.insert(member.pureType); assert((child->ToElement() && strcmp(child->Value(), "name") == 0)); member.name = child->ToElement()->GetText(); @@ -2324,14 +2415,14 @@ void writeCallVulkanTypeParameter(std::ostream & os, ParamData const& paramData) } } -void writeFunction(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique) +void writeFunction(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain) { - if (enhanced && !singular) + if (enhanced && (!singular || isStructureChain)) { - writeFunctionHeaderTemplate(os, indentation, commandData, !definition); + writeFunctionHeaderTemplate(os, indentation, commandData, !definition, isStructureChain); } os << indentation << (definition ? "VULKAN_HPP_INLINE " : ""); - writeFunctionHeaderReturnType(os, indentation, commandData, enhanced, singular, unique); + writeFunctionHeaderReturnType(os, indentation, commandData, enhanced, singular, unique, isStructureChain); if (definition && !commandData.className.empty()) { os << commandData.className << "::"; @@ -2352,7 +2443,7 @@ void writeFunction(std::ostream & os, std::string const& indentation, VkData con } else { - writeFunctionBodyEnhanced(os, indentation, vkData, commandData, singular); + writeFunctionBodyEnhanced(os, indentation, vkData, commandData, singular, isStructureChain); } } else @@ -2363,7 +2454,7 @@ void writeFunction(std::ostream & os, std::string const& indentation, VkData con } } -void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool singular) +void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool singular, bool isStructureChain) { if (1 < commandData.vectorParams.size()) { @@ -2373,7 +2464,7 @@ void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation std::string returnName; if (commandData.returnParam != ~0) { - returnName = writeFunctionBodyEnhancedLocalReturnVariable(os, indentation, commandData, singular); + returnName = writeFunctionBodyEnhancedLocalReturnVariable(os, indentation, commandData, singular, isStructureChain); } if (commandData.twoStep) @@ -2515,25 +2606,48 @@ void writeFunctionBodyEnhancedLocalCountVariable(std::ostream & os, std::string os << indentation << " " << commandData.params[returnit->second].pureType << " " << startLowerCase(strip(commandData.params[returnit->second].name, "p")) << ";" << std::endl; } -std::string writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool singular) +std::string writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool singular, bool isStructureChain) { std::string returnName = startLowerCase(strip(commandData.params[commandData.returnParam].name, "p")); // there is a returned parameter -> we need a local variable to hold that value if (commandData.returnType != commandData.enhancedReturnType) { - // the returned parameter is somehow enanced by us + // the returned parameter is somehow enhanced by us os << indentation << " "; if (singular) { - // in singular case, just use the return parameters pure type for the return variable - returnName = stripPluralS(returnName); - os << commandData.params[commandData.returnParam].pureType << " " << returnName; + if (isStructureChain) + { + std::string const &pureType = commandData.params[commandData.returnParam].pureType; + // For StructureChains use the template parameters + os << "StructureChain structureChain;" << std::endl; + returnName = stripPluralS(returnName); + os << indentation << " " << pureType << "& " << returnName << " = structureChain.template get<" << pureType << ">()"; + returnName = "structureChain"; + } + else + { + // in singular case, just use the return parameters pure type for the return variable + returnName = stripPluralS(returnName); + os << commandData.params[commandData.returnParam].pureType << " " << returnName; + } } else { // in non-singular case, use the enhanced type for the return variable (like vector<...>) - os << commandData.enhancedReturnType << " " << returnName; + if (isStructureChain) + { + std::string const &returnType = commandData.enhancedReturnType; + // For StructureChains use the template parameters + os << "StructureChain structureChain;" << std::endl; + os << indentation << " " << returnType << "& " << returnName << " = structureChain.template get<" << returnType << ">()"; + returnName = "structureChain"; + } + else + { + os << commandData.enhancedReturnType << " " << returnName; + } std::map::const_iterator it = commandData.vectorParams.find(commandData.returnParam); if (it != commandData.vectorParams.end() && !commandData.twoStep) @@ -2982,7 +3096,7 @@ void writeFunctionHeaderName(std::ostream & os, std::string const& name, bool si } } -void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique) +void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain) { std::string templateString; std::string returnType; @@ -2994,38 +3108,43 @@ void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indenta // the unique version returns something prefixed with 'Unique'; potentially a vector of that stuff // it's a vector, if it's not the singular version and the return parameter is a vector parameter bool returnsVector = !singular && (commandData.vectorParams.find(commandData.returnParam) != commandData.vectorParams.end()); + templateString = returnsVector ? "std::vector " : "Unique${returnType} "; - returnType = commandData.params[commandData.returnParam].pureType; - //os << replaceWithMap(, {{"returnType", commandData.params[commandData.returnParam].pureType }}); + returnType = isStructureChain ? "StructureChain" : commandData.params[commandData.returnParam].pureType; } else if ((commandData.enhancedReturnType != commandData.returnType) && (commandData.returnType != "void")) { // if the enhanced return type differs from the original return type, and it's not void, we return a ResultValueType<...>::type - if (!singular && (commandData.enhancedReturnType.find("Allocator") != std::string::npos)) + if (isStructureChain || (!singular && (commandData.enhancedReturnType.find("Allocator") != std::string::npos))) { // for the non-singular case with allocation, we need to prepend with 'typename' to keep compilers happy - templateString = "typename ResultValueType<${returnType}>::type "; + templateString = "typename "; + } + templateString += "ResultValueType<${returnType}>::type "; + + assert(commandData.returnType == "Result"); + // in singular case, we create the ResultValueType from the pure return type, otherwise from the enhanced return type + if (isStructureChain) + { + returnType = "StructureChain"; } else { - templateString = "ResultValueType<${returnType}>::type "; + returnType = singular ? commandData.params[commandData.returnParam].pureType : commandData.enhancedReturnType; } - assert(commandData.returnType == "Result"); - // in singular case, we create the ResultValueType from the pure return type, otherwise from the enhanced return type - returnType = singular ? commandData.params[commandData.returnParam].pureType : commandData.enhancedReturnType; } else if ((commandData.returnParam != ~0) && (1 < commandData.successCodes.size())) { // if there is a return parameter at all, and there are multiple success codes, we return a ResultValue<...> with the pure return type assert(commandData.returnType == "Result"); templateString = "ResultValue<${returnType}> "; - returnType = commandData.params[commandData.returnParam].pureType; + returnType = isStructureChain ? "StructureChain" : commandData.params[commandData.returnParam].pureType; } else { // and in every other case, we just return the enhanced return type. templateString = "${returnType} "; - returnType = commandData.enhancedReturnType; + returnType = isStructureChain ? "StructureChain" : commandData.enhancedReturnType; } } else @@ -3037,9 +3156,13 @@ void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indenta os << replaceWithMap(templateString, { { "returnType", returnType } }); } -void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault) +void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool withDefault, bool isStructureChain) { - if ((commandData.templateParam != ~0) && ((commandData.templateParam != commandData.returnParam) || (commandData.enhancedReturnType == "Result"))) + if (isStructureChain) + { + os << indentation << "template " << std::endl; + } + else if ((commandData.templateParam != ~0) && ((commandData.templateParam != commandData.returnParam) || (commandData.enhancedReturnType == "Result"))) { // if there's a template parameter, not being the return parameter or where the enhanced return type is 'Result' -> templatize on type 'T' assert(commandData.enhancedReturnType.find("Allocator") == std::string::npos); @@ -3275,20 +3398,27 @@ void writeTypeCommand(std::ostream & os, std::string const& indentation, VkData { enterProtect(os, commandData.protect); + bool isStructureChain = vkData.extendedStructs.find(commandData.enhancedReturnType) != vkData.extendedStructs.end(); + // first create the standard version of the function std::ostringstream standard; - writeFunction(standard, indentation, vkData, commandData, definition, false, false, false); + writeFunction(standard, indentation, vkData, commandData, definition, false, false, false, false); - // then the enhanced version, composed by up to four parts + // then the enhanced version, composed by up to five parts std::ostringstream enhanced; - writeFunction(enhanced, indentation, vkData, commandData, definition, true, false, false); + writeFunction(enhanced, indentation, vkData, commandData, definition, true, false, false, false); + + if (isStructureChain) + { + writeFunction(enhanced, indentation, vkData, commandData, definition, true, false, false, true); + } // then a singular version, if a sized vector would be returned std::map::const_iterator returnVector = commandData.vectorParams.find(commandData.returnParam); bool singular = (returnVector != commandData.vectorParams.end()) && (returnVector->second != ~0) && (commandData.params[returnVector->second].type.back() != '*'); if (singular) { - writeFunction(enhanced, indentation, vkData, commandData, definition, true, true, false); + writeFunction(enhanced, indentation, vkData, commandData, definition, true, true, false, false); } // special handling for createDevice and createInstance ! @@ -3298,11 +3428,11 @@ void writeTypeCommand(std::ostream & os, std::string const& indentation, VkData if (((vkData.deleterData.find(commandData.className) != vkData.deleterData.end()) || specialWriteUnique) && ((commandData.reducedName.substr(0, 8) == "allocate") || (commandData.reducedName.substr(0, 6) == "create"))) { enhanced << "#ifndef VULKAN_HPP_NO_SMART_HANDLE" << std::endl; - writeFunction(enhanced, indentation, vkData, commandData, definition, true, false, true); + writeFunction(enhanced, indentation, vkData, commandData, definition, true, false, true, false); if (singular) { - writeFunction(enhanced, indentation, vkData, commandData, definition, true, true, true); + writeFunction(enhanced, indentation, vkData, commandData, definition, true, true, true, false); } enhanced << "#endif /*VULKAN_HPP_NO_SMART_HANDLE*/" << std::endl; } @@ -3898,6 +4028,29 @@ void writeTypeStruct( std::ostream & os, VkData const& vkData, DependencyData co os << std::endl; } +void writeStructureChainValidation(std::ostream & os, VkData const& vkData, DependencyData const& dependencyData) +{ + std::map::const_iterator it = vkData.structs.find(dependencyData.name); + assert(it != vkData.structs.end()); + + if (!it->second.structExtends.empty()) { + enterProtect(os, it->second.protect); + + // write out allowed structure chains + for (auto extendName : it->second.structExtends) + { + std::map::const_iterator itExtend = vkData.structs.find(extendName); + assert(itExtend != vkData.structs.end()); + enterProtect(os, itExtend->second.protect); + + os << " template <> constexpr bool isStructureChainValid<" << extendName << ", " << dependencyData.name << ">() { return true; }" << std::endl; + + leaveProtect(os, itExtend->second.protect); + } + leaveProtect(os, it->second.protect); + } +} + void writeTypeUnion( std::ostream & os, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ) { std::map::const_iterator it = vkData.structs.find(dependencyData.name); @@ -4167,7 +4320,8 @@ int main( int argc, char **argv ) << flagsHeader << optionalClassHeader << arrayProxyHeader - << uniqueHandleHeader; + << uniqueHandleHeader + << structureChainHeader; // first of all, write out vk::Result and the exception handling stuff std::list::const_iterator it = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [](DependencyData const& dp) { return dp.name == "Result"; }); @@ -4199,6 +4353,17 @@ int main( int argc, char **argv ) assert(vkData.deleterTypes.find("") != vkData.deleterTypes.end()); writeTypes(ofs, vkData, defaultValues); + // write all template functions for the structure pointer chain validation + for (auto it = vkData.dependencies.begin(); it != vkData.dependencies.end(); ++it) + { + switch (it->category) + { + case DependencyData::Category::STRUCT: + writeStructureChainValidation(ofs, vkData, *it); + break; + } + } + // write all the to_string functions for enums and flags for (auto it = vkData.dependencies.begin(); it != vkData.dependencies.end(); ++it) { diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 151a3a3..a276624 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -33,7 +33,7 @@ # include # include #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ -static_assert( VK_HEADER_VERSION == 55 , "Wrong VK_HEADER_VERSION!" ); +static_assert( VK_HEADER_VERSION == 57 , "Wrong VK_HEADER_VERSION!" ); // 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default. // To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION @@ -425,6 +425,75 @@ namespace vk } #endif + + template constexpr bool isStructureChainValid() { return false; } + + template + class StructureChainElement + { + public: + explicit operator Element&() { return value; } + explicit operator const Element&() const { return value; } + private: + Element value; + }; + + template + class StructureChain : private StructureChainElement... + { + public: + StructureChain() + { + link(); + } + + StructureChain(StructureChain const &rhs) + { + linkAndCopy(rhs); + } + + StructureChain& operator=(StructureChain const &rhs) + { + linkAndCopy(rhs); + return *this; + } + + template ClassType& get() { return static_cast(*this);} + + private: + template + void link() + { + } + + template + void link() + { + static_assert(isStructureChainValid(), "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x.pNext = &y; + link(); + } + + template + void linkAndCopy(StructureChain const &rhs) + { + static_cast(*this) = static_cast(rhs); + } + + template + void linkAndCopy(StructureChain const &rhs) + { + static_assert(isStructureChainValid(), "The structure chain is not valid!"); + X& x = static_cast(*this); + Y& y = static_cast(*this); + x = static_cast(rhs); + x.pNext = &y; + linkAndCopy(rhs); + } + +}; enum class Result { eSuccess = VK_SUCCESS, @@ -25710,11 +25779,15 @@ namespace vk void getBufferMemoryRequirements2KHR( const BufferMemoryRequirementsInfo2KHR* pInfo, MemoryRequirements2KHR* pMemoryRequirements ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE MemoryRequirements2KHR getBufferMemoryRequirements2KHR( const BufferMemoryRequirementsInfo2KHR & info ) const; + template + StructureChain getBufferMemoryRequirements2KHR( const BufferMemoryRequirementsInfo2KHR & info ) const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ void getImageMemoryRequirements2KHR( const ImageMemoryRequirementsInfo2KHR* pInfo, MemoryRequirements2KHR* pMemoryRequirements ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE MemoryRequirements2KHR getImageMemoryRequirements2KHR( const ImageMemoryRequirementsInfo2KHR & info ) const; + template + StructureChain getImageMemoryRequirements2KHR( const ImageMemoryRequirementsInfo2KHR & info ) const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ void getImageSparseMemoryRequirements2KHR( const ImageSparseMemoryRequirementsInfo2KHR* pInfo, uint32_t* pSparseMemoryRequirementCount, SparseImageMemoryRequirements2KHR* pSparseMemoryRequirements ) const; @@ -27949,6 +28022,14 @@ namespace vk vkGetBufferMemoryRequirements2KHR( m_device, reinterpret_cast( &info ), reinterpret_cast( &memoryRequirements ) ); return memoryRequirements; } + template + VULKAN_HPP_INLINE StructureChain Device::getBufferMemoryRequirements2KHR( const BufferMemoryRequirementsInfo2KHR & info ) const + { + StructureChain structureChain; + MemoryRequirements2KHR& memoryRequirements = structureChain.template get(); + vkGetBufferMemoryRequirements2KHR( m_device, reinterpret_cast( &info ), reinterpret_cast( &memoryRequirements ) ); + return structureChain; + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE void Device::getImageMemoryRequirements2KHR( const ImageMemoryRequirementsInfo2KHR* pInfo, MemoryRequirements2KHR* pMemoryRequirements ) const @@ -27962,6 +28043,14 @@ namespace vk vkGetImageMemoryRequirements2KHR( m_device, reinterpret_cast( &info ), reinterpret_cast( &memoryRequirements ) ); return memoryRequirements; } + template + VULKAN_HPP_INLINE StructureChain Device::getImageMemoryRequirements2KHR( const ImageMemoryRequirementsInfo2KHR & info ) const + { + StructureChain structureChain; + MemoryRequirements2KHR& memoryRequirements = structureChain.template get(); + vkGetImageMemoryRequirements2KHR( m_device, reinterpret_cast( &info ), reinterpret_cast( &memoryRequirements ) ); + return structureChain; + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE void Device::getImageSparseMemoryRequirements2KHR( const ImageSparseMemoryRequirementsInfo2KHR* pInfo, uint32_t* pSparseMemoryRequirementCount, SparseImageMemoryRequirements2KHR* pSparseMemoryRequirements ) const @@ -28188,11 +28277,15 @@ namespace vk void getFeatures2KHR( PhysicalDeviceFeatures2KHR* pFeatures ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE PhysicalDeviceFeatures2KHR getFeatures2KHR() const; + template + StructureChain getFeatures2KHR() const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ void getProperties2KHR( PhysicalDeviceProperties2KHR* pProperties ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE PhysicalDeviceProperties2KHR getProperties2KHR() const; + template + StructureChain getProperties2KHR() const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ void getFormatProperties2KHR( Format format, FormatProperties2KHR* pFormatProperties ) const; @@ -28203,6 +28296,8 @@ namespace vk Result getImageFormatProperties2KHR( const PhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, ImageFormatProperties2KHR* pImageFormatProperties ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE ResultValueType::type getImageFormatProperties2KHR( const PhysicalDeviceImageFormatInfo2KHR & imageFormatInfo ) const; + template + typename ResultValueType>::type getImageFormatProperties2KHR( const PhysicalDeviceImageFormatInfo2KHR & imageFormatInfo ) const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ void getQueueFamilyProperties2KHR( uint32_t* pQueueFamilyPropertyCount, QueueFamilyProperties2KHR* pQueueFamilyProperties ) const; @@ -28271,6 +28366,8 @@ namespace vk Result getSurfaceCapabilities2KHR( const PhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, SurfaceCapabilities2KHR* pSurfaceCapabilities ) const; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE ResultValueType::type getSurfaceCapabilities2KHR( const PhysicalDeviceSurfaceInfo2KHR & surfaceInfo ) const; + template + typename ResultValueType>::type getSurfaceCapabilities2KHR( const PhysicalDeviceSurfaceInfo2KHR & surfaceInfo ) const; #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ Result getSurfaceFormats2KHR( const PhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, SurfaceFormat2KHR* pSurfaceFormats ) const; @@ -28795,6 +28892,14 @@ namespace vk vkGetPhysicalDeviceFeatures2KHR( m_physicalDevice, reinterpret_cast( &features ) ); return features; } + template + VULKAN_HPP_INLINE StructureChain PhysicalDevice::getFeatures2KHR() const + { + StructureChain structureChain; + PhysicalDeviceFeatures2KHR& features = structureChain.template get(); + vkGetPhysicalDeviceFeatures2KHR( m_physicalDevice, reinterpret_cast( &features ) ); + return structureChain; + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE void PhysicalDevice::getProperties2KHR( PhysicalDeviceProperties2KHR* pProperties ) const @@ -28808,6 +28913,14 @@ namespace vk vkGetPhysicalDeviceProperties2KHR( m_physicalDevice, reinterpret_cast( &properties ) ); return properties; } + template + VULKAN_HPP_INLINE StructureChain PhysicalDevice::getProperties2KHR() const + { + StructureChain structureChain; + PhysicalDeviceProperties2KHR& properties = structureChain.template get(); + vkGetPhysicalDeviceProperties2KHR( m_physicalDevice, reinterpret_cast( &properties ) ); + return structureChain; + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE void PhysicalDevice::getFormatProperties2KHR( Format format, FormatProperties2KHR* pFormatProperties ) const @@ -28834,6 +28947,14 @@ namespace vk Result result = static_cast( vkGetPhysicalDeviceImageFormatProperties2KHR( m_physicalDevice, reinterpret_cast( &imageFormatInfo ), reinterpret_cast( &imageFormatProperties ) ) ); return createResultValue( result, imageFormatProperties, "vk::PhysicalDevice::getImageFormatProperties2KHR" ); } + template + VULKAN_HPP_INLINE typename ResultValueType>::type PhysicalDevice::getImageFormatProperties2KHR( const PhysicalDeviceImageFormatInfo2KHR & imageFormatInfo ) const + { + StructureChain structureChain; + ImageFormatProperties2KHR& imageFormatProperties = structureChain.template get(); + Result result = static_cast( vkGetPhysicalDeviceImageFormatProperties2KHR( m_physicalDevice, reinterpret_cast( &imageFormatInfo ), reinterpret_cast( &imageFormatProperties ) ) ); + return createResultValue( result, structureChain, "vk::PhysicalDevice::getImageFormatProperties2KHR" ); + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE void PhysicalDevice::getQueueFamilyProperties2KHR( uint32_t* pQueueFamilyPropertyCount, QueueFamilyProperties2KHR* pQueueFamilyProperties ) const @@ -29015,6 +29136,14 @@ namespace vk Result result = static_cast( vkGetPhysicalDeviceSurfaceCapabilities2KHR( m_physicalDevice, reinterpret_cast( &surfaceInfo ), reinterpret_cast( &surfaceCapabilities ) ) ); return createResultValue( result, surfaceCapabilities, "vk::PhysicalDevice::getSurfaceCapabilities2KHR" ); } + template + VULKAN_HPP_INLINE typename ResultValueType>::type PhysicalDevice::getSurfaceCapabilities2KHR( const PhysicalDeviceSurfaceInfo2KHR & surfaceInfo ) const + { + StructureChain structureChain; + SurfaceCapabilities2KHR& surfaceCapabilities = structureChain.template get(); + Result result = static_cast( vkGetPhysicalDeviceSurfaceCapabilities2KHR( m_physicalDevice, reinterpret_cast( &surfaceInfo ), reinterpret_cast( &surfaceCapabilities ) ) ); + return createResultValue( result, structureChain, "vk::PhysicalDevice::getSurfaceCapabilities2KHR" ); + } #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ VULKAN_HPP_INLINE Result PhysicalDevice::getSurfaceFormats2KHR( const PhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, SurfaceFormat2KHR* pSurfaceFormats ) const @@ -29939,6 +30068,90 @@ namespace vk #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } +#ifdef VK_USE_PLATFORM_WIN32_KHR + template <> constexpr bool isStructureChainValid() { return true; } +#endif /*VK_USE_PLATFORM_WIN32_KHR*/ + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } + template <> constexpr bool isStructureChainValid() { return true; } VULKAN_HPP_INLINE std::string to_string(FramebufferCreateFlagBits) { return "(void)";