From a12c3807de31843ff81cbb712c05b9b08b1a3806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 27 Aug 2019 09:02:49 +0200 Subject: [PATCH] cleanup on stringstream usage. (#376) --- VulkanHppGenerator.cpp | 4859 ++++++++++++++++++++-------------------- VulkanHppGenerator.hpp | 114 +- vulkan/vulkan.hpp | 630 +++--- 3 files changed, 2741 insertions(+), 2862 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index e8304f3..e8b6603 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -17,12 +17,16 @@ #include #include #include -#include #include #include #include #include "VulkanHppGenerator.hpp" +void appendArgumentCount(std::string & str, size_t vectorIndex, std::string const& vectorName, std::string const& counterName, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool singular); +std::string appendFunctionBodyEnhancedLocalReturnVariableSingular(std::string & str, std::string const& indentation, std::string const& returnName, std::string const& typeName, bool isStructureChain); +void appendReinterpretCast(std::string & str, bool leadingConst, std::string const& type, bool trailingPointerToConst); +void appendTypesafeStuff(std::string &str, std::string const& typesafeCheck); +void appendVersionCheck(std::string & str, std::string const& version); bool beginsWith(std::string const& text, std::string const& prefix); bool endsWith(std::string const& text, std::string const& postfix); template void checkAlias(std::map const& data, std::string const& name, int line); @@ -30,15 +34,13 @@ void checkAttributes(std::map const& attributes, int l void checkElements(std::vector const& elements, std::set const& values); void checkEmptyElement(tinyxml2::XMLElement const* element); void checkOrderedElements(std::vector const& elements, std::vector const& values); -void cleanup(std::string const& fileName); +void cleanup(std::stringstream & ss); std::string createEnumValueName(std::string const& name, std::string const& prefix, std::string const& postfix, bool bitmask, std::string const& tag); std::string determineCommandName(std::string const& vulkanCommandName, std::string const& firstArgumentType); std::set determineSkippedParams(size_t returnParamIndex, std::map const& vectorParamIndices); bool determineStructureChaining(std::string const& structType, std::set const& extendedStructs, std::map const& structureAliases); std::string findTag(std::set const& tags, std::string const& name, std::string const& postfix = ""); -std::string generateArgumentCount(size_t vectorIndex, std::string const& vectorName, std::string const& counterName, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool singular); -std::string generateFunctionBodyEnhancedLocalReturnVariableSingular(std::string const& indentation, std::string const& typeName, std::string & returnName, bool isStructureChain); -std::string generateReinterpretCast(bool leadingConst, std::string const& type, bool trailingPointerToConst); +std::pair generateFunctionBodyStandardReturn(std::string const& returnType); std::map getAttributes(tinyxml2::XMLElement const* element); std::vector getChildElements(tinyxml2::XMLElement const* element); std::string getEnumPostfix(std::string const& name, std::set const& tags, std::string & prefix); @@ -58,7 +60,90 @@ std::string toUpperCase(std::string const& name); std::vector tokenize(std::string tokenString, char separator); std::string trim(std::string const& input); std::string trimEnd(std::string const& input); -std::pair writeFunctionBodyStandardReturn(std::string const& returnType); + +void appendArgumentCount(std::string & str, size_t vectorIndex, std::string const& vectorName, std::string const& counterName, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool singular) +{ + // this parameter is a count parameter for a vector parameter + if ((returnParamIndex == vectorIndex) && twoStep) + { + // the corresponding vector parameter is the return parameter and it's a two-step algorithm + // -> use the pointer to a local variable named like the counter parameter without leading 'p' + assert((counterName[0] == 'p') && isupper(counterName[1])); + str += "&" + startLowerCase(stripPrefix(counterName, "p")); + } + else + { + // the corresponding vector parameter is not the return parameter, or it's not a two-step algorithm + if (singular) + { + // for the singular version, the count is just 1. + str += "1 "; + } + else + { + // for the non-singular version, the count is the size of the vector parameter + // -> use the vector parameter name without leading 'p' to get the size (in number of elements, not in bytes) + assert(vectorName[0] == 'p'); + str += startLowerCase(stripPrefix(vectorName, "p")) + ".size() "; + } + if (templateParamIndex == vectorIndex) + { + // if the vector parameter is templatized -> multiply by the size of that type to get the size in bytes + str += "* sizeof( T ) "; + } + } +} + +std::string appendFunctionBodyEnhancedLocalReturnVariableSingular(std::string & str, std::string const& indentation, std::string const& returnName, std::string const& typeName, bool isStructureChain) +{ + std::string strippedReturnName = stripPluralS(returnName); + if (isStructureChain) + { + // For StructureChains use the template parameters + str += + "StructureChain structureChain;\n" + + indentation + " " + typeName + "& " + strippedReturnName + " = structureChain.template get<" + typeName + ">()"; + strippedReturnName = "structureChain"; + } + else + { + // in singular case, just use the return parameters pure type for the return variable + str += typeName + " " + strippedReturnName; + } + return strippedReturnName; +} + +void appendReinterpretCast(std::string & str, bool leadingConst, std::string const& type, bool trailingPointerToConst) +{ + str += "reinterpret_cast<"; + if (leadingConst) + { + str += "const "; + } + str += type; + if (trailingPointerToConst) + { + str += "* const"; + } + str += "*>"; +} + +void appendTypesafeStuff(std::string & str, std::string const& typesafeCheck) +{ + str += "// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.\n" + "// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION\n" + + typesafeCheck + "\n" + "# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )\n" + "# define VULKAN_HPP_TYPESAFE_CONVERSION\n" + "# endif\n" + "#endif\n"; +} + +void appendVersionCheck(std::string & str, std::string const& version) +{ + str += "static_assert( VK_HEADER_VERSION == " + version + " , \"Wrong VK_HEADER_VERSION!\" );\n" + "\n"; +} bool beginsWith(std::string const& text, std::string const& prefix) { @@ -75,11 +160,7 @@ void checkAlias(std::map const& data, std::string const& name, i { if (data.find(name) == data.end()) { - std::stringstream ss; - ss << line; - std::string lineNumber = ss.str(); - - throw std::runtime_error("Spec error on line " + lineNumber + ": missing alias <" + name + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(line) + ": missing alias <" + name + ">"); } } @@ -90,21 +171,17 @@ void checkAlias(std::map const& data, std::string const& name, i // optional : the optional attributes, with a set of allowed values per attribute void checkAttributes(std::map const& attributes, int line, std::map> const& required, std::map> const& optional) { - std::stringstream ss; - ss << line; - std::string lineNumber = ss.str(); - // check if all required attributes are included and if there is a set of allowed values, check if the actual value is part of that set for (auto const& r : required) { auto attributesIt = attributes.find(r.first); if (attributesIt == attributes.end()) { - throw std::runtime_error("Spec error on line " + lineNumber + ": missing attribute <" + r.first + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(line) + ": missing attribute <" + r.first + ">"); } if (!r.second.empty() && (r.second.find(attributesIt->second) == r.second.end())) { - throw std::runtime_error("Spec error on line " + lineNumber + ": unexpected attribute value <" + attributesIt->second + "> in attribute <" + r.first + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(line) + ": unexpected attribute value <" + attributesIt->second + "> in attribute <" + r.first + ">"); } } // check if all not required attributes or optional, and if there is a set of allowed values, check if the actual value is part of that set @@ -115,7 +192,7 @@ void checkAttributes(std::map const& attributes, int l auto optionalIt = optional.find(a.first); if (optionalIt == optional.end()) { - std::cerr << "warning: " << "Unknown attribute " + a.first + " in line " + lineNumber + "!" << std::endl; + std::cerr << "warning: " << "Unknown attribute " + a.first + " in line " + std::to_string(line) + "!" << std::endl; continue; } if (!optionalIt->second.empty()) @@ -125,7 +202,7 @@ void checkAttributes(std::map const& attributes, int l { if (optionalIt->second.find(v) == optionalIt->second.end()) { - throw std::runtime_error("Spec error on line " + lineNumber + ": unexpected attribute value <" + v + "> in attribute <" + a.first + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(line) + ": unexpected attribute value <" + v + "> in attribute <" + a.first + ">"); } } } @@ -139,10 +216,7 @@ void checkElements(std::vector const& elements, std { if (values.find(e->Value()) == values.end()) { - std::stringstream ss; - ss << e->GetLineNum(); - std::string lineNumber = ss.str(); - std::cerr << "warning: Unknown element in spec on line: " << lineNumber << " " << e->Value() << "!" << std::endl; + std::cerr << "warning: Unknown element in spec on line: " << std::to_string(e->GetLineNum()) << " " << e->Value() << "!" << std::endl; } } } @@ -157,32 +231,19 @@ void checkOrderedElements(std::vector const& elemen { for (size_t i = 0; i < elements.size(); i++) { - std::stringstream ss; - ss << elements[i]->GetLineNum(); - std::string lineNumber = ss.str(); - if (values.size() <= i) { - throw std::runtime_error("Spec error on line " + lineNumber + ": unexpected surplus element <" + elements[i]->Value() + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(elements[i]->GetLineNum()) + ": unexpected surplus element <" + elements[i]->Value() + ">"); } if (values[i] != elements[i]->Value()) { - throw std::runtime_error("Spec error on line " + lineNumber + ": unexpected element <" + elements[i]->Value() + ">, expected <" + values[i] + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(elements[i]->GetLineNum()) + ": unexpected element <" + elements[i]->Value() + ">, expected <" + values[i] + ">"); } } } -void cleanup(std::string const& fileName) +void cleanup(std::string &str) { - // get the generated file back for some cosmetics - std::ifstream ifs(fileName); - assert(!ifs.fail()); - - std::stringbuf file; - ifs >> &file; - ifs.close(); - std::string fileString = file.str(); - std::map replacements = { { "\n\n\n", "\n\n" }, @@ -191,18 +252,13 @@ void cleanup(std::string const& fileName) }; for (auto const& repl : replacements) { - std::string::size_type pos = fileString.find(repl.first); + std::string::size_type pos = str.find(repl.first); while (pos != std::string::npos) { - fileString.replace(pos, repl.first.length(), repl.second); - pos = fileString.find(repl.first, pos); + str.replace(pos, repl.first.length(), repl.second); + pos = str.find(repl.first, pos); } } - - std::ofstream ofs(VULKAN_HPP_FILE); - assert(!ofs.fail()); - ofs << fileString; - ofs.close(); } std::string createEnumValueName(std::string const& name, std::string const& prefix, std::string const& postfix, bool bitmask, std::string const& tag) @@ -284,77 +340,23 @@ std::string findTag(std::set const& tags, std::string const& name, return (tagIt != tags.end()) ? *tagIt : ""; } -std::string generateArgumentCount(size_t vectorIndex, std::string const& vectorName, std::string const& counterName, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool singular) +std::pair generateFunctionBodyStandardReturn(std::string const& returnType) { - std::string argumentCount; + bool castReturn = false; + std::string ret; + if (returnType != "void") + { + // there's something to return... + ret = "return "; - // this parameter is a count parameter for a vector parameter - if ((returnParamIndex == vectorIndex) && twoStep) - { - // the corresponding vector parameter is the return parameter and it's a two-step algorithm - // -> use the pointer to a local variable named like the counter parameter without leading 'p' - assert((counterName[0] == 'p') && isupper(counterName[1])); - argumentCount = "&" + startLowerCase(stripPrefix(counterName, "p")); - } - else - { - // the corresponding vector parameter is not the return parameter, or it's not a two-step algorithm - if (singular) + castReturn = beginsWith(returnType, "Vk"); + if (castReturn) { - // for the singular version, the count is just 1. - argumentCount = "1 "; - } - else - { - // for the non-singular version, the count is the size of the vector parameter - // -> use the vector parameter name without leading 'p' to get the size (in number of elements, not in bytes) - assert(vectorName[0] == 'p'); - argumentCount = startLowerCase(stripPrefix(vectorName, "p")) + ".size() "; - } - if (templateParamIndex == vectorIndex) - { - // if the vector parameter is templatized -> multiply by the size of that type to get the size in bytes - argumentCount += "* sizeof( T ) "; + // the return-type is a vulkan type -> need to cast to vk::-type + ret += "static_cast<" + stripPrefix(returnType, "Vk") + ">( "; } } - return argumentCount; -} - -std::string generateFunctionBodyEnhancedLocalReturnVariableSingular(std::string const& indentation, std::string const& typeName, std::string & returnName, bool isStructureChain) -{ - std::string returnVariable; - - returnName = stripPluralS(returnName); - if (isStructureChain) - { - // For StructureChains use the template parameters - returnVariable = - "StructureChain structureChain;\n" + - indentation + " " + typeName + "& " + returnName + " = structureChain.template get<" + typeName + ">()"; - returnName = "structureChain"; - } - else - { - // in singular case, just use the return parameters pure type for the return variable - returnVariable = typeName + " " + returnName; - } - return returnVariable; -} - -std::string generateReinterpretCast(bool leadingConst, std::string const& type, bool trailingPointerToConst) -{ - std::string reinterpretCast = "reinterpret_cast<"; - if (leadingConst) - { - reinterpretCast += "const "; - } - reinterpretCast += type; - if (trailingPointerToConst) - { - reinterpretCast += "* const"; - } - reinterpretCast += "*>"; - return reinterpretCast; + return std::make_pair(castReturn, ret); } std::map getAttributes(tinyxml2::XMLElement const* element) @@ -638,25 +640,6 @@ std::string trimEnd(std::string const& input) return result; } -std::pair writeFunctionBodyStandardReturn(std::string const& returnType) -{ - bool castReturn = false; - std::string ret; - if (returnType != "void") - { - // there's something to return... - ret = "return "; - - castReturn = beginsWith(returnType, "Vk"); - if (castReturn) - { - // the return-type is a vulkan type -> need to cast to vk::-type - ret += "static_cast<" + stripPrefix(returnType, "Vk") + ">( "; - } - } - return std::make_pair(castReturn, ret); -} - VulkanHppGenerator::VulkanHppGenerator() { m_handles.insert(std::make_pair("", HandleData())); // insert the default "handle" without class (for createInstance, and such) @@ -664,6 +647,2211 @@ VulkanHppGenerator::VulkanHppGenerator() #endif } +void VulkanHppGenerator::appendArgumentPlainType(std::string & str, ParamData const& paramData) const +{ + // this parameter is just a plain type + if (!paramData.type.postfix.empty()) + { + assert(paramData.type.postfix.back() == '*'); + // it's a pointer + std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); + if (paramData.type.prefix.find("const") != std::string::npos) + { + // it's a const pointer + if (paramData.type.type == "char") + { + // it's a const pointer to char -> it's a string -> get the data via c_str() + str += parameterName + (paramData.optional ? (" ? " + parameterName + "->c_str() : nullptr") : ".c_str()"); + } + else + { + // it's const pointer to something else -> just use the name + assert(!paramData.optional); + str += paramData.name; + } + } + else + { + // it's a non-const pointer, and char is the only type that occurs -> use the address of the parameter + assert(paramData.type.type.find("char") == std::string::npos); + str += "&" + parameterName; + } + } + else + { + // it's a plain parameter -> just use its name + str += paramData.name; + } +} + +void VulkanHppGenerator::appendArguments(std::string & str, CommandData const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular, size_t from, size_t to) const +{ + assert(from <= to); + + bool encounteredArgument = false; + for (size_t i = from; i < to; i++) + { + if (encounteredArgument) + { + str += ", "; + } + + auto it = vectorParamIndices.find(i); + if (it != vectorParamIndices.end()) + { + appendArgumentVector(str, it->first, commandData.params[it->first], returnParamIndex, templateParamIndex, twoStep, firstCall, singular); + } + else + { + it = find_if(vectorParamIndices.begin(), vectorParamIndices.end(), [i](std::pair const& vpi) { return vpi.second == i; }); + if (it != vectorParamIndices.end()) + { + appendArgumentCount(str, it->first, commandData.params[it->first].name, commandData.params[it->second].name, returnParamIndex, templateParamIndex, twoStep, singular); + } + else if (beginsWith(commandData.params[i].type.type, "Vk")) + { + appendArgumentVulkanType(str, commandData.params[i]); + } + else + { + appendArgumentPlainType(str, commandData.params[i]); + } + } + encounteredArgument = true; + } +} + +void VulkanHppGenerator::appendArgumentVector(std::string & str, size_t paramIndex, ParamData const& paramData, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool firstCall, bool singular) const +{ + // this parameter is a vector parameter + assert(paramData.type.postfix.back() == '*'); + if ((returnParamIndex == paramIndex) && twoStep && firstCall) + { + // this parameter is the return parameter, and it's the first call of a two-step algorithm -> just just nullptr + str += "nullptr"; + } + else + { + std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); + if (beginsWith(paramData.type.type, "Vk") || (paramIndex == templateParamIndex)) + { + // CHECK for !commandData.params[it->first].optional + + // this parameter is a vulkan type or a templated type -> need to reinterpret cast + appendReinterpretCast(str, paramData.type.prefix.find("const") == 0, paramData.type.type, paramData.type.postfix.rfind("* const") != std::string::npos); + str += "( " + (singular ? ("&" + stripPluralS(parameterName)) : (parameterName + ".data()")) + " )"; + } + else if (paramData.type.type == "char") + { + // the parameter is a vector to char -> it might be optional + // besides that, the parameter now is a std::string -> get the pointer via c_str() + str += parameterName + (paramData.optional ? (" ? " + parameterName + "->c_str() : nullptr") : ".c_str()"); + } + else + { + // this parameter is just a vetor -> get the pointer to its data + str += parameterName + ".data()"; + } + } +} + +void VulkanHppGenerator::appendArgumentVulkanType(std::string & str, ParamData const& paramData) const +{ + // this parameter is a vulkan type + if (!paramData.type.postfix.empty()) + { + assert(paramData.type.postfix.back() == '*'); + // it's a pointer -> needs a reinterpret cast to the vulkan type + std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); + appendReinterpretCast(str, paramData.type.prefix.find("const") != std::string::npos, paramData.type.type, false); + str += "( "; + if (paramData.optional) + { + // for an optional parameter, we need also a static_cast from optional type to const-pointer to pure type + str += "static_cast( " + parameterName + " )"; + } + else + { + // other parameters can just use the pointer + str += "&" + parameterName; + } + str += " )"; + } + else + { + // a non-pointer parameter needs a static_cast from vk::-type to vulkan type + str += "static_cast<" + paramData.type.type + ">( " + paramData.name + " )"; + } +} + +void VulkanHppGenerator::appendBaseTypes(std::string & str) const +{ + assert(!m_baseTypes.empty()); + for (auto const& baseType : m_baseTypes) + { + if (baseType.first != "VkFlags") // filter out VkFlags + { + str += " using " + stripPrefix(baseType.first, "Vk") + " = " + baseType.second + ";\n"; + } + } +} + +void VulkanHppGenerator::appendBitmasks(std::string & str) const +{ + for (auto const& bitmask : m_bitmasks) + { + auto bitmaskBits = m_bitmaskBits.find(bitmask.second.requirement); + assert(bitmaskBits != m_bitmaskBits.end()); + + std::string strippedBitmaskName = stripPrefix(bitmask.first, "Vk"); + std::string strippedEnumName = stripPrefix(bitmaskBits->first, "Vk"); + + str += "\n"; + appendPlatformEnter(str, bitmask.second.platform); + appendEnum(str, *bitmaskBits); + appendEnumToString(str, *bitmaskBits); + appendBitmask(str, strippedBitmaskName, bitmask.second.alias, strippedEnumName, bitmaskBits->second.values); + appendBitmaskToStringFunction(str, strippedBitmaskName, strippedEnumName, bitmaskBits->second.values); + appendPlatformLeave(str, bitmask.second.platform); + } +} + +void VulkanHppGenerator::appendBitmask(std::string & str, std::string const& bitmaskName, std::string const& bitmaskAlias, std::string const& enumName, std::vector const& enumValues) const +{ + // each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter + str += "\n" + " using " + bitmaskName + " = Flags<" + enumName + ", Vk" + bitmaskName + ">;\n"; + + if (!enumValues.empty()) + { + std::string allFlags; + for (auto const& value : enumValues) + { + if (!allFlags.empty()) + { + allFlags += " | "; + } + allFlags += "VkFlags(" + enumName + "::" + value.vkValue + ")"; + } + + static const std::string bitmaskOperatorsTemplate = R"( + VULKAN_HPP_INLINE ${bitmaskName} operator|( ${enumName} bit0, ${enumName} bit1 ) + { + return ${bitmaskName}( bit0 ) | bit1; + } + + VULKAN_HPP_INLINE ${bitmaskName} operator~( ${enumName} bits ) + { + return ~( ${bitmaskName}( bits ) ); + } + + template <> struct FlagTraits<${enumName}> + { + enum + { + allFlags = ${allFlags} + }; + }; +)"; + + str += replaceWithMap(bitmaskOperatorsTemplate, { { "bitmaskName", bitmaskName },{ "enumName", enumName },{ "allFlags", allFlags } }); + } + + if (!bitmaskAlias.empty()) + { + str += "\n" + " using " + stripPrefix(bitmaskAlias, "Vk") + " = " + bitmaskName + ";\n"; + } +} + +void VulkanHppGenerator::appendBitmaskToStringFunction(std::string & str, std::string const& bitmaskName, std::string const& enumName, std::vector const& enumValues) const +{ + str += "\n" + " VULKAN_HPP_INLINE std::string to_string( " + bitmaskName + (enumValues.empty() ? " " : " value ") + " )\n" + " {\n"; + + if (enumValues.empty()) + { + str += "\n return \"{}\";\n"; + } + else + { + // 'or' together all the bits in the value + str += "\n" + " if ( !value ) return \"{}\";\n" + " std::string result;\n"; + for (auto const& evd : enumValues) + { + if (evd.singleBit) + { + str += "\n" + " if ( value & " + enumName + "::" + evd.vkValue + " ) result += \"" + evd.vkValue.substr(1) + " | \";"; + } + } + str += "\n" + " return \"{ \" + result.substr(0, result.size() - 3) + \" }\";\n"; + } + + str += " }\n"; +} + +void VulkanHppGenerator::appendCall(std::string & str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular) const +{ + // the original function call + str += "d." + commandData.first + "( "; + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + if (!handle.empty()) + { + // if it's member of a class -> the first argument is the member variable, starting with "m_" + assert(handle == commandData.second.params[0].type.type); + str += "m_" + startLowerCase(stripPrefix(handle, "Vk")); + if (1 < commandData.second.params.size()) + { + str += ", "; + } + } + + appendArguments(str, commandData.second, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, firstCall, singular, handle.empty() ? 0 : 1, commandData.second.params.size()); + str += " )"; +} + +void VulkanHppGenerator::appendCommand(std::string & str, std::string const& indentation, std::string const& name, std::pair const& commandData, bool definition) const +{ + bool twoStep = isTwoStepAlgorithm(commandData.second.params); + std::map vectorParamIndices = determineVectorParamIndices(commandData.second.params); + + size_t returnParamIndex = determineReturnParamIndex(commandData.second, vectorParamIndices, twoStep); + bool isStructureChain = (returnParamIndex != INVALID_INDEX) && determineStructureChaining(commandData.second.params[returnParamIndex].type.type, m_extendedStructs, m_structureAliases); + std::string enhancedReturnType = determineEnhancedReturnType(commandData.second, returnParamIndex, vectorParamIndices, twoStep, false); // get the enhanced return type without structureChain + + size_t templateParamIndex = determineTemplateParamIndex(commandData.second.params, vectorParamIndices); + + // first create the standard version of the function + std::string standard; + appendFunction(standard, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, false, false, false, false, false); + + // then the enhanced version, composed by up to eight parts + std::string enhanced; + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, false, false, false); + + if (enhancedReturnType.find("Allocator") != std::string::npos) + { + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, false, false, true); + } + + if (isStructureChain) + { + std::string enhancedReturnTypeWithStructureChain = determineEnhancedReturnType(commandData.second, returnParamIndex, vectorParamIndices, twoStep, true); + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnTypeWithStructureChain, definition, true, false, false, true, false); + + if (enhancedReturnTypeWithStructureChain.find("Allocator") != std::string::npos) + { + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnTypeWithStructureChain, definition, true, false, false, true, true); + } + } + + // then a singular version, if a sized vector would be returned + std::map::const_iterator returnVector = vectorParamIndices.find(returnParamIndex); + bool singular = (returnVector != vectorParamIndices.end()) && + (returnVector->second != INVALID_INDEX) && + (commandData.second.params[returnVector->first].type.type != "void") && + (commandData.second.params[returnVector->second].type.postfix.empty() || (commandData.second.params[returnVector->second].type.postfix.back() != '*')); + if (singular) + { + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, true, false, false, false); + } + + // special handling for createDevice and createInstance ! + bool specialWriteUnique = (commandData.first == "vkCreateDevice") || (commandData.first == "vkCreateInstance"); + + // and then the same for the Unique* versions (a deleteCommand is available for the commandData's class, and the function starts with 'allocate' or 'create') + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + auto handleIt = m_handles.find(m_commandToHandle.find(commandData.first)->second); + assert(handleIt != m_handles.end()); + if ((!handleIt->second.deleteCommand.empty() || specialWriteUnique) && ((commandData.first.substr(2, 8) == "Allocate") || (commandData.first.substr(2, 6) == "Create"))) + { + enhanced += "#ifndef VULKAN_HPP_NO_SMART_HANDLE\n"; + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, true, false, false); + + if (enhancedReturnType.find("Allocator") != std::string::npos) + { + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, true, false, true); + } + + if (singular) + { + appendFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, true, true, false, false); + } + enhanced += "#endif /*VULKAN_HPP_NO_SMART_HANDLE*/\n"; + } + + // and append one or both of them + if (standard == enhanced) + { + // standard and enhanced string are equal -> just use one of them and we're done + str += standard; + } + else + { + // standard and enhanced string differ -> use both, wrapping the enhanced by !VULKAN_HPP_DISABLE_ENHANCED_MODE + // determine the argument list of that standard, and compare it with that of the enhanced + // if they are equal -> need to have just one; if they differ -> need to have both + size_t standardStart = standard.find('('); + size_t standardCount = standard.find(')', standardStart) - standardStart; + size_t enhancedStart = enhanced.find('('); + bool unchangedInterface = (standard.substr(standardStart, standardCount) == enhanced.substr(enhancedStart, standardCount)); + if (unchangedInterface) + { + str += "#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE\n"; + } + str += standard + + (unchangedInterface ? "#else" : "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE") + "\n" + + enhanced + + "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/\n"; + } +} + +void VulkanHppGenerator::appendDispatchLoaderDynamic(std::string & str) +{ + str += R"( + class DispatchLoaderDynamic + { + public: +)"; + + for (auto const& handle : m_handles) + { + for (auto const& command : handle.second.commands) + { + std::string enter, leave; + appendPlatformEnter(enter, command.second.platform); + appendPlatformLeave(leave, command.second.platform); + + str += enter + " PFN_" + command.first + " " + command.first + " = 0;\n" + leave; + } + } + + // append initialization function to fetch function pointers + str += R"( + public: + DispatchLoaderDynamic() = default; + +#if !defined(VK_NO_PROTOTYPES) + // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library. + DispatchLoaderDynamic(vk::Instance const& instance, vk::Device const& device = {}) + { + init(instance, device); + } + + // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library. + void init(vk::Instance const& instance, vk::Device const& device = {}) + { + init(static_cast(instance), ::vkGetInstanceProcAddr, static_cast(device), device ? ::vkGetDeviceProcAddr : nullptr); + } +#endif // !defined(VK_NO_PROTOTYPES) + + // This interface does not require a linked vulkan library. + DispatchLoaderDynamic( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) + { + init( instance, getInstanceProcAddr, device, getDeviceProcAddr ); + } + + // This interface does not require a linked vulkan library. + void init( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) + { + VULKAN_HPP_ASSERT(instance && getInstanceProcAddr); + VULKAN_HPP_ASSERT(!!device == !!getDeviceProcAddr); + vkGetInstanceProcAddr = getInstanceProcAddr; + vkGetDeviceProcAddr = getDeviceProcAddr ? getDeviceProcAddr : PFN_vkGetDeviceProcAddr( vkGetInstanceProcAddr( instance, "vkGetDeviceProcAddr") ); +)"; + + for (auto const& handle : m_handles) + { + for (auto const& command : handle.second.commands) + { + if ((command.first != "vkGetDeviceProcAddr") && (command.first != "vkGetInstanceProcAddr")) + { + std::string enter, leave; + appendPlatformEnter(enter, command.second.platform); + appendPlatformLeave(leave, command.second.platform); + + str += enter; + if (!command.second.params.empty() + && m_handles.find(command.second.params[0].type.type) != m_handles.end() + && command.second.params[0].type.type != "VkInstance" + && command.second.params[0].type.type != "VkPhysicalDevice") + { + str += " " + command.first + " = PFN_" + command.first + + "( device ? vkGetDeviceProcAddr( device, \"" + command.first + "\" ) : vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n"; + } + else + { + str += " " + command.first + " = PFN_" + command.first + "( vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n"; + } + str += leave; + } + } + } + str += " }\n" + " };\n"; +} + +void VulkanHppGenerator::appendDispatchLoaderStatic(std::string & str) +{ + str += R"( + class DispatchLoaderStatic + { + public:)"; + + for (auto const& handle : m_handles) + { + for (auto const& command : handle.second.commands) + { + std::string parameterList, parameters; + bool firstParam = true; + for (auto param : command.second.params) + { + if (!firstParam) + { + parameterList += ", "; + parameters += ", "; + } + parameterList += param.type.prefix + (param.type.prefix.empty() ? "" : " ") + param.type.type + param.type.postfix + " " + param.name; + if (!param.arraySize.empty()) + { + parameterList += "[" + param.arraySize + "]"; + } + parameters += param.name; + firstParam = false; + } + std::string commandName = stripPrefix(command.first, "vk"); + + str += "\n"; + appendPlatformEnter(str, command.second.platform); + str += " " + command.second.returnType + " vk" + commandName + "( " + parameterList + " ) const\n" + " {\n" + " return ::vk" + commandName + "( " + parameters + " );\n" + " }\n"; + appendPlatformLeave(str, command.second.platform); + } + } + str += " };\n"; +} + +void VulkanHppGenerator::appendDispatchLoaderDefault(std::string & str) +{ + str += "\n" + "#if !defined(VK_NO_PROTOTYPES)"; + appendDispatchLoaderStatic(str); + str += R"( + typedef DispatchLoaderStatic DispatchLoaderDefault; +#else // !defined(VK_NO_PROTOTYPES) + class NeedExplicitDispatchLoader; + typedef NeedExplicitDispatchLoader DispatchLoaderDefault; +#endif +)"; +} + +void VulkanHppGenerator::appendEnum(std::string & str, std::pair const& enumData) const +{ + str += " enum class " + stripPrefix(enumData.first, "Vk") + "\n" + " {"; + + bool first = true; + for (auto const& value : enumData.second.values) + { + if (!first) + { + str += ","; + } + str += "\n " + value.vkValue + " = " + value.vulkanValue; + first = false; + } + for (auto const& value : enumData.second.aliases) + { + // make sure to only list alias values that differ from all non-alias values + if (std::find_if(enumData.second.values.begin(), enumData.second.values.end(), [&value](EnumValueData const& evd) { return value.second == evd.vkValue; }) == enumData.second.values.end()) + { + if (!first) + { + str += ","; + } + str += "\n " + value.second + " = " + value.first; + first = false; + } + } + if (!first) + { + str += "\n "; + } + + str += "};\n"; +} + +void VulkanHppGenerator::appendEnums(std::string & str) const +{ + for (auto const& e : m_enums) + { + str += "\n"; + appendPlatformEnter(str, e.second.platform); + appendEnum(str, e); + appendEnumToString(str, e); + appendPlatformLeave(str, e.second.platform); + } +} + +void VulkanHppGenerator::appendEnumToString(std::string & str, std::pair const& enumData) const +{ + std::string enumName = stripPrefix(enumData.first, "Vk"); + + str += "\n" + " VULKAN_HPP_INLINE std::string to_string( " + enumName + (enumData.second.values.empty() ? "" : " value") + " )\n" + " {"; + + if (enumData.second.values.empty()) + { + str += "\n" + " return \"(void)\";\n"; + } + else + { + str += "\n" + " switch ( value )\n" + " {\n"; + for (auto const& value : enumData.second.values) + { + str += " case " + enumName + "::" + value.vkValue + " : return \"" + value.vkValue.substr(1) + "\";\n"; + } + str += " default: return \"invalid\";\n" + " }\n"; + } + + str += " }\n"; +} + +void VulkanHppGenerator::appendForwardDeclarations(std::string & str) const +{ + str += "\n"; + for (auto const& structure : m_structures) + { + appendPlatformEnter(str, structure.second.platform); + str += std::string(" ") + (structure.second.isUnion ? "union" : "struct") + " " + stripPrefix(structure.first, "Vk") + ";\n"; + for (std::string const& alias : structure.second.aliases) + { + str += " using " + stripPrefix(alias, "Vk") + " = " + stripPrefix(structure.first, "Vk") + ";\n"; + } + appendPlatformLeave(str, structure.second.platform); + } +} + +void VulkanHppGenerator::appendFunction(std::string & str, std::string const& indentation, std::string const& name, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain, bool withAllocator) const +{ + appendFunctionHeaderTemplate(str, indentation, returnParamIndex, templateParamIndex, enhancedReturnType, enhanced, singular, unique, !definition, isStructureChain); + + str += indentation + (definition ? "VULKAN_HPP_INLINE " : ""); + + appendFunctionHeaderReturnType(str, commandData.second, returnParamIndex, vectorParamIndices, enhancedReturnType, enhanced, singular, unique, isStructureChain); + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + if (definition && !handle.empty()) + { + str += stripPrefix(handle, "Vk") + "::"; + } + + // append the function header name + str += (singular ? stripPluralS(name) : name); + if (unique) + { + str += "Unique"; + } + + appendFunctionHeaderArguments(str, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, enhanced, singular, !definition, withAllocator); + str += std::string(definition ? "" : ";") + "\n"; + + if (definition) + { + // append the function body + str += indentation + "{\n"; + if (enhanced) + { + appendFunctionBodyEnhanced(str, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, singular, unique, isStructureChain, withAllocator); + } + else + { + appendFunctionBodyStandard(str, indentation, commandData); + } + str += indentation + "}\n"; + } +} + +void VulkanHppGenerator::appendFunctionBodyEnhanced(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool unique, bool isStructureChain, bool withAllocator) const +{ + if (unique && !singular && (vectorParamIndices.find(returnParamIndex) != vectorParamIndices.end())) // returns a vector of UniqueStuff + { + appendFunctionBodyEnhancedVectorOfUniqueHandles(str, indentation, commandName, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, singular, withAllocator); + } + else + { + if (1 < vectorParamIndices.size()) + { + appendFunctionBodyEnhancedMultiVectorSizeCheck(str, indentation, commandName, commandData, returnParamIndex, vectorParamIndices); + } + + std::string returnName; + if (returnParamIndex != INVALID_INDEX) + { + returnName = appendFunctionBodyEnhancedLocalReturnVariable(str, indentation, commandData.second, returnParamIndex, vectorParamIndices, twoStep, enhancedReturnType, singular, isStructureChain, withAllocator); + } + + if (twoStep) + { + appendFunctionBodyEnhancedTwoStep(str, indentation, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular, returnName); + } + else + { + appendFunctionBodyEnhancedSingleStep(str, indentation, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular); + } + + if ((commandData.second.returnType == "VkResult") || !commandData.second.successCodes.empty()) + { + appendFunctionBodyEnhancedReturnResultValue(str, indentation, returnName, commandName, commandData, returnParamIndex, twoStep, singular, unique); + } + else if ((returnParamIndex != INVALID_INDEX) && (stripPrefix(commandData.second.returnType, "Vk") != enhancedReturnType)) + { + // for the other returning cases, when the return type is somhow enhanced, just return the local returnVariable + str += indentation + " return " + returnName + ";\n"; + } + } +} + +std::string VulkanHppGenerator::appendFunctionBodyEnhancedLocalReturnVariable(std::string & str, std::string const& indentation, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool isStructureChain, bool withAllocator) const +{ + std::string pureReturnType = stripPrefix(commandData.params[returnParamIndex].type.type, "Vk"); + std::string returnName = startLowerCase(stripPrefix(commandData.params[returnParamIndex].name, "p")); + + // there is a returned parameter -> we need a local variable to hold that value + if (stripPrefix(commandData.returnType, "Vk") != enhancedReturnType) + { + // the returned parameter is somehow enhanced by us + str += indentation + " "; + if (singular) + { + returnName = appendFunctionBodyEnhancedLocalReturnVariableSingular(str, indentation, returnName, pureReturnType, isStructureChain); + } + else + { + // in non-singular case, use the enhanced type for the return variable (like vector<...>) + if (isStructureChain && vectorParamIndices.empty()) + { + // For StructureChains use the template parameters + str += "StructureChain structureChain;\n" + + indentation + " " + enhancedReturnType + "& " + returnName + " = structureChain.template get<" + enhancedReturnType + ">()"; + returnName = "structureChain"; + } + else + { + str += enhancedReturnType + " " + returnName; + } + + std::map::const_iterator vpiIt = vectorParamIndices.find(returnParamIndex); + if (vpiIt != vectorParamIndices.end() && !twoStep) + { + appendFunctionBodyEnhancedLocalReturnVariableVectorSize(str, commandData.params, *vpiIt, returnParamIndex, vectorParamIndices, withAllocator); + } + else if (withAllocator) + { + str += "( vectorAllocator )"; + } + } + str += ";\n"; + } + else + { + // the return parameter is not enhanced -> the type is supposed to be a Result and there are more than one success codes! + assert((commandData.returnType == "VkResult") && (1 < commandData.successCodes.size())); + str += indentation + " " + pureReturnType + " " + returnName + ";\n"; + } + + return returnName; +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedLocalReturnVariableVectorSize(std::string & str, std::vector const& params, std::pair const& vectorParamIndex, size_t returnParamIndex, std::map const& vectorParamIndices, bool withAllocator) const +{ + // if the return parameter is a vector parameter, and not part of a two-step algorithm, initialize its size + std::string size; + if (vectorParamIndex.second == INVALID_INDEX) + { + assert(!params[returnParamIndex].len.empty()); + // the size of the vector is not given by an other parameter, but by some member of a parameter, described as 'parameter::member' + // -> replace the '::' by '.' and filter out the leading 'p' to access that value + size = startLowerCase(stripPrefix(params[returnParamIndex].len, "p")); + size_t pos = size.find("::"); + assert(pos != std::string::npos); + size.replace(pos, 2, "."); + } + else + { + // the size of the vector is given by an other parameter + // first check, if that size has become the size of some other vector parameter + // -> look for it and get it's actual size + for (auto const& vpi : vectorParamIndices) + { + if ((vpi.first != vectorParamIndex.first) || (vpi.second != vectorParamIndex.second)) + { + size = startLowerCase(stripPrefix(params[vpi.first].name, "p")) + ".size()"; + break; + } + } + if (size.empty()) + { + // otherwise, just use that parameter + size = params[vectorParamIndex.second].name; + } + } + assert(!size.empty()); + str += "( " + size + (withAllocator ? ", vectorAllocator" : "") + " )"; +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedMultiVectorSizeCheck(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices) const +{ + std::string const sizeCheckTemplate = + R"#(#ifdef VULKAN_HPP_NO_EXCEPTIONS +${i} VULKAN_HPP_ASSERT( ${firstVectorName}.size() == ${secondVectorName}.size() ); +#else +${i} if ( ${firstVectorName}.size() != ${secondVectorName}.size() ) +${i} { +${i} throw LogicError( VULKAN_HPP_NAMESPACE_STRING "::${className}::${commandName}: ${firstVectorName}.size() != ${secondVectorName}.size()" ); +${i} } +#endif /*VULKAN_HPP_NO_EXCEPTIONS*/ +)#"; + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + + // add some error checks if multiple vectors need to have the same size + for (std::map::const_iterator it0 = vectorParamIndices.begin(); it0 != vectorParamIndices.end(); ++it0) + { + if (it0->first != returnParamIndex) + { + for (std::map::const_iterator it1 = std::next(it0); it1 != vectorParamIndices.end(); ++it1) + { + if ((it1->first != returnParamIndex) && (it0->second == it1->second)) + { + str += replaceWithMap(sizeCheckTemplate, std::map({ + { "firstVectorName", startLowerCase(stripPrefix(commandData.second.params[it0->first].name, "p")) }, + { "secondVectorName", startLowerCase(stripPrefix(commandData.second.params[it1->first].name, "p")) }, + { "className", handle }, + { "commandName", commandName }, + { "i", indentation } + })); + } + } + } + } +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedReturnResultValue(std::string & str, std::string const& indentation, std::string const& returnName, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, bool twoStep, bool singular, bool unique) const +{ + std::string type = (returnParamIndex != INVALID_INDEX) ? commandData.second.params[returnParamIndex].type.type : ""; + std::string returnVectorName = (returnParamIndex != INVALID_INDEX) ? stripPostfix(stripPrefix(commandData.second.params[returnParamIndex].name, "p"), "s") : ""; + + if (commandData.second.returnType == "void") { + std::cerr << "warning: skipping appendFunctionBodyEnhancedReturnResultValue for function " << commandName << " because the returnType is void"; + return; + } + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + + if (unique) + { + // the unique version needs a Deleter object for destruction of the newly created stuff + // get the DeleterData corresponding to the returned type + // special handling for "createDevice", as Device is created from PhysicalDevice, but destroyed on its own + bool noParent = handle.empty() || (commandData.first == "vkCreateDevice"); + str += "\n" + + indentation + ((commandData.first == "vkAllocateMemory") ? " ObjectFree<" : " ObjectDestroy<") + (noParent ? "NoParent" : stripPrefix(handle, "Vk")) + ",Dispatch> deleter( " + (noParent ? "" : "*this, ") + "allocator, d );\n" + + indentation + " return createResultValue<" + stripPrefix(type, "Vk") + ",Dispatch>( result, "; + } + else + { + str += indentation + " return createResultValue( result, "; + } + + // if the return type is "Result" or there is at least one success code, create the Result/Value construct to return + if (returnParamIndex != INVALID_INDEX) + { + // if there's a return parameter, list it in the Result/Value constructor + str += returnName + ", "; + } + + // now the function name (with full namespace) as a string + str += "VULKAN_HPP_NAMESPACE_STRING\"::" + (handle.empty() ? "" : stripPrefix(handle, "Vk") + "::") + (singular ? stripPluralS(commandName) : commandName) + (unique ? "Unique" : "") + "\""; + + if (!twoStep && (1 < commandData.second.successCodes.size())) + { + // and for the single-step algorithms with more than one success code list them all + str += ", { Result::" + commandData.second.successCodes[0]; + for (size_t i = 1; i < commandData.second.successCodes.size(); i++) + { + str += ", Result::" + commandData.second.successCodes[i]; + } + str += " }"; + } + + if (unique) + { + str += ", deleter"; + } + + str += " );\n"; +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedSingleStep(std::string & str, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular) const +{ + str += indentation + " "; + if (commandData.second.returnType == "VkResult") + { + str += "Result result = static_cast( "; + } + else if (commandData.second.returnType != "void") + { + str += "return "; + } + appendCall(str, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, false, true, singular); + if (commandData.second.returnType == "VkResult") + { + str += " )"; + } + str += ";\n"; +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedTwoStep(std::string & str, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, std::string const& returnName) const +{ + assert(!singular); + assert((commandData.second.returnType == "VkResult") || (commandData.second.returnType == "void")); + assert(returnParamIndex != INVALID_INDEX); + + // local count variable to hold the size of the vector to fill + std::map::const_iterator returnit = vectorParamIndices.find(returnParamIndex); + assert(returnit != vectorParamIndices.end() && (returnit->second != INVALID_INDEX)); + + // take the pure type of the size parameter; strip the leading 'p' from its name for its local name + std::string sizeName = startLowerCase(stripPrefix(commandData.second.params[returnit->second].name, "p")); + str += indentation + " " + stripPrefix(commandData.second.params[returnit->second].type.type, "Vk") + " " + sizeName + ";\n"; + + std::string const multiSuccessTemplate = + R"(${i} Result result; +${i} do +${i} { +${i} result = static_cast( ${call1} ); +${i} if ( ( result == Result::eSuccess ) && ${sizeName} ) +${i} { +${i} ${returnName}.resize( ${sizeName} ); +${i} result = static_cast( ${call2} ); +${i} } +${i} } while ( result == Result::eIncomplete ); +${i} if ( result == Result::eSuccess ) +${i} { +${i} VULKAN_HPP_ASSERT( ${sizeName} <= ${returnName}.size() ); +${i} ${returnName}.resize( ${sizeName} ); +${i} } +)"; + std::string const singleSuccessTemplate = + R"(${i} Result result = static_cast( ${call1} ); +${i} if ( ( result == Result::eSuccess ) && ${sizeName} ) +${i} { +${i} ${returnName}.resize( ${sizeName} ); +${i} result = static_cast( ${call2} ); +${i} } +)"; + std::string const voidMultiCallTemplate = + R"(${i} ${call1}; +${i} ${returnName}.resize( ${sizeName} ); +${i} ${call2}; +)"; + std::string const& selectedTemplate = (commandData.second.returnType == "VkResult") ? ((1 < commandData.second.successCodes.size()) ? multiSuccessTemplate : singleSuccessTemplate) : voidMultiCallTemplate; + + std::string call1, call2; + appendCall(call1, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, true, true, false); + appendCall(call2, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, true, false, false); + + str += replaceWithMap(selectedTemplate, + { + { "sizeName", sizeName }, + { "returnName", returnName }, + { "call1", call1 }, + { "call2", call2 }, + { "i", indentation } + }); +} + +void VulkanHppGenerator::appendFunctionBodyEnhancedVectorOfUniqueHandles(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool singular, bool withAllocator) const +{ + std::string const stringTemplate = + R"(${i} static_assert( sizeof( ${type} ) <= sizeof( UniqueHandle<${type}, Dispatch> ), "${type} is greater than UniqueHandle<${type}, Dispatch>!" ); +${i} std::vector, Allocator> ${typeVariable}s${allocator}; +${i} ${typeVariable}s.reserve( ${vectorSize} ); +${i} ${type}* buffer = reinterpret_cast<${type}*>( reinterpret_cast( ${typeVariable}s.data() ) + ${vectorSize} * ( sizeof( UniqueHandle<${type}, Dispatch> ) - sizeof( ${type} ) ) ); +${i} Result result = static_cast(d.vk${command}( m_device, ${arguments}, reinterpret_cast( buffer ) ) ); +${i} if (result == vk::Result::eSuccess) +${i} { +${i} ${Deleter}<${DeleterTemplate},Dispatch> deleter( *this, ${deleterArg}, d ); +${i} for ( size_t i=0 ; i<${vectorSize} ; i++ ) +${i} { +${i} ${typeVariable}s.push_back( UniqueHandle<${type}, Dispatch>( buffer[i], deleter ) ); +${i} } +${i} } + +${i} return createResultValue( result, ${typeVariable}s, VULKAN_HPP_NAMESPACE_STRING "::${class}::${commandName}Unique" ); +)"; + + std::string type = (returnParamIndex != INVALID_INDEX) ? commandData.second.params[returnParamIndex].type.type : ""; + std::string typeVariable = startLowerCase(stripPrefix(type, "Vk")); + std::string arguments; + appendArguments(arguments, commandData.second, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, true, singular, 1, commandData.second.params.size() - 1); + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + + auto handleIt = m_handles.find(type); + assert(handleIt != m_handles.end()); + + bool isCreateFunction = (commandData.first.substr(2, 6) == "Create"); + str += replaceWithMap(stringTemplate, std::map + { + { "i", indentation }, + { "type", stripPrefix(type, "Vk") }, + { "typeVariable", typeVariable }, + { "allocator", withAllocator ? "( vectorAllocator )" : "" }, + { "vectorSize", isCreateFunction ? "createInfos.size()" : "allocateInfo." + typeVariable + "Count" }, + { "command", stripPrefix(commandData.first, "vk") }, + { "arguments", arguments }, + { "Deleter", handleIt->second.deletePool.empty() ? "ObjectDestroy" : "PoolFree" }, + { "DeleterTemplate", stripPrefix(handle, "Vk") + (handleIt->second.deletePool.empty() ? "" : "," + stripPrefix(handleIt->second.deletePool, "Vk")) }, + { "deleterArg", handleIt->second.deletePool.empty() ? "allocator" : "allocateInfo." + startLowerCase(stripPrefix(handleIt->second.deletePool, "Vk")) }, + { "class", stripPrefix(handle, "Vk") }, + { "commandName", commandName } + }); +} + +void VulkanHppGenerator::appendFunctionBodyStandard(std::string & str, std::string const& indentation, std::pair const& commandData) const +{ + std::pair returnData = generateFunctionBodyStandardReturn(commandData.second.returnType); + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + assert(handle.empty() || (handle == commandData.second.params[0].type.type)); + + str += indentation + " " + returnData.second + "d." + commandData.first + "( " + (handle.empty() ? "" : ("m_" + startLowerCase(stripPrefix(handle, "Vk")))); + for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) + { + if (0 < i) + { + str += ", "; + } + appendFunctionBodyStandardArgument(str, commandData.second.params[i].type, commandData.second.params[i].name); + } + str += std::string(" )") + (returnData.first ? " )" : "") + ";\n"; +} + +void VulkanHppGenerator::appendFunctionBodyStandardArgument(std::string & str, TypeData const& typeData, std::string const& name) const +{ + if (beginsWith(typeData.type, "Vk")) + { + // the parameter is a vulkan type + if (!typeData.postfix.empty()) + { + assert(typeData.postfix.back() == '*'); + // it's a pointer -> need to reinterpret_cast it + appendReinterpretCast(str, typeData.prefix.find("const") == 0, typeData.type, typeData.postfix.find("* const") != std::string::npos); + } + else + { + // it's a value -> need to static_cast ist + str += "static_cast<" + typeData.type + ">"; + } + str += "( " + name + " )"; + } + else + { + // it's a non-vulkan type -> just use it + str += name; + } +} + +bool VulkanHppGenerator::appendFunctionHeaderArgumentEnhanced(std::string & str, ParamData const& param, size_t paramIndex, std::map const& vectorParamIndices, bool skip, bool argEncountered, bool isTemplateParam, bool isLastArgument, bool singular, bool withDefaults, bool withAllocator) const +{ + if (!skip) + { + if (argEncountered) + { + str += ", "; + } + std::string strippedParameterName = startLowerCase(stripPrefix(param.name, "p")); + + std::map::const_iterator it = vectorParamIndices.find(paramIndex); + if (it == vectorParamIndices.end()) + { + // the argument ist not a vector + if (param.type.postfix.empty()) + { + // and its not a pointer -> just use its type and name here + appendFunctionHeaderArgumentEnhancedSimple(str, param, isLastArgument, withDefaults, withAllocator); + } + else + { + // the argument is not a vector, but a pointer + assert(param.type.postfix.back() == '*'); + appendFunctionHeaderArgumentEnhancedPointer(str, param, strippedParameterName, withDefaults, withAllocator); + } + } + else + { + // the argument is a vector + appendFunctionHeaderArgumentEnhancedVector(str, param, strippedParameterName, it->second != INVALID_INDEX, isTemplateParam, singular, withDefaults, withAllocator); + } + argEncountered = true; + } + return argEncountered; +} + +void VulkanHppGenerator::appendFunctionHeaderArgumentEnhancedPointer(std::string & str, ParamData const& param, std::string const& strippedParameterName, bool withDefaults, bool withAllocator) const +{ + assert(param.type.postfix.back() == '*'); + if (param.optional) + { + // for an optional argument, trim the leading 'p' from the name + str += "Optional<" + param.type.prefix + (param.type.prefix.empty() ? "" : " ") + stripPrefix(param.type.type, "Vk") + "> " + strippedParameterName; + if (withDefaults && !withAllocator) + { + str += " = nullptr"; + } + } + else if (param.type.type == "void") + { + // for void-pointer, just use type and name + str += param.type.compose() + " " + param.name; + } + else if (param.type.type != "char") + { + // for non-char-pointer, change to reference + assert(param.type.postfix == "*"); + str += param.type.prefix + (param.type.prefix.empty() ? "" : " ") + stripPrefix(param.type.type, "Vk") + " & " + strippedParameterName; + } + else + { + // for char-pointer, change to const reference to std::string + str += "const std::string & " + strippedParameterName; + } +} + +void VulkanHppGenerator::appendFunctionHeaderArgumentEnhancedSimple(std::string & str, ParamData const& param, bool lastArgument, bool withDefaults, bool withAllocator) const +{ + str += param.type.compose() + " " + param.name; + if (!param.arraySize.empty()) + { + str += "[" + param.arraySize + "]"; + } + + if (withDefaults && lastArgument && !withAllocator) + { + // check if the very last argument is a flag without any bits -> provide some empty default for it + std::map::const_iterator bitmasksIt = m_bitmasks.find(param.type.type); + if (bitmasksIt != m_bitmasks.end()) + { + // get the enum corresponding to this flag, to check if it's empty + std::string strippedBitmaskName = stripPrefix(bitmasksIt->first, "Vk"); + std::map::const_iterator enumIt = m_bitmaskBits.find(bitmasksIt->second.requirement); + assert(enumIt != m_bitmaskBits.end()); + if (enumIt->second.values.empty()) + { + // there are no bits in this flag -> provide the default + str += " = " + stripPrefix(param.type.type, "Vk") + "()"; + } + } + } +} + +void VulkanHppGenerator::appendFunctionHeaderArgumentEnhancedVector(std::string & str, ParamData const& param, std::string const& strippedParameterName, bool hasSizeParam, bool isTemplateParam, bool singular, bool withDefaults, bool withAllocator) const +{ + assert(param.type.postfix.back() == '*'); + + // it's optional, if it's marked as optional and there's no size specified + bool optional = param.optional && !hasSizeParam; + if (param.type.type.find("char") != std::string::npos) + { + // it's a char-vector -> use a std::string (either optional or a const-reference + if (optional) + { + str += "Optional " + strippedParameterName; + if (withDefaults && !withAllocator) + { + str += " = nullptr"; + } + } + else + { + str += "const std::string & " + strippedParameterName; + } + } + else + { + // it's a non-char vector (they are never optional) + assert(!optional); + if (singular) + { + // in singular case, change from pointer to reference + str += param.type.prefix + (param.type.prefix.empty() ? "" : " ") + stripPrefix(param.type.type, "Vk") + " & " + stripPluralS(strippedParameterName); + } + else + { + // otherwise, use our ArrayProxy + bool isConst = (param.type.prefix.find("const") != std::string::npos); + str += "ArrayProxy<" + (isTemplateParam ? (isConst ? "const T" : "T") : stripPostfix(param.type.compose(), "*")) + "> " + strippedParameterName; + } + } +} + +void VulkanHppGenerator::appendFunctionHeaderArguments(std::string & str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool enhanced, bool singular, bool withDefaults, bool withAllocator) const +{ + str += "("; + if (enhanced) + { + appendFunctionHeaderArgumentsEnhanced(str, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular, withDefaults, withAllocator); + } + else + { + appendFunctionHeaderArgumentsStandard(str, commandData, withDefaults); + } + str += ")"; + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + if (!m_commandToHandle.find(commandData.first)->second.empty()) + { + str += " const"; + } +} + +void VulkanHppGenerator::appendFunctionHeaderArgumentsEnhanced(std::string & str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, bool withDefaults, bool withAllocator) const +{ + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + + // check if there's at least one argument left to put in here + std::set skippedParams = determineSkippedParams(returnParamIndex, vectorParamIndices); + if (skippedParams.size() + (handle.empty() ? 0 : 1) < commandData.second.params.size()) + { + // determine the last argument, where we might provide some default for + size_t lastArgument = INVALID_INDEX; + for (size_t i = commandData.second.params.size() - 1; i < commandData.second.params.size(); i--) + { + if (skippedParams.find(i) == skippedParams.end()) + { + lastArgument = i; + break; + } + } + + str += " "; + bool argEncountered = false; + for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) + { + argEncountered = appendFunctionHeaderArgumentEnhanced(str, commandData.second.params[i], i, vectorParamIndices, skippedParams.find(i) != skippedParams.end(), argEncountered, + (templateParamIndex == i), (lastArgument == i), singular, withDefaults, withAllocator); + } + + if (argEncountered) + { + str += ", "; + } + } + if (withAllocator) + { + str += "Allocator const& vectorAllocator, "; + } + str += "Dispatch const &d"; + if (withDefaults && !withAllocator) + { + str += " = Dispatch()"; + } + str += " "; +} + +void VulkanHppGenerator::appendFunctionHeaderArgumentsStandard(std::string & str, std::pair const& commandData, bool withDefaults) const +{ + // for the standard case, just list all the arguments as we've got them + // determine the last argument, where we might provide some default for + size_t lastArgument = commandData.second.params.size() - 1; + + assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); + std::string const& handle = m_commandToHandle.find(commandData.first)->second; + + bool argEncountered = false; + for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) + { + argEncountered = appendFunctionHeaderArgumentStandard(str, commandData.second.params[i], argEncountered, lastArgument == i, withDefaults); + } + if (argEncountered) + { + str += ", "; + } + + str += "Dispatch const &d"; + if (withDefaults) + { + str += " = Dispatch() "; + } +} + +bool VulkanHppGenerator::appendFunctionHeaderArgumentStandard(std::string & str, ParamData const& param, bool argEncountered, bool isLastArgument, bool withDefaults) const +{ + if (argEncountered) + { + str += ","; + } + + str += " " + param.type.compose() + " " + param.name; + if (!param.arraySize.empty()) + { + str += "[" + param.arraySize + "]"; + } + + if (withDefaults && isLastArgument) + { + // check if the very last argument is a flag without any bits -> provide some empty default for it + std::map::const_iterator bitmasksIt = m_bitmasks.find(param.type.type); + if (bitmasksIt != m_bitmasks.end()) + { + // get the enum corresponding to this flag, to check if it's empty + std::string strippedBitmaskName = stripPrefix(bitmasksIt->first, "Vk"); + std::map::const_iterator enumIt = m_bitmaskBits.find(bitmasksIt->second.requirement); + assert(enumIt != m_bitmaskBits.end()); + if (enumIt->second.values.empty()) + { + // there are no bits in this flag -> provide the default + str += " = " + stripPrefix(param.type.type, "Vk") + "()"; + } + } + } + return true; +} + +void VulkanHppGenerator::appendFunctionHeaderReturnType(std::string & str, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool isStructureChain) const +{ + if (enhanced) + { + // the enhanced function might return some pretty complex return stuff + bool isVector = (enhancedReturnType.find("Allocator") != std::string::npos); + if (unique) + { + // 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 && (vectorParamIndices.find(returnParamIndex) != vectorParamIndices.end()); + + std::string returnType = isStructureChain ? "StructureChain" : stripPrefix(commandData.params[returnParamIndex].type.type, "Vk"); + str += returnsVector ? (((isStructureChain || (!singular && isVector)) ? "typename " : "")) + std::string("ResultValueType,Allocator>>::type " + : "typename ResultValueType>::type "; + } + else if ((enhancedReturnType != stripPrefix(commandData.returnType, "Vk")) && (commandData.returnType != "void")) + { + // if the enhanced return type differs from the original return type, and it's not void, we return a ResultValueType<...>::type + assert(commandData.returnType == "VkResult"); + // in singular case, we create the ResultValueType from the pure return type, otherwise from the enhanced return type + std::string returnType = isStructureChain ? "StructureChain" : (singular ? stripPrefix(commandData.params[returnParamIndex].type.type, "Vk") : enhancedReturnType); + // for the non-singular case with allocation, we need to prepend with 'typename' to keep compilers happy + str += ((isStructureChain || (!singular && isVector)) ? "typename " : "") + std::string("ResultValueType<") + returnType + ">::type "; + } + else if ((returnParamIndex != INVALID_INDEX) && (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 == "VkResult"); + str += "ResultValue<" + (isStructureChain ? "StructureChain" : stripPrefix(commandData.params[returnParamIndex].type.type, "Vk")) + "> "; + } + else + { + // and in every other case, we just return the enhanced return type. + str += (isStructureChain && !isVector ? "StructureChain" : enhancedReturnType) + " "; + } + } + else + { + // the non-enhanced function just uses the return type + str += stripPrefix(commandData.returnType, "Vk") + " "; + } +} + +void VulkanHppGenerator::appendFunctionHeaderTemplate(std::string & str, std::string const& indentation, size_t returnParamIndex, size_t templateParamIndex, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool withDefault, bool isStructureChain) const +{ + bool withAllocator = (enhancedReturnType.find("Allocator") != std::string::npos); + str += indentation + "template<"; + if (enhanced) + { + if (isStructureChain) + { + str += std::string("typename ") + (withAllocator ? "StructureChain" : "X, typename Y, typename ...Z") + ", "; + } + else if ((templateParamIndex != INVALID_INDEX) && ((templateParamIndex != returnParamIndex) || (enhancedReturnType == "Result"))) + { + assert(!withAllocator); + str += "typename T, "; + } + if (!singular && withAllocator) + { + // otherwise, if there's an Allocator used in the enhanced return type, we templatize on that Allocator + assert((enhancedReturnType.substr(0, 12) == "std::vector<") && (enhancedReturnType.find(',') != std::string::npos) && (12 < enhancedReturnType.find(','))); + str += "typename Allocator"; + if (withDefault) + { + // for the default type get the type from the enhancedReturnType, which is of the form 'std::vector' + assert(!isStructureChain || !unique); + str += " = std::allocator<" + (isStructureChain ? "StructureChain" : (unique ? "Unique" : "") + enhancedReturnType.substr(12, enhancedReturnType.find(',') - 12)) + ">"; + } + str += ", "; + } + } + str += std::string("typename Dispatch") + (withDefault ? " = DispatchLoaderDefault" : "") + ">\n"; +} + +void VulkanHppGenerator::appendHandle(std::string & str, std::pair const& handleData, std::set & listedHandles) const +{ + if (listedHandles.find(handleData.first) == listedHandles.end()) + { + listedHandles.insert(handleData.first); + + // first check for any handle that needs to be listed before this one + for (auto const& command : handleData.second.commands) + { + for (auto const& parameter : command.second.params) + { + std::string typeName = parameter.type.type; + auto handlesIt = m_handles.find(typeName); + if ((handlesIt != m_handles.end()) && (listedHandles.find(typeName) == listedHandles.end())) + { + appendHandle(str, *handlesIt, listedHandles); + } + } + } + + if (handleData.first.empty()) + { + for (auto const& command : handleData.second.commands) + { + std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); + if (command.first == "vkCreateInstance") + { + // special handling for createInstance, as we need to explicitly place the forward declarations and the deleter classes here +#if !defined(NDEBUG) + auto handleIt = m_handles.find(""); + assert((handleIt != m_handles.end()) && (handleIt->second.childrenHandles.size() == 2)); + assert(handleIt->second.childrenHandles.find("VkInstance") != handleIt->second.childrenHandles.end()); +#endif + + appendUniqueTypes(str, "", { "VkInstance" }); + } + str += "\n"; + appendPlatformEnter(str, command.second.platform); + appendCommand(str, " ", commandName, command, false); + appendPlatformLeave(str, command.second.platform); + } + } + else + { + // then append any forward declaration of Deleters used by this handle + if (!handleData.second.childrenHandles.empty()) + { + appendUniqueTypes(str, handleData.first, handleData.second.childrenHandles); + } + else if (handleData.first == "VkPhysicalDevice") + { + // special handling for class Device, as it's created from PhysicalDevice, but destroys itself + appendUniqueTypes(str, "", { "VkDevice" }); + } + + std::string commands; + // list all the commands that are mapped to members of this class + for (auto const& command : handleData.second.commands) + { + std::string enter, leave, commandString; + appendPlatformEnter(enter, command.second.platform); + appendPlatformLeave(leave, command.second.platform); + std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); + appendCommand(commandString, " ", commandName, command, false); + commands += "\n" + enter + commandString; + + // special handling for destroy functions which are not aliased. + if (!command.second.isAlias && (((command.first.substr(2, 7) == "Destroy") && (commandName != "destroy")) || (command.first.substr(2, 4) == "Free"))) + { + commandName = (command.first.substr(2, 7) == "Destroy") ? "destroy" : "free"; + std::string destroyCommandString; + appendCommand(destroyCommandString, " ", commandName, command, false); + commands += "\n" + destroyCommandString; + } + commands += leave; + } + + static const std::string templateString = R"( + class ${className} + { + public: + using CType = Vk${className}; + + static VULKAN_HPP_CONST_OR_CONSTEXPR ObjectType objectType = ObjectType::e${className}; + + public: + VULKAN_HPP_CONSTEXPR ${className}() + : m_${memberName}(VK_NULL_HANDLE) + {} + + VULKAN_HPP_CONSTEXPR ${className}( std::nullptr_t ) + : m_${memberName}(VK_NULL_HANDLE) + {} + + VULKAN_HPP_TYPESAFE_EXPLICIT ${className}( Vk${className} ${memberName} ) + : m_${memberName}( ${memberName} ) + {} + +#if defined(VULKAN_HPP_TYPESAFE_CONVERSION) + ${className} & operator=(Vk${className} ${memberName}) + { + m_${memberName} = ${memberName}; + return *this; + } +#endif + + ${className} & operator=( std::nullptr_t ) + { + m_${memberName} = VK_NULL_HANDLE; + return *this; + } + + bool operator==( ${className} const & rhs ) const + { + return m_${memberName} == rhs.m_${memberName}; + } + + bool operator!=(${className} const & rhs ) const + { + return m_${memberName} != rhs.m_${memberName}; + } + + bool operator<(${className} const & rhs ) const + { + return m_${memberName} < rhs.m_${memberName}; + } +${commands} + VULKAN_HPP_TYPESAFE_EXPLICIT operator Vk${className}() const + { + return m_${memberName}; + } + + explicit operator bool() const + { + return m_${memberName} != VK_NULL_HANDLE; + } + + bool operator!() const + { + return m_${memberName} == VK_NULL_HANDLE; + } + + private: + Vk${className} m_${memberName}; + }; + static_assert( sizeof( ${className} ) == sizeof( Vk${className} ), "handle and wrapper have different size!" ); + + template <> + struct cpp_type + { + using type = ${className}; + }; +)"; + + str += replaceWithMap(templateString, { + { "className", stripPrefix(handleData.first, "Vk") }, + { "memberName", startLowerCase(stripPrefix(handleData.first, "Vk")) }, + { "commands", commands } + }); + + if (!handleData.second.alias.empty()) + { + str += " using " + stripPrefix(handleData.second.alias, "Vk") + " = " + stripPrefix(handleData.first, "Vk") + ";\n"; + } + } + } +} + +void VulkanHppGenerator::appendHandles(std::string & str) const +{ + std::set listedHandles; + for (auto const& handle : m_handles) + { + appendHandle(str, handle, listedHandles); + } +} + +void VulkanHppGenerator::appendHandlesCommandDefintions(std::string & str) const +{ + for (auto const& handle : m_handles) + { + // finally the commands, that are member functions of this handle + for (auto const& command : handle.second.commands) + { + std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); + std::string strippedName = startLowerCase(stripPrefix(command.first, "vk")); + + str += "\n"; + appendPlatformEnter(str, command.second.platform); + appendCommand(str, " ", commandName, command, true); + + // special handling for destroy functions + if (!command.second.isAlias && (((command.first.substr(2, 7) == "Destroy") && (commandName != "destroy")) || (command.first.substr(2, 4) == "Free"))) + { + commandName = (command.first.substr(2, 7) == "Destroy") ? "destroy" : "free"; + str += "\n"; + appendCommand(str, " ", commandName, command, true); + } + appendPlatformLeave(str, command.second.platform); + } + } + str += "\n"; +} + +// Intended only for `enum class Result`! +void VulkanHppGenerator::appendResultExceptions(std::string & str) const +{ + std::string templateString = R"( + class ${className} : public SystemError + { + public: + ${className}( std::string const& message ) + : SystemError( make_error_code( ${enumName}::${enumMemberName} ), message ) {} + ${className}( char const * message ) + : SystemError( make_error_code( ${enumName}::${enumMemberName} ), message ) {} + }; +)"; + + auto enumData = m_enums.find("VkResult"); + for (auto const& value : enumData->second.values) + { + if (beginsWith(value.vkValue, "eError")) + { + str += replaceWithMap(templateString, + { + { "className", stripPrefix(value.vkValue, "eError") + "Error" }, + { "enumName", stripPrefix(enumData->first, "Vk") }, + { "enumMemberName", value.vkValue } + }); + } + } + str += "\n"; +} + +void VulkanHppGenerator::appendPlatformEnter(std::string & str, std::string const& platform) const +{ + if (!platform.empty()) + { + auto it = m_platforms.find(platform); + assert((it != m_platforms.end()) && !it->second.empty()); + str += "#ifdef " + it->second + "\n"; + } +} + +void VulkanHppGenerator::appendPlatformLeave(std::string & str, std::string const& platform) const +{ + if (!platform.empty()) + { + auto it = m_platforms.find(platform); + assert((it != m_platforms.end()) && !it->second.empty()); + str += "#endif /*" + it->second + "*/\n"; + } +} + +void VulkanHppGenerator::appendStruct(std::string & str, std::pair const& structure, std::set & listedStructures) const +{ + if (listedStructures.find(structure.first) == listedStructures.end()) + { + listedStructures.insert(structure.first); + for (auto const& member : structure.second.members) + { + auto structureIt = m_structures.find(member.type.type); + if ((structureIt != m_structures.end()) && (listedStructures.find(member.type.type) == listedStructures.end())) + { + appendStruct(str, *structureIt, listedStructures); + } + } + if (!structure.second.subStruct.empty()) + { + auto structureIt = m_structures.find(structure.second.subStruct); + if ((structureIt != m_structures.end()) && (listedStructures.find(structureIt->first) == listedStructures.end())) + { + appendStruct(str, *structureIt, listedStructures); + } + } + + if (structure.second.isUnion) + { + appendUnion(str, structure); + } + else + { + appendStructure(str, structure); + } + } +} + +void VulkanHppGenerator::appendStructCompareOperators(std::string & str, std::pair const& structData) const +{ + // two structs are compared by comparing each of the elements + std::string compareMembers; + std::string intro = ""; + for (auto const& member : structData.second.members) + { + compareMembers += intro; + if (member.arraySize.empty()) + { + compareMembers += "( " + member.name + " == rhs." + member.name + " )"; + } + else + { + compareMembers += "( memcmp( " + member.name + ", rhs." + member.name + ", " + member.arraySize + " * sizeof( " + member.type.compose() + " ) ) == 0 )"; + } + intro = "\n && "; + } + + static const std::string compareTemplate = R"( + bool operator==( ${name} const& rhs ) const + { + return ${compareMembers}; + } + + bool operator!=( ${name} const& rhs ) const + { + return !operator==( rhs ); + } +)"; + + str += replaceWithMap(compareTemplate, { { "name", stripPrefix(structData.first, "Vk") }, { "compareMembers", compareMembers } }); +} + +std::string VulkanHppGenerator::appendStructConstructor(std::pair const& structData, std::string const& prefix, bool withLayoutStructure) const +{ + // the constructor with all the elements as arguments, with defaults + std::string ctorOpening = prefix + stripPrefix(structData.first, "Vk") + "( "; + std::string indentation(ctorOpening.size(), ' '); + + std::string arguments, initializers, copyOps; + bool listedArgument = false; + bool firstArgument = true; + for (auto const& member : structData.second.members) + { + // gather the arguments + listedArgument = appendStructConstructorArgument(arguments, listedArgument, indentation, member); + + // gather the initializers; skip members 'pNext' and 'sType', they are directly set by initializers + if ((member.name != "pNext") && (member.name != "sType")) + { + if (withLayoutStructure) + { + // withLayoutStructure means: we pass the arguments into the layout::class + if (!firstArgument) + { + initializers += ", "; + } + initializers += member.name + "_"; + firstArgument = false; + } + else if (member.arraySize.empty()) + { + // here, we can only handle non-array arguments + initializers += prefix + " " + (firstArgument ? ":" : ",") + " " + member.name + "( " + member.name + "_ )\n"; + firstArgument = false; + } + else + { + // here we can handle the arrays, copying over from argument (with trailing '_') to member + // size is arraySize times sizeof type + copyOps += "\n" + + prefix + " memcpy( &" + member.name + ", " + member.name + "_.data(), " + member.arraySize + " * sizeof( " + member.type.compose() + " ) );"; + } + } + } + if (!copyOps.empty()) + { + copyOps += "\n" + prefix; + } + + std::string structConstructor = prefix + stripPrefix(structData.first, "Vk") + (arguments.empty() ? "()\n" : std::string("( " + arguments + " )")) + "\n"; + if (withLayoutStructure) + { + structConstructor += prefix + " : layout::" + stripPrefix(structData.first, "Vk") + "( " + initializers + " )\n" + prefix + "{}\n"; + } + else + { + structConstructor += initializers; + if (copyOps.empty()) + { + structConstructor += prefix + "{}\n"; + } + else + { + structConstructor += prefix + "{\n" + copyOps + "\n" + prefix + "}\n"; + } + + if (!structData.second.subStruct.empty()) + { + auto const& subStruct = m_structures.find(structData.second.subStruct); + assert(subStruct != m_structures.end()); + + std::string subStructArgumentName = startLowerCase(stripPrefix(subStruct->first, "Vk")); + ctorOpening = prefix + "explicit " + stripPrefix(structData.first, "Vk") + "( "; + indentation = std::string(ctorOpening.size(), ' '); + + std::string subCopies; + firstArgument = true; + for (size_t i = 0; i < subStruct->second.members.size(); i++) + { + assert(structData.second.members[i].arraySize.empty()); + subCopies += prefix + " " + (firstArgument ? ":" : ",") + " " + structData.second.members[i].name + "( " + subStructArgumentName + "." + subStruct->second.members[i].name + " )\n"; + firstArgument = false; + } + + std::string subArguments; + listedArgument = true; + for (size_t i = subStruct->second.members.size(); i < structData.second.members.size(); i++) + { + listedArgument = appendStructConstructorArgument(subArguments, listedArgument, indentation, structData.second.members[i]); + + assert(structData.second.members[i].arraySize.empty()); + subCopies += prefix + " , " + structData.second.members[i].name + "( " + structData.second.members[i].name + "_ )\n"; + } + + structConstructor += "\n" + " explicit " + stripPrefix(structData.first, "Vk") + "( " + stripPrefix(subStruct->first, "Vk") + " const& " + subStructArgumentName + subArguments + " )\n" + + subCopies + + " {}\n"; + } + } + + return structConstructor; +} + +bool VulkanHppGenerator::appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const +{ + // skip members 'pNext' and 'sType', as they are never explicitly set + if ((memberData.name != "pNext") && (memberData.name != "sType")) + { + str += (listedArgument ? (",\n" + indentation) : ""); + if (memberData.arraySize.empty()) + { + str += memberData.type.compose() + " " + memberData.name + "_ = " + ((!memberData.type.postfix.empty() && memberData.type.postfix.back() == '*') ? "nullptr" : defaultValue(memberData.type.type)); + } + else + { + str += "std::array<" + memberData.type.compose() + "," + memberData.arraySize + "> const& " + memberData.name + "_ = { { " + defaultValue(memberData.type.type) + " } }"; + } + listedArgument = true; + } + return listedArgument; +} + +void VulkanHppGenerator::appendStructCopyConstructors(std::string & str, std::string const& name, bool withLayoutStructure) const +{ + static const std::string templateString = R"( + ${name}( Vk${name} const & rhs ) + { + *reinterpret_cast(this) = rhs; + } + + ${name}& operator=( Vk${name} const & rhs ) + { + *reinterpret_cast(this) = rhs; + return *this; + } +)"; + static const std::string layoutTemplateString = R"( + ${name}( Vk${name} const & rhs ) + : layout::${name}( rhs ) + {} + + ${name}& operator=( Vk${name} const & rhs ) + { + *reinterpret_cast(this) = rhs; + return *this; + } +)"; + + str += replaceWithMap(withLayoutStructure ? layoutTemplateString : templateString, { { "name", name } }); +} + +void VulkanHppGenerator::appendStructMembers(std::string & str, StructureData const& structData, std::string const& prefix) const +{ + for (auto const& member : structData.members) + { + str += prefix + member.type.compose() + " " + member.name; + if (member.name == "sType") // special handling for sType + { + auto enumIt = m_enums.find("VkStructureType"); + assert(enumIt != m_enums.end()); + if (!member.values.empty()) + { + assert(beginsWith(member.values, "VK_STRUCTURE_TYPE")); + auto nameIt = std::find_if(enumIt->second.values.begin(), enumIt->second.values.end(), [&member](EnumValueData const& evd) { return member.values == evd.vulkanValue; }); + assert(nameIt != enumIt->second.values.end()); + str += " = StructureType::" + nameIt->vkValue; + } + } + else if (member.name == "pNext") // special handling for pNext + { + str += " = nullptr"; + } + else if (!member.arraySize.empty()) // special handling for arrays + { + str += "[" + member.arraySize + "]"; + } + str += ";\n"; + } +} + +void VulkanHppGenerator::appendStructs(std::string & str) const +{ + std::set listedStructures; + for (auto const& structure : m_structures) + { + appendStruct(str, structure, listedStructures); + } +} + +void VulkanHppGenerator::appendStructSetter(std::string & str, std::string const& structureName, MemberData const& memberData) const +{ + if (memberData.type.type != "VkStructureType") // filter out StructureType, which is supposed to be immutable ! + { + std::string memberType = memberData.arraySize.empty() ? memberData.type.compose() : "std::array<" + memberData.type.compose() + "," + memberData.arraySize + ">"; + + // copy over the argument, either by assigning simple data, or by memcpy array data + str += "\n" + " " + structureName + " & set" + startUpperCase(memberData.name) + "( " + memberType + " " + memberData.name + "_ )\n" + " {\n" + " "; + if (memberData.arraySize.empty()) + { + str += memberData.name + " = " + memberData.name + "_"; + } + else + { + str += "memcpy( " + memberData.name + ", " + memberData.name + "_.data(), " + memberData.arraySize + " * sizeof( " + memberData.type.compose() + " ) )"; + } + str += ";\n" + " return *this;\n" + " }\n"; + } +} + +void VulkanHppGenerator::appendStructure(std::string & str, std::pair const& structure) const +{ + str += "\n"; + appendPlatformEnter(str, structure.second.platform); + + std::string baseClass; + bool withLayoutStructure = (!structure.second.members.empty() && (structure.second.members.front().name == "sType")); + if (withLayoutStructure) + { + baseClass = " : public layout::" + stripPrefix(structure.first, "Vk"); + static const std::string layoutStructureTemplate = R"( + namespace layout + { + struct ${name} + { + protected: +${constructor} + + ${name}( Vk${name} const & rhs ) + { + *reinterpret_cast(this) = rhs; + } + + ${name}& operator=( Vk${name} const & rhs ) + { + *reinterpret_cast(this) = rhs; + return *this; + } + + public: +${members} }; + static_assert( sizeof( ${name} ) == sizeof( Vk${name} ), "layout struct and wrapper have different size!" ); + } +)"; + + std::string members; + appendStructMembers(members, structure.second, " "); + + str += replaceWithMap(layoutStructureTemplate, + { + { "name", stripPrefix(structure.first, "Vk") }, + { "constructor", appendStructConstructor(structure, " ", false)}, + { "members", members} + }); + } + + // only structs that are not returnedOnly get a constructor! + std::string constructorAndSetters; + if (!structure.second.returnedOnly) + { + constructorAndSetters += appendStructConstructor(structure, " ", withLayoutStructure); + appendStructCopyConstructors(constructorAndSetters, stripPrefix(structure.first, "Vk"), withLayoutStructure); + for (auto const& member : structure.second.members) + { + appendStructSetter(constructorAndSetters, stripPrefix(structure.first, "Vk"), member); + } + } + + // operator==() and operator!=() + // only structs without a union as a member can have a meaningfull == and != operation; we filter them out + std::string compareOperators; + if (!containsUnion(structure.first)) + { + appendStructCompareOperators(compareOperators, structure); + } + + // the member variables + std::string members; + if (withLayoutStructure) + { + // hide sType when a layout structure is used to keep standard_layout + members = "\n private:\n using layout::" + stripPrefix(structure.first, "Vk") + "::sType;\n"; + } + else + { + members = "\n public:\n"; + appendStructMembers(members, structure.second, " "); + } + + static const std::string structureTemplate = R"( + struct ${name}${baseClass} + { +${constructorAndSetters} + + operator ${vkName} const&() const + { + return *reinterpret_cast( this ); + } + + operator ${vkName} &() + { + return *reinterpret_cast<${vkName}*>( this ); + } + +${compareOperators} + +${members} + }; + static_assert( sizeof( ${name} ) == sizeof( ${vkName} ), "struct and wrapper have different size!" ); + static_assert( std::is_standard_layout<${name}>::value, "struct wrapper is not a standard layout!" ); +)"; + + str += replaceWithMap(structureTemplate, + { + { "name", stripPrefix(structure.first, "Vk") }, + { "baseClass", baseClass }, + { "constructorAndSetters", constructorAndSetters }, + { "vkName", structure.first }, + { "compareOperators", compareOperators }, + { "members", members } + }); + appendPlatformLeave(str, structure.second.platform); +} + +void VulkanHppGenerator::appendStructureChainValidation(std::string & str) +{ + // append all template functions for the structure pointer chain validation + for (auto const& structure : m_structures) + { + if (!structure.second.structExtends.empty()) + { + appendPlatformEnter(str, structure.second.platform); + + // append out allowed structure chains + for (auto extendName : structure.second.structExtends) + { + std::map::const_iterator itExtend = m_structures.find(extendName); + if (itExtend == m_structures.end()) + { + std::string errorString; + errorString = extendName + " does not specify a struct in structextends field."; + + // check if symbol name is an alias to a struct + auto itAlias = std::find_if(m_structures.begin(), m_structures.end(), [&extendName](std::pair const &it) -> bool {return std::find(it.second.aliases.begin(), it.second.aliases.end(), extendName) != it.second.aliases.end(); }); + if (itAlias != m_structures.end()) + { + errorString += " The symbol is an alias and maps to " + itAlias->first + "."; + } + + errorString += "\n"; + throw std::runtime_error(errorString); + } + if (structure.second.platform != itExtend->second.platform) + { + appendPlatformEnter(str, itExtend->second.platform); + } + + str += " template <> struct isStructureChainValid<" + stripPrefix(extendName, "Vk") + ", " + stripPrefix(structure.first, "Vk") + ">{ enum { value = true }; };\n"; + + if (structure.second.platform != itExtend->second.platform) + { + appendPlatformLeave(str, itExtend->second.platform); + } + } + appendPlatformLeave(str, structure.second.platform); + } + } +} + +void VulkanHppGenerator::appendThrowExceptions(std::string & str) const +{ + auto enumData = m_enums.find("VkResult"); + + str += "\n" + " VULKAN_HPP_INLINE void throwResultException( Result result, char const * message )\n" + " {\n" + " switch ( result )\n" + " {\n"; + for (auto const& value : enumData->second.values) + { + if (beginsWith(value.vkValue, "eError")) + { + str += " case Result::" + value.vkValue + ": throw " + stripPrefix(value.vkValue, "eError") + "Error( message );\n"; + } + } + str += " default: throw SystemError( make_error_code( result ) );\n" + " }\n" + " }\n"; +} + +void VulkanHppGenerator::appendUnion(std::string & str, std::pair const& structure) const +{ + str += "\n" + " union " + stripPrefix(structure.first, "Vk") + "\n" + " {\n"; + + if (!structure.second.returnedOnly) + { + bool firstTime = true; + for (auto const& member : structure.second.members) + { + // VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t constructor. + auto compareBool32Alias = [](MemberData const& member) { return member.type.type == std::string("uint32_t"); }; + if (member.type.type == "VkBool32") { + if (std::find_if(structure.second.members.begin(), structure.second.members.end(), compareBool32Alias) != structure.second.members.end()) + { + continue; + } + } + + // one constructor per union element + str += " " + stripPrefix(structure.first, "Vk") + "( " + (member.arraySize.empty() ? (member.type.compose() + " ") : ("const std::array<" + member.type.compose() + "," + member.arraySize + ">& ")) + member.name + "_"; + + // just the very first constructor gets default arguments + if (firstTime) + { + std::string value = defaultValue(member.type.type); + str += (member.arraySize.empty() ? (" = " + value) : (" = { { " + value + " } }")); + firstTime = false; + } + str += " )\n" + " {\n" + " " + (member.arraySize.empty() ? (member.name + " = " + member.name + "_") : ("memcpy( " + member.name + ", " + member.name + "_.data(), " + member.arraySize + " * sizeof( " + member.type.compose() + " ) )")) + ";\n" + " }\n" + "\n"; + } + + // one setter per union element + for (auto const& member : structure.second.members) + { + appendStructSetter(str, stripPrefix(structure.first, "Vk"), member); + } + } + + // the implicit cast operators to the native type + str += " operator " + structure.first + " const&() const\n" + " {\n" + " return *reinterpret_cast(this);\n" + " }\n" + "\n" + " operator " + structure.first + " &()\n" + " {\n" + " return *reinterpret_cast<" + structure.first + "*>(this);\n" + " }\n" + "\n"; + + // the union member variables + // if there's at least one Vk... type in this union, check for unrestricted unions support + bool needsUnrestrictedUnions = (std::find_if(structure.second.members.begin(), structure.second.members.end(), [](MemberData const& member) { return beginsWith(member.type.type, "Vk"); }) != structure.second.members.end()); + if (needsUnrestrictedUnions) + { + str += "#ifdef VULKAN_HPP_HAS_UNRESTRICTED_UNIONS\n"; + } + for (auto const& member : structure.second.members) + { + str += " " + member.type.compose() + " " + member.name + (member.arraySize.empty() ? "" : ("[" + member.arraySize + "]")) + ";\n"; + } + if (needsUnrestrictedUnions) + { + str += "#else\n"; + for (auto const& member : structure.second.members) + { + str += " " + member.type.prefix + (member.type.prefix.empty() ? "" : " ") + member.type.type + member.type.postfix + " " + member.name + (member.arraySize.empty() ? "" : ("[" + member.arraySize + "]")) + ";\n"; + } + str += "#endif /*VULKAN_HPP_HAS_UNRESTRICTED_UNIONS*/\n"; + } + str += " };\n"; +} + +void VulkanHppGenerator::appendUniqueTypes(std::string & str, std::string const& parentType, std::set const& childrenTypes) const +{ + str += "\n" + "#ifndef VULKAN_HPP_NO_SMART_HANDLE"; + if (!parentType.empty()) + { + str += "\n" + " class " + stripPrefix(parentType, "Vk") + ";"; + } + + for (auto const& childType : childrenTypes) + { + auto handleIt = m_handles.find(childType); + assert(handleIt != m_handles.end()); + + std::string type = stripPrefix(childType, "Vk"); + std::string deleterType = handleIt->second.deletePool.empty() ? "Object" : "Pool"; + std::string deleterAction = (handleIt->second.deleteCommand.substr(2, 4) == "Free") ? "Free" : "Destroy"; + std::string deleterParent = parentType.empty() ? "NoParent" : stripPrefix(parentType, "Vk"); + std::string deleterPool = handleIt->second.deletePool.empty() ? "" : ", " + stripPrefix(handleIt->second.deletePool, "Vk"); + str += "\n" + " template class UniqueHandleTraits<" + type + ", Dispatch> { public: using deleter = " + deleterType + deleterAction + "<" + deleterParent + deleterPool + ", Dispatch>; };\n" + " using Unique" + type + " = UniqueHandle<" + type + ", DispatchLoaderDefault>;"; + } + str += "\n" + "#endif /*VULKAN_HPP_NO_SMART_HANDLE*/\n"; +} + +void VulkanHppGenerator::EnumData::addEnumValue(std::string const &valueName, bool bitmask, bool bitpos, std::string const& prefix, std::string const& postfix, std::string const& tag) +{ + std::string translatedName = createEnumValueName(valueName, prefix, postfix, bitmask, tag); + + auto it = std::find_if(values.begin(), values.end(), [&translatedName](EnumValueData const& evd) { return evd.vkValue == translatedName; }); + if (it == values.end()) + { + values.push_back(EnumValueData(valueName, translatedName, bitpos)); + } + else + { + assert(it->vulkanValue == valueName); + } +} + bool VulkanHppGenerator::containsUnion(std::string const& type) const { // a simple recursive check if a type is or contains a union @@ -890,102 +3078,6 @@ std::map VulkanHppGenerator::determineVectorParamIndices(std::ve return vectorParamIndices; } -std::string VulkanHppGenerator::generateArgumentPlainType(ParamData const& paramData) const -{ - std::string argument; - - // this parameter is just a plain type - if (!paramData.type.postfix.empty()) - { - assert(paramData.type.postfix.back() == '*'); - // it's a pointer - std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); - if (paramData.type.prefix.find("const") != std::string::npos) - { - // it's a const pointer - if (paramData.type.type == "char") - { - // it's a const pointer to char -> it's a string -> get the data via c_str() - argument = parameterName + (paramData.optional ? (" ? " + parameterName + "->c_str() : nullptr") : ".c_str()"); - } - else - { - // it's const pointer to something else -> just use the name - assert(!paramData.optional); - argument = paramData.name; - } - } - else - { - // it's a non-const pointer, and char is the only type that occurs -> use the address of the parameter - assert(paramData.type.type.find("char") == std::string::npos); - argument = "&" + parameterName; - } - } - else - { - // it's a plain parameter -> just use its name - argument = paramData.name; - } - return argument; -} - -std::string VulkanHppGenerator::generateArgumentVulkanType(ParamData const& paramData) const -{ - std::string argument; - - // this parameter is a vulkan type - if (!paramData.type.postfix.empty()) - { - assert(paramData.type.postfix.back() == '*'); - // it's a pointer -> needs a reinterpret cast to the vulkan type - std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); - argument = generateReinterpretCast(paramData.type.prefix.find("const") != std::string::npos, paramData.type.type, false) + "( "; - if (paramData.optional) - { - // for an optional parameter, we need also a static_cast from optional type to const-pointer to pure type - argument += "static_cast( " + parameterName + " )"; - } - else - { - // other parameters can just use the pointer - argument += "&" + parameterName; - } - argument += " )"; - } - else - { - // a non-pointer parameter needs a static_cast from vk::-type to vulkan type - argument = "static_cast<" + paramData.type.type + ">( " + paramData.name + " )"; - } - return argument; -} - -std::string VulkanHppGenerator::generateCall(std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular) const -{ - std::ostringstream call; - - // the original function call - call << "d." << commandData.first << "( "; - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - if (!handle.empty()) - { - // if it's member of a class -> the first argument is the member variable, starting with "m_" - assert(handle == commandData.second.params[0].type.type); - call << "m_" << startLowerCase(stripPrefix(handle, "Vk")); - if (1 < commandData.second.params.size()) - { - call << ", "; - } - } - - writeArguments(call, commandData.second, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, firstCall, singular, handle.empty() ? 0 : 1, commandData.second.params.size()); - call << " )"; - return call.str(); -} - std::string const& VulkanHppGenerator::getTypesafeCheck() const { return m_typesafeCheck; @@ -1001,42 +3093,6 @@ std::string const& VulkanHppGenerator::getVulkanLicenseHeader() const return m_vulkanLicenseHeader; } -std::string VulkanHppGenerator::generateArgumentVector(size_t paramIndex, ParamData const& paramData, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool firstCall, bool singular) const -{ - std::string argumentVector; - - // this parameter is a vector parameter - assert(paramData.type.postfix.back() == '*'); - if ((returnParamIndex == paramIndex) && twoStep && firstCall) - { - // this parameter is the return parameter, and it's the first call of a two-step algorithm -> just just nullptr - argumentVector = "nullptr"; - } - else - { - std::string parameterName = startLowerCase(stripPrefix(paramData.name, "p")); - if (beginsWith(paramData.type.type, "Vk") || (paramIndex == templateParamIndex)) - { - // CHECK for !commandData.params[it->first].optional - - // this parameter is a vulkan type or a templated type -> need to reinterpret cast - argumentVector = generateReinterpretCast(paramData.type.prefix.find("const") == 0, paramData.type.type, paramData.type.postfix.rfind("* const") != std::string::npos) + "( " + (singular ? ("&" + stripPluralS(parameterName)) : (parameterName + ".data()")) + " )"; - } - else if (paramData.type.type == "char") - { - // the parameter is a vector to char -> it might be optional - // besides that, the parameter now is a std::string -> get the pointer via c_str() - argumentVector = parameterName + (paramData.optional ? (" ? " + parameterName + "->c_str() : nullptr") : ".c_str()"); - } - else - { - // this parameter is just a vetor -> get the pointer to its data - argumentVector = parameterName + ".data()"; - } - } - return argumentVector; -} - bool VulkanHppGenerator::isTwoStepAlgorithm(std::vector const& params) const { // we generate a two-step algorithm for functions returning a vector of stuff, where the length is specified as a pointer as well @@ -1321,7 +3377,7 @@ void VulkanHppGenerator::readComment(tinyxml2::XMLElement const* element) // and add a little message on our own m_vulkanLicenseHeader += "\n\n// This header is generated from the Khronos Vulkan XML API Registry."; - m_vulkanLicenseHeader = trim(m_vulkanLicenseHeader); + m_vulkanLicenseHeader = trim(m_vulkanLicenseHeader) + "\n"; } } @@ -2032,11 +4088,7 @@ void VulkanHppGenerator::readType(tinyxml2::XMLElement const* element) } else if ((categoryIt->second != "enum") && (categoryIt->second != "include")) { - std::stringstream ss; - ss << element->GetLineNum(); - std::string lineNumber = ss.str(); - - throw std::runtime_error("Spec error on line " + lineNumber + ": unknown category <" + categoryIt->second + ">"); + throw std::runtime_error("Spec error on line " + std::to_string(element->GetLineNum()) + ": unknown category <" + categoryIt->second + ">"); } } #if !defined(NDEBUG) @@ -2123,2164 +4175,6 @@ void VulkanHppGenerator::unlinkCommandFromHandle(std::string const& name) handlesIt->second.commands.erase(it); } -void VulkanHppGenerator::writeArguments(std::ostream & os, CommandData const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular, size_t from, size_t to) const -{ - assert(from <= to); - - bool encounteredArgument = false; - for (size_t i = from; i < to; i++) - { - if (encounteredArgument) - { - os << ", "; - } - - auto it = vectorParamIndices.find(i); - if (it != vectorParamIndices.end()) - { - os << generateArgumentVector(it->first, commandData.params[it->first], returnParamIndex, templateParamIndex, twoStep, firstCall, singular); - } - else - { - it = find_if(vectorParamIndices.begin(), vectorParamIndices.end(), [i](std::pair const& vpi) { return vpi.second == i; }); - if (it != vectorParamIndices.end()) - { - os << generateArgumentCount(it->first, commandData.params[it->first].name, commandData.params[it->second].name, returnParamIndex, templateParamIndex, twoStep, singular); - } - else if (beginsWith(commandData.params[i].type.type, "Vk")) - { - os << generateArgumentVulkanType(commandData.params[i]); - } - else - { - os << generateArgumentPlainType(commandData.params[i]); - } - } - encounteredArgument = true; - } -} - -void VulkanHppGenerator::writeBaseTypes(std::ostream & os) const -{ - assert(!m_baseTypes.empty()); - for (auto const& baseType : m_baseTypes) - { - if (baseType.first != "VkFlags") // filter out VkFlags - { - os << " using " << stripPrefix(baseType.first, "Vk") << " = " << baseType.second << ";" << std::endl; - } - } -} - -void VulkanHppGenerator::writeBitmasks(std::ostream & os) const -{ - for (auto const& bitmask : m_bitmasks) - { - auto bitmaskBits = m_bitmaskBits.find(bitmask.second.requirement); - assert(bitmaskBits != m_bitmaskBits.end()); - - os << std::endl; - writePlatformEnter(os, bitmask.second.platform); - writeEnum(os, *bitmaskBits); - writeEnumToString(os, *bitmaskBits); - std::string strippedBitmaskName = stripPrefix(bitmask.first, "Vk"); - std::string strippedEnumName = stripPrefix(bitmaskBits->first, "Vk"); - writeBitmask(os, strippedBitmaskName, bitmask.second.alias, strippedEnumName, bitmaskBits->second.values); - writeBitmaskToStringFunction(os, strippedBitmaskName, strippedEnumName, bitmaskBits->second.values); - writePlatformLeave(os, bitmask.second.platform); - } -} - -void VulkanHppGenerator::writeBitmask(std::ostream & os, std::string const& bitmaskName, std::string const& bitmaskAlias, std::string const& enumName, std::vector const& enumValues) const -{ - // each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter - os << std::endl - << " using " << bitmaskName << " = Flags<" << enumName << ", Vk" << bitmaskName << ">;" << std::endl; - - if (!enumValues.empty()) - { - std::string allFlags; - for (auto const& value : enumValues) - { - if (!allFlags.empty()) - { - allFlags += " | "; - } - allFlags += "VkFlags(" + enumName + "::" + value.vkValue + ")"; - } - - static const std::string bitmaskOperatorsTemplate = R"( - VULKAN_HPP_INLINE ${bitmaskName} operator|( ${enumName} bit0, ${enumName} bit1 ) - { - return ${bitmaskName}( bit0 ) | bit1; - } - - VULKAN_HPP_INLINE ${bitmaskName} operator~( ${enumName} bits ) - { - return ~( ${bitmaskName}( bits ) ); - } - - template <> struct FlagTraits<${enumName}> - { - enum - { - allFlags = ${allFlags} - }; - }; -)"; - - os << replaceWithMap(bitmaskOperatorsTemplate, { { "bitmaskName", bitmaskName },{ "enumName", enumName },{ "allFlags", allFlags } }); - } - - if (!bitmaskAlias.empty()) - { - os << std::endl - << " using " << stripPrefix(bitmaskAlias, "Vk") << " = " << bitmaskName << ";" << std::endl; - } -} - -void VulkanHppGenerator::writeBitmaskToStringFunction(std::ostream & os, std::string const& bitmaskName, std::string const& enumName, std::vector const& enumValues) const -{ - std::string functionBody; - if (enumValues.empty()) - { - functionBody = "\n return \"{}\";"; - } - else - { - // 'or' together all the bits in the value - static const std::string caseTemplate = R"( - if ( value & ${typeName}::${value} ) result += "${valueString} | ";)"; - - std::string casesString; - for (auto const& evd : enumValues) - { - if (evd.singleBit) - { - casesString += replaceWithMap(caseTemplate, {{ "typeName", enumName },{ "value", evd.vkValue },{ "valueString", evd.vkValue.substr(1) }}); - } - } - - static const std::string bodyTemplate = R"( - if ( !value ) return "{}"; - std::string result; -${cases} - return "{ " + result.substr(0, result.size() - 3) + " }";)"; - functionBody = replaceWithMap(bodyTemplate, { { "cases", casesString } }); - } - - static const std::string toStringTemplate = R"( - VULKAN_HPP_INLINE std::string to_string( ${typeName}${argumentName} ) - {${functionBody} - } -)"; - os << replaceWithMap(toStringTemplate, { { "typeName", bitmaskName },{ "argumentName", enumValues.empty() ? " " : " value " },{ "functionBody", functionBody } }); -} - -void VulkanHppGenerator::writeCommand(std::ostream & os, std::string const& indentation, std::string const& name, std::pair const& commandData, bool definition) const -{ - bool twoStep = isTwoStepAlgorithm(commandData.second.params); - std::map vectorParamIndices = determineVectorParamIndices(commandData.second.params); - - size_t returnParamIndex = determineReturnParamIndex(commandData.second, vectorParamIndices, twoStep); - bool isStructureChain = (returnParamIndex != INVALID_INDEX) && determineStructureChaining(commandData.second.params[returnParamIndex].type.type, m_extendedStructs, m_structureAliases); - std::string enhancedReturnType = determineEnhancedReturnType(commandData.second, returnParamIndex, vectorParamIndices, twoStep, false); // get the enhanced return type without structureChain - - size_t templateParamIndex = determineTemplateParamIndex(commandData.second.params, vectorParamIndices); - - // first create the standard version of the function - std::ostringstream standard; - writeFunction(standard, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, false, false, false, false, false); - - // then the enhanced version, composed by up to eight parts - std::ostringstream enhanced; - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, false, false, false); - - if (enhancedReturnType.find("Allocator") != std::string::npos) - { - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, false, false, true); - } - - if (isStructureChain) - { - std::string enhancedReturnTypeWithStructureChain = determineEnhancedReturnType(commandData.second, returnParamIndex, vectorParamIndices, twoStep, true); - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnTypeWithStructureChain, definition, true, false, false, true, false); - - if (enhancedReturnTypeWithStructureChain.find("Allocator") != std::string::npos) - { - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnTypeWithStructureChain, definition, true, false, false, true, true); - } - } - - // then a singular version, if a sized vector would be returned - std::map::const_iterator returnVector = vectorParamIndices.find(returnParamIndex); - bool singular = (returnVector != vectorParamIndices.end()) && - (returnVector->second != INVALID_INDEX) && - (commandData.second.params[returnVector->first].type.type != "void") && - (commandData.second.params[returnVector->second].type.postfix.empty() || (commandData.second.params[returnVector->second].type.postfix.back() != '*')); - if (singular) - { - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, true, false, false, false); - } - - // special handling for createDevice and createInstance ! - bool specialWriteUnique = (commandData.first == "vkCreateDevice") || (commandData.first == "vkCreateInstance"); - - // and then the same for the Unique* versions (a deleteCommand is available for the commandData's class, and the function starts with 'allocate' or 'create') - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - auto handleIt = m_handles.find(m_commandToHandle.find(commandData.first)->second); - assert(handleIt != m_handles.end()); - if ((!handleIt->second.deleteCommand.empty() || specialWriteUnique) && ((commandData.first.substr(2, 8) == "Allocate") || (commandData.first.substr(2, 6) == "Create"))) - { - enhanced << "#ifndef VULKAN_HPP_NO_SMART_HANDLE" << std::endl; - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, true, false, false); - - if (enhancedReturnType.find("Allocator") != std::string::npos) - { - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, false, true, false, true); - } - - if (singular) - { - writeFunction(enhanced, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, definition, true, true, true, false, false); - } - enhanced << "#endif /*VULKAN_HPP_NO_SMART_HANDLE*/" << std::endl; - } - - // and write one or both of them - std::string standardString = standard.str(); - std::string enhancedString = enhanced.str(); - if (standardString == enhancedString) - { - // standard and enhanced string are equal -> just use one of them and we're done - os << standardString; - } - else - { - // standard and enhanced string differ -> use both, wrapping the enhanced by !VULKAN_HPP_DISABLE_ENHANCED_MODE - // determine the argument list of that standard, and compare it with that of the enhanced - // if they are equal -> need to have just one; if they differ -> need to have both - size_t standardStart = standardString.find('('); - size_t standardCount = standardString.find(')', standardStart) - standardStart; - size_t enhancedStart = enhancedString.find('('); - bool unchangedInterface = (standardString.substr(standardStart, standardCount) == enhancedString.substr(enhancedStart, standardCount)); - if (unchangedInterface) - { - os << "#ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; - } - os << standardString - << (unchangedInterface ? "#else" : "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE") << std::endl - << enhancedString - << "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl; - } -} - -void VulkanHppGenerator::writeDispatchLoaderDynamic(std::ostream &os) -{ - os << std::endl - << " class DispatchLoaderDynamic" << std::endl - << " {" << std::endl - << " public:" << std::endl; - - for (auto const& handle : m_handles) - { - for (auto const& command : handle.second.commands) - { - writePlatformEnter(os, command.second.platform); - os << " PFN_" << command.first << " " << command.first << " = 0;" << std::endl; - writePlatformLeave(os, command.second.platform); - } - } - - // write initialization function to fetch function pointers - os << R"( - public: - DispatchLoaderDynamic() = default; - -#if !defined(VK_NO_PROTOTYPES) - // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library. - DispatchLoaderDynamic(vk::Instance const& instance, vk::Device const& device = {}) - { - init(instance, device); - } - - // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library. - void init(vk::Instance const& instance, vk::Device const& device = {}) - { - init(static_cast(instance), ::vkGetInstanceProcAddr, static_cast(device), device ? ::vkGetDeviceProcAddr : nullptr); - } -#endif // !defined(VK_NO_PROTOTYPES) - - // This interface does not require a linked vulkan library. - DispatchLoaderDynamic( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) - { - init( instance, getInstanceProcAddr, device, getDeviceProcAddr ); - } - - // This interface does not require a linked vulkan library. - void init( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) - { - VULKAN_HPP_ASSERT(instance && getInstanceProcAddr); - VULKAN_HPP_ASSERT(!!device == !!getDeviceProcAddr); - vkGetInstanceProcAddr = getInstanceProcAddr; - vkGetDeviceProcAddr = getDeviceProcAddr ? getDeviceProcAddr : PFN_vkGetDeviceProcAddr( vkGetInstanceProcAddr( instance, "vkGetDeviceProcAddr") ); -)"; - - for (auto const& handle : m_handles) - { - for (auto const& command : handle.second.commands) - { - if ((command.first != "vkGetDeviceProcAddr") && (command.first != "vkGetInstanceProcAddr")) - { - writePlatformEnter(os, command.second.platform); - if (!command.second.params.empty() - && m_handles.find(command.second.params[0].type.type) != m_handles.end() - && command.second.params[0].type.type != "VkInstance" - && command.second.params[0].type.type != "VkPhysicalDevice") - { - os << " " << command.first << " = PFN_" << command.first - << "( device ? vkGetDeviceProcAddr( device, \"" << command.first << "\" ) : vkGetInstanceProcAddr( instance, \"" << command.first << "\" ) );" << std::endl; - } - else - { - os << " " << command.first << " = PFN_" << command.first << "( vkGetInstanceProcAddr( instance, \"" << command.first << "\" ) );" << std::endl; - } - writePlatformLeave(os, command.second.platform); - } - } - } - os << " }" << std::endl; - os << " };\n"; -} - -void VulkanHppGenerator::writeDispatchLoaderStatic(std::ostream &os) -{ - static const std::string commandTemplate = - R"( ${returnType} vk${commandName}( ${parameterList} ) const - { - return ::vk${commandName}( ${parameters} ); - } -)"; - - std::ostringstream commands; - for (auto const& handle : m_handles) - { - for (auto const& command : handle.second.commands) - { - std::string parameterList, parameters; - bool firstParam = true; - for (auto param : command.second.params) - { - if (!firstParam) - { - parameterList += ", "; - parameters += ", "; - } - parameterList += param.type.prefix + (param.type.prefix.empty() ? "" : " ") + param.type.type + param.type.postfix + " " + param.name; - if (!param.arraySize.empty()) - { - parameterList += "[" + param.arraySize + "]"; - } - parameters += param.name; - firstParam = false; - } - - commands << std::endl; - writePlatformEnter(commands, command.second.platform); - commands << replaceWithMap(commandTemplate, - { - { "returnType", command.second.returnType }, - { "commandName", stripPrefix(command.first, "vk") }, - { "parameterList", parameterList }, - { "parameters", parameters }, - }); - writePlatformLeave(commands, command.second.platform); - } - } - - static const std::string dispatchTemplate = R"( - class DispatchLoaderStatic - { - public:${commands} }; -)"; - - os << replaceWithMap(dispatchTemplate, { { "commands", commands.str() } }); -} - -void VulkanHppGenerator::writeDispatchLoaderDefault(std::ostream &os) -{ - os << std::endl - << "#if !defined(VK_NO_PROTOTYPES)"; - writeDispatchLoaderStatic(os); - os << R"( - typedef DispatchLoaderStatic DispatchLoaderDefault; -#else // !defined(VK_NO_PROTOTYPES) - class NeedExplicitDispatchLoader; - typedef NeedExplicitDispatchLoader DispatchLoaderDefault; -#endif -)"; -} - -void VulkanHppGenerator::writeEnum(std::ostream & os, std::pair const& enumData) const -{ - std::string values; - for (auto const& value : enumData.second.values) - { - if (!values.empty()) - { - values += ","; - } - values += "\n " + value.vkValue + " = " + value.vulkanValue; - } - for (auto const& value : enumData.second.aliases) - { - // make sure to only list alias values that differ from all non-alias values - if (std::find_if(enumData.second.values.begin(), enumData.second.values.end(), [&value](EnumValueData const& evd) { return value.second == evd.vkValue; }) == enumData.second.values.end()) - { - if (!values.empty()) - { - values += ","; - } - values += "\n " + value.second + " = " + value.first; - } - } - if (!values.empty()) - { - values += "\n "; - } - - static const std::string enumTemplate = -R"( enum class ${name} - {${values}}; -)"; - - os << replaceWithMap(enumTemplate, - { - { "name", stripPrefix(enumData.first, "Vk") }, - { "values", values }, - }); -} - -void VulkanHppGenerator::writeEnums(std::ostream & os) const -{ - for (auto const& e : m_enums) - { - os << std::endl; - writePlatformEnter(os, e.second.platform); - writeEnum(os, e); - writeEnumToString(os, e); - writePlatformLeave(os, e.second.platform); - } -} - -void VulkanHppGenerator::writeEnumToString(std::ostream & os, std::pair const& enumData) const -{ - std::string enumName = stripPrefix(enumData.first, "Vk"); - std::string functionBody; - if (enumData.second.values.empty()) - { - functionBody = "\n return \"(void)\";"; - } - else - { - static const std::string caseTemplate = R"( case ${type}::${value} : return "${valueText}";)"; - std::ostringstream casesString; - for (auto const& value : enumData.second.values) - { - casesString << replaceWithMap(caseTemplate, { { "type", enumName },{ "value", value.vkValue },{ "valueText", value.vkValue.substr(1) } }) << std::endl; - } - - static const std::string switchTemplate = R"( - switch ( value ) - { -${cases} default: return "invalid"; - })"; - functionBody = replaceWithMap(switchTemplate, { { "cases", casesString.str() } }); - } - - static const std::string enumToString = R"( - VULKAN_HPP_INLINE std::string to_string( ${typeName}${argumentName} ) - {${functionBody} - } -)"; - os << replaceWithMap(enumToString, - { - { "typeName", enumName }, - { "argumentName", enumData.second.values.empty() ? "" : " value" }, - { "functionBody", functionBody } - }); -} - -void VulkanHppGenerator::writeForwardDeclarations(std::ostream & os) const -{ - os << std::endl; - for (auto const& structure : m_structures) - { - writePlatformEnter(os, structure.second.platform); - os << " " << (structure.second.isUnion ? "union" : "struct") << " " << stripPrefix(structure.first, "Vk") << ";" << std::endl; - for (std::string const& alias : structure.second.aliases) - { - os << " using " << stripPrefix(alias, "Vk") << " = " << stripPrefix(structure.first, "Vk") << ";" << std::endl; - } - writePlatformLeave(os, structure.second.platform); - } -} - -void VulkanHppGenerator::writeFunction(std::ostream & os, std::string const& indentation, std::string const& name, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain, bool withAllocator) const -{ - writeFunctionHeaderTemplate(os, indentation, returnParamIndex, templateParamIndex, enhancedReturnType, enhanced, singular, unique, !definition, isStructureChain); - - os << indentation << (definition ? "VULKAN_HPP_INLINE " : ""); - writeFunctionHeaderReturnType(os, commandData.second, returnParamIndex, vectorParamIndices, enhancedReturnType, enhanced, singular, unique, isStructureChain); - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - if (definition && !handle.empty()) - { - os << stripPrefix(handle, "Vk") << "::"; - } - - // write the function header name - os << (singular ? stripPluralS(name) : name); - if (unique) - { - os << "Unique"; - } - - writeFunctionHeaderArguments(os, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, enhanced, singular, !definition, withAllocator); - os << (definition ? "" : ";") << std::endl; - - if (definition) - { - // write the function body - os << indentation << "{" << std::endl; - if (enhanced) - { - writeFunctionBodyEnhanced(os, indentation, name, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, enhancedReturnType, singular, unique, isStructureChain, withAllocator); - } - else - { - writeFunctionBodyStandard(os, indentation, commandData); - } - os << indentation << "}" << std::endl; - } -} - -void VulkanHppGenerator::writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool unique, bool isStructureChain, bool withAllocator) const -{ - if (unique && !singular && (vectorParamIndices.find(returnParamIndex) != vectorParamIndices.end())) // returns a vector of UniqueStuff - { - writeFunctionBodyEnhancedVectorOfUniqueHandles(os, indentation, commandName, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, singular, withAllocator); - } - else - { - if (1 < vectorParamIndices.size()) - { - writeFunctionBodyEnhancedMultiVectorSizeCheck(os, indentation, commandName, commandData, returnParamIndex, vectorParamIndices); - } - - std::string returnName; - if (returnParamIndex != INVALID_INDEX) - { - returnName = writeFunctionBodyEnhancedLocalReturnVariable(os, indentation, commandData.second, returnParamIndex, vectorParamIndices, twoStep, enhancedReturnType, singular, isStructureChain, withAllocator); - } - - if (twoStep) - { - writeFunctionBodyEnhancedTwoStep(os, indentation, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular, returnName); - } - else - { - writeFunctionBodyEnhancedSingleStep(os, indentation, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular); - } - - if ((commandData.second.returnType == "VkResult") || !commandData.second.successCodes.empty()) - { - - writeFunctionBodyEnhancedReturnResultValue(os, indentation, returnName, commandName, commandData, returnParamIndex, twoStep, singular, unique); - } - else if ((returnParamIndex != INVALID_INDEX) && (stripPrefix(commandData.second.returnType, "Vk") != enhancedReturnType)) - { - // for the other returning cases, when the return type is somhow enhanced, just return the local returnVariable - os << indentation << " return " << returnName << ";" << std::endl; - } - } -} - -std::string VulkanHppGenerator::writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool isStructureChain, bool withAllocator) const -{ - std::string pureReturnType = stripPrefix(commandData.params[returnParamIndex].type.type, "Vk"); - std::string returnName = startLowerCase(stripPrefix(commandData.params[returnParamIndex].name, "p")); - - // there is a returned parameter -> we need a local variable to hold that value - if (stripPrefix(commandData.returnType, "Vk") != enhancedReturnType) - { - // the returned parameter is somehow enhanced by us - os << indentation << " "; - if (singular) - { - os << generateFunctionBodyEnhancedLocalReturnVariableSingular(indentation, pureReturnType, returnName, isStructureChain); - } - else - { - // in non-singular case, use the enhanced type for the return variable (like vector<...>) - if (isStructureChain && vectorParamIndices.empty()) - { - // For StructureChains use the template parameters - std::string const returnVariableTemplate = -R"(StructureChain structureChain; -${i} ${enhancedReturnType}& ${returnName} = structureChain.template get<${enhancedReturnType}>())"; - - os << replaceWithMap(returnVariableTemplate, { { "i", indentation }, { "enhancedReturnType", enhancedReturnType }, { "returnName", returnName } }); - returnName = "structureChain"; - } - else - { - os << enhancedReturnType << " " << returnName; - } - - std::map::const_iterator vpiIt = vectorParamIndices.find(returnParamIndex); - if (vpiIt != vectorParamIndices.end() && !twoStep) - { - writeFunctionBodyEnhancedLocalReturnVariableVectorSize(os, commandData.params, *vpiIt, returnParamIndex, vectorParamIndices, withAllocator); - } - else if (withAllocator) - { - os << "( vectorAllocator )"; - } - } - os << ";" << std::endl; - } - else - { - // the return parameter is not enhanced -> the type is supposed to be a Result and there are more than one success codes! - assert((commandData.returnType == "VkResult") && (1 < commandData.successCodes.size())); - os << indentation << " " << pureReturnType << " " << returnName << ";" << std::endl; - } - - return returnName; -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedLocalReturnVariableVectorSize(std::ostream & os, std::vector const& params, std::pair const& vectorParamIndex, size_t returnParamIndex, std::map const& vectorParamIndices, bool withAllocator) const -{ - // if the return parameter is a vector parameter, and not part of a two-step algorithm, initialize its size - std::string size; - if (vectorParamIndex.second == INVALID_INDEX) - { - assert(!params[returnParamIndex].len.empty()); - // the size of the vector is not given by an other parameter, but by some member of a parameter, described as 'parameter::member' - // -> replace the '::' by '.' and filter out the leading 'p' to access that value - size = startLowerCase(stripPrefix(params[returnParamIndex].len, "p")); - size_t pos = size.find("::"); - assert(pos != std::string::npos); - size.replace(pos, 2, "."); - } - else - { - // the size of the vector is given by an other parameter - // first check, if that size has become the size of some other vector parameter - // -> look for it and get it's actual size - for (auto const& vpi : vectorParamIndices) - { - if ((vpi.first != vectorParamIndex.first) || (vpi.second != vectorParamIndex.second)) - { - size = startLowerCase(stripPrefix(params[vpi.first].name, "p")) + ".size()"; - break; - } - } - if (size.empty()) - { - // otherwise, just use that parameter - size = params[vectorParamIndex.second].name; - } - } - assert(!size.empty()); - os << "( " << size << (withAllocator ? ", vectorAllocator" : "") << " )"; -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedMultiVectorSizeCheck(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices) const -{ - std::string const sizeCheckTemplate = - R"#(#ifdef VULKAN_HPP_NO_EXCEPTIONS -${i} VULKAN_HPP_ASSERT( ${firstVectorName}.size() == ${secondVectorName}.size() ); -#else -${i} if ( ${firstVectorName}.size() != ${secondVectorName}.size() ) -${i} { -${i} throw LogicError( VULKAN_HPP_NAMESPACE_STRING "::${className}::${commandName}: ${firstVectorName}.size() != ${secondVectorName}.size()" ); -${i} } -#endif /*VULKAN_HPP_NO_EXCEPTIONS*/ -)#"; - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - - // add some error checks if multiple vectors need to have the same size - for (std::map::const_iterator it0 = vectorParamIndices.begin(); it0 != vectorParamIndices.end(); ++it0) - { - if (it0->first != returnParamIndex) - { - for (std::map::const_iterator it1 = std::next(it0); it1 != vectorParamIndices.end(); ++it1) - { - if ((it1->first != returnParamIndex) && (it0->second == it1->second)) - { - os << replaceWithMap(sizeCheckTemplate, std::map({ - { "firstVectorName", startLowerCase(stripPrefix(commandData.second.params[it0->first].name, "p")) }, - { "secondVectorName", startLowerCase(stripPrefix(commandData.second.params[it1->first].name, "p")) }, - { "className", handle }, - { "commandName", commandName }, - { "i", indentation } - })); - } - } - } - } -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedReturnResultValue(std::ostream & os, std::string const& indentation, std::string const& returnName, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, bool twoStep, bool singular, bool unique) const -{ - std::string type = (returnParamIndex != INVALID_INDEX) ? commandData.second.params[returnParamIndex].type.type : ""; - std::string returnVectorName = (returnParamIndex != INVALID_INDEX) ? stripPostfix(stripPrefix(commandData.second.params[returnParamIndex].name, "p"), "s") : ""; - - if (commandData.second.returnType == "void") { - std::cerr << "warning: skipping writeFunctionBodyEnhancedReturnResultValue for function " << commandName << " because the returnType is void"; - return; - } - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - - if (unique) - { - // the unique version needs a Deleter object for destruction of the newly created stuff - // get the DeleterData corresponding to the returned type - // special handling for "createDevice", as Device is created from PhysicalDevice, but destroyed on its own - bool noParent = handle.empty() || (commandData.first == "vkCreateDevice"); - os << std::endl - << indentation << ((commandData.first == "vkAllocateMemory") ? " ObjectFree<" : " ObjectDestroy<") << (noParent ? "NoParent" : stripPrefix(handle, "Vk")) << ",Dispatch> deleter( " << (noParent ? "" : "*this, ") << "allocator, d );" << std::endl - << indentation << " return createResultValue<" << stripPrefix(type, "Vk") << ",Dispatch>( result, "; - } - else - { - os << indentation << " return createResultValue( result, "; - } - - // if the return type is "Result" or there is at least one success code, create the Result/Value construct to return - if (returnParamIndex != INVALID_INDEX) - { - // if there's a return parameter, list it in the Result/Value constructor - os << returnName << ", "; - } - - // now the function name (with full namespace) as a string - os << "VULKAN_HPP_NAMESPACE_STRING\"::" << (handle.empty() ? "" : stripPrefix(handle, "Vk") + "::") << (singular ? stripPluralS(commandName) : commandName) << (unique ? "Unique" : "") << "\""; - - if (!twoStep && (1 < commandData.second.successCodes.size())) - { - // and for the single-step algorithms with more than one success code list them all - os << ", { Result::" << commandData.second.successCodes[0]; - for (size_t i = 1; i < commandData.second.successCodes.size(); i++) - { - os << ", Result::" << commandData.second.successCodes[i]; - } - os << " }"; - } - - if (unique) - { - os << ", deleter"; - } - - os << " );" << std::endl; -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedSingleStep(std::ostream & os, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular) const -{ - std::string const resultCallTemplate = "${i} Result result = static_cast( ${call} );\n"; - std::string const returnCallTemplate = "${i} return ${call};\n"; - std::string const voidCallTemplate = "${i} ${call};\n"; - std::string const& selectedTemplate = (commandData.second.returnType == "VkResult") ? resultCallTemplate : (commandData.second.returnType == "void") ? voidCallTemplate : returnCallTemplate; - os << replaceWithMap(selectedTemplate, - { - { "call", generateCall(commandData, returnParamIndex, templateParamIndex, vectorParamIndices, false, true, singular) }, - { "i", indentation } - }); -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedTwoStep(std::ostream & os, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, std::string const& returnName) const -{ - assert(!singular); - assert((commandData.second.returnType == "VkResult") || (commandData.second.returnType == "void")); - assert(returnParamIndex != INVALID_INDEX); - - // local count variable to hold the size of the vector to fill - std::map::const_iterator returnit = vectorParamIndices.find(returnParamIndex); - assert(returnit != vectorParamIndices.end() && (returnit->second != INVALID_INDEX)); - - // take the pure type of the size parameter; strip the leading 'p' from its name for its local name - std::string sizeName = startLowerCase(stripPrefix(commandData.second.params[returnit->second].name, "p")); - os << indentation << " " << stripPrefix(commandData.second.params[returnit->second].type.type, "Vk") << " " << sizeName << ";" << std::endl; - - std::string const multiSuccessTemplate = - R"(${i} Result result; -${i} do -${i} { -${i} result = static_cast( ${call1} ); -${i} if ( ( result == Result::eSuccess ) && ${sizeName} ) -${i} { -${i} ${returnName}.resize( ${sizeName} ); -${i} result = static_cast( ${call2} ); -${i} } -${i} } while ( result == Result::eIncomplete ); -${i} if ( result == Result::eSuccess ) -${i} { -${i} VULKAN_HPP_ASSERT( ${sizeName} <= ${returnName}.size() ); -${i} ${returnName}.resize( ${sizeName} ); -${i} } -)"; - std::string const singleSuccessTemplate = - R"(${i} Result result = static_cast( ${call1} ); -${i} if ( ( result == Result::eSuccess ) && ${sizeName} ) -${i} { -${i} ${returnName}.resize( ${sizeName} ); -${i} result = static_cast( ${call2} ); -${i} } -)"; - std::string const voidMultiCallTemplate = - R"(${i} ${call1}; -${i} ${returnName}.resize( ${sizeName} ); -${i} ${call2}; -)"; - std::string const& selectedTemplate = (commandData.second.returnType == "VkResult") ? ((1 < commandData.second.successCodes.size()) ? multiSuccessTemplate : singleSuccessTemplate) : voidMultiCallTemplate; - os << replaceWithMap(selectedTemplate, - { - { "sizeName", sizeName }, - { "returnName", returnName }, - { "call1", generateCall(commandData, returnParamIndex, templateParamIndex, vectorParamIndices, true, true, false) }, - { "call2", generateCall(commandData, returnParamIndex, templateParamIndex, vectorParamIndices, true, false, false) }, - { "i", indentation } - }); -} - -void VulkanHppGenerator::writeFunctionBodyEnhancedVectorOfUniqueHandles(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool singular, bool withAllocator) const -{ - std::string const stringTemplate = - R"(${i} static_assert( sizeof( ${type} ) <= sizeof( UniqueHandle<${type}, Dispatch> ), "${type} is greater than UniqueHandle<${type}, Dispatch>!" ); -${i} std::vector, Allocator> ${typeVariable}s${allocator}; -${i} ${typeVariable}s.reserve( ${vectorSize} ); -${i} ${type}* buffer = reinterpret_cast<${type}*>( reinterpret_cast( ${typeVariable}s.data() ) + ${vectorSize} * ( sizeof( UniqueHandle<${type}, Dispatch> ) - sizeof( ${type} ) ) ); -${i} Result result = static_cast(d.vk${command}( m_device, ${arguments}, reinterpret_cast( buffer ) ) ); -${i} if (result == vk::Result::eSuccess) -${i} { -${i} ${Deleter}<${DeleterTemplate},Dispatch> deleter( *this, ${deleterArg}, d ); -${i} for ( size_t i=0 ; i<${vectorSize} ; i++ ) -${i} { -${i} ${typeVariable}s.push_back( UniqueHandle<${type}, Dispatch>( buffer[i], deleter ) ); -${i} } -${i} } - -${i} return createResultValue( result, ${typeVariable}s, VULKAN_HPP_NAMESPACE_STRING "::${class}::${commandName}Unique" ); -)"; - - std::string type = (returnParamIndex != INVALID_INDEX) ? commandData.second.params[returnParamIndex].type.type : ""; - std::string typeVariable = startLowerCase(stripPrefix(type, "Vk")); - std::ostringstream arguments; - writeArguments(arguments, commandData.second, returnParamIndex, templateParamIndex, vectorParamIndices, twoStep, true, singular, 1, commandData.second.params.size() - 1); - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - - auto handleIt = m_handles.find(type); - assert(handleIt != m_handles.end()); - - bool isCreateFunction = (commandData.first.substr(2, 6) == "Create"); - os << replaceWithMap(stringTemplate, std::map - { - { "i", indentation }, - { "type", stripPrefix(type, "Vk") }, - { "typeVariable", typeVariable }, - { "allocator", withAllocator ? "( vectorAllocator )" : "" }, - { "vectorSize", isCreateFunction ? "createInfos.size()" : "allocateInfo." + typeVariable + "Count" }, - { "command", stripPrefix(commandData.first, "vk") }, - { "arguments", arguments.str() }, - { "Deleter", handleIt->second.deletePool.empty() ? "ObjectDestroy" : "PoolFree" }, - { "DeleterTemplate", stripPrefix(handle, "Vk") + (handleIt->second.deletePool.empty() ? "" : "," + stripPrefix(handleIt->second.deletePool, "Vk")) }, - { "deleterArg", handleIt->second.deletePool.empty() ? "allocator" : "allocateInfo." + startLowerCase(stripPrefix(handleIt->second.deletePool, "Vk")) }, - { "class", stripPrefix(handle, "Vk") }, - { "commandName", commandName } - }); -} - -void VulkanHppGenerator::writeFunctionBodyStandard(std::ostream & os, std::string const& indentation, std::pair const& commandData) const -{ - std::pair returnData = writeFunctionBodyStandardReturn(commandData.second.returnType); - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - assert(handle.empty() || (handle == commandData.second.params[0].type.type)); - - std::string arguments; - for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) - { - if (0 < i) - { - arguments += ", "; - } - arguments += writeFunctionBodyStandardArgument(commandData.second.params[i].type, commandData.second.params[i].name); - } - - std::string const standardTemplate = - R"(${i} ${return}d.${command}( ${handleArg}${arguments} )${castClose}; -)"; - - os << replaceWithMap(standardTemplate, - { - { "i", indentation }, - { "return", returnData.second }, - { "command", commandData.first }, - { "handleArg", handle.empty() ? "" : ("m_" + startLowerCase(stripPrefix(handle, "Vk"))) }, - { "arguments", arguments }, - { "castClose", returnData.first ? " )" : "" } - }); -} - -std::string VulkanHppGenerator::writeFunctionBodyStandardArgument(TypeData const& typeData, std::string const& name) const -{ - std::string argument; - if (beginsWith(typeData.type, "Vk")) - { - // the parameter is a vulkan type - if (!typeData.postfix.empty()) - { - assert(typeData.postfix.back() == '*'); - // it's a pointer -> need to reinterpret_cast it - argument += generateReinterpretCast(typeData.prefix.find("const") == 0, typeData.type, typeData.postfix.find("* const") != std::string::npos); - } - else - { - // it's a value -> need to static_cast ist - argument = "static_cast<" + typeData.type + ">"; - } - argument += "( " + name + " )"; - } - else - { - // it's a non-vulkan type -> just use it - argument = name; - } - return argument; -} - -bool VulkanHppGenerator::writeFunctionHeaderArgumentEnhanced(std::ostream & os, ParamData const& param, size_t paramIndex, std::map const& vectorParamIndices, bool skip, bool argEncountered, bool isTemplateParam, bool isLastArgument, bool singular, bool withDefaults, bool withAllocator) const -{ - if (!skip) - { - if (argEncountered) - { - os << ", "; - } - std::string strippedParameterName = startLowerCase(stripPrefix(param.name, "p")); - - std::map::const_iterator it = vectorParamIndices.find(paramIndex); - if (it == vectorParamIndices.end()) - { - // the argument ist not a vector - if (param.type.postfix.empty()) - { - // and its not a pointer -> just use its type and name here - writeFunctionHeaderArgumentEnhancedSimple(os, param, isLastArgument, withDefaults, withAllocator); - } - else - { - // the argument is not a vector, but a pointer - assert(param.type.postfix.back() == '*'); - writeFunctionHeaderArgumentEnhancedPointer(os, param, strippedParameterName, withDefaults, withAllocator); - } - } - else - { - // the argument is a vector - writeFunctionHeaderArgumentEnhancedVector(os, param, strippedParameterName, it->second != INVALID_INDEX, isTemplateParam, singular, withDefaults, withAllocator); - } - argEncountered = true; - } - return argEncountered; -} - -void VulkanHppGenerator::writeFunctionHeaderArgumentEnhancedPointer(std::ostream & os, ParamData const& param, std::string const& strippedParameterName, bool withDefaults, bool withAllocator) const -{ - assert(param.type.postfix.back() == '*'); - if (param.optional) - { - // for an optional argument, trim the leading 'p' from the name - os << "Optional<" << param.type.prefix << (param.type.prefix.empty() ? "" : " ") << stripPrefix(param.type.type, "Vk") << "> " << strippedParameterName; - if (withDefaults && !withAllocator) - { - os << " = nullptr"; - } - } - else if (param.type.type == "void") - { - // for void-pointer, just use type and name - os << param.type.compose() << " " << param.name; - } - else if (param.type.type != "char") - { - // for non-char-pointer, change to reference - assert(param.type.postfix == "*"); - os << param.type.prefix << (param.type.prefix.empty() ? "" : " ") << stripPrefix(param.type.type, "Vk") << " & " << strippedParameterName; - } - else - { - // for char-pointer, change to const reference to std::string - os << "const std::string & " << strippedParameterName; - } -} - -void VulkanHppGenerator::writeFunctionHeaderArgumentEnhancedSimple(std::ostream & os, ParamData const& param, bool lastArgument, bool withDefaults, bool withAllocator) const -{ - os << param.type.compose() << " " << param.name; - if (!param.arraySize.empty()) - { - os << "[" << param.arraySize << "]"; - } - - if (withDefaults && lastArgument && !withAllocator) - { - // check if the very last argument is a flag without any bits -> provide some empty default for it - std::map::const_iterator bitmasksIt = m_bitmasks.find(param.type.type); - if (bitmasksIt != m_bitmasks.end()) - { - // get the enum corresponding to this flag, to check if it's empty - std::string strippedBitmaskName = stripPrefix(bitmasksIt->first, "Vk"); - std::map::const_iterator enumIt = m_bitmaskBits.find(bitmasksIt->second.requirement); - assert(enumIt != m_bitmaskBits.end()); - if (enumIt->second.values.empty()) - { - // there are no bits in this flag -> provide the default - os << " = " << stripPrefix(param.type.type, "Vk") << "()"; - } - } - } -} - -void VulkanHppGenerator::writeFunctionHeaderArgumentEnhancedVector(std::ostream & os, ParamData const& param, std::string const& strippedParameterName, bool hasSizeParam, bool isTemplateParam, bool singular, bool withDefaults, bool withAllocator) const -{ - assert(param.type.postfix.back() == '*'); - - // it's optional, if it's marked as optional and there's no size specified - bool optional = param.optional && !hasSizeParam; - if (param.type.type.find("char") != std::string::npos) - { - // it's a char-vector -> use a std::string (either optional or a const-reference - if (optional) - { - os << "Optional " << strippedParameterName; - if (withDefaults && !withAllocator) - { - os << " = nullptr"; - } - } - else - { - os << "const std::string & " << strippedParameterName; - } - } - else - { - // it's a non-char vector (they are never optional) - assert(!optional); - if (singular) - { - // in singular case, change from pointer to reference - os << param.type.prefix << (param.type.prefix.empty() ? "" : " ") << stripPrefix(param.type.type, "Vk") << " & " << stripPluralS(strippedParameterName); - } - else - { - // otherwise, use our ArrayProxy - bool isConst = (param.type.prefix.find("const") != std::string::npos); - os << "ArrayProxy<" << (isTemplateParam ? (isConst ? "const T" : "T") : stripPostfix(param.type.compose(), "*")) << "> " << strippedParameterName; - } - } -} - -void VulkanHppGenerator::writeFunctionHeaderArguments(std::ostream & os, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool enhanced, bool singular, bool withDefaults, bool withAllocator) const -{ - os << "("; - if (enhanced) - { - writeFunctionHeaderArgumentsEnhanced(os, commandData, returnParamIndex, templateParamIndex, vectorParamIndices, singular, withDefaults, withAllocator); - } - else - { - writeFunctionHeaderArgumentsStandard(os, commandData, withDefaults); - } - os << ")"; - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - if (!m_commandToHandle.find(commandData.first)->second.empty()) - { - os << " const"; - } -} - -void VulkanHppGenerator::writeFunctionHeaderArgumentsEnhanced(std::ostream & os, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, bool withDefaults, bool withAllocator) const -{ - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - - // check if there's at least one argument left to put in here - std::set skippedParams = determineSkippedParams(returnParamIndex, vectorParamIndices); - if (skippedParams.size() + (handle.empty() ? 0 : 1) < commandData.second.params.size()) - { - // determine the last argument, where we might provide some default for - size_t lastArgument = INVALID_INDEX; - for (size_t i = commandData.second.params.size() - 1; i < commandData.second.params.size(); i--) - { - if (skippedParams.find(i) == skippedParams.end()) - { - lastArgument = i; - break; - } - } - - os << " "; - bool argEncountered = false; - for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) - { - argEncountered = writeFunctionHeaderArgumentEnhanced(os, commandData.second.params[i], i, vectorParamIndices, skippedParams.find(i) != skippedParams.end(), argEncountered, (templateParamIndex == i), (lastArgument == i), singular, withDefaults, withAllocator); - } - - if (argEncountered) - { - os << ", "; - } - } - if (withAllocator) - { - os << "Allocator const& vectorAllocator, "; - } - os << "Dispatch const &d"; - if (withDefaults && !withAllocator) - { - os << " = Dispatch()"; - } - - os << " "; -} - -void VulkanHppGenerator::writeFunctionHeaderArgumentsStandard(std::ostream & os, std::pair const& commandData, bool withDefaults) const -{ - // for the standard case, just list all the arguments as we've got them - // determine the last argument, where we might provide some default for - size_t lastArgument = commandData.second.params.size() - 1; - - assert(m_commandToHandle.find(commandData.first) != m_commandToHandle.end()); - std::string const& handle = m_commandToHandle.find(commandData.first)->second; - - bool argEncountered = false; - for (size_t i = handle.empty() ? 0 : 1; i < commandData.second.params.size(); i++) - { - argEncountered = writeFunctionHeaderArgumentStandard(os, commandData.second.params[i], argEncountered, lastArgument == i, withDefaults); - } - if (argEncountered) - { - os << ", "; - } - - os << "Dispatch const &d"; - if (withDefaults) - { - os << " = Dispatch() "; - } -} - -bool VulkanHppGenerator::writeFunctionHeaderArgumentStandard(std::ostream & os, ParamData const& param, bool argEncountered, bool isLastArgument, bool withDefaults) const -{ - if (argEncountered) - { - os << ","; - } - - os << " " << param.type.compose() << " " << param.name; - if (!param.arraySize.empty()) - { - os << "[" << param.arraySize << "]"; - } - - if (withDefaults && isLastArgument) - { - // check if the very last argument is a flag without any bits -> provide some empty default for it - std::map::const_iterator bitmasksIt = m_bitmasks.find(param.type.type); - if (bitmasksIt != m_bitmasks.end()) - { - // get the enum corresponding to this flag, to check if it's empty - std::string strippedBitmaskName = stripPrefix(bitmasksIt->first, "Vk"); - std::map::const_iterator enumIt = m_bitmaskBits.find(bitmasksIt->second.requirement); - assert(enumIt != m_bitmaskBits.end()); - if (enumIt->second.values.empty()) - { - // there are no bits in this flag -> provide the default - os << " = " << stripPrefix(param.type.type, "Vk") << "()"; - } - } - } - return true; -} - -void VulkanHppGenerator::writeFunctionHeaderReturnType(std::ostream & os, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool isStructureChain) const -{ - std::string templateString; - std::string returnType; - if (enhanced) - { - // the enhanced function might return some pretty complex return stuff - bool isVector = (enhancedReturnType.find("Allocator") != std::string::npos); - if (isStructureChain || (!singular && isVector)) - { - // for the non-singular case with allocation, we need to prepend with 'typename' to keep compilers happy - templateString = "typename "; - } - if (unique) - { - // 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 && (vectorParamIndices.find(returnParamIndex) != vectorParamIndices.end()); - - templateString += returnsVector ? "ResultValueType,Allocator>>::type " : "typename ResultValueType>::type "; - returnType = isStructureChain ? "StructureChain" : stripPrefix(commandData.params[returnParamIndex].type.type, "Vk"); - } - else if ((enhancedReturnType != stripPrefix(commandData.returnType, "Vk")) && (commandData.returnType != "void")) - { - // if the enhanced return type differs from the original return type, and it's not void, we return a ResultValueType<...>::type - templateString += "ResultValueType<${returnType}>::type "; - - assert(commandData.returnType == "VkResult"); - // in singular case, we create the ResultValueType from the pure return type, otherwise from the enhanced return type - returnType = isStructureChain ? "StructureChain" : (singular ? stripPrefix(commandData.params[returnParamIndex].type.type, "Vk") : enhancedReturnType); - } - else if ((returnParamIndex != INVALID_INDEX) && (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 == "VkResult"); - templateString = "ResultValue<${returnType}> "; - returnType = isStructureChain ? "StructureChain" : stripPrefix(commandData.params[returnParamIndex].type.type, "Vk"); - } - else - { - // and in every other case, we just return the enhanced return type. - templateString = "${returnType} "; - returnType = isStructureChain && !isVector ? "StructureChain" : enhancedReturnType; - } - } - else - { - // the non-enhanced function just uses the return type - templateString = "${returnType} "; - returnType = stripPrefix(commandData.returnType, "Vk"); - } - os << replaceWithMap(templateString, { { "returnType", returnType } }); -} - -void VulkanHppGenerator::writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, size_t returnParamIndex, size_t templateParamIndex, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool withDefault, bool isStructureChain) const -{ - bool withAllocator = (enhancedReturnType.find("Allocator") != std::string::npos); - os << indentation << "template<"; - if (enhanced) - { - if (isStructureChain) - { - os << "typename " << (withAllocator ? "StructureChain" : "X, typename Y, typename ...Z") << ", "; - } - else if ((templateParamIndex != INVALID_INDEX) && ((templateParamIndex != returnParamIndex) || (enhancedReturnType == "Result"))) - { - assert(!withAllocator); - os << "typename T, "; - } - if (!singular && withAllocator) - { - // otherwise, if there's an Allocator used in the enhanced return type, we templatize on that Allocator - assert((enhancedReturnType.substr(0, 12) == "std::vector<") && (enhancedReturnType.find(',') != std::string::npos) && (12 < enhancedReturnType.find(','))); - os << "typename Allocator"; - if (withDefault) - { - // for the default type get the type from the enhancedReturnType, which is of the form 'std::vector' - assert(!isStructureChain || !unique); - os << " = std::allocator<" << (isStructureChain ? "StructureChain" : (unique ? "Unique" : "") + enhancedReturnType.substr(12, enhancedReturnType.find(',') - 12)) << ">"; - } - os << ", "; - } - } - os << "typename Dispatch" << (withDefault ? " = DispatchLoaderDefault" : "") << ">" << std::endl; -} - -void VulkanHppGenerator::writeHandle(std::ostream & os, std::pair const& handleData, std::set & listedHandles) const -{ - if (listedHandles.find(handleData.first) == listedHandles.end()) - { - listedHandles.insert(handleData.first); - - // first check for any handle that needs to be listed before this one - for (auto const& command : handleData.second.commands) - { - for (auto const& parameter : command.second.params) - { - std::string typeName = parameter.type.type; - auto handlesIt = m_handles.find(typeName); - if ((handlesIt != m_handles.end()) && (listedHandles.find(typeName) == listedHandles.end())) - { - writeHandle(os, *handlesIt, listedHandles); - } - } - } - - if (handleData.first.empty()) - { - for (auto const& command : handleData.second.commands) - { - std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); - if (command.first == "vkCreateInstance") - { - // special handling for createInstance, as we need to explicitly place the forward declarations and the deleter classes here -#if !defined(NDEBUG) - auto handleIt = m_handles.find(""); - assert((handleIt != m_handles.end()) && (handleIt->second.childrenHandles.size() == 2)); - assert(handleIt->second.childrenHandles.find("VkInstance") != handleIt->second.childrenHandles.end()); -#endif - - writeUniqueTypes(os, "", { "VkInstance" }); - } - os << std::endl; - writePlatformEnter(os, command.second.platform); - writeCommand(os, " ", commandName, command, false); - writePlatformLeave(os, command.second.platform); - } - } - else - { - // then write any forward declaration of Deleters used by this handle - if (!handleData.second.childrenHandles.empty()) - { - writeUniqueTypes(os, handleData.first, handleData.second.childrenHandles); - } - else if (handleData.first == "VkPhysicalDevice") - { - // special handling for class Device, as it's created from PhysicalDevice, but destroys itself - writeUniqueTypes(os, "", { "VkDevice" }); - } - - std::ostringstream commands; - // list all the commands that are mapped to members of this class - for (auto const& command : handleData.second.commands) - { - commands << std::endl; - writePlatformEnter(commands, command.second.platform); - std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); - writeCommand(commands, " ", commandName, command, false); - - // special handling for destroy functions which are not aliased. - if (!command.second.isAlias && (((command.first.substr(2, 7) == "Destroy") && (commandName != "destroy")) || (command.first.substr(2, 4) == "Free"))) - { - commandName = (command.first.substr(2, 7) == "Destroy") ? "destroy" : "free"; - commands << std::endl; - writeCommand(commands, " ", commandName, command, false); - } - writePlatformLeave(commands, command.second.platform); - } - - static const std::string templateString = R"( - class ${className} - { - public: - using CType = Vk${className}; - - static VULKAN_HPP_CONST_OR_CONSTEXPR ObjectType objectType = ObjectType::e${className}; - - public: - VULKAN_HPP_CONSTEXPR ${className}() - : m_${memberName}(VK_NULL_HANDLE) - {} - - VULKAN_HPP_CONSTEXPR ${className}( std::nullptr_t ) - : m_${memberName}(VK_NULL_HANDLE) - {} - - VULKAN_HPP_TYPESAFE_EXPLICIT ${className}( Vk${className} ${memberName} ) - : m_${memberName}( ${memberName} ) - {} - -#if defined(VULKAN_HPP_TYPESAFE_CONVERSION) - ${className} & operator=(Vk${className} ${memberName}) - { - m_${memberName} = ${memberName}; - return *this; - } -#endif - - ${className} & operator=( std::nullptr_t ) - { - m_${memberName} = VK_NULL_HANDLE; - return *this; - } - - bool operator==( ${className} const & rhs ) const - { - return m_${memberName} == rhs.m_${memberName}; - } - - bool operator!=(${className} const & rhs ) const - { - return m_${memberName} != rhs.m_${memberName}; - } - - bool operator<(${className} const & rhs ) const - { - return m_${memberName} < rhs.m_${memberName}; - } -${commands} - VULKAN_HPP_TYPESAFE_EXPLICIT operator Vk${className}() const - { - return m_${memberName}; - } - - explicit operator bool() const - { - return m_${memberName} != VK_NULL_HANDLE; - } - - bool operator!() const - { - return m_${memberName} == VK_NULL_HANDLE; - } - - private: - Vk${className} m_${memberName}; - }; - static_assert( sizeof( ${className} ) == sizeof( Vk${className} ), "handle and wrapper have different size!" ); - - template <> - struct cpp_type - { - using type = ${className}; - }; -)"; - - os << replaceWithMap(templateString, { - { "className", stripPrefix(handleData.first, "Vk") }, - { "memberName", startLowerCase(stripPrefix(handleData.first, "Vk")) }, - { "commands", commands.str() } - }); - - if (!handleData.second.alias.empty()) - { - os << " using " << stripPrefix(handleData.second.alias, "Vk") << " = " << stripPrefix(handleData.first, "Vk") << ";" << std::endl; - } - } - } -} - -void VulkanHppGenerator::writeHandles(std::ostream & os) const -{ - std::set listedHandles; - for (auto const& handle : m_handles) - { - writeHandle(os, handle, listedHandles); - } -} - -void VulkanHppGenerator::writeHandlesCommandDefintions(std::ostream & os) const -{ - for (auto const& handle : m_handles) - { - // finally the commands, that are member functions of this handle - for (auto const& command : handle.second.commands) - { - os << std::endl; - writePlatformEnter(os, command.second.platform); - std::string commandName = determineCommandName(command.first, command.second.params[0].type.type); - std::string strippedName = startLowerCase(stripPrefix(command.first, "vk")); - writeCommand(os, " ", commandName, command, true); - - // special handling for destroy functions - if (!command.second.isAlias && (((command.first.substr(2, 7) == "Destroy") && (commandName != "destroy")) || (command.first.substr(2, 4) == "Free"))) - { - commandName = (command.first.substr(2, 7) == "Destroy") ? "destroy" : "free"; - os << std::endl; - writeCommand(os, " ", commandName, command, true); - } - writePlatformLeave(os, command.second.platform); - } - } - os << std::endl; -} - -// Intended only for `enum class Result`! -void VulkanHppGenerator::writeResultExceptions(std::ostream & os) const -{ - std::string templateString = R"( - class ${className} : public SystemError - { - public: - ${className}( std::string const& message ) - : SystemError( make_error_code( ${enumName}::${enumMemberName} ), message ) {} - ${className}( char const * message ) - : SystemError( make_error_code( ${enumName}::${enumMemberName} ), message ) {} - }; -)"; - - auto enumData = m_enums.find("VkResult"); - for (auto const& value : enumData->second.values) - { - if (beginsWith(value.vkValue, "eError")) - { - os << replaceWithMap(templateString, - { - { "className", stripPrefix(value.vkValue, "eError") + "Error" }, - { "enumName", stripPrefix(enumData->first, "Vk") }, - { "enumMemberName", value.vkValue } - }); - } - } - os << std::endl; -} - -void VulkanHppGenerator::writePlatformEnter(std::ostream & os, std::string const& platform) const -{ - if (!platform.empty()) - { - auto it = m_platforms.find(platform); - assert((it != m_platforms.end()) && !it->second.empty()); - os << "#ifdef " << it->second << std::endl; - } -} - -void VulkanHppGenerator::writePlatformLeave(std::ostream & os, std::string const& platform) const -{ - if (!platform.empty()) - { - auto it = m_platforms.find(platform); - assert((it != m_platforms.end()) && !it->second.empty()); - os << "#endif /*" << it->second << "*/" << std::endl; - } -} - -void VulkanHppGenerator::writeStruct(std::ostream & os, std::pair const& structure, std::set & listedStructures) const -{ - if (listedStructures.find(structure.first) == listedStructures.end()) - { - listedStructures.insert(structure.first); - for (auto const& member : structure.second.members) - { - auto structureIt = m_structures.find(member.type.type); - if ((structureIt != m_structures.end()) && (listedStructures.find(member.type.type) == listedStructures.end())) - { - writeStruct(os, *structureIt, listedStructures); - } - } - if (!structure.second.subStruct.empty()) - { - auto structureIt = m_structures.find(structure.second.subStruct); - if ((structureIt != m_structures.end()) && (listedStructures.find(structureIt->first) == listedStructures.end())) - { - writeStruct(os, *structureIt, listedStructures); - } - } - - if (structure.second.isUnion) - { - writeUnion(os, structure); - } - else - { - writeStructure(os, structure); - } - } -} - -void VulkanHppGenerator::writeStructCompareOperators(std::ostream & os, std::pair const& structData) const -{ - // two structs are compared by comparing each of the elements - std::string compareMembers; - std::string intro = ""; - for (auto const& member : structData.second.members) - { - const std::string compareMemberTemplate = std::string("${intro}") + (member.arraySize.empty() ? "( ${name} == rhs.${name} )" : "( memcmp( ${name}, rhs.${name}, ${size} * sizeof( ${type} ) ) == 0 )"); - compareMembers += replaceWithMap(compareMemberTemplate, - { - { "intro", intro }, - { "name", member.name }, - { "size", member.arraySize }, - { "type", member.type.compose() } - }); - intro = "\n && "; - } - - static const std::string compareTemplate = R"( - bool operator==( ${name} const& rhs ) const - { - return ${compareMembers}; - } - - bool operator!=( ${name} const& rhs ) const - { - return !operator==( rhs ); - } -)"; - - os << replaceWithMap(compareTemplate, { { "name", stripPrefix(structData.first, "Vk") }, { "compareMembers", compareMembers } }); -} - -std::string VulkanHppGenerator::writeStructConstructor(std::pair const& structData, std::string const& prefix, bool withLayoutStructure) const -{ - std::ostringstream os; - - // the constructor with all the elements as arguments, with defaults - std::string ctorOpening = prefix + stripPrefix(structData.first, "Vk") + "( "; - std::string indentation(ctorOpening.size(), ' '); - - std::string arguments, initializers, copyOps; - bool listedArgument = false; - bool firstArgument = true; - for (auto const& member : structData.second.members) - { - // gather the arguments - arguments += writeStructConstructorArgument(listedArgument, indentation, member); - - // gather the initializers; skip members 'pNext' and 'sType', they are directly set by initializers - if ((member.name != "pNext") && (member.name != "sType")) - { - if (withLayoutStructure) - { - // withLayoutStructure means: we pass the arguments into the layout::class - if (!firstArgument) - { - initializers += ", "; - } - initializers += member.name + "_"; - firstArgument = false; - } - else if (member.arraySize.empty()) - { - // here, we can only handle non-array arguments - static const std::string templateString = prefix + " ${sep} ${memberName}( ${value} )\n"; - initializers += replaceWithMap(templateString, { { "sep", firstArgument ? ":" : "," },{ "memberName", member.name },{ "value", member.name + "_" } }); - firstArgument = false; - } - else - { - // here we can handle the arrays, copying over from argument (with trailing '_') to member - // size is arraySize times sizeof type - static const std::string templateString = "\n" + prefix + " memcpy( &${member}, ${member}_.data(), ${arraySize} * sizeof( ${type} ) );"; - copyOps += replaceWithMap(templateString, { { "member", member.name },{ "arraySize", member.arraySize },{ "type", member.type.compose() } }); - } - } - } - if (!copyOps.empty()) - { - copyOps += "\n" + prefix; - } - - std::string subStructConstructor; - if (!structData.second.subStruct.empty()) - { - auto const& subStruct = m_structures.find(structData.second.subStruct); - assert(subStruct != m_structures.end()); - - std::string subStructArgumentName = startLowerCase(stripPrefix(subStruct->first, "Vk")); - ctorOpening = prefix + "explicit " + stripPrefix(structData.first, "Vk") + "( "; - indentation = std::string(ctorOpening.size(), ' '); - - static const std::string copyTemplate = prefix + " ${sep} ${member}( ${value} )\n"; - std::string subCopies; - firstArgument = true; - for (size_t i = 0; i < subStruct->second.members.size(); i++) - { - assert(structData.second.members[i].arraySize.empty()); - subCopies += replaceWithMap(copyTemplate, - { - { "sep", firstArgument ? ":" : "," }, - { "member", structData.second.members[i].name }, - { "value", subStructArgumentName + "." + subStruct->second.members[i].name } - }); - firstArgument = false; - } - - std::string subArguments; - listedArgument = true; - for (size_t i = subStruct->second.members.size(); i < structData.second.members.size(); i++) - { - subArguments += writeStructConstructorArgument(listedArgument, indentation, structData.second.members[i]); - - assert(structData.second.members[i].arraySize.empty()); - subCopies += replaceWithMap(copyTemplate, { { "sep", "," }, { "member", structData.second.members[i].name }, { "value", structData.second.members[i].name + "_" } }); - } - - std::string constructorTemplate = R"( - explicit ${type}( ${subType} const& ${subTypeName}${subArguments} ) -${subCopies} - {} -)"; - subStructConstructor = replaceWithMap(constructorTemplate, - { - { "type", stripPrefix(structData.first, "Vk") }, - { "subType", stripPrefix(subStruct->first, "Vk") }, - { "subTypeName", subStructArgumentName }, - { "subArguments", subArguments }, - { "subCopies", subCopies } - }); - } - - std::string structConstructor = prefix + stripPrefix(structData.first, "Vk") + (arguments.empty() ? "()\n" : std::string("( " + arguments + " )")) + "\n"; - if (withLayoutStructure) - { - structConstructor += prefix + " : layout::" + stripPrefix(structData.first, "Vk") + "( " + initializers + " )\n" + prefix + "{}\n"; - } - else - { - structConstructor += initializers; - if (copyOps.empty()) - { - structConstructor += prefix + "{}\n"; - } - else - { - structConstructor += prefix + "{\n" + copyOps + "\n" + prefix + "}\n"; - } - structConstructor += subStructConstructor; - } - - return structConstructor; -} - -std::string VulkanHppGenerator::writeStructConstructorArgument(bool & listedArgument, std::string const& indentation, MemberData const& memberData) const -{ - std::string argument; - - // skip members 'pNext' and 'sType', as they are never explicitly set - if ((memberData.name != "pNext") && (memberData.name != "sType")) - { - static const std::string simpleArgumentTemplate = "${type} ${name} = ${value}"; - static const std::string arrayArgumentTemplate = "std::array<${type},${size}> const& ${name} = { { ${value} } }"; - const std::string argumentTemplate = "${intro}" + (memberData.arraySize.empty() ? simpleArgumentTemplate : arrayArgumentTemplate); - argument = replaceWithMap(argumentTemplate, - { - { "intro", listedArgument ? (",\n" + indentation) : "" }, - { "type", memberData.type.compose() }, - { "size", memberData.arraySize }, - { "name", memberData.name + "_" }, - { "value", (memberData.arraySize.empty() && (!memberData.type.postfix.empty() && memberData.type.postfix.back() == '*')) ? "nullptr" : defaultValue(memberData.type.type) } - }); - - listedArgument = true; - } - return argument; -} - -std::string VulkanHppGenerator::writeStructCopyConstructors(std::string const& name, bool withLayoutStructure) const -{ - static const std::string templateString = R"( - ${name}( Vk${name} const & rhs ) - { - *reinterpret_cast(this) = rhs; - } - - ${name}& operator=( Vk${name} const & rhs ) - { - *reinterpret_cast(this) = rhs; - return *this; - } -)"; - static const std::string layoutTemplateString = R"( - ${name}( Vk${name} const & rhs ) - : layout::${name}( rhs ) - {} - - ${name}& operator=( Vk${name} const & rhs ) - { - *reinterpret_cast(this) = rhs; - return *this; - } -)"; - - std::ostringstream os; - os << replaceWithMap(withLayoutStructure ? layoutTemplateString : templateString, { { "name", name } }); - return os.str(); -} - -std::string VulkanHppGenerator::writeStructMembers(StructureData const& structData, std::string const& prefix) const -{ - std::ostringstream os; - - for (auto const& member : structData.members) - { - os << prefix << member.type.compose() << " " << member.name; - if (member.name == "sType") // special handling for sType - { - auto enumIt = m_enums.find("VkStructureType"); - assert(enumIt != m_enums.end()); - if (!member.values.empty()) - { - assert(beginsWith(member.values, "VK_STRUCTURE_TYPE")); - auto nameIt = std::find_if(enumIt->second.values.begin(), enumIt->second.values.end(), [&member](EnumValueData const& evd) { return member.values == evd.vulkanValue; }); - assert(nameIt != enumIt->second.values.end()); - os << " = StructureType::" << nameIt->vkValue; - } - } - else if (member.name == "pNext") // special handling for pNext - { - os << " = nullptr"; - } - else if (!member.arraySize.empty()) // special handling for arrays - { - os << "[" << member.arraySize << "]"; - } - os << ";" << std::endl; - } - return os.str(); -} - -void VulkanHppGenerator::writeStructs(std::ostream & os) const -{ - std::set listedStructures; - for (auto const& structure : m_structures) - { - writeStruct(os, structure, listedStructures); - } -} - -void VulkanHppGenerator::writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData) const -{ - if (memberData.type.type != "VkStructureType") // filter out StructureType, which is supposed to be immutable ! - { - // copy over the argument, either by assigning simple data, or by memcpy array data - const std::string copyOpTemplate = memberData.arraySize.empty() ? "${name} = ${name}_" : "memcpy( ${name}, ${name}_.data(), ${size} * sizeof( ${type} ) )"; - std::string copyOp = replaceWithMap(copyOpTemplate, { { "name", memberData.name }, { "size", memberData.arraySize }, { "type", memberData.type.compose() } }); - - // the setters return a reference to the structure - static const std::string setterTemplate = R"( - ${structureName} & ${functionName}( ${memberType} ${memberName}_ ) - { - ${copyOp}; - return *this; - } -)"; - - os << replaceWithMap(setterTemplate, - { - { "structureName", structureName }, - { "functionName", "set" + startUpperCase(memberData.name) }, - { "memberType", memberData.arraySize.empty() ? memberData.type.compose() : "std::array<" + memberData.type.compose() + "," + memberData.arraySize + ">" }, - { "memberName", memberData.name }, - { "copyOp", copyOp } - }); - } -} - -void VulkanHppGenerator::writeStructure(std::ostream & os, std::pair const& structure) const -{ - os << std::endl; - writePlatformEnter(os, structure.second.platform); - - std::string baseClass; - bool withLayoutStructure = (!structure.second.members.empty() && (structure.second.members.front().name == "sType")); - if (withLayoutStructure) - { - baseClass = " : public layout::" + stripPrefix(structure.first, "Vk"); - static const std::string layoutStructureTemplate = R"( - namespace layout - { - struct ${name} - { - protected: -${constructor} - - ${name}( Vk${name} const & rhs ) - { - *reinterpret_cast(this) = rhs; - } - - ${name}& operator=( Vk${name} const & rhs ) - { - *reinterpret_cast(this) = rhs; - return *this; - } - - public: -${members} }; - static_assert( sizeof( ${name} ) == sizeof( Vk${name} ), "layout struct and wrapper have different size!" ); - } -)"; - - os << replaceWithMap(layoutStructureTemplate, - { - { "name", stripPrefix(structure.first, "Vk") }, - { "constructor", writeStructConstructor(structure, " ", false)}, - { "members", writeStructMembers(structure.second, " ")} - }); - } - - // only structs that are not returnedOnly get a constructor! - std::ostringstream constructorAndSetters; - if (!structure.second.returnedOnly) - { - constructorAndSetters << writeStructConstructor(structure, " ", withLayoutStructure); - constructorAndSetters << writeStructCopyConstructors(stripPrefix(structure.first, "Vk"), withLayoutStructure); - for (auto const& member : structure.second.members) - { - writeStructSetter(constructorAndSetters, stripPrefix(structure.first, "Vk"), member); - } - } - - // operator==() and operator!=() - // only structs without a union as a member can have a meaningfull == and != operation; we filter them out - std::ostringstream compareOperators; - if (!containsUnion(structure.first)) - { - writeStructCompareOperators(compareOperators, structure); - } - - // the member variables - std::string members; - if (withLayoutStructure) - { - // hide sType when a layout structure is used to keep standard_layout - members = "\n private:\n using layout::" + stripPrefix(structure.first, "Vk") + "::sType;\n"; - } - else - { - members = "\n public:\n" + writeStructMembers(structure.second, " "); - } - - static const std::string structureTemplate = R"( - struct ${name}${baseClass} - { -${constructorAndSetters} - - operator ${vkName} const&() const - { - return *reinterpret_cast( this ); - } - - operator ${vkName} &() - { - return *reinterpret_cast<${vkName}*>( this ); - } - -${compareOperators} - -${members} - }; - static_assert( sizeof( ${name} ) == sizeof( ${vkName} ), "struct and wrapper have different size!" ); - static_assert( std::is_standard_layout<${name}>::value, "struct wrapper is not a standard layout!" ); -)"; - - os << replaceWithMap(structureTemplate, - { - { "name", stripPrefix(structure.first, "Vk") }, - { "baseClass", baseClass }, - { "constructorAndSetters", constructorAndSetters.str() }, - { "vkName", structure.first }, - { "compareOperators", compareOperators.str() }, - { "members", members } - }); - writePlatformLeave(os, structure.second.platform); -} - -void VulkanHppGenerator::writeStructureChainValidation(std::ostream & os) -{ - // write all template functions for the structure pointer chain validation - for (auto const& structure : m_structures) - { - if (!structure.second.structExtends.empty()) - { - writePlatformEnter(os, structure.second.platform); - - // write out allowed structure chains - for (auto extendName : structure.second.structExtends) - { - std::map::const_iterator itExtend = m_structures.find(extendName); - if (itExtend == m_structures.end()) - { - std::stringstream errorString; - errorString << extendName << " does not specify a struct in structextends field."; - - // check if symbol name is an alias to a struct - auto itAlias = std::find_if(m_structures.begin(), m_structures.end(), [&extendName](std::pair const &it) -> bool {return std::find(it.second.aliases.begin(), it.second.aliases.end(), extendName) != it.second.aliases.end(); }); - if (itAlias != m_structures.end()) - { - errorString << " The symbol is an alias and maps to " << itAlias->first << "."; - } - - errorString << std::endl; - throw std::runtime_error(errorString.str()); - } - if (structure.second.platform != itExtend->second.platform) - { - writePlatformEnter(os, itExtend->second.platform); - } - - os << " template <> struct isStructureChainValid<" << stripPrefix(extendName, "Vk") << ", " << stripPrefix(structure.first, "Vk") << ">{ enum { value = true }; };" << std::endl; - - if (structure.second.platform != itExtend->second.platform) - { - writePlatformLeave(os, itExtend->second.platform); - } - } - writePlatformLeave(os, structure.second.platform); - } - } -} - -void VulkanHppGenerator::writeThrowExceptions(std::ostream & os) const -{ - auto enumData = m_enums.find("VkResult"); - - std::string casesString; - for (auto const& value : enumData->second.values) - { - if (beginsWith(value.vkValue, "eError")) - { - casesString += " case Result::" + value.vkValue + ": throw " + stripPrefix(value.vkValue, "eError") + "Error( message );\n"; - } - } - - static const std::string exceptionTemplate = R"( - VULKAN_HPP_INLINE void throwResultException( Result result, char const * message ) - { - switch ( result ) - { -${cases} default: throw SystemError( make_error_code( result ) ); - } - } -)"; - os << replaceWithMap(exceptionTemplate, { { "cases", casesString } }); -} - -void VulkanHppGenerator::writeUnion(std::ostream & os, std::pair const& structure) const -{ - std::ostringstream oss; - os << std::endl - << " union " << stripPrefix(structure.first, "Vk") << std::endl - << " {" << std::endl; - - if (!structure.second.returnedOnly) - { - bool firstTime = true; - for (auto const& member : structure.second.members) - { - // VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t constructor. - auto compareBool32Alias = [](MemberData const& member) { return member.type.type == std::string("uint32_t"); }; - if (member.type.type == "VkBool32") { - if (std::find_if(structure.second.members.begin(), structure.second.members.end(), compareBool32Alias) != structure.second.members.end()) - { - continue; - } - } - - // one constructor per union element - os << " " << stripPrefix(structure.first, "Vk") << "( " << (member.arraySize.empty() ? (member.type.compose() + " ") : ("const std::array<" + member.type.compose() + "," + member.arraySize + ">& ")) << member.name << "_"; - - // just the very first constructor gets default arguments - if (firstTime) - { - std::string value = defaultValue(member.type.type); - os << (member.arraySize.empty() ? (" = " + value) : (" = { { " + value + " } }")); - firstTime = false; - } - os << " )" << std::endl - << " {" << std::endl - << " " << (member.arraySize.empty() ? (member.name + " = " + member.name + "_") : ("memcpy( " + member.name + ", " + member.name + "_.data(), " + member.arraySize + " * sizeof( " + member.type.compose() + " ) )")) << ";" << std::endl - << " }" << std::endl - << std::endl; - } - - // one setter per union element - for (auto const& member : structure.second.members) - { - writeStructSetter(os, stripPrefix(structure.first, "Vk"), member); - } - } - - // the implicit cast operators to the native type - os << " operator " << structure.first << " const&() const" << std::endl - << " {" << std::endl - << " return *reinterpret_cast(this);" << std::endl - << " }" << std::endl - << std::endl - << " operator " << structure.first << " &()" << std::endl - << " {" << std::endl - << " return *reinterpret_cast<" << structure.first << "*>(this);" << std::endl - << " }" << std::endl - << std::endl; - - // the union member variables - // if there's at least one Vk... type in this union, check for unrestricted unions support - bool needsUnrestrictedUnions = (std::find_if(structure.second.members.begin(), structure.second.members.end(), [](MemberData const& member) { return beginsWith(member.type.type, "Vk"); }) != structure.second.members.end()); - if (needsUnrestrictedUnions) - { - os << "#ifdef VULKAN_HPP_HAS_UNRESTRICTED_UNIONS" << std::endl; - } - for (auto const& member : structure.second.members) - { - os << " " << member.type.compose() << " " << member.name << (member.arraySize.empty() ? "" : ("[" + member.arraySize + "]")) << ";" << std::endl; - } - if (needsUnrestrictedUnions) - { - os << "#else" << std::endl; - for (auto const& member : structure.second.members) - { - os << " " << member.type.prefix + (member.type.prefix.empty() ? "" : " ") + member.type.type + member.type.postfix << " " << member.name << (member.arraySize.empty() ? "" : ("[" + member.arraySize + "]")) << ";" << std::endl; - } - os << "#endif /*VULKAN_HPP_HAS_UNRESTRICTED_UNIONS*/" << std::endl; - } - os << " };" << std::endl; -} - -void VulkanHppGenerator::writeUniqueTypes(std::ostream &os, std::string const& parentType, std::set const& childrenTypes) const -{ - os << std::endl - << "#ifndef VULKAN_HPP_NO_SMART_HANDLE"; - if (!parentType.empty()) - { - os << std::endl - << " class " << stripPrefix(parentType, "Vk") << ";"; - } - - for (auto const& childType : childrenTypes) - { - auto handleIt = m_handles.find(childType); - assert(handleIt != m_handles.end()); - - static const std::string uniqueTypesTemplate = R"( - template class UniqueHandleTraits<${type}, Dispatch> { public: using deleter = ${deleterType}${deleterAction}<${deleterParent}${deleterPool}, Dispatch>; }; - using Unique${type} = UniqueHandle<${type}, DispatchLoaderDefault>;)"; - - os << replaceWithMap(uniqueTypesTemplate, - { - { "type", stripPrefix(childType, "Vk") }, - { "deleterType", handleIt->second.deletePool.empty() ? "Object" : "Pool" }, - { "deleterAction", (handleIt->second.deleteCommand.substr(2, 4) == "Free") ? "Free" : "Destroy" }, - { "deleterParent", parentType.empty() ? "NoParent" : stripPrefix(parentType, "Vk") }, - { "deleterPool", handleIt->second.deletePool.empty() ? "" : ", " + stripPrefix(handleIt->second.deletePool, "Vk") } - }); - } - os << std::endl - << "#endif /*VULKAN_HPP_NO_SMART_HANDLE*/" << std::endl; -} - -void VulkanHppGenerator::EnumData::addEnumValue(std::string const &valueName, bool bitmask, bool bitpos, std::string const& prefix, std::string const& postfix, std::string const& tag) -{ - std::string translatedName = createEnumValueName(valueName, prefix, postfix, bitmask, tag); - - auto it = std::find_if(values.begin(), values.end(), [&translatedName](EnumValueData const& evd) { return evd.vkValue == translatedName; }); - if (it == values.end()) - { - values.push_back(EnumValueData(valueName, translatedName, bitpos)); - } - else - { - assert(it->vulkanValue == valueName); - } -} - std::string VulkanHppGenerator::TypeData::compose() const { return prefix + (prefix.empty() ? "" : " ") + ((type.substr(0, 2) == "Vk") ? "vk::" : "") + stripPrefix(type, "Vk") + postfix; @@ -5255,72 +5149,65 @@ namespace std } else { - std::stringstream lineNumber; - lineNumber << child->GetLineNum(); - std::cerr << "warning: Unhandled tag " << value << " at line number: " << lineNumber.str() << "!" << std::endl; + std::cerr << "warning: Unhandled tag " << value << " at line number: " << std::to_string(child->GetLineNum()) << "!" << std::endl; } } generator.checkCorrectness(); + std::string str; + static const size_t estimatedLength = 4 * 1024 * 1024; + str.reserve(estimatedLength); + str += generator.getVulkanLicenseHeader() + + includes + + "\n"; + appendVersionCheck(str, generator.getVersion()); + appendTypesafeStuff(str, generator.getTypesafeCheck()); + str += defines + + "\n" + + "namespace VULKAN_HPP_NAMESPACE\n" + + "{\n" + + classArrayProxy + + classFlags + + classOptional + + classStructureChain + + classUniqueHandle; + generator.appendDispatchLoaderDefault(str); + str += classObjectDestroy + + classObjectFree + + classPoolFree + + "\n"; + generator.appendBaseTypes(str); + generator.appendEnums(str); + str += typeTraits; + generator.appendBitmasks(str); + str += "} // namespace VULKAN_HPP_NAMESPACE\n" + + is_error_code_enum + + "\n" + + "namespace VULKAN_HPP_NAMESPACE\n" + + "{\n" + + "#ifndef VULKAN_HPP_NO_EXCEPTIONS" + + exceptions; + generator.appendResultExceptions(str); + generator.appendThrowExceptions(str); + str += "#endif\n" + + structResultValue; + generator.appendForwardDeclarations(str); + generator.appendHandles(str); + generator.appendStructs(str); + generator.appendHandlesCommandDefintions(str); + generator.appendStructureChainValidation(str); + generator.appendDispatchLoaderDynamic(str); + str += "} // namespace VULKAN_HPP_NAMESPACE\n" + "#endif\n"; + + //assert(str.length() < estimatedLength); + cleanup(str); + std::ofstream ofs(VULKAN_HPP_FILE); assert(!ofs.fail()); - ofs << generator.getVulkanLicenseHeader() << std::endl - << includes - << std::endl - << "static_assert( VK_HEADER_VERSION == " << generator.getVersion() << " , \"Wrong VK_HEADER_VERSION!\" );" << std::endl - << std::endl - << "// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default." << std::endl - << "// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION" << std::endl - << generator.getTypesafeCheck() << std::endl - << "# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )" << std::endl - << "# define VULKAN_HPP_TYPESAFE_CONVERSION" << std::endl - << "# endif" << std::endl - << "#endif" << std::endl - << defines - << std::endl - << "namespace VULKAN_HPP_NAMESPACE" << std::endl - << "{" - << classArrayProxy - << classFlags - << classOptional - << classStructureChain - << classUniqueHandle; - generator.writeDispatchLoaderDefault(ofs); - ofs << classObjectDestroy - << classObjectFree - << classPoolFree - << std::endl; - generator.writeBaseTypes(ofs); - generator.writeEnums(ofs); - ofs << typeTraits; - generator.writeBitmasks(ofs); - ofs << "} // namespace VULKAN_HPP_NAMESPACE" << std::endl - << is_error_code_enum - << std::endl - << "namespace VULKAN_HPP_NAMESPACE" << std::endl - << "{" << std::endl - << "#ifndef VULKAN_HPP_NO_EXCEPTIONS" - << exceptions; - generator.writeResultExceptions(ofs); - generator.writeThrowExceptions(ofs); - ofs << "#endif" << std::endl; - ofs << structResultValue; - generator.writeForwardDeclarations(ofs); - generator.writeHandles(ofs); - generator.writeStructs(ofs); - generator.writeHandlesCommandDefintions(ofs); - - generator.writeStructureChainValidation(ofs); - - generator.writeDispatchLoaderDynamic(ofs); - - ofs << "} // namespace VULKAN_HPP_NAMESPACE" << std::endl - << "#endif" << std::endl; - + ofs << str; ofs.close(); - - cleanup(VULKAN_HPP_FILE); } catch (std::exception const& e) { diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 3c040e8..eb6bcba 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -25,6 +25,19 @@ class VulkanHppGenerator public: VulkanHppGenerator(); + void appendBaseTypes(std::string & str) const; + void appendBitmasks(std::string & str) const; + void appendDispatchLoaderDynamic(std::string & str); // use vkGet*ProcAddress to get function pointers + void appendDispatchLoaderStatic(std::string & str); // use exported symbols from loader + void appendDispatchLoaderDefault(std::string & str); // typedef to DispatchLoaderStatic or undefined type, based on VK_NO_PROTOTYPES + void appendEnums(std::string & str) const; + void appendForwardDeclarations(std::string & str) const; + void appendHandles(std::string & str) const; + void appendHandlesCommandDefintions(std::string & str) const; + void appendResultExceptions(std::string & str) const; + void appendStructs(std::string & str) const; + void appendStructureChainValidation(std::string & str); + void appendThrowExceptions(std::string & str) const; void checkCorrectness(); std::string const& getTypesafeCheck() const; std::string const& getVersion() const; @@ -37,19 +50,6 @@ class VulkanHppGenerator void readPlatforms(tinyxml2::XMLElement const* element); void readTags(tinyxml2::XMLElement const* element); void readTypes(tinyxml2::XMLElement const* element); - void writeBaseTypes(std::ostream & os) const; - void writeBitmasks(std::ostream & os) const; - void writeDispatchLoaderDynamic(std::ostream &os); // use vkGet*ProcAddress to get function pointers - void writeDispatchLoaderStatic(std::ostream &os); // use exported symbols from loader - void writeDispatchLoaderDefault(std::ostream &os); // typedef to DispatchLoaderStatic or undefined type, based on VK_NO_PROTOTYPES - void writeEnums(std::ostream & os) const; - void writeForwardDeclarations(std::ostream & os) const; - void writeHandles(std::ostream & os) const; - void writeHandlesCommandDefintions(std::ostream & os) const; - void writeResultExceptions(std::ostream & os) const; - void writeStructs(std::ostream & os) const; - void writeStructureChainValidation(std::ostream & os); - void writeThrowExceptions(std::ostream& os) const; private: struct BitmaskData @@ -158,6 +158,50 @@ class VulkanHppGenerator }; private: + void appendArgumentPlainType(std::string & str, ParamData const& paramData) const; + void appendArguments(std::string & str, CommandData const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular, size_t from, size_t to) const; + void appendArgumentVector(std::string & str, size_t paramIndex, ParamData const& paramData, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool firstCall, bool singular) const; + void appendArgumentVulkanType(std::string & str, ParamData const& paramData) const; + void appendBitmask(std::string & os, std::string const& bitmaskName, std::string const& bitmaskAlias, std::string const& enumName, std::vector const& enumValues) const; + void appendBitmaskToStringFunction(std::string & str, std::string const& flagsName, std::string const& enumName, std::vector const& enumValues) const; + void appendCall(std::string &str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular) const; + void appendCommand(std::string & str, std::string const& indentation, std::string const& name, std::pair const& commandData, bool definition) const; + void appendEnum(std::string & str, std::pair const& enumData) const; + void appendEnumToString(std::string & str, std::pair const& enumData) const; + void appendFunction(std::string & str, std::string const& indentation, std::string const& name, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain, bool withAllocator) const; + void appendFunctionBodyEnhanced(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool unique, bool isStructureChain, bool withAllocator) const; + std::string appendFunctionBodyEnhancedLocalReturnVariable(std::string & str, std::string const& indentation, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool isStructureChain, bool withAllocator) const; + void appendFunctionBodyEnhancedLocalReturnVariableVectorSize(std::string & str, std::vector const& params, std::pair const& vectorParamIndex, size_t returnParamIndex, std::map const& vectorParamIndices, bool withAllocator) const; + void appendFunctionBodyEnhancedMultiVectorSizeCheck(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices) const; + void appendFunctionBodyEnhancedReturnResultValue(std::string & str, std::string const& indentation, std::string const& returnName, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, bool twoStep, bool singular, bool unique) const; + void appendFunctionBodyEnhancedSingleStep(std::string & str, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular) const; + void appendFunctionBodyEnhancedTwoStep(std::string & str, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, std::string const& returnName) const; + void appendFunctionBodyEnhancedVectorOfUniqueHandles(std::string & str, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool singular, bool withAllocator) const; + void appendFunctionBodyStandard(std::string & str, std::string const& indentation, std::pair const& commandData) const; + void appendFunctionBodyStandardArgument(std::string & str, TypeData const& typeData, std::string const& name) const; + bool appendFunctionHeaderArgumentEnhanced(std::string & str, ParamData const& param, size_t paramIndex, std::map const& vectorParamIndices, bool skip, bool argEncountered, bool isTemplateParam, bool isLastArgument, bool singular, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArgumentEnhancedPointer(std::string & str, ParamData const& param, std::string const& strippedParameterName, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArgumentEnhancedSimple(std::string & str, ParamData const& param, bool lastArgument, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArgumentEnhancedVector(std::string & str, ParamData const& param, std::string const& strippedParameterName, bool hasSizeParam, bool isTemplateParam, bool singular, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArguments(std::string & str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool enhanced, bool singular, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArgumentsEnhanced(std::string & str, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, bool withDefaults, bool withAllocator) const; + void appendFunctionHeaderArgumentsStandard(std::string & str, std::pair const& commandData, bool withDefaults) const; + bool appendFunctionHeaderArgumentStandard(std::string & str, ParamData const& param, bool argEncountered, bool isLastArgument, bool withDefaults) const; + void appendFunctionHeaderReturnType(std::string & str, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool isStructureChain) const; + void appendFunctionHeaderTemplate(std::string & str, std::string const& indentation, size_t returnParamIndex, size_t templateParamIndex, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool withDefault, bool isStructureChain) const; + void appendHandle(std::string & str, std::pair const& handle, std::set & listedHandles) const; + void appendPlatformEnter(std::string & str, std::string const& platform) const; + void appendPlatformLeave(std::string & str, std::string const& platform) const; + void appendStruct(std::string & str, std::pair const& structure, std::set & listedStructures) const; + void appendStructCompareOperators(std::string & str, std::pair const& structure) const; + std::string appendStructConstructor(std::pair const& structData, std::string const& prefix, bool withLayoutStructure) const; + bool appendStructConstructorArgument(std::string & str, bool listedArgument, std::string const& indentation, MemberData const& memberData) const; + void appendStructCopyConstructors(std::string & str, std::string const& vkName, bool withLayoutStructure) const; + void appendStructMembers(std::string & str, StructureData const& structData, std::string const& prefix) const; + void appendStructSetter(std::string & str, std::string const& structureName, MemberData const& memberData) const; + void appendStructure(std::string & str, std::pair const& structure) const; + void appendUnion(std::string & str, std::pair const& structure) const; + void appendUniqueTypes(std::string &str, std::string const& parentType, std::set const& childrenTypes) const; bool containsUnion(std::string const& type) const; std::string defaultValue(std::string const& type) const; std::string determineEnhancedReturnType(CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, bool twoStep, bool isStructureChain) const; @@ -165,10 +209,6 @@ class VulkanHppGenerator std::string determineSubStruct(std::pair const& structure) const; size_t determineTemplateParamIndex(std::vector const& params, std::map const& vectorParamIndices) const; std::map determineVectorParamIndices(std::vector const& params) const; - std::string generateArgumentPlainType(ParamData const& paramData) const; - std::string generateArgumentVector(size_t paramIndex, ParamData const& paramData, size_t returnParamIndex, size_t templateParamIndex, bool twoStep, bool firstCall, bool singular) const; - std::string generateArgumentVulkanType(ParamData const& paramData) const; - std::string generateCall(std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular) const; bool isTwoStepAlgorithm(std::vector const& params) const; void linkCommandToHandle(std::string const& name, CommandData const& commandData); void readBaseType(tinyxml2::XMLElement const* element, std::map const& attributes); @@ -200,46 +240,6 @@ class VulkanHppGenerator void readType(tinyxml2::XMLElement const* element); void registerDeleter(std::string const& name, std::pair const& commandData); void unlinkCommandFromHandle(std::string const& name); - void writeArguments(std::ostream & os, CommandData const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool firstCall, bool singular, size_t from, size_t to) const; - void writeBitmask(std::ostream & os, std::string const& bitmaskName, std::string const& bitmaskAlias, std::string const& enumName, std::vector const& enumValues) const; - void writeBitmaskToStringFunction(std::ostream & os, std::string const& flagsName, std::string const& enumName, std::vector const& enumValues) const; - void writeCommand(std::ostream &os, std::string const& indentation, std::string const& name, std::pair const& commandData, bool definition) const; - void writeEnum(std::ostream & os, std::pair const& enumData) const; - void writeEnumToString(std::ostream & os, std::pair const& enumData) const; - void writeFunction(std::ostream & os, std::string const& indentation, std::string const& name, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool definition, bool enhanced, bool singular, bool unique, bool isStructureChain, bool withAllocator) const; - void writeFunctionBodyEnhanced(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool unique, bool isStructureChain, bool withAllocator) const; - std::string writeFunctionBodyEnhancedLocalReturnVariable(std::ostream & os, std::string const& indentation, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, bool twoStep, std::string const& enhancedReturnType, bool singular, bool isStructureChain, bool withAllocator) const; - void writeFunctionBodyEnhancedLocalReturnVariableVectorSize(std::ostream & os, std::vector const& params, std::pair const& vectorParamIndex, size_t returnParamIndex, std::map const& vectorParamIndices, bool withAllocator) const; - void writeFunctionBodyEnhancedMultiVectorSizeCheck(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices) const; - void writeFunctionBodyEnhancedReturnResultValue(std::ostream & os, std::string const& indentation, std::string const& returnName, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, bool twoStep, bool singular, bool unique) const; - void writeFunctionBodyEnhancedSingleStep(std::ostream & os, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular) const; - void writeFunctionBodyEnhancedTwoStep(std::ostream & os, std::string const& indentation, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, std::string const& returnName) const; - void writeFunctionBodyEnhancedVectorOfUniqueHandles(std::ostream & os, std::string const& indentation, std::string const& commandName, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool twoStep, bool singular, bool withAllocator) const; - void writeFunctionBodyStandard(std::ostream & os, std::string const& indentation, std::pair const& commandData) const; - std::string writeFunctionBodyStandardArgument(TypeData const& typeData, std::string const& name) const; - bool writeFunctionHeaderArgumentEnhanced(std::ostream & os, ParamData const& param, size_t paramIndex, std::map const& vectorParamIndices, bool skip, bool argEncountered, bool isTemplateParam, bool isLastArgument, bool singular, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArgumentEnhancedPointer(std::ostream & os, ParamData const& param, std::string const& strippedParameterName, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArgumentEnhancedSimple(std::ostream & os, ParamData const& param, bool lastArgument, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArgumentEnhancedVector(std::ostream & os, ParamData const& param, std::string const& strippedParameterName, bool hasSizeParam, bool isTemplateParam, bool singular, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArguments(std::ostream & os, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool enhanced, bool singular, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArgumentsEnhanced(std::ostream & os, std::pair const& commandData, size_t returnParamIndex, size_t templateParamIndex, std::map const& vectorParamIndices, bool singular, bool withDefaults, bool withAllocator) const; - void writeFunctionHeaderArgumentsStandard(std::ostream & os, std::pair const& commandData, bool withDefaults) const; - bool writeFunctionHeaderArgumentStandard(std::ostream & os, ParamData const& param, bool argEncountered, bool isLastArgument, bool withDefaults) const; - void writeFunctionHeaderReturnType(std::ostream & os, CommandData const& commandData, size_t returnParamIndex, std::map const& vectorParamIndices, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool isStructureChain) const; - void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, size_t returnParamIndex, size_t templateParamIndex, std::string const& enhancedReturnType, bool enhanced, bool singular, bool unique, bool withDefault, bool isStructureChain) const; - void writeHandle(std::ostream & os, std::pair const& handle, std::set & listedHandles) const; - void writePlatformEnter(std::ostream & os, std::string const& platform) const; - void writePlatformLeave(std::ostream & os, std::string const& platform) const; - void writeStruct(std::ostream & os, std::pair const& structure, std::set & listedStructures) const; - void writeStructCompareOperators(std::ostream & os, std::pair const& structure) const; - std::string writeStructConstructor(std::pair const& structData, std::string const& prefix, bool withLayoutStructure) const; - std::string writeStructConstructorArgument(bool & listedArgument, std::string const& indentation, MemberData const& memberData) const; - std::string writeStructCopyConstructors(std::string const& vkName, bool withLayoutStructure) const; - std::string writeStructMembers(StructureData const& structData, std::string const& prefix) const; - void writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData) const; - void writeStructure(std::ostream & os, std::pair const& structure) const; - void writeUnion(std::ostream & os, std::pair const& structure) const; - void writeUniqueTypes(std::ostream &os, std::string const& parentType, std::set const& childrenTypes) const; #if !defined(NDEBUG) void readRequires(tinyxml2::XMLElement const* element, std::map const& attributes); #endif diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index a3fbd2a..caecf53 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -18025,8 +18025,8 @@ namespace VULKAN_HPP_NAMESPACE { GeometryDataNV( vk::GeometryTrianglesNV triangles_ = vk::GeometryTrianglesNV(), vk::GeometryAABBNV aabbs_ = vk::GeometryAABBNV() ) - : triangles( triangles_ ) - , aabbs( aabbs_ ) + : triangles( triangles_ ) + , aabbs( aabbs_ ) {} GeometryDataNV( VkGeometryDataNV const & rhs ) @@ -18640,12 +18640,12 @@ namespace VULKAN_HPP_NAMESPACE PFN_vkFreeFunction pfnFree_ = nullptr, PFN_vkInternalAllocationNotification pfnInternalAllocation_ = nullptr, PFN_vkInternalFreeNotification pfnInternalFree_ = nullptr ) - : pUserData( pUserData_ ) - , pfnAllocation( pfnAllocation_ ) - , pfnReallocation( pfnReallocation_ ) - , pfnFree( pfnFree_ ) - , pfnInternalAllocation( pfnInternalAllocation_ ) - , pfnInternalFree( pfnInternalFree_ ) + : pUserData( pUserData_ ) + , pfnAllocation( pfnAllocation_ ) + , pfnReallocation( pfnReallocation_ ) + , pfnFree( pfnFree_ ) + , pfnInternalAllocation( pfnInternalAllocation_ ) + , pfnInternalFree( pfnInternalFree_ ) {} AllocationCallbacks( VkAllocationCallbacks const & rhs ) @@ -18737,10 +18737,10 @@ namespace VULKAN_HPP_NAMESPACE vk::ComponentSwizzle g_ = vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle b_ = vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle a_ = vk::ComponentSwizzle::eIdentity ) - : r( r_ ) - , g( g_ ) - , b( b_ ) - , a( a_ ) + : r( r_ ) + , g( g_ ) + , b( b_ ) + , a( a_ ) {} ComponentMapping( VkComponentMapping const & rhs ) @@ -19262,15 +19262,15 @@ namespace VULKAN_HPP_NAMESPACE vk::AttachmentStoreOp stencilStoreOp_ = vk::AttachmentStoreOp::eStore, vk::ImageLayout initialLayout_ = vk::ImageLayout::eUndefined, vk::ImageLayout finalLayout_ = vk::ImageLayout::eUndefined ) - : flags( flags_ ) - , format( format_ ) - , samples( samples_ ) - , loadOp( loadOp_ ) - , storeOp( storeOp_ ) - , stencilLoadOp( stencilLoadOp_ ) - , stencilStoreOp( stencilStoreOp_ ) - , initialLayout( initialLayout_ ) - , finalLayout( finalLayout_ ) + : flags( flags_ ) + , format( format_ ) + , samples( samples_ ) + , loadOp( loadOp_ ) + , storeOp( storeOp_ ) + , stencilLoadOp( stencilLoadOp_ ) + , stencilStoreOp( stencilStoreOp_ ) + , initialLayout( initialLayout_ ) + , finalLayout( finalLayout_ ) {} AttachmentDescription( VkAttachmentDescription const & rhs ) @@ -19556,8 +19556,8 @@ namespace VULKAN_HPP_NAMESPACE { AttachmentReference( uint32_t attachment_ = 0, vk::ImageLayout layout_ = vk::ImageLayout::eUndefined ) - : attachment( attachment_ ) - , layout( layout_ ) + : attachment( attachment_ ) + , layout( layout_ ) {} AttachmentReference( VkAttachmentReference const & rhs ) @@ -19721,8 +19721,8 @@ namespace VULKAN_HPP_NAMESPACE { Extent2D( uint32_t width_ = 0, uint32_t height_ = 0 ) - : width( width_ ) - , height( height_ ) + : width( width_ ) + , height( height_ ) {} Extent2D( VkExtent2D const & rhs ) @@ -19780,8 +19780,8 @@ namespace VULKAN_HPP_NAMESPACE { SampleLocationEXT( float x_ = 0, float y_ = 0 ) - : x( x_ ) - , y( y_ ) + : x( x_ ) + , y( y_ ) {} SampleLocationEXT( VkSampleLocationEXT const & rhs ) @@ -19956,8 +19956,8 @@ namespace VULKAN_HPP_NAMESPACE { AttachmentSampleLocationsEXT( uint32_t attachmentIndex_ = 0, vk::SampleLocationsInfoEXT sampleLocationsInfo_ = vk::SampleLocationsInfoEXT() ) - : attachmentIndex( attachmentIndex_ ) - , sampleLocationsInfo( sampleLocationsInfo_ ) + : attachmentIndex( attachmentIndex_ ) + , sampleLocationsInfo( sampleLocationsInfo_ ) {} AttachmentSampleLocationsEXT( VkAttachmentSampleLocationsEXT const & rhs ) @@ -20498,8 +20498,8 @@ namespace VULKAN_HPP_NAMESPACE { Offset2D( int32_t x_ = 0, int32_t y_ = 0 ) - : x( x_ ) - , y( y_ ) + : x( x_ ) + , y( y_ ) {} Offset2D( VkOffset2D const & rhs ) @@ -20557,8 +20557,8 @@ namespace VULKAN_HPP_NAMESPACE { Rect2D( vk::Offset2D offset_ = vk::Offset2D(), vk::Extent2D extent_ = vk::Extent2D() ) - : offset( offset_ ) - , extent( extent_ ) + : offset( offset_ ) + , extent( extent_ ) {} Rect2D( VkRect2D const & rhs ) @@ -21021,11 +21021,11 @@ namespace VULKAN_HPP_NAMESPACE vk::DeviceMemory memory_ = vk::DeviceMemory(), vk::DeviceSize memoryOffset_ = 0, vk::SparseMemoryBindFlags flags_ = vk::SparseMemoryBindFlags() ) - : resourceOffset( resourceOffset_ ) - , size( size_ ) - , memory( memory_ ) - , memoryOffset( memoryOffset_ ) - , flags( flags_ ) + : resourceOffset( resourceOffset_ ) + , size( size_ ) + , memory( memory_ ) + , memoryOffset( memoryOffset_ ) + , flags( flags_ ) {} SparseMemoryBind( VkSparseMemoryBind const & rhs ) @@ -21108,9 +21108,9 @@ namespace VULKAN_HPP_NAMESPACE SparseBufferMemoryBindInfo( vk::Buffer buffer_ = vk::Buffer(), uint32_t bindCount_ = 0, const vk::SparseMemoryBind* pBinds_ = nullptr ) - : buffer( buffer_ ) - , bindCount( bindCount_ ) - , pBinds( pBinds_ ) + : buffer( buffer_ ) + , bindCount( bindCount_ ) + , pBinds( pBinds_ ) {} SparseBufferMemoryBindInfo( VkSparseBufferMemoryBindInfo const & rhs ) @@ -21177,9 +21177,9 @@ namespace VULKAN_HPP_NAMESPACE SparseImageOpaqueMemoryBindInfo( vk::Image image_ = vk::Image(), uint32_t bindCount_ = 0, const vk::SparseMemoryBind* pBinds_ = nullptr ) - : image( image_ ) - , bindCount( bindCount_ ) - , pBinds( pBinds_ ) + : image( image_ ) + , bindCount( bindCount_ ) + , pBinds( pBinds_ ) {} SparseImageOpaqueMemoryBindInfo( VkSparseImageOpaqueMemoryBindInfo const & rhs ) @@ -21246,9 +21246,9 @@ namespace VULKAN_HPP_NAMESPACE ImageSubresource( vk::ImageAspectFlags aspectMask_ = vk::ImageAspectFlags(), uint32_t mipLevel_ = 0, uint32_t arrayLayer_ = 0 ) - : aspectMask( aspectMask_ ) - , mipLevel( mipLevel_ ) - , arrayLayer( arrayLayer_ ) + : aspectMask( aspectMask_ ) + , mipLevel( mipLevel_ ) + , arrayLayer( arrayLayer_ ) {} ImageSubresource( VkImageSubresource const & rhs ) @@ -21315,9 +21315,9 @@ namespace VULKAN_HPP_NAMESPACE Offset3D( int32_t x_ = 0, int32_t y_ = 0, int32_t z_ = 0 ) - : x( x_ ) - , y( y_ ) - , z( z_ ) + : x( x_ ) + , y( y_ ) + , z( z_ ) {} explicit Offset3D( Offset2D const& offset2D, @@ -21325,7 +21325,6 @@ namespace VULKAN_HPP_NAMESPACE : x( offset2D.x ) , y( offset2D.y ) , z( z_ ) - {} Offset3D( VkOffset3D const & rhs ) @@ -21392,9 +21391,9 @@ namespace VULKAN_HPP_NAMESPACE Extent3D( uint32_t width_ = 0, uint32_t height_ = 0, uint32_t depth_ = 0 ) - : width( width_ ) - , height( height_ ) - , depth( depth_ ) + : width( width_ ) + , height( height_ ) + , depth( depth_ ) {} explicit Extent3D( Extent2D const& extent2D, @@ -21402,7 +21401,6 @@ namespace VULKAN_HPP_NAMESPACE : width( extent2D.width ) , height( extent2D.height ) , depth( depth_ ) - {} Extent3D( VkExtent3D const & rhs ) @@ -21472,12 +21470,12 @@ namespace VULKAN_HPP_NAMESPACE vk::DeviceMemory memory_ = vk::DeviceMemory(), vk::DeviceSize memoryOffset_ = 0, vk::SparseMemoryBindFlags flags_ = vk::SparseMemoryBindFlags() ) - : subresource( subresource_ ) - , offset( offset_ ) - , extent( extent_ ) - , memory( memory_ ) - , memoryOffset( memoryOffset_ ) - , flags( flags_ ) + : subresource( subresource_ ) + , offset( offset_ ) + , extent( extent_ ) + , memory( memory_ ) + , memoryOffset( memoryOffset_ ) + , flags( flags_ ) {} SparseImageMemoryBind( VkSparseImageMemoryBind const & rhs ) @@ -21568,9 +21566,9 @@ namespace VULKAN_HPP_NAMESPACE SparseImageMemoryBindInfo( vk::Image image_ = vk::Image(), uint32_t bindCount_ = 0, const vk::SparseImageMemoryBind* pBinds_ = nullptr ) - : image( image_ ) - , bindCount( bindCount_ ) - , pBinds( pBinds_ ) + : image( image_ ) + , bindCount( bindCount_ ) + , pBinds( pBinds_ ) {} SparseImageMemoryBindInfo( VkSparseImageMemoryBindInfo const & rhs ) @@ -21820,9 +21818,9 @@ namespace VULKAN_HPP_NAMESPACE BufferCopy( vk::DeviceSize srcOffset_ = 0, vk::DeviceSize dstOffset_ = 0, vk::DeviceSize size_ = 0 ) - : srcOffset( srcOffset_ ) - , dstOffset( dstOffset_ ) - , size( size_ ) + : srcOffset( srcOffset_ ) + , dstOffset( dstOffset_ ) + , size( size_ ) {} BufferCopy( VkBufferCopy const & rhs ) @@ -22197,10 +22195,10 @@ namespace VULKAN_HPP_NAMESPACE uint32_t mipLevel_ = 0, uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 ) - : aspectMask( aspectMask_ ) - , mipLevel( mipLevel_ ) - , baseArrayLayer( baseArrayLayer_ ) - , layerCount( layerCount_ ) + : aspectMask( aspectMask_ ) + , mipLevel( mipLevel_ ) + , baseArrayLayer( baseArrayLayer_ ) + , layerCount( layerCount_ ) {} ImageSubresourceLayers( VkImageSubresourceLayers const & rhs ) @@ -22278,12 +22276,12 @@ namespace VULKAN_HPP_NAMESPACE vk::ImageSubresourceLayers imageSubresource_ = vk::ImageSubresourceLayers(), vk::Offset3D imageOffset_ = vk::Offset3D(), vk::Extent3D imageExtent_ = vk::Extent3D() ) - : bufferOffset( bufferOffset_ ) - , bufferRowLength( bufferRowLength_ ) - , bufferImageHeight( bufferImageHeight_ ) - , imageSubresource( imageSubresource_ ) - , imageOffset( imageOffset_ ) - , imageExtent( imageExtent_ ) + : bufferOffset( bufferOffset_ ) + , bufferRowLength( bufferRowLength_ ) + , bufferImageHeight( bufferImageHeight_ ) + , imageSubresource( imageSubresource_ ) + , imageOffset( imageOffset_ ) + , imageExtent( imageExtent_ ) {} BufferImageCopy( VkBufferImageCopy const & rhs ) @@ -22930,8 +22928,8 @@ namespace VULKAN_HPP_NAMESPACE { ClearDepthStencilValue( float depth_ = 0, uint32_t stencil_ = 0 ) - : depth( depth_ ) - , stencil( stencil_ ) + : depth( depth_ ) + , stencil( stencil_ ) {} ClearDepthStencilValue( VkClearDepthStencilValue const & rhs ) @@ -23032,9 +23030,9 @@ namespace VULKAN_HPP_NAMESPACE ClearAttachment( vk::ImageAspectFlags aspectMask_ = vk::ImageAspectFlags(), uint32_t colorAttachment_ = 0, vk::ClearValue clearValue_ = vk::ClearValue() ) - : aspectMask( aspectMask_ ) - , colorAttachment( colorAttachment_ ) - , clearValue( clearValue_ ) + : aspectMask( aspectMask_ ) + , colorAttachment( colorAttachment_ ) + , clearValue( clearValue_ ) {} ClearAttachment( VkClearAttachment const & rhs ) @@ -23089,9 +23087,9 @@ namespace VULKAN_HPP_NAMESPACE ClearRect( vk::Rect2D rect_ = vk::Rect2D(), uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 ) - : rect( rect_ ) - , baseArrayLayer( baseArrayLayer_ ) - , layerCount( layerCount_ ) + : rect( rect_ ) + , baseArrayLayer( baseArrayLayer_ ) + , layerCount( layerCount_ ) {} ClearRect( VkClearRect const & rhs ) @@ -23158,9 +23156,9 @@ namespace VULKAN_HPP_NAMESPACE IndirectCommandsTokenNVX( vk::IndirectCommandsTokenTypeNVX tokenType_ = vk::IndirectCommandsTokenTypeNVX::ePipeline, vk::Buffer buffer_ = vk::Buffer(), vk::DeviceSize offset_ = 0 ) - : tokenType( tokenType_ ) - , buffer( buffer_ ) - , offset( offset_ ) + : tokenType( tokenType_ ) + , buffer( buffer_ ) + , offset( offset_ ) {} IndirectCommandsTokenNVX( VkIndirectCommandsTokenNVX const & rhs ) @@ -23516,9 +23514,9 @@ namespace VULKAN_HPP_NAMESPACE CoarseSampleLocationNV( uint32_t pixelX_ = 0, uint32_t pixelY_ = 0, uint32_t sample_ = 0 ) - : pixelX( pixelX_ ) - , pixelY( pixelY_ ) - , sample( sample_ ) + : pixelX( pixelX_ ) + , pixelY( pixelY_ ) + , sample( sample_ ) {} CoarseSampleLocationNV( VkCoarseSampleLocationNV const & rhs ) @@ -23586,10 +23584,10 @@ namespace VULKAN_HPP_NAMESPACE uint32_t sampleCount_ = 0, uint32_t sampleLocationCount_ = 0, const vk::CoarseSampleLocationNV* pSampleLocations_ = nullptr ) - : shadingRate( shadingRate_ ) - , sampleCount( sampleCount_ ) - , sampleLocationCount( sampleLocationCount_ ) - , pSampleLocations( pSampleLocations_ ) + : shadingRate( shadingRate_ ) + , sampleCount( sampleCount_ ) + , sampleLocationCount( sampleLocationCount_ ) + , pSampleLocations( pSampleLocations_ ) {} CoarseSampleOrderCustomNV( VkCoarseSampleOrderCustomNV const & rhs ) @@ -24183,9 +24181,9 @@ namespace VULKAN_HPP_NAMESPACE SpecializationMapEntry( uint32_t constantID_ = 0, uint32_t offset_ = 0, size_t size_ = 0 ) - : constantID( constantID_ ) - , offset( offset_ ) - , size( size_ ) + : constantID( constantID_ ) + , offset( offset_ ) + , size( size_ ) {} SpecializationMapEntry( VkSpecializationMapEntry const & rhs ) @@ -24253,10 +24251,10 @@ namespace VULKAN_HPP_NAMESPACE const vk::SpecializationMapEntry* pMapEntries_ = nullptr, size_t dataSize_ = 0, const void* pData_ = nullptr ) - : mapEntryCount( mapEntryCount_ ) - , pMapEntries( pMapEntries_ ) - , dataSize( dataSize_ ) - , pData( pData_ ) + : mapEntryCount( mapEntryCount_ ) + , pMapEntries( pMapEntries_ ) + , dataSize( dataSize_ ) + , pData( pData_ ) {} SpecializationInfo( VkSpecializationInfo const & rhs ) @@ -24694,10 +24692,10 @@ namespace VULKAN_HPP_NAMESPACE uint8_t minor_ = 0, uint8_t subminor_ = 0, uint8_t patch_ = 0 ) - : major( major_ ) - , minor( minor_ ) - , subminor( subminor_ ) - , patch( patch_ ) + : major( major_ ) + , minor( minor_ ) + , subminor( subminor_ ) + , patch( patch_ ) {} ConformanceVersionKHR( VkConformanceVersionKHR const & rhs ) @@ -26545,9 +26543,9 @@ namespace VULKAN_HPP_NAMESPACE DescriptorBufferInfo( vk::Buffer buffer_ = vk::Buffer(), vk::DeviceSize offset_ = 0, vk::DeviceSize range_ = 0 ) - : buffer( buffer_ ) - , offset( offset_ ) - , range( range_ ) + : buffer( buffer_ ) + , offset( offset_ ) + , range( range_ ) {} DescriptorBufferInfo( VkDescriptorBufferInfo const & rhs ) @@ -26614,9 +26612,9 @@ namespace VULKAN_HPP_NAMESPACE DescriptorImageInfo( vk::Sampler sampler_ = vk::Sampler(), vk::ImageView imageView_ = vk::ImageView(), vk::ImageLayout imageLayout_ = vk::ImageLayout::eUndefined ) - : sampler( sampler_ ) - , imageView( imageView_ ) - , imageLayout( imageLayout_ ) + : sampler( sampler_ ) + , imageView( imageView_ ) + , imageLayout( imageLayout_ ) {} DescriptorImageInfo( VkDescriptorImageInfo const & rhs ) @@ -26682,8 +26680,8 @@ namespace VULKAN_HPP_NAMESPACE { DescriptorPoolSize( vk::DescriptorType type_ = vk::DescriptorType::eSampler, uint32_t descriptorCount_ = 0 ) - : type( type_ ) - , descriptorCount( descriptorCount_ ) + : type( type_ ) + , descriptorCount( descriptorCount_ ) {} DescriptorPoolSize( VkDescriptorPoolSize const & rhs ) @@ -27051,11 +27049,11 @@ namespace VULKAN_HPP_NAMESPACE uint32_t descriptorCount_ = 0, vk::ShaderStageFlags stageFlags_ = vk::ShaderStageFlags(), const vk::Sampler* pImmutableSamplers_ = nullptr ) - : binding( binding_ ) - , descriptorType( descriptorType_ ) - , descriptorCount( descriptorCount_ ) - , stageFlags( stageFlags_ ) - , pImmutableSamplers( pImmutableSamplers_ ) + : binding( binding_ ) + , descriptorType( descriptorType_ ) + , descriptorCount( descriptorCount_ ) + , stageFlags( stageFlags_ ) + , pImmutableSamplers( pImmutableSamplers_ ) {} DescriptorSetLayoutBinding( VkDescriptorSetLayoutBinding const & rhs ) @@ -27553,12 +27551,12 @@ namespace VULKAN_HPP_NAMESPACE vk::DescriptorType descriptorType_ = vk::DescriptorType::eSampler, size_t offset_ = 0, size_t stride_ = 0 ) - : dstBinding( dstBinding_ ) - , dstArrayElement( dstArrayElement_ ) - , descriptorCount( descriptorCount_ ) - , descriptorType( descriptorType_ ) - , offset( offset_ ) - , stride( stride_ ) + : dstBinding( dstBinding_ ) + , dstArrayElement( dstArrayElement_ ) + , descriptorCount( descriptorCount_ ) + , descriptorType( descriptorType_ ) + , offset( offset_ ) + , stride( stride_ ) {} DescriptorUpdateTemplateEntry( VkDescriptorUpdateTemplateEntry const & rhs ) @@ -27979,61 +27977,61 @@ namespace VULKAN_HPP_NAMESPACE vk::Bool32 sparseResidencyAliased_ = 0, vk::Bool32 variableMultisampleRate_ = 0, vk::Bool32 inheritedQueries_ = 0 ) - : robustBufferAccess( robustBufferAccess_ ) - , fullDrawIndexUint32( fullDrawIndexUint32_ ) - , imageCubeArray( imageCubeArray_ ) - , independentBlend( independentBlend_ ) - , geometryShader( geometryShader_ ) - , tessellationShader( tessellationShader_ ) - , sampleRateShading( sampleRateShading_ ) - , dualSrcBlend( dualSrcBlend_ ) - , logicOp( logicOp_ ) - , multiDrawIndirect( multiDrawIndirect_ ) - , drawIndirectFirstInstance( drawIndirectFirstInstance_ ) - , depthClamp( depthClamp_ ) - , depthBiasClamp( depthBiasClamp_ ) - , fillModeNonSolid( fillModeNonSolid_ ) - , depthBounds( depthBounds_ ) - , wideLines( wideLines_ ) - , largePoints( largePoints_ ) - , alphaToOne( alphaToOne_ ) - , multiViewport( multiViewport_ ) - , samplerAnisotropy( samplerAnisotropy_ ) - , textureCompressionETC2( textureCompressionETC2_ ) - , textureCompressionASTC_LDR( textureCompressionASTC_LDR_ ) - , textureCompressionBC( textureCompressionBC_ ) - , occlusionQueryPrecise( occlusionQueryPrecise_ ) - , pipelineStatisticsQuery( pipelineStatisticsQuery_ ) - , vertexPipelineStoresAndAtomics( vertexPipelineStoresAndAtomics_ ) - , fragmentStoresAndAtomics( fragmentStoresAndAtomics_ ) - , shaderTessellationAndGeometryPointSize( shaderTessellationAndGeometryPointSize_ ) - , shaderImageGatherExtended( shaderImageGatherExtended_ ) - , shaderStorageImageExtendedFormats( shaderStorageImageExtendedFormats_ ) - , shaderStorageImageMultisample( shaderStorageImageMultisample_ ) - , shaderStorageImageReadWithoutFormat( shaderStorageImageReadWithoutFormat_ ) - , shaderStorageImageWriteWithoutFormat( shaderStorageImageWriteWithoutFormat_ ) - , shaderUniformBufferArrayDynamicIndexing( shaderUniformBufferArrayDynamicIndexing_ ) - , shaderSampledImageArrayDynamicIndexing( shaderSampledImageArrayDynamicIndexing_ ) - , shaderStorageBufferArrayDynamicIndexing( shaderStorageBufferArrayDynamicIndexing_ ) - , shaderStorageImageArrayDynamicIndexing( shaderStorageImageArrayDynamicIndexing_ ) - , shaderClipDistance( shaderClipDistance_ ) - , shaderCullDistance( shaderCullDistance_ ) - , shaderFloat64( shaderFloat64_ ) - , shaderInt64( shaderInt64_ ) - , shaderInt16( shaderInt16_ ) - , shaderResourceResidency( shaderResourceResidency_ ) - , shaderResourceMinLod( shaderResourceMinLod_ ) - , sparseBinding( sparseBinding_ ) - , sparseResidencyBuffer( sparseResidencyBuffer_ ) - , sparseResidencyImage2D( sparseResidencyImage2D_ ) - , sparseResidencyImage3D( sparseResidencyImage3D_ ) - , sparseResidency2Samples( sparseResidency2Samples_ ) - , sparseResidency4Samples( sparseResidency4Samples_ ) - , sparseResidency8Samples( sparseResidency8Samples_ ) - , sparseResidency16Samples( sparseResidency16Samples_ ) - , sparseResidencyAliased( sparseResidencyAliased_ ) - , variableMultisampleRate( variableMultisampleRate_ ) - , inheritedQueries( inheritedQueries_ ) + : robustBufferAccess( robustBufferAccess_ ) + , fullDrawIndexUint32( fullDrawIndexUint32_ ) + , imageCubeArray( imageCubeArray_ ) + , independentBlend( independentBlend_ ) + , geometryShader( geometryShader_ ) + , tessellationShader( tessellationShader_ ) + , sampleRateShading( sampleRateShading_ ) + , dualSrcBlend( dualSrcBlend_ ) + , logicOp( logicOp_ ) + , multiDrawIndirect( multiDrawIndirect_ ) + , drawIndirectFirstInstance( drawIndirectFirstInstance_ ) + , depthClamp( depthClamp_ ) + , depthBiasClamp( depthBiasClamp_ ) + , fillModeNonSolid( fillModeNonSolid_ ) + , depthBounds( depthBounds_ ) + , wideLines( wideLines_ ) + , largePoints( largePoints_ ) + , alphaToOne( alphaToOne_ ) + , multiViewport( multiViewport_ ) + , samplerAnisotropy( samplerAnisotropy_ ) + , textureCompressionETC2( textureCompressionETC2_ ) + , textureCompressionASTC_LDR( textureCompressionASTC_LDR_ ) + , textureCompressionBC( textureCompressionBC_ ) + , occlusionQueryPrecise( occlusionQueryPrecise_ ) + , pipelineStatisticsQuery( pipelineStatisticsQuery_ ) + , vertexPipelineStoresAndAtomics( vertexPipelineStoresAndAtomics_ ) + , fragmentStoresAndAtomics( fragmentStoresAndAtomics_ ) + , shaderTessellationAndGeometryPointSize( shaderTessellationAndGeometryPointSize_ ) + , shaderImageGatherExtended( shaderImageGatherExtended_ ) + , shaderStorageImageExtendedFormats( shaderStorageImageExtendedFormats_ ) + , shaderStorageImageMultisample( shaderStorageImageMultisample_ ) + , shaderStorageImageReadWithoutFormat( shaderStorageImageReadWithoutFormat_ ) + , shaderStorageImageWriteWithoutFormat( shaderStorageImageWriteWithoutFormat_ ) + , shaderUniformBufferArrayDynamicIndexing( shaderUniformBufferArrayDynamicIndexing_ ) + , shaderSampledImageArrayDynamicIndexing( shaderSampledImageArrayDynamicIndexing_ ) + , shaderStorageBufferArrayDynamicIndexing( shaderStorageBufferArrayDynamicIndexing_ ) + , shaderStorageImageArrayDynamicIndexing( shaderStorageImageArrayDynamicIndexing_ ) + , shaderClipDistance( shaderClipDistance_ ) + , shaderCullDistance( shaderCullDistance_ ) + , shaderFloat64( shaderFloat64_ ) + , shaderInt64( shaderInt64_ ) + , shaderInt16( shaderInt16_ ) + , shaderResourceResidency( shaderResourceResidency_ ) + , shaderResourceMinLod( shaderResourceMinLod_ ) + , sparseBinding( sparseBinding_ ) + , sparseResidencyBuffer( sparseResidencyBuffer_ ) + , sparseResidencyImage2D( sparseResidencyImage2D_ ) + , sparseResidencyImage3D( sparseResidencyImage3D_ ) + , sparseResidency2Samples( sparseResidency2Samples_ ) + , sparseResidency4Samples( sparseResidency4Samples_ ) + , sparseResidency8Samples( sparseResidency8Samples_ ) + , sparseResidency16Samples( sparseResidency16Samples_ ) + , sparseResidencyAliased( sparseResidencyAliased_ ) + , variableMultisampleRate( variableMultisampleRate_ ) + , inheritedQueries( inheritedQueries_ ) {} PhysicalDeviceFeatures( VkPhysicalDeviceFeatures const & rhs ) @@ -30020,9 +30018,9 @@ namespace VULKAN_HPP_NAMESPACE DispatchIndirectCommand( uint32_t x_ = 0, uint32_t y_ = 0, uint32_t z_ = 0 ) - : x( x_ ) - , y( y_ ) - , z( z_ ) + : x( x_ ) + , y( y_ ) + , z( z_ ) {} DispatchIndirectCommand( VkDispatchIndirectCommand const & rhs ) @@ -30172,8 +30170,8 @@ namespace VULKAN_HPP_NAMESPACE { DisplayModeParametersKHR( vk::Extent2D visibleRegion_ = vk::Extent2D(), uint32_t refreshRate_ = 0 ) - : visibleRegion( visibleRegion_ ) - , refreshRate( refreshRate_ ) + : visibleRegion( visibleRegion_ ) + , refreshRate( refreshRate_ ) {} DisplayModeParametersKHR( VkDisplayModeParametersKHR const & rhs ) @@ -31209,11 +31207,11 @@ namespace VULKAN_HPP_NAMESPACE uint32_t firstIndex_ = 0, int32_t vertexOffset_ = 0, uint32_t firstInstance_ = 0 ) - : indexCount( indexCount_ ) - , instanceCount( instanceCount_ ) - , firstIndex( firstIndex_ ) - , vertexOffset( vertexOffset_ ) - , firstInstance( firstInstance_ ) + : indexCount( indexCount_ ) + , instanceCount( instanceCount_ ) + , firstIndex( firstIndex_ ) + , vertexOffset( vertexOffset_ ) + , firstInstance( firstInstance_ ) {} DrawIndexedIndirectCommand( VkDrawIndexedIndirectCommand const & rhs ) @@ -31297,10 +31295,10 @@ namespace VULKAN_HPP_NAMESPACE uint32_t instanceCount_ = 0, uint32_t firstVertex_ = 0, uint32_t firstInstance_ = 0 ) - : vertexCount( vertexCount_ ) - , instanceCount( instanceCount_ ) - , firstVertex( firstVertex_ ) - , firstInstance( firstInstance_ ) + : vertexCount( vertexCount_ ) + , instanceCount( instanceCount_ ) + , firstVertex( firstVertex_ ) + , firstInstance( firstInstance_ ) {} DrawIndirectCommand( VkDrawIndirectCommand const & rhs ) @@ -31374,8 +31372,8 @@ namespace VULKAN_HPP_NAMESPACE { DrawMeshTasksIndirectCommandNV( uint32_t taskCount_ = 0, uint32_t firstTask_ = 0 ) - : taskCount( taskCount_ ) - , firstTask( firstTask_ ) + : taskCount( taskCount_ ) + , firstTask( firstTask_ ) {} DrawMeshTasksIndirectCommandNV( VkDrawMeshTasksIndirectCommandNV const & rhs ) @@ -33986,9 +33984,9 @@ namespace VULKAN_HPP_NAMESPACE VertexInputBindingDescription( uint32_t binding_ = 0, uint32_t stride_ = 0, vk::VertexInputRate inputRate_ = vk::VertexInputRate::eVertex ) - : binding( binding_ ) - , stride( stride_ ) - , inputRate( inputRate_ ) + : binding( binding_ ) + , stride( stride_ ) + , inputRate( inputRate_ ) {} VertexInputBindingDescription( VkVertexInputBindingDescription const & rhs ) @@ -34056,10 +34054,10 @@ namespace VULKAN_HPP_NAMESPACE uint32_t binding_ = 0, vk::Format format_ = vk::Format::eUndefined, uint32_t offset_ = 0 ) - : location( location_ ) - , binding( binding_ ) - , format( format_ ) - , offset( offset_ ) + : location( location_ ) + , binding( binding_ ) + , format( format_ ) + , offset( offset_ ) {} VertexInputAttributeDescription( VkVertexInputAttributeDescription const & rhs ) @@ -34466,12 +34464,12 @@ namespace VULKAN_HPP_NAMESPACE float height_ = 0, float minDepth_ = 0, float maxDepth_ = 0 ) - : x( x_ ) - , y( y_ ) - , width( width_ ) - , height( height_ ) - , minDepth( minDepth_ ) - , maxDepth( maxDepth_ ) + : x( x_ ) + , y( y_ ) + , width( width_ ) + , height( height_ ) + , minDepth( minDepth_ ) + , maxDepth( maxDepth_ ) {} Viewport( VkViewport const & rhs ) @@ -35038,13 +35036,13 @@ namespace VULKAN_HPP_NAMESPACE uint32_t compareMask_ = 0, uint32_t writeMask_ = 0, uint32_t reference_ = 0 ) - : failOp( failOp_ ) - , passOp( passOp_ ) - , depthFailOp( depthFailOp_ ) - , compareOp( compareOp_ ) - , compareMask( compareMask_ ) - , writeMask( writeMask_ ) - , reference( reference_ ) + : failOp( failOp_ ) + , passOp( passOp_ ) + , depthFailOp( depthFailOp_ ) + , compareOp( compareOp_ ) + , compareMask( compareMask_ ) + , writeMask( writeMask_ ) + , reference( reference_ ) {} StencilOpState( VkStencilOpState const & rhs ) @@ -35331,14 +35329,14 @@ namespace VULKAN_HPP_NAMESPACE vk::BlendFactor dstAlphaBlendFactor_ = vk::BlendFactor::eZero, vk::BlendOp alphaBlendOp_ = vk::BlendOp::eAdd, vk::ColorComponentFlags colorWriteMask_ = vk::ColorComponentFlags() ) - : blendEnable( blendEnable_ ) - , srcColorBlendFactor( srcColorBlendFactor_ ) - , dstColorBlendFactor( dstColorBlendFactor_ ) - , colorBlendOp( colorBlendOp_ ) - , srcAlphaBlendFactor( srcAlphaBlendFactor_ ) - , dstAlphaBlendFactor( dstAlphaBlendFactor_ ) - , alphaBlendOp( alphaBlendOp_ ) - , colorWriteMask( colorWriteMask_ ) + : blendEnable( blendEnable_ ) + , srcColorBlendFactor( srcColorBlendFactor_ ) + , dstColorBlendFactor( dstColorBlendFactor_ ) + , colorBlendOp( colorBlendOp_ ) + , srcAlphaBlendFactor( srcAlphaBlendFactor_ ) + , dstAlphaBlendFactor( dstAlphaBlendFactor_ ) + , alphaBlendOp( alphaBlendOp_ ) + , colorWriteMask( colorWriteMask_ ) {} PipelineColorBlendAttachmentState( VkPipelineColorBlendAttachmentState const & rhs ) @@ -35951,8 +35949,8 @@ namespace VULKAN_HPP_NAMESPACE { XYColorEXT( float x_ = 0, float y_ = 0 ) - : x( x_ ) - , y( y_ ) + : x( x_ ) + , y( y_ ) {} XYColorEXT( VkXYColorEXT const & rhs ) @@ -36355,11 +36353,11 @@ namespace VULKAN_HPP_NAMESPACE std::array const& srcOffsets_ = { { vk::Offset3D() } }, vk::ImageSubresourceLayers dstSubresource_ = vk::ImageSubresourceLayers(), std::array const& dstOffsets_ = { { vk::Offset3D() } } ) - : srcSubresource( srcSubresource_ ) - , dstSubresource( dstSubresource_ ) + : srcSubresource( srcSubresource_ ) + , dstSubresource( dstSubresource_ ) { - memcpy( &srcOffsets, srcOffsets_.data(), 2 * sizeof( vk::Offset3D ) ); - memcpy( &dstOffsets, dstOffsets_.data(), 2 * sizeof( vk::Offset3D ) ); + memcpy( &srcOffsets, srcOffsets_.data(), 2 * sizeof( vk::Offset3D ) ); + memcpy( &dstOffsets, dstOffsets_.data(), 2 * sizeof( vk::Offset3D ) ); } @@ -36437,11 +36435,11 @@ namespace VULKAN_HPP_NAMESPACE vk::ImageSubresourceLayers dstSubresource_ = vk::ImageSubresourceLayers(), vk::Offset3D dstOffset_ = vk::Offset3D(), vk::Extent3D extent_ = vk::Extent3D() ) - : srcSubresource( srcSubresource_ ) - , srcOffset( srcOffset_ ) - , dstSubresource( dstSubresource_ ) - , dstOffset( dstOffset_ ) - , extent( extent_ ) + : srcSubresource( srcSubresource_ ) + , srcOffset( srcOffset_ ) + , dstSubresource( dstSubresource_ ) + , dstOffset( dstOffset_ ) + , extent( extent_ ) {} ImageCopy( VkImageCopy const & rhs ) @@ -37190,11 +37188,11 @@ namespace VULKAN_HPP_NAMESPACE uint32_t levelCount_ = 0, uint32_t baseArrayLayer_ = 0, uint32_t layerCount_ = 0 ) - : aspectMask( aspectMask_ ) - , baseMipLevel( baseMipLevel_ ) - , levelCount( levelCount_ ) - , baseArrayLayer( baseArrayLayer_ ) - , layerCount( layerCount_ ) + : aspectMask( aspectMask_ ) + , baseMipLevel( baseMipLevel_ ) + , levelCount( levelCount_ ) + , baseArrayLayer( baseArrayLayer_ ) + , layerCount( layerCount_ ) {} ImageSubresourceRange( VkImageSubresourceRange const & rhs ) @@ -37706,11 +37704,11 @@ namespace VULKAN_HPP_NAMESPACE vk::ImageSubresourceLayers dstSubresource_ = vk::ImageSubresourceLayers(), vk::Offset3D dstOffset_ = vk::Offset3D(), vk::Extent3D extent_ = vk::Extent3D() ) - : srcSubresource( srcSubresource_ ) - , srcOffset( srcOffset_ ) - , dstSubresource( dstSubresource_ ) - , dstOffset( dstOffset_ ) - , extent( extent_ ) + : srcSubresource( srcSubresource_ ) + , srcOffset( srcOffset_ ) + , dstSubresource( dstSubresource_ ) + , dstOffset( dstOffset_ ) + , extent( extent_ ) {} ImageResolve( VkImageResolve const & rhs ) @@ -39439,10 +39437,10 @@ namespace VULKAN_HPP_NAMESPACE uint32_t bindingUnit_ = 0, uint32_t dynamicCount_ = 0, uint32_t divisor_ = 0 ) - : tokenType( tokenType_ ) - , bindingUnit( bindingUnit_ ) - , dynamicCount( dynamicCount_ ) - , divisor( divisor_ ) + : tokenType( tokenType_ ) + , bindingUnit( bindingUnit_ ) + , dynamicCount( dynamicCount_ ) + , divisor( divisor_ ) {} IndirectCommandsLayoutTokenNVX( VkIndirectCommandsLayoutTokenNVX const & rhs ) @@ -39718,9 +39716,9 @@ namespace VULKAN_HPP_NAMESPACE InputAttachmentAspectReference( uint32_t subpass_ = 0, uint32_t inputAttachmentIndex_ = 0, vk::ImageAspectFlags aspectMask_ = vk::ImageAspectFlags() ) - : subpass( subpass_ ) - , inputAttachmentIndex( inputAttachmentIndex_ ) - , aspectMask( aspectMask_ ) + : subpass( subpass_ ) + , inputAttachmentIndex( inputAttachmentIndex_ ) + , aspectMask( aspectMask_ ) {} InputAttachmentAspectReference( VkInputAttachmentAspectReference const & rhs ) @@ -41624,8 +41622,8 @@ namespace VULKAN_HPP_NAMESPACE { ObjectTableEntryNVX( vk::ObjectEntryTypeNVX type_ = vk::ObjectEntryTypeNVX::eDescriptorSet, vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX() ) - : type( type_ ) - , flags( flags_ ) + : type( type_ ) + , flags( flags_ ) {} ObjectTableEntryNVX( VkObjectTableEntryNVX const & rhs ) @@ -41685,10 +41683,10 @@ namespace VULKAN_HPP_NAMESPACE vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX(), vk::PipelineLayout pipelineLayout_ = vk::PipelineLayout(), vk::DescriptorSet descriptorSet_ = vk::DescriptorSet() ) - : type( type_ ) - , flags( flags_ ) - , pipelineLayout( pipelineLayout_ ) - , descriptorSet( descriptorSet_ ) + : type( type_ ) + , flags( flags_ ) + , pipelineLayout( pipelineLayout_ ) + , descriptorSet( descriptorSet_ ) {} explicit ObjectTableDescriptorSetEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, @@ -41698,7 +41696,6 @@ namespace VULKAN_HPP_NAMESPACE , flags( objectTableEntryNVX.flags ) , pipelineLayout( pipelineLayout_ ) , descriptorSet( descriptorSet_ ) - {} ObjectTableDescriptorSetEntryNVX( VkObjectTableDescriptorSetEntryNVX const & rhs ) @@ -41774,10 +41771,10 @@ namespace VULKAN_HPP_NAMESPACE vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX(), vk::Buffer buffer_ = vk::Buffer(), vk::IndexType indexType_ = vk::IndexType::eUint16 ) - : type( type_ ) - , flags( flags_ ) - , buffer( buffer_ ) - , indexType( indexType_ ) + : type( type_ ) + , flags( flags_ ) + , buffer( buffer_ ) + , indexType( indexType_ ) {} explicit ObjectTableIndexBufferEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, @@ -41787,7 +41784,6 @@ namespace VULKAN_HPP_NAMESPACE , flags( objectTableEntryNVX.flags ) , buffer( buffer_ ) , indexType( indexType_ ) - {} ObjectTableIndexBufferEntryNVX( VkObjectTableIndexBufferEntryNVX const & rhs ) @@ -41862,9 +41858,9 @@ namespace VULKAN_HPP_NAMESPACE ObjectTablePipelineEntryNVX( vk::ObjectEntryTypeNVX type_ = vk::ObjectEntryTypeNVX::eDescriptorSet, vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX(), vk::Pipeline pipeline_ = vk::Pipeline() ) - : type( type_ ) - , flags( flags_ ) - , pipeline( pipeline_ ) + : type( type_ ) + , flags( flags_ ) + , pipeline( pipeline_ ) {} explicit ObjectTablePipelineEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, @@ -41872,7 +41868,6 @@ namespace VULKAN_HPP_NAMESPACE : type( objectTableEntryNVX.type ) , flags( objectTableEntryNVX.flags ) , pipeline( pipeline_ ) - {} ObjectTablePipelineEntryNVX( VkObjectTablePipelineEntryNVX const & rhs ) @@ -41940,10 +41935,10 @@ namespace VULKAN_HPP_NAMESPACE vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX(), vk::PipelineLayout pipelineLayout_ = vk::PipelineLayout(), vk::ShaderStageFlags stageFlags_ = vk::ShaderStageFlags() ) - : type( type_ ) - , flags( flags_ ) - , pipelineLayout( pipelineLayout_ ) - , stageFlags( stageFlags_ ) + : type( type_ ) + , flags( flags_ ) + , pipelineLayout( pipelineLayout_ ) + , stageFlags( stageFlags_ ) {} explicit ObjectTablePushConstantEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, @@ -41953,7 +41948,6 @@ namespace VULKAN_HPP_NAMESPACE , flags( objectTableEntryNVX.flags ) , pipelineLayout( pipelineLayout_ ) , stageFlags( stageFlags_ ) - {} ObjectTablePushConstantEntryNVX( VkObjectTablePushConstantEntryNVX const & rhs ) @@ -42028,9 +42022,9 @@ namespace VULKAN_HPP_NAMESPACE ObjectTableVertexBufferEntryNVX( vk::ObjectEntryTypeNVX type_ = vk::ObjectEntryTypeNVX::eDescriptorSet, vk::ObjectEntryUsageFlagsNVX flags_ = vk::ObjectEntryUsageFlagsNVX(), vk::Buffer buffer_ = vk::Buffer() ) - : type( type_ ) - , flags( flags_ ) - , buffer( buffer_ ) + : type( type_ ) + , flags( flags_ ) + , buffer( buffer_ ) {} explicit ObjectTableVertexBufferEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, @@ -42038,7 +42032,6 @@ namespace VULKAN_HPP_NAMESPACE : type( objectTableEntryNVX.type ) , flags( objectTableEntryNVX.flags ) , buffer( buffer_ ) - {} ObjectTableVertexBufferEntryNVX( VkObjectTableVertexBufferEntryNVX const & rhs ) @@ -42574,8 +42567,8 @@ namespace VULKAN_HPP_NAMESPACE { PerformanceValueINTEL( vk::PerformanceValueTypeINTEL type_ = vk::PerformanceValueTypeINTEL::eUint32, vk::PerformanceValueDataINTEL data_ = vk::PerformanceValueDataINTEL() ) - : type( type_ ) - , data( data_ ) + : type( type_ ) + , data( data_ ) {} PerformanceValueINTEL( VkPerformanceValueINTEL const & rhs ) @@ -52462,9 +52455,9 @@ namespace VULKAN_HPP_NAMESPACE PushConstantRange( vk::ShaderStageFlags stageFlags_ = vk::ShaderStageFlags(), uint32_t offset_ = 0, uint32_t size_ = 0 ) - : stageFlags( stageFlags_ ) - , offset( offset_ ) - , size( size_ ) + : stageFlags( stageFlags_ ) + , offset( offset_ ) + , size( size_ ) {} PushConstantRange( VkPushConstantRange const & rhs ) @@ -53476,8 +53469,8 @@ namespace VULKAN_HPP_NAMESPACE { VertexInputBindingDivisorDescriptionEXT( uint32_t binding_ = 0, uint32_t divisor_ = 0 ) - : binding( binding_ ) - , divisor( divisor_ ) + : binding( binding_ ) + , divisor( divisor_ ) {} VertexInputBindingDivisorDescriptionEXT( VkVertexInputBindingDivisorDescriptionEXT const & rhs ) @@ -53831,8 +53824,8 @@ namespace VULKAN_HPP_NAMESPACE { ShadingRatePaletteNV( uint32_t shadingRatePaletteEntryCount_ = 0, const vk::ShadingRatePaletteEntryNV* pShadingRatePaletteEntries_ = nullptr ) - : shadingRatePaletteEntryCount( shadingRatePaletteEntryCount_ ) - , pShadingRatePaletteEntries( pShadingRatePaletteEntries_ ) + : shadingRatePaletteEntryCount( shadingRatePaletteEntryCount_ ) + , pShadingRatePaletteEntries( pShadingRatePaletteEntries_ ) {} ShadingRatePaletteNV( VkShadingRatePaletteNV const & rhs ) @@ -53998,10 +53991,10 @@ namespace VULKAN_HPP_NAMESPACE vk::ViewportCoordinateSwizzleNV y_ = vk::ViewportCoordinateSwizzleNV::ePositiveX, vk::ViewportCoordinateSwizzleNV z_ = vk::ViewportCoordinateSwizzleNV::ePositiveX, vk::ViewportCoordinateSwizzleNV w_ = vk::ViewportCoordinateSwizzleNV::ePositiveX ) - : x( x_ ) - , y( y_ ) - , z( z_ ) - , w( w_ ) + : x( x_ ) + , y( y_ ) + , z( z_ ) + , w( w_ ) {} ViewportSwizzleNV( VkViewportSwizzleNV const & rhs ) @@ -54181,8 +54174,8 @@ namespace VULKAN_HPP_NAMESPACE { ViewportWScalingNV( float xcoeff_ = 0, float ycoeff_ = 0 ) - : xcoeff( xcoeff_ ) - , ycoeff( ycoeff_ ) + : xcoeff( xcoeff_ ) + , ycoeff( ycoeff_ ) {} ViewportWScalingNV( VkViewportWScalingNV const & rhs ) @@ -54573,9 +54566,9 @@ namespace VULKAN_HPP_NAMESPACE RectLayerKHR( vk::Offset2D offset_ = vk::Offset2D(), vk::Extent2D extent_ = vk::Extent2D(), uint32_t layer_ = 0 ) - : offset( offset_ ) - , extent( extent_ ) - , layer( layer_ ) + : offset( offset_ ) + , extent( extent_ ) + , layer( layer_ ) {} explicit RectLayerKHR( Rect2D const& rect2D, @@ -54583,7 +54576,6 @@ namespace VULKAN_HPP_NAMESPACE : offset( rect2D.offset ) , extent( rect2D.extent ) , layer( layer_ ) - {} RectLayerKHR( VkRectLayerKHR const & rhs ) @@ -54649,8 +54641,8 @@ namespace VULKAN_HPP_NAMESPACE { PresentRegionKHR( uint32_t rectangleCount_ = 0, const vk::RectLayerKHR* pRectangles_ = nullptr ) - : rectangleCount( rectangleCount_ ) - , pRectangles( pRectangles_ ) + : rectangleCount( rectangleCount_ ) + , pRectangles( pRectangles_ ) {} PresentRegionKHR( VkPresentRegionKHR const & rhs ) @@ -54803,8 +54795,8 @@ namespace VULKAN_HPP_NAMESPACE { PresentTimeGOOGLE( uint32_t presentID_ = 0, uint64_t desiredPresentTime_ = 0 ) - : presentID( presentID_ ) - , desiredPresentTime( desiredPresentTime_ ) + : presentID( presentID_ ) + , desiredPresentTime( desiredPresentTime_ ) {} PresentTimeGOOGLE( VkPresentTimeGOOGLE const & rhs ) @@ -55951,16 +55943,16 @@ namespace VULKAN_HPP_NAMESPACE const vk::AttachmentReference* pDepthStencilAttachment_ = nullptr, uint32_t preserveAttachmentCount_ = 0, const uint32_t* pPreserveAttachments_ = nullptr ) - : flags( flags_ ) - , pipelineBindPoint( pipelineBindPoint_ ) - , inputAttachmentCount( inputAttachmentCount_ ) - , pInputAttachments( pInputAttachments_ ) - , colorAttachmentCount( colorAttachmentCount_ ) - , pColorAttachments( pColorAttachments_ ) - , pResolveAttachments( pResolveAttachments_ ) - , pDepthStencilAttachment( pDepthStencilAttachment_ ) - , preserveAttachmentCount( preserveAttachmentCount_ ) - , pPreserveAttachments( pPreserveAttachments_ ) + : flags( flags_ ) + , pipelineBindPoint( pipelineBindPoint_ ) + , inputAttachmentCount( inputAttachmentCount_ ) + , pInputAttachments( pInputAttachments_ ) + , colorAttachmentCount( colorAttachmentCount_ ) + , pColorAttachments( pColorAttachments_ ) + , pResolveAttachments( pResolveAttachments_ ) + , pDepthStencilAttachment( pDepthStencilAttachment_ ) + , preserveAttachmentCount( preserveAttachmentCount_ ) + , pPreserveAttachments( pPreserveAttachments_ ) {} SubpassDescription( VkSubpassDescription const & rhs ) @@ -56087,13 +56079,13 @@ namespace VULKAN_HPP_NAMESPACE vk::AccessFlags srcAccessMask_ = vk::AccessFlags(), vk::AccessFlags dstAccessMask_ = vk::AccessFlags(), vk::DependencyFlags dependencyFlags_ = vk::DependencyFlags() ) - : srcSubpass( srcSubpass_ ) - , dstSubpass( dstSubpass_ ) - , srcStageMask( srcStageMask_ ) - , dstStageMask( dstStageMask_ ) - , srcAccessMask( srcAccessMask_ ) - , dstAccessMask( dstAccessMask_ ) - , dependencyFlags( dependencyFlags_ ) + : srcSubpass( srcSubpass_ ) + , dstSubpass( dstSubpass_ ) + , srcStageMask( srcStageMask_ ) + , dstStageMask( dstStageMask_ ) + , srcAccessMask( srcAccessMask_ ) + , dstAccessMask( dstAccessMask_ ) + , dependencyFlags( dependencyFlags_ ) {} SubpassDependency( VkSubpassDependency const & rhs ) @@ -57186,8 +57178,8 @@ namespace VULKAN_HPP_NAMESPACE { SubpassSampleLocationsEXT( uint32_t subpassIndex_ = 0, vk::SampleLocationsInfoEXT sampleLocationsInfo_ = vk::SampleLocationsInfoEXT() ) - : subpassIndex( subpassIndex_ ) - , sampleLocationsInfo( sampleLocationsInfo_ ) + : subpassIndex( subpassIndex_ ) + , sampleLocationsInfo( sampleLocationsInfo_ ) {} SubpassSampleLocationsEXT( VkSubpassSampleLocationsEXT const & rhs )