From b81f8ec376047f488b90182a7f291a2664fe6779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 17 May 2016 13:16:34 +0200 Subject: [PATCH] Introduced define VK_CPP_NO_EXCEPTIONS, to support calling vk-functions without throwing exceptions on error conditions. Now, depending on that define, some functions can return a struct containing the vk::Result and some generated value. --- README.md | 21 +- VkCppGenerator.cpp | 5959 ++++++++++++++++++++++---------------------- vulkan/vk_cpp.hpp | 680 ++--- 3 files changed, 3308 insertions(+), 3352 deletions(-) diff --git a/README.md b/README.md index 646b2d7..5216bc9 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,6 @@ parameter matches the handle. In addition to this we made a few changes to the s * ```const T *``` has been replaced by ```const T &``` to allow temporary objects. This is useful to pass small structures like ```vk::ClearColorValue``` or ```vk::Extent*``` ```commandBuffer.clearColorImage(image, layout, std::array{1.0f, 1.0f, 1.0f, 1.0f}, {...});``` Optional parameters are being replaced by ```Optional``` which accept a type of ```const T```, ```T```, or ```const std::string```. ```nullptr``` can be used to initialize an empty ```Optional```. -* The wrapper will throw a ```std::system_error``` if a ```vk::Result``` return value is not an success code. If there's only a single success code it's not returned at all. In this case functions with a single output value do return this output value instead. Here are a few code examples: ```c++ @@ -176,7 +175,25 @@ Here are a few code examples: std::cerr << "Vulkan failure: " << e.what() << std::endl; } ``` - +# Exceptions and return types +The wrapper functions will throw a ```std::system_error``` if the result of the wrapped function is not a success code. +By defining ```VK_CPP_NO_EXCEPTIONS``` before include vk_cpp.hpp, this can be disabled. +Depending on exceptions being enabled or disabled, the return type of some functions change. + +With exceptions enabled (the default) there are four different cases on the return types: +* Just one possible success code +* * no output value -> return type is ```void``` +* * one output value -> return type is T, which is the type of the output value +* Multiple possible success codes +* * no output value -> return type is ```vk::Result``` +* * one output value -> return type is a structure ```vk::ResultValue``` with a member ```result``` of type ```vk::Result``` holding the actual result code, and a member ```value``` of type T, which is the type of the output value, holding that output value. + +With exceptions disabled, the return type of those wrapper functions where the wrapped function has just one possible success code is different: +* no output value -> return type is ```vk::Result``` +* one output value -> return type is ```vk::ResultValue```, as described above. + +Note: With exceptions disabled, it is the user's responsibility to check for errors! + # Usage To start with the C++ version of the Vulkan API download header from GIT, put it in a vulkan subdirectory and add ```#include ``` to your source code. diff --git a/VkCppGenerator.cpp b/VkCppGenerator.cpp index e7612ff..55f8ad9 100644 --- a/VkCppGenerator.cpp +++ b/VkCppGenerator.cpp @@ -1,2911 +1,3048 @@ -// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -const std::string nvidiaLicenseHeader( -"// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved.\n" -"//\n" -"// Redistribution and use in source and binary forms, with or without\n" -"// modification, are permitted provided that the following conditions\n" -"// are met:\n" -"// * Redistributions of source code must retain the above copyright\n" -"// notice, this list of conditions and the following disclaimer.\n" -"// * Redistributions in binary form must reproduce the above copyright\n" -"// notice, this list of conditions and the following disclaimer in the\n" -"// documentation and/or other materials provided with the distribution.\n" -"// * Neither the name of NVIDIA CORPORATION nor the names of its\n" -"// contributors may be used to endorse or promote products derived\n" -"// from this software without specific prior written permission.\n" -"//\n" -"// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY\n" -"// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" -"// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n" -"// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n" -"// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n" -"// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n" -"// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n" -"// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n" -"// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" -"// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" -"// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" -); - -const std::string exceptionHeader( - "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" - "# define noexcept _NOEXCEPT\n" - "#endif\n" - "\n" - " class ErrorCategoryImpl : public std::error_category\n" - " {\n" - " public:\n" - " virtual const char* name() const noexcept override { return \"vk::Result\"; }\n" - " virtual std::string message(int ev) const override { return to_string(static_cast(ev)); }\n" - " };\n" - "\n" - "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" - "# undef noexcept\n" - "#endif\n" - "\n" - " inline const std::error_category& errorCategory()\n" - " {\n" - " static ErrorCategoryImpl instance;\n" - " return instance;\n" - " }\n" - "\n" - " inline std::error_code make_error_code(Result e)\n" - " {\n" - " return std::error_code(static_cast(e), errorCategory());\n" - " }\n" - "\n" - " inline std::error_condition make_error_condition(Result e)\n" - " {\n" - " return std::error_condition(static_cast(e), errorCategory());\n" - " }\n" - "\n" - ); - -const std::string flagsHeader( -" template \n" -" class Flags\n" -" {\n" -" public:\n" -" Flags()\n" -" : m_mask(0)\n" -" {\n" -" }\n" -"\n" -" Flags(BitType bit)\n" -" : m_mask(static_cast(bit))\n" -" {\n" -" }\n" -"\n" -" Flags(Flags const& rhs)\n" -" : m_mask(rhs.m_mask)\n" -" {\n" -" }\n" -"\n" -" Flags & operator=(Flags const& rhs)\n" -" {\n" -" m_mask = rhs.m_mask;\n" -" return *this;\n" -" }\n" -"\n" -" Flags & operator|=(Flags const& rhs)\n" -" {\n" -" m_mask |= rhs.m_mask;\n" -" return *this;\n" -" }\n" -"\n" -" Flags & operator&=(Flags const& rhs)\n" -" {\n" -" m_mask &= rhs.m_mask;\n" -" return *this;\n" -" }\n" -"\n" -" Flags & operator^=(Flags const& rhs)\n" -" {\n" -" m_mask ^= rhs.m_mask;\n" -" return *this;\n" -" }\n" -"\n" -" Flags operator|(Flags const& rhs) const\n" -" {\n" -" Flags result(*this);\n" -" result |= rhs;\n" -" return result;\n" -" }\n" -"\n" -" Flags operator&(Flags const& rhs) const\n" -" {\n" -" Flags result(*this);\n" -" result &= rhs;\n" -" return result;\n" -" }\n" -"\n" -" Flags operator^(Flags const& rhs) const\n" -" {\n" -" Flags result(*this);\n" -" result ^= rhs;\n" -" return result;\n" -" }\n" -"\n" -" bool operator!() const\n" -" {\n" -" return !m_mask;\n" -" }\n" -"\n" -" bool operator==(Flags const& rhs) const\n" -" {\n" -" return m_mask == rhs.m_mask;\n" -" }\n" -"\n" -" bool operator!=(Flags const& rhs) const\n" -" {\n" -" return m_mask != rhs.m_mask;\n" -" }\n" -"\n" -" explicit operator bool() const\n" -" {\n" -" return !!m_mask;\n" -" }\n" -"\n" -" explicit operator MaskType() const\n" -" {\n" -" return m_mask;\n" -" }\n" -"\n" -" private:\n" -" MaskType m_mask;\n" -" };\n" -" \n" -" template \n" -" Flags operator|(BitType bit, Flags const& flags)\n" -" {\n" -" return flags | bit;\n" -" }\n" -" \n" -" template \n" -" Flags operator&(BitType bit, Flags const& flags)\n" -" {\n" -" return flags & bit;\n" -" }\n" -" \n" -" template \n" -" Flags operator^(BitType bit, Flags const& flags)\n" -" {\n" -" return flags ^ bit;\n" -" }\n" -"\n" -); - -std::string const optionalClassHeader = ( - " template \n" - " class Optional\n" - " {\n" - " public:\n" - " Optional(RefType & reference) { m_ptr = &reference; }\n" - " Optional(std::nullptr_t) { m_ptr = nullptr; }\n" - "\n" - " operator RefType*() const { return m_ptr; }\n" - " RefType const* operator->() const { return m_ptr; }\n" - " explicit operator bool() const { return !!m_ptr; }\n" - "\n" - " private:\n" - " RefType *m_ptr;\n" - " };\n" - "\n" -); - -std::string const arrayProxyHeader = ( - " template \n" - " class ArrayProxy\n" - " {\n" - " public:\n" - " ArrayProxy(std::nullptr_t)\n" - " : m_count(0)\n" - " , m_ptr(nullptr)\n" - " {}\n" - "\n" - " ArrayProxy(T & ptr)\n" - " : m_count(1)\n" - " , m_ptr(&ptr)\n" - " {}\n" - "\n" - " ArrayProxy(uint32_t count, T * ptr)\n" - " : m_count(count)\n" - " , m_ptr(ptr)\n" - " {}\n" - "\n" - " template \n" - " ArrayProxy(std::array::type, N> & data)\n" - " : m_count(N)\n" - " , m_ptr(data.data())\n" - " {}\n" - "\n" - " template \n" - " ArrayProxy(std::array::type, N> const& data)\n" - " : m_count(N)\n" - " , m_ptr(data.data())\n" - " {}\n" - "\n" - " template ::type>>\n" - " ArrayProxy(std::vector::type, Allocator> & data)\n" - " : m_count(static_cast(data.size()))\n" - " , m_ptr(data.data())\n" - " {}\n" - "\n" - " template ::type>>\n" - " ArrayProxy(std::vector::type, Allocator> const& data)\n" - " : m_count(static_cast(data.size()))\n" - " , m_ptr(data.data())\n" - " {}\n" - "\n" - " ArrayProxy(std::initializer_list const& data)\n" - " : m_count(static_cast(data.end() - data.begin()))\n" - " , m_ptr(data.begin())\n" - " {}\n" - "\n" - " uint32_t size() const\n" - " {\n" - " return m_count;\n" - " }\n" - "\n" - " T * data() const\n" - " {\n" - " return m_ptr;\n" - " }\n" - "\n" - " private:\n" - " uint32_t m_count;\n" - " T * m_ptr;\n" - " };\n" - "\n" -); - -std::string const versionCheckHeader = ( - "#if !defined(VK_CPP_HAS_UNRESTRICTED_UNIONS)\n" - "# if defined(__clang__)\n" - "# if __has_feature(cxx_unrestricted_unions)\n" - "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" - "# endif\n" - "# elif defined(__GNUC__)\n" - "# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)\n" - "# if 40600 <= GCC_VERSION\n" - "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" - "# endif\n" - "# elif defined(_MSC_VER)\n" - "# if 1900 <= _MSC_VER\n" - "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" - "# endif\n" - "# endif\n" - "#endif\n" - "\n" - ); - -// trim from end -std::string trimEnd(std::string const& input) -{ - std::string result = input; - result.erase(std::find_if(result.rbegin(), result.rend(), std::not1(std::ptr_fun(std::isspace))).base(), result.end()); - return result; -} - -struct MemberData -{ - std::string type; - std::string name; - std::string arraySize; - std::string pureType; - std::string len; - bool optional; -}; - -struct CommandData -{ - CommandData() - : handleCommand(false) - , twoStep(false) - {} - - std::string returnType; - std::vector arguments; - std::vector successCodes; - std::string protect; - bool handleCommand; - bool twoStep; -}; - -struct DependencyData -{ - enum class Category - { - COMMAND, - ENUM, - FLAGS, - FUNC_POINTER, - HANDLE, - REQUIRED, - SCALAR, - STRUCT, - UNION - }; - - DependencyData(Category c, std::string const& n) - : category(c) - , name(n) - {} - - Category category; - std::string name; - std::set dependencies; -}; - -struct NameValue -{ - std::string name; - std::string value; -}; - -struct EnumData -{ - bool bitmask; - std::string prefix; - std::string postfix; - std::vector members; - std::string protect; - - void addEnum(std::string const & name, std::string const& tag, bool appendTag); -}; - -struct FlagData -{ - std::string protect; -}; - -struct HandleData -{ - std::vector commands; -}; - -struct ScalarData -{ - std::string protect; -}; - -struct StructData -{ - StructData() - : returnedOnly(false) - {} - - bool returnedOnly; - std::vector members; - std::string protect; -}; - -struct VkData -{ - std::map commands; - std::list dependencies; - std::map enums; - std::map flags; - std::map handles; - std::map scalars; - std::map structs; - std::set tags; - std::string typesafeCheck; - std::string version; - std::set vkTypes; - std::string vulkanLicenseHeader; -}; - -void createDefaults( VkData const& vkData, std::map & defaultValues ); -std::string determineFunctionName(std::string const& name, CommandData const& commandData); -std::string determineReturnType(CommandData const& commandData, size_t returnIndex, bool isVector = false); -void enterProtect(std::ofstream &ofs, std::string const& protect); -std::string extractTag(std::string const& name); -size_t findReturnIndex(CommandData const& commandData, std::map const& vectorParameters); -std::string findTag(std::string const& name, std::set const& tags); -size_t findTemplateIndex(CommandData const& commandData, std::map const& vectorParameters); -std::string generateEnumNameForFlags(std::string const& name); -std::map getVectorParameters(CommandData const& commandData); -bool hasPointerArguments(CommandData const& commandData); -bool isVectorSizeParameter(std::map const& vectorParameters, size_t idx); -void leaveProtect(std::ofstream &ofs, std::string const& protect); -bool noDependencies(std::set const& dependencies, std::map & listedTypes); -bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ); -std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData); -void readCommands( tinyxml2::XMLElement * element, VkData & vkData ); -void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData); -void readComment(tinyxml2::XMLElement * element, std::string & header); -void readEnums( tinyxml2::XMLElement * element, VkData & vkData ); -void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::string const& tag ); -void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag); -void readExtensions( tinyxml2::XMLElement * element, VkData & vkData ); -void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData); -void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ); -void readTypeBitmask( tinyxml2::XMLElement * element, VkData & vkData); -void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ); -void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ); -void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData); -void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ); -void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); -void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ); -void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); -void readTags(tinyxml2::XMLElement * element, std::set & tags); -void readTypes(tinyxml2::XMLElement * element, VkData & vkData); -void sortDependencies( std::list & dependencies ); -std::string reduceName(std::string const& name); -std::string strip(std::string const& value, std::string const& prefix, std::string const& tag = std::string()); -std::string stripCommand(std::string const& value); -std::string toCamelCase(std::string const& value); -std::string toUpperCase(std::string const& name); -void writeCall(std::ofstream & ofs, std::string const& name, size_t templateIndex, CommandData const& commandData, std::set const& vkTypes, std::map const& vectorParameters, size_t returnIndex, bool firstCall); -void writeEnumsToString(std::ofstream & ofs, VkData const& vkData); -void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::vector const& successCodes); -void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes, size_t returnIndex, std::map const& vectorParameters); -void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map const& vectorParameters); -void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set const& vkTypes); -void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set const& vkTypes, std::map const& defaultValues ); -void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::set const& vkTypes, std::map const& structs ); -void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes ); -void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes); -void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes); -void writeTypeEnum(std::ofstream & ofs, DependencyData const& dependencyData, EnumData const& enumData); -void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, FlagData const& flagData ); -void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies); -void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ); -void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ); -void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ); -void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues); -void writeVersionCheck(std::ofstream & ofs, std::string const& version); -void writeTypesafeCheck(std::ofstream & ofs, std::string const& typesafeCheck); - -void EnumData::addEnum(std::string const & name, std::string const& tag, bool appendTag) -{ - assert(tag.empty() || (name.find(tag) != std::string::npos)); - members.push_back(NameValue()); - members.back().name = "e" + toCamelCase(strip(name, prefix, tag)); - members.back().value = name; - if (!postfix.empty()) - { - size_t pos = members.back().name.find(postfix); - if (pos != std::string::npos) - { - members.back().name.erase(pos); - } - } - if (appendTag && !tag.empty()) - { - members.back().name += tag; - } -} - -void createDefaults( VkData const& vkData, std::map & defaultValues ) -{ - for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) - { - assert( defaultValues.find( it->name ) == defaultValues.end() ); - switch( it->category ) - { - case DependencyData::Category::COMMAND : // commands should never be asked for defaults - break; - case DependencyData::Category::ENUM : - { - assert(vkData.enums.find(it->name) != vkData.enums.end()); - EnumData const & enumData = vkData.enums.find(it->name)->second; - if (!enumData.members.empty()) - { - defaultValues[it->name] = it->name + "::" + vkData.enums.find(it->name)->second.members.front().name; - } - else - { - defaultValues[it->name] = it->name + "()"; - } - } - break; - case DependencyData::Category::FLAGS : - case DependencyData::Category::HANDLE: - case DependencyData::Category::STRUCT: - case DependencyData::Category::UNION : // just call the default constructor for flags, structs, and structs (which are mapped to classes) - defaultValues[it->name] = it->name + "()"; - break; - case DependencyData::Category::FUNC_POINTER : // func_pointers explicitly have no default! - defaultValues[it->name]; - break; - case DependencyData::Category::REQUIRED : // all required default to "0" - case DependencyData::Category::SCALAR : // all scalars default to "0" - defaultValues[it->name] = "0"; - break; - default : - assert( false ); - break; - } - } -} - -std::string determineFunctionName(std::string const& name, CommandData const& commandData) -{ - if (commandData.handleCommand) - { - std::string strippedName = name; - std::string searchName = commandData.arguments[0].pureType; - size_t pos = name.find(searchName); - if (pos == std::string::npos) - { - assert(isupper(searchName[0])); - searchName[0] = tolower(searchName[0]); - pos = name.find(searchName); - } - if (pos != std::string::npos) - { - strippedName.erase(pos, commandData.arguments[0].pureType.length()); - } - else if ((commandData.arguments[0].pureType == "CommandBuffer") && (name.find("cmd") == 0)) - { - strippedName.erase(0, 3); - pos = 0; - } - if (pos == 0) - { - assert(isupper(strippedName[0])); - strippedName[0] = tolower(strippedName[0]); - } - return strippedName; - } - return name; -} - -std::string determineReturnType(CommandData const& commandData, size_t returnIndex, bool isVector) -{ - std::string returnType; - if ( (returnIndex != ~0) - && ( (commandData.returnType == "void") - || ( (commandData.returnType == "Result") - && ( (commandData.successCodes.size() == 1) - || ( (commandData.successCodes.size() == 2) - && (commandData.successCodes[1] == "eIncomplete") - && commandData.twoStep))))) - { - if (isVector) - { - if (commandData.arguments[returnIndex].pureType == "void") - { - returnType = "std::vector"; - } - else - { - returnType = "std::vector<" + commandData.arguments[returnIndex].pureType + ",Allocator>"; - } - } - else - { - assert(commandData.arguments[returnIndex].type.back() == '*'); - assert(commandData.arguments[returnIndex].type.find("const") == std::string::npos); - returnType = commandData.arguments[returnIndex].type; - returnType.pop_back(); - } - } - else if ((commandData.returnType == "Result") && (commandData.successCodes.size() == 1)) - { - // an original return of type "Result" with less just one successCode is changed to void, errors throw an exception - returnType = "void"; - } - else - { - // the return type just stays the original return type - returnType = commandData.returnType; - } - return returnType; -} - -void enterProtect(std::ofstream &ofs, std::string const& protect) -{ - if (!protect.empty()) - { - ofs << "#ifdef " << protect << std::endl; - } -} - -std::string extractTag(std::string const& name) -{ - // the name is supposed to look like: VK__ - size_t start = name.find('_'); - assert(start != std::string::npos); - size_t end = name.find('_', start + 1); - assert(end != std::string::npos); - return name.substr(start + 1, end - start - 1); -} - -size_t findReturnIndex(CommandData const& commandData, std::map const& vectorParameters) -{ - for (size_t i = 0; i < commandData.arguments.size(); i++) - { - if ((commandData.arguments[i].type.find('*') != std::string::npos) && (commandData.arguments[i].type.find("const") == std::string::npos) && !isVectorSizeParameter(vectorParameters, i)) - { -#if !defined(NDEBUG) - for (size_t j = i + 1; j < commandData.arguments.size(); j++) - { - assert((commandData.arguments[j].type.find('*') == std::string::npos) || (commandData.arguments[j].type.find("const") != std::string::npos)); - } -#endif - return i; - } - } - return ~0; -} - -std::string findTag(std::string const& name, std::set const& tags) -{ - for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) - { - size_t pos = name.find(*it); - if ((pos != std::string::npos) && (pos == name.length() - it->length())) - { - return *it; - } - } - return ""; -} - -size_t findTemplateIndex(CommandData const& commandData, std::map const& vectorParameters) -{ - for (size_t i = 0; i < commandData.arguments.size(); i++) - { - if ((commandData.arguments[i].name == "pData") || (commandData.arguments[i].name == "pValues")) - { - assert(vectorParameters.find(i) != vectorParameters.end()); - return i; - } - } - return ~0; -} - -std::string getEnumName(std::string const& name) // get vkcpp enum name from vk enum name -{ - return strip(name, "Vk"); -} - -std::string generateEnumNameForFlags(std::string const& name) -{ - std::string generatedName = name; - size_t pos = generatedName.rfind("Flags"); - assert(pos != std::string::npos); - generatedName.replace(pos, 5, "FlagBits"); - return generatedName; -} - -std::map getVectorParameters(CommandData const& commandData) -{ - std::map lenParameters; - for (size_t i = 0; i < commandData.arguments.size(); i++) - { - if (!commandData.arguments[i].len.empty()) - { - lenParameters.insert(std::make_pair(i, ~0)); - for (size_t j = 0; j < commandData.arguments.size(); j++) - { - if (commandData.arguments[i].len == commandData.arguments[j].name) - { - lenParameters[i] = j; - } - } - assert( (lenParameters[i] != ~0) - || (commandData.arguments[i].len == "dataSize/4") - || (commandData.arguments[i].len == "latexmath:[$dataSize \\over 4$]") - || (commandData.arguments[i].len == "null-terminated") - || (commandData.arguments[i].len == "pAllocateInfo->descriptorSetCount") - || (commandData.arguments[i].len == "pAllocateInfo->commandBufferCount")); - assert((lenParameters[i] == ~0) || (lenParameters[i] < i)); - } - } - return lenParameters; -} - -bool hasPointerArguments(CommandData const& commandData) -{ - for (size_t i = 0; i < commandData.arguments.size(); i++) - { - size_t pos = commandData.arguments[i].type.find('*'); - if ((pos != std::string::npos) && (commandData.arguments[i].type.find('*', pos + 1) == std::string::npos)) - { - return true; - } - } - return false; -} - -bool isVectorSizeParameter(std::map const& vectorParameters, size_t idx) -{ - for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) - { - if (it->second == idx) - { - return true; - } - } - return false; -} - -void leaveProtect(std::ofstream &ofs, std::string const& protect) -{ - if (!protect.empty()) - { - ofs << "#endif /*" << protect << "*/" << std::endl; - } -} - -bool noDependencies(std::set const& dependencies, std::set & listedTypes) -{ - bool ok = true; - for ( std::set::const_iterator it = dependencies.begin() ; it != dependencies.end() && ok ; ++it ) - { - ok = ( listedTypes.find( *it ) != listedTypes.end() ); - } - return( ok ); -} - -bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ) -{ - arguments.push_back( MemberData() ); - MemberData & arg = arguments.back(); - - if (element->Attribute("len")) - { - arg.len = element->Attribute("len"); - } - - tinyxml2::XMLNode * child = element->FirstChild(); - assert( child ); - if ( child->ToText() ) - { - std::string value = trimEnd(child->Value()); - assert( (value == "const") || (value == "struct") ); - arg.type = value + " "; - child = child->NextSibling(); - assert( child ); - } - - assert( child->ToElement() ); - assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); - std::string type = strip( child->ToElement()->GetText(), "Vk" ); - typeData.dependencies.insert( type ); - arg.type += type; - arg.pureType = type; - - child = child->NextSibling(); - assert( child ); - if ( child->ToText() ) - { - std::string value = trimEnd(child->Value()); - assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); - arg.type += value; - child = child->NextSibling(); - } - - assert( child->ToElement() && ( strcmp( child->Value(), "name" ) == 0 ) ); - arg.name = child->ToElement()->GetText(); - - if ( arg.name.back() == ']' ) - { - assert( !child->NextSibling() ); - size_t pos = arg.name.find( '[' ); - assert( pos != std::string::npos ); - arg.arraySize = arg.name.substr( pos + 1, arg.name.length() - 2 - pos ); - arg.name.erase( pos ); - } - - child = child->NextSibling(); - if ( child ) - { - if ( child->ToText() ) - { - std::string value = child->Value(); - if ( value == "[" ) - { - child = child->NextSibling(); - assert( child ); - assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); - arg.arraySize = child->ToElement()->GetText(); - child = child->NextSibling(); - assert( child ); - assert( child->ToText() ); - assert( strcmp( child->Value(), "]" ) == 0 ); - assert( !child->NextSibling() ); - } - else - { - assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); - arg.arraySize = value.substr( 1, value.length() - 2 ); - assert( !child->NextSibling() ); - } - } - } - - arg.optional = element->Attribute("optional") && (strcmp(element->Attribute("optional"), "true") == 0); - - return element->Attribute("optional") && (strcmp(element->Attribute("optional"), "false,true") == 0); -} - -std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * typeElement = element->FirstChildElement(); - assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) ); - tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); - assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) ); - assert( !nameElement->NextSiblingElement() ); - - std::string type = strip( typeElement->GetText(), "Vk" ); - std::string name = stripCommand( nameElement->GetText() ); - - vkData.dependencies.push_back( DependencyData( DependencyData::Category::COMMAND, name ) ); - assert( vkData.commands.find( name ) == vkData.commands.end() ); - std::map::iterator it = vkData.commands.insert( std::make_pair( name, CommandData() ) ).first; - it->second.returnType = type; - - return it; -} - -void readCommands(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - assert( child ); - do - { - assert( strcmp( child->Value(), "command" ) == 0 ); - readCommandsCommand( child, vkData ); - } while ( child = child->NextSiblingElement() ); -} - -void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - assert( child && ( strcmp( child->Value(), "proto" ) == 0 ) ); - - std::map::iterator it = readCommandProto(child, vkData); - - if (element->Attribute("successcodes")) - { - std::string successCodes = element->Attribute("successcodes"); - size_t start = 0, end; - do - { - end = successCodes.find(',', start); - std::string code = successCodes.substr(start, end - start); - std::string tag = findTag(code, vkData.tags); - it->second.successCodes.push_back("e" + toCamelCase(strip(code, "VK_", tag)) + tag); - start = end + 1; - } while (end != std::string::npos); - } - - // HACK: the current vk.xml misses to specify successcodes on command vkCreateDebugReportCallbackEXT! - if (it->first == "createDebugReportCallbackEXT") - { - it->second.successCodes.clear(); - it->second.successCodes.push_back("eSuccess"); - } - - while ( child = child->NextSiblingElement() ) - { - std::string value = child->Value(); - if ( value == "param" ) - { - it->second.twoStep |= readCommandParam(child, vkData.dependencies.back(), it->second.arguments); - } - else - { - assert( ( value == "implicitexternsyncparams" ) || ( value == "validity" ) ); - } - } - - // HACK: the current vk.xml misses to specify on param pSparseMemoryRequirementCount on command vkGetImageSparseMemoryRequirements! - if (it->first == "getImageSparseMemoryRequirements") - { - it->second.twoStep = true; - } - - assert(!it->second.arguments.empty()); - std::map::iterator hit = vkData.handles.find(it->second.arguments[0].pureType); - if (hit != vkData.handles.end()) - { - hit->second.commands.push_back(it->first); - it->second.handleCommand = true; - DependencyData const& dep = vkData.dependencies.back(); - std::list::iterator dit = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [hit](DependencyData const& dd) { return dd.name == hit->first; }); - for (std::set::const_iterator depit = dep.dependencies.begin(); depit != dep.dependencies.end(); ++depit) - { - if (*depit != hit->first) - { - dit->dependencies.insert(*depit); - } - } - } -} - -void readComment(tinyxml2::XMLElement * element, std::string & header) -{ - assert(element->GetText()); - assert(header.empty()); - header = element->GetText(); - assert(header.find("\nCopyright") == 0); - - size_t pos = header.find("\n\n-----"); - assert(pos != std::string::npos); - header.erase(pos); - - for (size_t pos = header.find('\n'); pos != std::string::npos; pos = header.find('\n', pos + 1)) - { - header.replace(pos, 1, "\n// "); - } - - header += "\n\n// This header is generated from the Khronos Vulkan XML API Registry."; -} - -void readEnums( tinyxml2::XMLElement * element, VkData & vkData ) -{ - assert( element->Attribute( "name" ) ); - std::string name = getEnumName(element->Attribute("name")); - if ( name != "API Constants" ) - { - vkData.dependencies.push_back( DependencyData( DependencyData::Category::ENUM, name ) ); - std::map::iterator it = vkData.enums.insert( std::make_pair( name, EnumData() ) ).first; - std::string tag; - - if (name == "Result") - { - // special handling for VKResult, as its enums just have VK_ in common - it->second.prefix = "VK_"; - } - else - { - assert(element->Attribute("type")); - std::string type = element->Attribute("type"); - assert((type == "bitmask") || (type == "enum")); - it->second.bitmask = (type == "bitmask"); - std::string prefix, postfix; - if (it->second.bitmask) - { - size_t pos = name.find("FlagBits"); - assert(pos != std::string::npos); - it->second.prefix = "VK" + toUpperCase(name.substr(0, pos)) + "_"; - it->second.postfix = "Bit"; - } - else - { - it->second.prefix = "VK" + toUpperCase(name) + "_"; - } - - // if the enum name contains a tag remove it from the prefix to generate correct enum value names. - for (std::set::const_iterator tit = vkData.tags.begin(); tit != vkData.tags.end(); ++tit) - { - size_t pos = it->second.prefix.find(*tit); - if ((pos != std::string::npos) && (pos == it->second.prefix.length() - tit->length() - 1)) - { - it->second.prefix.erase(pos); - tag = *tit; - break; - } - } - } - - readEnumsEnum( element, it->second, tag ); - - assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); - vkData.vkTypes.insert( name ); - } -} - -void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::string const& tag ) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - if ( child->Attribute( "name" ) ) - { - enumData.addEnum(child->Attribute("name"), tag, false); - } - } while ( child = child->NextSiblingElement() ); -} - -void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - std::string value = child->Value(); - - if ( value == "command" ) - { - assert(child->Attribute("name")); - std::string name = stripCommand(child->Attribute("name")); - std::map::iterator cit = vkData.commands.find(name); - assert(cit != vkData.commands.end()); - cit->second.protect = protect; - } - else if (value == "type") - { - assert(child->Attribute("name")); - std::string name = strip(child->Attribute("name"), "Vk"); - std::map::iterator eit = vkData.enums.find(name); - if (eit != vkData.enums.end()) - { - eit->second.protect = protect; - } - else - { - std::map::iterator fit = vkData.flags.find(name); - if (fit != vkData.flags.end()) - { - fit->second.protect = protect; - - // if the enum of this flags is auto-generated, protect it as well - std::string enumName = generateEnumNameForFlags(name); - std::map::iterator eit = vkData.enums.find(enumName); - assert(eit != vkData.enums.end()); - if (eit->second.members.empty()) - { - eit->second.protect = protect; - } - } - else - { - std::map::iterator scit = vkData.scalars.find(name); - if (scit != vkData.scalars.end()) - { - scit->second.protect = protect; - } - else - { - std::map::iterator stit = vkData.structs.find(name); - assert(stit != vkData.structs.end() && stit->second.protect.empty()); - stit->second.protect = protect; - } - } - } - } - else if ( value == "enum") - { - // TODO process enums which don't extend existing enums - if (child->Attribute("extends")) - { - assert(child->Attribute("name")); - assert(vkData.enums.find(getEnumName(child->Attribute("extends"))) != vkData.enums.end()); - assert(!!child->Attribute("bitpos") + !!child->Attribute("offset") + !!child->Attribute("value") == 1); - vkData.enums[getEnumName(child->Attribute("extends"))].addEnum(child->Attribute("name"), child->Attribute("value") ? "" : tag, true ); - } - } - else - { - assert(value=="usage"); - } - } while ( child = child->NextSiblingElement() ); -} - -void readExtensions(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - assert( child ); - do - { - assert( strcmp( child->Value(), "extension" ) == 0 ); - readExtensionsExtension( child, vkData ); - } while ( child = child->NextSiblingElement() ); -} - -void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData) -{ - assert( element->Attribute( "name" ) ); - std::string tag = extractTag(element->Attribute("name")); - assert(vkData.tags.find(tag) != vkData.tags.end()); - - // don't parse disabled extensions - if (strcmp(element->Attribute("supported"), "disabled") == 0) - { - return; - } - - std::string protect; - if (element->Attribute("protect")) - { - protect = element->Attribute( "protect" ); - } - - tinyxml2::XMLElement * child = element->FirstChildElement(); - assert( child && ( strcmp( child->Value(), "require" ) == 0 ) && !child->NextSiblingElement() ); - readExtensionRequire( child, vkData, protect, tag ); -} - -void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ) -{ - tinyxml2::XMLElement * typeElement = element->FirstChildElement(); - assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() ); - std::string type = typeElement->GetText(); - assert( ( type == "uint32_t" ) || ( type == "uint64_t" ) ); - - tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); - assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); - std::string name = strip( nameElement->GetText(), "Vk" ); - - // skip "Flags", - if ( name != "Flags" ) - { - dependencies.push_back( DependencyData( DependencyData::Category::SCALAR, name ) ); - dependencies.back().dependencies.insert( type ); - } - else - { - assert( type == "uint32_t" ); - } -} - -void readTypeBitmask(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * typeElement = element->FirstChildElement(); - assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() && ( strcmp( typeElement->GetText(), "VkFlags" ) == 0 ) ); - std::string type = typeElement->GetText(); - - tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); - assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); - std::string name = strip( nameElement->GetText(), "Vk" ); - - assert( !nameElement->NextSiblingElement() ); - - std::string requires; - if (element->Attribute("requires")) - { - requires = strip(element->Attribute("requires"), "Vk"); - } - else { - // Generate FlagBits name - requires = generateEnumNameForFlags(name); - vkData.dependencies.push_back(DependencyData(DependencyData::Category::ENUM, requires)); - std::map::iterator it = vkData.enums.insert(std::make_pair(requires, EnumData())).first; - it->second.bitmask = true; - vkData.vkTypes.insert(requires); - } - - vkData.dependencies.push_back( DependencyData( DependencyData::Category::FLAGS, name ) ); - vkData.dependencies.back().dependencies.insert( requires ); - vkData.flags.insert(std::make_pair(name, FlagData())); - - assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); - vkData.vkTypes.insert( name ); -} - -void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - if (child && (strcmp(child->GetText(), "VK_HEADER_VERSION") == 0)) - { - vkData.version = element->LastChild()->ToText()->Value(); - } - else if (element->Attribute("name") && strcmp(element->Attribute("name"), "VK_DEFINE_NON_DISPATCHABLE_HANDLE") == 0) - { - std::string text = element->LastChild()->ToText()->Value(); - size_t start = text.find('#'); - size_t end = text.find_first_of("\r\n", start + 1); - vkData.typesafeCheck = text.substr(start, end - start); - } -} - -void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - assert( child && ( strcmp( child->Value(), "name" ) == 0 ) && child->GetText() ); - dependencies.push_back( DependencyData( DependencyData::Category::FUNC_POINTER, child->GetText() ) ); -} - -void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * typeElement = element->FirstChildElement(); - assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() ); -#if !defined(NDEBUG) - std::string type = typeElement->GetText(); - assert( type.find( "VK_DEFINE" ) == 0 ); -#endif - - tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); - assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); - std::string name = strip( nameElement->GetText(), "Vk" ); - - vkData.dependencies.push_back( DependencyData( DependencyData::Category::HANDLE, name ) ); - - assert(vkData.vkTypes.find(name) == vkData.vkTypes.end()); - vkData.vkTypes.insert(name); - assert(vkData.handles.find(name) == vkData.handles.end()); - vkData.handles[name]; // add this to the handles map -} - -void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) -{ - members.push_back( MemberData() ); - MemberData & member = members.back(); - - tinyxml2::XMLNode * child = element->FirstChild(); - assert( child ); - if ( child->ToText()) - { - std::string value = trimEnd(child->Value()); - assert( (value == "const") || (value == "struct") ); - member.type = value + " "; - child = child->NextSibling(); - assert( child ); - } - - assert( child->ToElement() ); - assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); - std::string type = strip( child->ToElement()->GetText(), "Vk" ); - dependencies.insert( type ); - member.type += type; - member.pureType = type; - - child = child->NextSibling(); - assert( child ); - if ( child->ToText()) - { - std::string value = trimEnd(child->Value()); - assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); - member.type += value; - child = child->NextSibling(); - } - - assert( ( child->ToElement() && strcmp( child->Value(), "name" ) == 0 )); - member.name = child->ToElement()->GetText(); - - if ( member.name.back() == ']' ) - { - assert( !child->NextSibling() ); - size_t pos = member.name.find( '[' ); - assert( pos != std::string::npos ); - member.arraySize = member.name.substr( pos + 1, member.name.length() - 2 - pos ); - member.name.erase( pos ); - } - - child = child->NextSibling(); - if ( child ) - { - assert( member.arraySize.empty() ); - if ( child->ToText() ) - { - std::string value = child->Value(); - if ( value == "[" ) - { - child = child->NextSibling(); - assert( child ); - assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); - member.arraySize = child->ToElement()->GetText(); - child = child->NextSibling(); - assert( child ); - assert( child->ToText() ); - assert( strcmp( child->Value(), "]" ) == 0 ); - assert( !child->NextSibling() ); - } - else - { - assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); - member.arraySize = value.substr( 1, value.length() - 2 ); - assert( !child->NextSibling() ); - } - } - } -} - -void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ) -{ - assert( !element->Attribute( "returnedonly" ) || ( strcmp( element->Attribute( "returnedonly" ), "true" ) == 0 ) ); - - assert( element->Attribute( "name" ) ); - std::string name = strip( element->Attribute( "name" ), "Vk" ); - - if ( name == "Rect3D" ) - { - return; - } - - vkData.dependencies.push_back( DependencyData( DependencyData::Category::STRUCT, name ) ); - - assert( vkData.structs.find( name ) == vkData.structs.end() ); - std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; - it->second.returnedOnly = !!element->Attribute( "returnedonly" ); - - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - assert( child->Value() ); - std::string value = child->Value(); - if ( value == "member" ) - { - readTypeStructMember( child, it->second.members, vkData.dependencies.back().dependencies ); - } - else - { - assert( value == "validity" ); - } - } while ( child = child->NextSiblingElement() ); - - assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); - vkData.vkTypes.insert( name ); -} - -void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) -{ - members.push_back( MemberData() ); - MemberData & member = members.back(); - - tinyxml2::XMLNode * child = element->FirstChild(); - assert( child ); - if ( child->ToText() ) - { - assert( ( strcmp( child->Value(), "const" ) == 0 ) || ( strcmp( child->Value(), "struct" ) == 0 ) ); - member.type = std::string( child->Value() ) + " "; - child = child->NextSibling(); - assert( child ); - } - - assert( child->ToElement() ); - assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); - std::string type = strip( child->ToElement()->GetText(), "Vk" ); - dependencies.insert( type ); - member.type += type; - member.pureType = type; - - child = child->NextSibling(); - assert( child ); - if ( child->ToText() ) - { - std::string value = child->Value(); - assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); - member.type += value; - child = child->NextSibling(); - } - - assert( child->ToElement() && ( strcmp( child->Value(), "name" ) == 0 ) ); - member.name = child->ToElement()->GetText(); - - if ( member.name.back() == ']' ) - { - assert( !child->NextSibling() ); - size_t pos = member.name.find( '[' ); - assert( pos != std::string::npos ); - member.arraySize = member.name.substr( pos + 1, member.name.length() - 2 - pos ); - member.name.erase( pos ); - } - - child = child->NextSibling(); - if ( child ) - { - if ( child->ToText() ) - { - std::string value = child->Value(); - if ( value == "[" ) - { - child = child->NextSibling(); - assert( child ); - assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); - member.arraySize = child->ToElement()->GetText(); - child = child->NextSibling(); - assert( child ); - assert( child->ToText() ); - assert( strcmp( child->Value(), "]" ) == 0 ); - assert( !child->NextSibling() ); - } - else - { - assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); - member.arraySize = value.substr( 1, value.length() - 2 ); - assert( !child->NextSibling() ); - } - } - } -} - -void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ) -{ - assert( element->Attribute( "name" ) ); - std::string name = strip( element->Attribute( "name" ), "Vk" ); - - vkData.dependencies.push_back( DependencyData( DependencyData::Category::UNION, name ) ); - - assert( vkData.structs.find( name ) == vkData.structs.end() ); - std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; - - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - assert( strcmp( child->Value(), "member" ) == 0 ); - readTypeUnionMember( child, it->second.members, vkData.dependencies.back().dependencies ); - } while ( child = child->NextSiblingElement() ); - - assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); - vkData.vkTypes.insert( name ); -} - -void readTags(tinyxml2::XMLElement * element, std::set & tags) -{ - tags.insert("EXT"); - tags.insert("KHR"); - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - assert(child->Attribute("name")); - tags.insert(child->Attribute("name")); - } while (child = child->NextSiblingElement()); -} - -void readTypes(tinyxml2::XMLElement * element, VkData & vkData) -{ - tinyxml2::XMLElement * child = element->FirstChildElement(); - do - { - assert( strcmp( child->Value(), "type" ) == 0 ); - std::string type = child->Value(); - assert( type == "type" ); - if ( child->Attribute( "category" ) ) - { - std::string category = child->Attribute( "category" ); - if ( category == "basetype" ) - { - readTypeBasetype( child, vkData.dependencies ); - } - else if ( category == "bitmask" ) - { - readTypeBitmask( child, vkData); - } - else if ( category == "define" ) - { - readTypeDefine( child, vkData ); - } - else if ( category == "funcpointer" ) - { - readTypeFuncpointer( child, vkData.dependencies ); - } - else if ( category == "handle" ) - { - readTypeHandle( child, vkData ); - } - else if ( category == "struct" ) - { - readTypeStruct( child, vkData ); - } - else if ( category == "union" ) - { - readTypeUnion( child, vkData ); - } - else - { - assert( ( category == "enum" ) || ( category == "include" ) ); - } - } - else - { - assert( child->Attribute( "requires" ) && child->Attribute( "name" ) ); - vkData.dependencies.push_back( DependencyData( DependencyData::Category::REQUIRED, child->Attribute( "name" ) ) ); - } - } while ( child = child->NextSiblingElement() ); -} - -void sortDependencies( std::list & dependencies ) -{ - std::set listedTypes = { "VkFlags" }; - std::list sortedDependencies; - - while ( !dependencies.empty() ) - { -#if !defined(NDEBUG) - bool ok = false; -#endif - for ( std::list::iterator it = dependencies.begin() ; it != dependencies.end() ; ++it ) - { - if ( noDependencies( it->dependencies, listedTypes ) ) - { - sortedDependencies.push_back( *it ); - listedTypes.insert( it->name ); - dependencies.erase( it ); -#if !defined(NDEBUG) - ok = true; -#endif - break; - } - } - assert( ok ); - } - - dependencies.swap(sortedDependencies); -} - -std::string reduceName(std::string const& name) -{ - std::string reducedName; - if ((name[0] == 'p') && (1 < name.length()) && (isupper(name[1]) || name[1] == 'p')) - { - reducedName = strip(name, "p"); - reducedName[0] = tolower(reducedName[0]); - } - else - { - reducedName = name; - } - - return reducedName; -} - -std::string strip(std::string const& value, std::string const& prefix, std::string const& postfix) -{ - std::string strippedValue = value; - if (strippedValue.find(prefix) == 0) - { - strippedValue.erase(0, prefix.length()); - } - if (!postfix.empty()) - { - size_t pos = strippedValue.rfind(postfix); - assert(pos != std::string::npos); - strippedValue.erase(pos); - } - return strippedValue; -} - -std::string stripCommand(std::string const& value) -{ - std::string stripped = strip(value, "vk"); - assert(isupper(stripped[0])); - stripped[0] = tolower(stripped[0]); - return stripped; -} - -std::string toCamelCase(std::string const& value) -{ - assert(!value.empty() && (isupper(value[0]) || isdigit(value[0]))); - std::string result; - result.reserve(value.size()); - result.push_back(value[0]); - for (size_t i = 1; i < value.size(); i++) - { - if (value[i] != '_') - { - if ((value[i - 1] == '_') || isdigit(value[i-1])) - { - result.push_back(value[i]); - } - else - { - result.push_back(tolower(value[i])); - } - } - } - return result; -} - -std::string toUpperCase(std::string const& name) -{ - assert(isupper(name.front())); - std::string convertedName; - - for (size_t i = 0; i const& vkTypes, std::map const& vectorParameters, size_t returnIndex, bool firstCall) -{ - std::map countIndices; - for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) - { - countIndices.insert(std::make_pair(it->second, it->first)); - } - if ((vectorParameters.size() == 1) - && ((commandData.arguments[vectorParameters.begin()->first].len == "dataSize/4") || (commandData.arguments[vectorParameters.begin()->first].len == "latexmath:[$dataSize \\over 4$]"))) - { - assert(commandData.arguments[3].name == "dataSize"); - countIndices.insert(std::make_pair(3, vectorParameters.begin()->first)); - } - - assert(islower(name[0])); - ofs << "vk" << static_cast(toupper(name[0])) << name.substr(1) << "( "; - size_t i = 0; - if (commandData.handleCommand) - { - ofs << "m_" << commandData.arguments[0].name; - i++; - } - for (; i < commandData.arguments.size(); i++) - { - if (0 < i) - { - ofs << ", "; - } - std::map::const_iterator it = countIndices.find(i); - if (it != countIndices.end()) - { - if ((returnIndex == it->second) && commandData.twoStep) - { - ofs << "&" << reduceName(commandData.arguments[it->first].name); - } - else - { - ofs << reduceName(commandData.arguments[it->second].name) << ".size() "; - if (templateIndex == it->second) - { - ofs << "* sizeof( T ) "; - } - } - } - else - { - it = vectorParameters.find(i); - if (it != vectorParameters.end()) - { - assert(commandData.arguments[it->first].type.back() == '*'); - if ((returnIndex == it->first) && commandData.twoStep && firstCall) - { - ofs << "nullptr"; - } - else - { - std::set::const_iterator vkit = vkTypes.find(commandData.arguments[it->first].pureType); - if ((vkit != vkTypes.end()) || (it->first == templateIndex)) - { - ofs << "reinterpret_cast<"; - if (commandData.arguments[it->first].type.find("const") != std::string::npos) - { - ofs << "const "; - } - if (vkit != vkTypes.end()) - { - ofs << "Vk"; - } - ofs << commandData.arguments[it->first].pureType << "*>( " << reduceName(commandData.arguments[it->first].name) << ".data() )"; - } - else if (commandData.arguments[it->first].pureType == "char") - { - ofs << reduceName(commandData.arguments[it->first].name); - if (commandData.arguments[it->first].optional) - { - ofs << " ? " << reduceName(commandData.arguments[it->first].name) << "->c_str() : nullptr"; - } - else - { - ofs << ".c_str()"; - } - } - else - { - ofs << reduceName(commandData.arguments[it->first].name) << ".data()"; - } - } - } - else if (vkTypes.find(commandData.arguments[i].pureType) != vkTypes.end()) - { - if (commandData.arguments[i].type.back() == '*') - { - if (commandData.arguments[i].type.find("const") != std::string::npos) - { - ofs << "reinterpret_cast( "; - if (commandData.arguments[i].optional) - { - ofs << "static_cast( "; - } - else - { - ofs << "&"; - } - ofs << reduceName(commandData.arguments[i].name) << (commandData.arguments[i].optional ? "))" : " )"); - } - else - { - assert(!commandData.arguments[i].optional); - ofs << "reinterpret_cast( &" << reduceName(commandData.arguments[i].name) << " )"; - } - } - else - { - ofs << "static_cast( " << commandData.arguments[i].name << " )"; - } - } - else - { - if (commandData.arguments[i].type.back() == '*') - { - if (commandData.arguments[i].type.find("const") != std::string::npos) - { - assert(commandData.arguments[i].type.find("char") != std::string::npos); - ofs << reduceName(commandData.arguments[i].name); - if (commandData.arguments[i].optional) - { - ofs << " ? " << reduceName(commandData.arguments[i].name) << "->c_str() : nullptr"; - } - else - { - ofs << ".c_str()"; - } - } - else - { - assert(commandData.arguments[i].type.find("char") == std::string::npos); - ofs << "&" << reduceName(commandData.arguments[i].name); - } - } - else - { - ofs << commandData.arguments[i].name; - } - } - } - } - ofs << " )"; -} - -void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::vector const& successCodes) -{ - assert(!successCodes.empty()); - ofs << indentation << " if ("; - if (successCodes.size() == 1) - { - assert(successCodes.front() == "eSuccess"); - ofs << " result != Result::eSuccess"; - } - else - { - for (size_t i = 0; i < successCodes.size() - 1; i++) - { - ofs << " ( result != Result::" << successCodes[i] << " ) &&"; - } - ofs << " ( result != Result::" << successCodes.back() << " )"; - } - ofs << " )" << std::endl; - ofs << indentation << " {" << std::endl - << indentation << " throw std::system_error( result, \"vk::"; - if (!className.empty()) - { - ofs << className << "::"; - } - ofs << functionName << "\" );" << std::endl - << indentation << " }" << std::endl; -} - -void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes, size_t returnIndex, std::map const& vectorParameters) -{ - ofs << indentation << "{" << std::endl; - - // add a static_assert if a type is templated and its size needs to be some multiple of the original size - if ((templateIndex != ~0) && (commandData.arguments[templateIndex].pureType != "void")) - { - ofs << indentation << " static_assert( sizeof( T ) % sizeof( " << commandData.arguments[templateIndex].pureType << " ) == 0, \"wrong size of template type T\" );" << std::endl; - } - - // add some error checks if multiple vectors need to have the same size - if (1 < vectorParameters.size()) - { - for (std::map::const_iterator it0 = vectorParameters.begin(); it0 != vectorParameters.end(); ++it0) - { - if (it0->first != returnIndex) - { - for (std::map::const_iterator it1 = std::next(it0); it1 != vectorParameters.end(); ++it1) - { - if ((it1->first != returnIndex) && (it0->second == it1->second)) - { - ofs << indentation << " if ( " << reduceName(commandData.arguments[it0->first].name) << ".size() != " << reduceName(commandData.arguments[it1->first].name) << ".size() )" << std::endl - << indentation << " {" << std::endl - << indentation << " throw std::logic_error( \"vk::" << className << "::" << functionName << ": " << reduceName(commandData.arguments[it0->first].name) << ".size() != " << reduceName(commandData.arguments[it1->first].name) << ".size()\" );" << std::endl - << indentation << " }" << std::endl; - } - } - } - } - } - - // write the local variable to hold a returned value - if ((returnIndex != ~0) && (commandData.returnType != returnType)) - { - ofs << indentation << " " << returnType << " " << reduceName(commandData.arguments[returnIndex].name); - - std::map::const_iterator it = vectorParameters.find(returnIndex); - if (it != vectorParameters.end() && !commandData.twoStep) - { - std::string size; - if ((it->second == ~0) && !commandData.arguments[returnIndex].len.empty()) - { - size = reduceName(commandData.arguments[returnIndex].len); - size_t pos = size.find("->"); - assert(pos != std::string::npos); - size.replace(pos, 2, "."); - } - else - { - for (std::map::const_iterator sit = vectorParameters.begin(); sit != vectorParameters.end(); ++sit) - { - if ((sit->first != returnIndex) && (sit->second == it->second)) - { - size = reduceName(commandData.arguments[sit->first].name) + ".size()"; - break; - } - } - } - assert(!size.empty()); - ofs << "( " << size << " )"; - } - ofs << ";" << std::endl; - } - - // local count variable to hold the size of the vector to fill - if (commandData.twoStep) - { - assert(returnIndex != ~0); - - std::map::const_iterator returnit = vectorParameters.find(returnIndex); - assert(returnit != vectorParameters.end() && (returnit->second != ~0)); - assert((commandData.returnType == "Result") || (commandData.returnType == "void")); - - ofs << indentation << " " << commandData.arguments[returnit->second].pureType << " " << reduceName(commandData.arguments[returnit->second].name) << ";" << std::endl; - } - - // write the function call - ofs << indentation << " "; - std::string localIndentation = " "; - if (commandData.returnType == "Result") - { - ofs << "Result result"; - if (commandData.twoStep && (1 < commandData.successCodes.size())) - { - ofs << ";" << std::endl - << indentation << " do" << std::endl - << indentation << " {" << std::endl - << indentation << " result"; - localIndentation += " "; - } - ofs << " = static_cast( "; - } - else if (commandData.returnType != "void") - { - assert(!commandData.twoStep); - ofs << "return "; - } - writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, true); - if (commandData.returnType == "Result") - { - ofs << " )"; - } - ofs << ";" << std::endl; - - if (commandData.twoStep) - { - std::map::const_iterator returnit = vectorParameters.find(returnIndex); - - if (commandData.returnType == "Result") - { - ofs << indentation << localIndentation << "if ( ( result == Result::eSuccess ) && " << reduceName(commandData.arguments[returnit->second].name) << " )" << std::endl - << indentation << localIndentation << "{" << std::endl - << indentation << localIndentation << " "; - } - else - { - ofs << indentation << " "; - } - - // resize the vector to hold the data according to the result from the first call - ofs << reduceName(commandData.arguments[returnit->first].name) << ".resize( " << reduceName(commandData.arguments[returnit->second].name) << " );" << std::endl; - - // write the function call a second time - if (commandData.returnType == "Result") - { - ofs << indentation << localIndentation << " result = static_cast( "; - } - else - { - ofs << indentation << " "; - } - writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, false); - if (commandData.returnType == "Result") - { - ofs << " )"; - } - ofs << ";" << std::endl; - if (commandData.returnType == "Result") - { - ofs << indentation << localIndentation << "}" << std::endl; - if (1 < commandData.successCodes.size()) - { - ofs << indentation << " } while ( result == Result::eIncomplete );" << std::endl; - } - writeExceptionCheck(ofs, indentation, className, functionName, {"eSuccess"}); - } - } - else if ((commandData.returnType == "Result") || !commandData.successCodes.empty()) - { - writeExceptionCheck(ofs, indentation, className, functionName, commandData.successCodes); - } - - // return the returned value - if ((returnIndex != ~0) && (commandData.returnType != returnType)) - { - ofs << indentation << " return " << reduceName(commandData.arguments[returnIndex].name) << ";" << std::endl; - } - else if (returnType == "Result") - { - ofs << indentation << " return result;" << std::endl; - } - - ofs << indentation << "}" << std::endl; -} - -void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map const& vectorParameters) -{ - std::set skippedArguments; - for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) - { - if (it->second != ~0) - { - skippedArguments.insert(it->second); - } - } - if ((vectorParameters.size() == 1) - && ((commandData.arguments[vectorParameters.begin()->first].len == "dataSize/4") || (commandData.arguments[vectorParameters.begin()->first].len == "latexmath:[$dataSize \\over 4$]"))) - { - assert(commandData.arguments[3].name == "dataSize"); - skippedArguments.insert(3); - } - if ((returnIndex != ~0) && (commandData.returnType != returnType)) - { - skippedArguments.insert(returnIndex); - } - - ofs << indentation; - if ((templateIndex != ~0) && ((templateIndex != returnIndex) || (returnType == "Result"))) - { - assert(returnType.find("Allocator") == std::string::npos); - ofs << "template " << std::endl - << indentation; - } - else if (returnType.find("Allocator") != std::string::npos) - { - assert((returnType.substr(0, 12) == "std::vector<") && (returnType.find(',') != std::string::npos) && (12 < returnType.find(','))); - ofs << "template >" << std::endl - << indentation; - } - else if (!commandData.handleCommand) - { - ofs << "inline "; - } - ofs << returnType << " " << reduceName(name) << "("; - if (skippedArguments.size() + (commandData.handleCommand ? 1 : 0) < commandData.arguments.size()) - { - size_t lastArgument = ~0; - for (size_t i = commandData.arguments.size() - 1; i < commandData.arguments.size(); i--) - { - if (skippedArguments.find(i) == skippedArguments.end()) - { - lastArgument = i; - break; - } - } - - ofs << " "; - bool argEncountered = false; - for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) - { - if (skippedArguments.find(i) == skippedArguments.end()) - { - if (argEncountered) - { - ofs << ", "; - } - - std::map::const_iterator it = vectorParameters.find(i); - size_t pos = commandData.arguments[i].type.find('*'); - if (it == vectorParameters.end()) - { - if (pos == std::string::npos) - { - ofs << commandData.arguments[i].type << " " << reduceName(commandData.arguments[i].name); - if (!commandData.arguments[i].arraySize.empty()) - { - ofs << "[" << commandData.arguments[i].arraySize << "]"; - } - } - else - { - assert(commandData.arguments[i].type[pos] == '*'); - if (commandData.arguments[i].optional) - { - ofs << "Optional<" << trimEnd(commandData.arguments[i].type.substr(0, pos)) << "> " << reduceName(commandData.arguments[i].name) << " = nullptr"; - } - else if (commandData.arguments[i].type.find("char") == std::string::npos) - { - ofs << trimEnd(commandData.arguments[i].type.substr(0, pos)) << " & " << reduceName(commandData.arguments[i].name); - } - else - { - ofs << "const std::string & " << reduceName(commandData.arguments[i].name); - } - } - } - else - { - bool optional = commandData.arguments[i].optional && ((it == vectorParameters.end()) || (it->second == ~0)); - assert(pos != std::string::npos); - assert(commandData.arguments[i].type[pos] == '*'); - if (commandData.arguments[i].type.find("char") != std::string::npos) - { - if (optional) - { - ofs << "Optional " << reduceName(commandData.arguments[i].name) << " = nullptr"; - } - else - { - ofs << "const std::string & " << reduceName(commandData.arguments[i].name); - } - } - else - { - assert(!optional); - bool isConst = (commandData.arguments[i].type.find("const") != std::string::npos); - ofs << "ArrayProxy<" << ((templateIndex == i) ? (isConst ? "const T" : "T") : trimEnd(commandData.arguments[i].type.substr(0, pos))) << "> " << reduceName(commandData.arguments[i].name); - } - } - argEncountered = true; - } - } - ofs << " "; - } - ofs << ")"; - if (commandData.handleCommand) - { - ofs << " const"; - } - ofs << std::endl; -} - -void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set const& vkTypes) -{ - if ( vkTypes.find( memberData.pureType ) != vkTypes.end() ) - { - if ( memberData.type.back() == '*' ) - { - ofs << "reinterpret_cast<"; - if ( memberData.type.find( "const" ) == 0 ) - { - ofs << "const "; - } - ofs << "Vk" << memberData.pureType << '*'; - } - else - { - ofs << "static_cast( " << memberData.name << " )"; - } - else - { - ofs << memberData.name; - } -} - -void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set const& vkTypes, std::map const& defaultValues ) -{ - // check if there is a member element with no default available - bool noDefault = false; - for (size_t i = 0; i < structData.members.size() && !noDefault; i++) - { - std::map::const_iterator it = defaultValues.find(structData.members[i].pureType); - assert(it != defaultValues.end()); - noDefault = it->second.empty(); - } - - if (!noDefault) - { - // if there's a default for all member, provide a default constructor - ofs << " " << name << "()" << std::endl - << " : " << name << "( "; - bool listedArgument = false; - for (size_t i = 0; i < structData.members.size(); i++) - { - if (listedArgument) - { - ofs << ", "; - } - if ((structData.members[i].name != "pNext") && (structData.members[i].name != "sType")) - { - if (structData.members[i].type.back() == '*') - { - ofs << "nullptr"; - } - else - { - std::map::const_iterator it = defaultValues.find(structData.members[i].pureType); - assert((it != defaultValues.end()) && !it->second.empty()); - - if (structData.members[i].arraySize.empty()) - { - ofs << it->second; - } - else - { - ofs << "{ " << it->second << " }"; - } - } - listedArgument = true; - } - } - ofs << " )" << std::endl - << " {}" << std::endl - << std::endl; - } - - // the constructor with all the elements as arguments - ofs << " " << name << "( "; - std::vector noDefaultArgs, defaultArgs; - bool listedArgument = false; - for (size_t i = 0; i const& " + structData.members[i].name << "_"; - } - listedArgument = true; - } - } - ofs << " )" << std::endl; - - // the body of the constructor, copying over data from argument list into wrapped struct - ofs << " {" << std::endl; - for ( size_t i=0 ; i const& vkTypes ) -{ - ofs << " " << name << "& set" << static_cast(toupper(memberData.name[0])) << memberData.name.substr(1) << "( "; - if ( memberData.arraySize.empty() ) - { - ofs << memberData.type << " "; - } - else - { - ofs << "std::array<" << memberData.type << "," << memberData.arraySize << "> "; - } - ofs << memberData.name << "_ )" << std::endl - << " {" << std::endl; - if ( !memberData.arraySize.empty() ) - { - ofs << " memcpy( &" << memberData.name << ", " << memberData.name << "_.data(), " << memberData.arraySize << " * sizeof( " << memberData.type << " ) )"; - } - else - { - ofs << " " << memberData.name << " = " << memberData.name << "_"; - } - ofs << ";" << std::endl - << " return *this;" << std::endl - << " }" << std::endl - << std::endl; -} - -void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes ) -{ - if (!commandData.handleCommand) - { - writeTypeCommandStandard(ofs, " ", dependencyData.name, dependencyData, commandData, vkTypes); - - ofs << std::endl - << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; - writeTypeCommandEnhanced(ofs, " ", "", dependencyData.name, dependencyData, commandData, vkTypes); - ofs << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl - << std::endl; - } -} - -void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes) -{ - enterProtect(ofs, commandData.protect); - std::map vectorParameters = getVectorParameters(commandData); - size_t returnIndex = findReturnIndex(commandData, vectorParameters); - size_t templateIndex = findTemplateIndex(commandData, vectorParameters); - std::map::const_iterator returnVector = vectorParameters.find(returnIndex); - std::string returnType = determineReturnType(commandData, returnIndex, returnVector != vectorParameters.end()); - - writeFunctionHeader(ofs, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters); - writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkTypes, returnIndex, vectorParameters); - leaveProtect(ofs, commandData.protect); -} - -void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes) -{ - enterProtect(ofs, commandData.protect); - ofs << indentation; - if (!commandData.handleCommand) - { - ofs << "inline "; - } - ofs << commandData.returnType << " " << functionName << "( "; - bool argEncountered = false; - for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) - { - if (argEncountered) - { - ofs << ", "; - } - ofs << commandData.arguments[i].type << " " << commandData.arguments[i].name; - if (!commandData.arguments[i].arraySize.empty()) - { - ofs << "[" << commandData.arguments[i].arraySize << "]"; - } - argEncountered = true; - } - ofs << " )"; - if (commandData.handleCommand) - { - ofs << " const"; - } - ofs << std::endl - << indentation << "{" << std::endl - << indentation << " "; - bool castReturn = false; - if (commandData.returnType != "void") - { - ofs << "return "; - castReturn = (vkTypes.find(commandData.returnType) != vkTypes.end()); - if (castReturn) - { - ofs << "static_cast<" << commandData.returnType << ">( "; - } - } - - std::string callName(dependencyData.name); - assert(islower(callName[0])); - callName[0] = toupper(callName[0]); - - ofs << "vk" << callName << "( "; - if (commandData.handleCommand) - { - ofs << "m_" << commandData.arguments[0].name; - } - argEncountered = false; - for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) - { - if (0 < i) - { - ofs << ", "; - } - writeMemberData(ofs, commandData.arguments[i], vkTypes); - } - ofs << " )"; - if (castReturn) - { - ofs << " )"; - } - ofs << ";" << std::endl - << indentation << "}" << std::endl; - leaveProtect(ofs, commandData.protect); -} - -void writeTypeEnum( std::ofstream & ofs, DependencyData const& dependencyData, EnumData const& enumData ) -{ - enterProtect(ofs, enumData.protect); - ofs << " enum class " << dependencyData.name << std::endl - << " {" << std::endl; - for ( size_t i=0 ; iname << ": return \"" << itMember->name.substr(1) << "\";" << std::endl; - } - ofs << " default: return \"invalid\";" << std::endl - << " }" << std::endl; - } - ofs << " }" << std::endl; - leaveProtect(ofs, enumData.protect); - ofs << std::endl; -} - -void writeFlagsToString(std::ofstream & ofs, DependencyData const& dependencyData, EnumData const &enumData) -{ - enterProtect(ofs, enumData.protect); - std::string enumPrefix = *dependencyData.dependencies.begin() + "::"; - ofs << " inline std::string to_string(" << dependencyData.name << (enumData.members.empty() ? ")" : " value)") << std::endl - << " {" << std::endl; - if (enumData.members.empty()) - { - ofs << " return \"{}\";" << std::endl; - } - else - { - ofs << " if (!value) return \"{}\";" << std::endl - << " std::string result;" << std::endl; - - for (auto itMember = enumData.members.begin(); itMember != enumData.members.end(); ++itMember) - { - ofs << " if (value & " << enumPrefix + itMember->name << ") result += \"" << itMember->name.substr(1) << " | \";" << std::endl; - } - ofs << " return \"{\" + result.substr(0, result.size() - 3) + \"}\";" << std::endl; - } - ofs << " }" << std::endl; - leaveProtect(ofs, enumData.protect); - ofs << std::endl; -} - -void writeEnumsToString(std::ofstream & ofs, VkData const& vkData) -{ - for (auto it = vkData.dependencies.begin(); it != vkData.dependencies.end(); ++it) - { - switch (it->category) - { - case DependencyData::Category::ENUM: - assert(vkData.enums.find(it->name) != vkData.enums.end()); - writeEnumsToString(ofs, *it, vkData.enums.find(it->name)->second); - break; - case DependencyData::Category::FLAGS: - writeFlagsToString(ofs, *it, vkData.enums.find(*it->dependencies.begin())->second); - break; - } - } -} - -void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, FlagData const& flagData ) -{ - assert( dependencyData.dependencies.size() == 1 ); - enterProtect(ofs, flagData.protect); - ofs << " using " << dependencyData.name << " = Flags<" << *dependencyData.dependencies.begin() << ", Vk" << dependencyData.name << ">;" << std::endl - << std::endl - << " inline " << dependencyData.name << " operator|( " << *dependencyData.dependencies.begin() << " bit0, " << *dependencyData.dependencies.begin() << " bit1 )" << std::endl - << " {" << std::endl - << " return " << dependencyData.name << "( bit0 ) | bit1;" << std::endl - << " }" << std::endl; - leaveProtect(ofs, flagData.protect); - ofs << std::endl; -} - -void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies) -{ - std::string memberName = dependencyData.name; - assert(isupper(memberName[0])); - memberName[0] = tolower(memberName[0]); - - ofs << " class " << dependencyData.name << std::endl - << " {" << std::endl - << " public:" << std::endl - << " " << dependencyData.name << "()" << std::endl - << " : m_" << memberName << "(VK_NULL_HANDLE)" << std::endl - << " {}" << std::endl - << std::endl - << "#if defined(VK_CPP_TYPESAFE_CONVERSION)" << std::endl - // construct from native handle - << " " << dependencyData.name << "(Vk" << dependencyData.name << " " << memberName << ")" << std::endl - << " : m_" << memberName << "(" << memberName << ")" << std::endl - << " {}" << std::endl - << std::endl - // assignment from native handle - << " " << dependencyData.name << "& operator=(Vk" << dependencyData.name << " " << memberName << ")" << std::endl - << " {" << std::endl - << " m_" << memberName << " = " << memberName << ";" << std::endl - << " return *this;" << std::endl - << " }" << std::endl - << "#endif\n" - << std::endl; - - if (!handle.commands.empty()) - { - for (size_t i = 0; i < handle.commands.size(); i++) - { - std::string commandName = handle.commands[i]; - std::map::const_iterator cit = vkData.commands.find(commandName); - assert((cit != vkData.commands.end()) && cit->second.handleCommand); - std::list::const_iterator dep = std::find_if(dependencies.begin(), dependencies.end(), [commandName](DependencyData const& dd) { return dd.name == commandName; }); - assert(dep != dependencies.end()); - std::string className = dependencyData.name; - std::string functionName = determineFunctionName(dep->name, cit->second); - - bool hasPointers = hasPointerArguments(cit->second); - if (!hasPointers) - { - ofs << "#ifdef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; - } - writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkData.vkTypes); - if (!hasPointers) - { - ofs << "#endif /*!VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl; - } - - ofs << std::endl - << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; - writeTypeCommandEnhanced(ofs, " ", className, functionName, *dep, cit->second, vkData.vkTypes); - ofs << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl; - - if (i < handle.commands.size() - 1) - { - ofs << std::endl; - } - } - ofs << std::endl; - } - ofs << "#if !defined(VK_CPP_TYPESAFE_CONVERSION)" << std::endl - << " explicit" << std::endl - << "#endif" << std::endl - << " operator Vk" << dependencyData.name << "() const" << std::endl - << " {" << std::endl - << " return m_" << memberName << ";" << std::endl - << " }" << std::endl - << std::endl - << " explicit operator bool() const" << std::endl - << " {" << std::endl - << " return m_" << memberName << " != VK_NULL_HANDLE;" << std::endl - << " }" << std::endl - << std::endl - << " bool operator!() const" << std::endl - << " {" << std::endl - << " return m_" << memberName << " == VK_NULL_HANDLE;" << std::endl - << " }" << std::endl - << std::endl - << " private:" << std::endl - << " Vk" << dependencyData.name << " m_" << memberName << ";" << std::endl - << " };" << std::endl -#if 1 - << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"handle and wrapper have different size!\" );" << std::endl -#endif - << std::endl; -} - -void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ) -{ - assert( dependencyData.dependencies.size() == 1 ); - ofs << " using " << dependencyData.name << " = " << *dependencyData.dependencies.begin() << ";" << std::endl - << std::endl; -} - -void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ) -{ - std::map::const_iterator it = vkData.structs.find( dependencyData.name ); - assert( it != vkData.structs.end() ); - - enterProtect(ofs, it->second.protect); - ofs << " struct " << dependencyData.name << std::endl - << " {" << std::endl; - - // only structs that are not returnedOnly get a constructor! - if ( !it->second.returnedOnly ) - { - writeStructConstructor( ofs, dependencyData.name, it->second, vkData.vkTypes, defaultValues ); - } - - // create the setters - if (!it->second.returnedOnly) - { - for (size_t i = 0; isecond.members.size(); i++) - { - writeStructSetter( ofs, dependencyData.name, it->second.members[i], vkData.vkTypes ); - } - } - - // the cast-operator to the wrapped struct - ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl - << " {" << std::endl - << " return *reinterpret_cast(this);" << std::endl - << " }" << std::endl - << std::endl; - - // the member variables - for (size_t i = 0; i < it->second.members.size(); i++) - { - ofs << " " << it->second.members[i].type << " " << it->second.members[i].name; - if (!it->second.members[i].arraySize.empty()) - { - ofs << "[" << it->second.members[i].arraySize << "]"; - } - ofs << ";" << std::endl; - } - ofs << " };" << std::endl; -#if 1 - ofs << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"struct and wrapper have different size!\" );" << std::endl; -#endif - leaveProtect(ofs, it->second.protect); - ofs << std::endl; -} - -void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ) -{ - std::ostringstream oss; - ofs << " union " << dependencyData.name << std::endl - << " {" << std::endl; - - for ( size_t i=0 ; i& "; - } - ofs << unionData.members[i].name << "_"; - - // just the very first constructor gets default arguments - if ( i == 0 ) - { - std::map::const_iterator it = defaultValues.find( unionData.members[i].pureType ); - assert( it != defaultValues.end() ); - if ( unionData.members[i].arraySize.empty() ) - { - ofs << " = " << it->second; - } - else - { - ofs << " = { " << it->second << " }"; - } - } - ofs << " )" << std::endl - << " {" << std::endl - << " "; - if ( unionData.members[i].arraySize.empty() ) - { - ofs << unionData.members[i].name << " = " << unionData.members[i].name << "_"; - } - else - { - ofs << "memcpy( &" << unionData.members[i].name << ", " << unionData.members[i].name << "_.data(), " << unionData.members[i].arraySize << " * sizeof( " << unionData.members[i].type << " ) )"; - } - ofs << ";" << std::endl - << " }" << std::endl - << std::endl; - } - - for (size_t i = 0; i(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 = false; - for (size_t i = 0; i < unionData.members.size() && !needsUnrestrictedUnions; i++) - { - needsUnrestrictedUnions = (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end()); - } - if (needsUnrestrictedUnions) - { - ofs << "#ifdef VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl; - for (size_t i = 0; i < unionData.members.size(); i++) - { - ofs << " " << unionData.members[i].type << " " << unionData.members[i].name; - if (!unionData.members[i].arraySize.empty()) - { - ofs << "[" << unionData.members[i].arraySize << "]"; - } - ofs << ";" << std::endl; - } - ofs << "#else" << std::endl; - } - for (size_t i = 0; i < unionData.members.size(); i++) - { - ofs << " "; - if (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end()) - { - ofs << "Vk"; - } - ofs << unionData.members[i].type << " " << unionData.members[i].name; - if (!unionData.members[i].arraySize.empty()) - { - ofs << "[" << unionData.members[i].arraySize << "]"; - } - ofs << ";" << std::endl; - } - if (needsUnrestrictedUnions) - { - ofs << "#endif // VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl; - } - ofs << " };" << std::endl - << std::endl; -} - -void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues) -{ - for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) - { - switch( it->category ) - { - case DependencyData::Category::COMMAND : - assert( vkData.commands.find( it->name ) != vkData.commands.end() ); - writeTypeCommand( ofs, *it, vkData.commands.find( it->name )->second, vkData.vkTypes ); - break; - case DependencyData::Category::ENUM : - assert( vkData.enums.find( it->name ) != vkData.enums.end() ); - writeTypeEnum( ofs, *it, vkData.enums.find( it->name )->second ); - break; - case DependencyData::Category::FLAGS : - assert(vkData.flags.find(it->name) != vkData.flags.end()); - writeTypeFlags( ofs, *it, vkData.flags.find( it->name)->second ); - break; - case DependencyData::Category::FUNC_POINTER : - case DependencyData::Category::REQUIRED : - // skip FUNC_POINTER and REQUIRED, they just needed to be in the dependencies list to resolve dependencies - break; - case DependencyData::Category::HANDLE : - assert(vkData.handles.find(it->name) != vkData.handles.end()); - writeTypeHandle(ofs, vkData, *it, vkData.handles.find(it->name)->second, vkData.dependencies); - break; - case DependencyData::Category::SCALAR : - writeTypeScalar( ofs, *it ); - break; - case DependencyData::Category::STRUCT : - writeTypeStruct( ofs, vkData, *it, defaultValues ); - break; - case DependencyData::Category::UNION : - assert( vkData.structs.find( it->name ) != vkData.structs.end() ); - writeTypeUnion( ofs, vkData, *it, vkData.structs.find( it->name )->second, defaultValues ); - break; - default : - assert( false ); - break; - } - } -} - -void writeVersionCheck(std::ofstream & ofs, std::string const& version) -{ - ofs << "static_assert( VK_HEADER_VERSION == " << version << " , \"Wrong VK_HEADER_VERSION!\" );" << std::endl - << std::endl; -} - -void writeTypesafeCheck(std::ofstream & ofs, std::string const& typesafeCheck) -{ - ofs << "// 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 VK_CPP_TYPESAFE_CONVERSION" << std::endl - << typesafeCheck << std::endl - << "#define VK_CPP_TYPESAFE_CONVERSION 1" << std::endl - << "#endif" << std::endl - << std::endl; -} - -int main( int argc, char **argv ) -{ - try { - tinyxml2::XMLDocument doc; - - std::string filename = (argc == 1) ? VK_SPEC : argv[1]; - std::cout << "Loading vk.xml from " << filename << std::endl; - std::cout << "Writing vk_cpp.hpp to " << VK_CPP << std::endl; - - tinyxml2::XMLError error = doc.LoadFile(filename.c_str()); - if (error != tinyxml2::XML_SUCCESS) - { - std::cout << "VkGenerate: failed to load file " << argv[1] << " . Error code: " << error << std::endl; - return -1; - } - - tinyxml2::XMLElement * registryElement = doc.FirstChildElement(); - assert(strcmp(registryElement->Value(), "registry") == 0); - assert(!registryElement->NextSiblingElement()); - - VkData vkData; - - tinyxml2::XMLElement * child = registryElement->FirstChildElement(); - do - { - assert(child->Value()); - const std::string value = child->Value(); - if (value == "commands") - { - readCommands(child, vkData); - } - else if (value == "comment") - { - readComment(child, vkData.vulkanLicenseHeader); - } - else if (value == "enums") - { - readEnums(child, vkData); - } - else if (value == "extensions") - { - readExtensions(child, vkData); - } - else if (value == "tags") - { - readTags(child, vkData.tags); - } - else if (value == "types") - { - readTypes(child, vkData); - } - else - { - assert((value == "feature") || (value == "vendorids")); - } - } while (child = child->NextSiblingElement()); - - sortDependencies(vkData.dependencies); - - std::map defaultValues; - createDefaults(vkData, defaultValues); - - std::ofstream ofs(VK_CPP); - ofs << nvidiaLicenseHeader << std::endl - << vkData.vulkanLicenseHeader << std::endl - << std::endl - << std::endl - << "#ifndef VK_CPP_H_" << std::endl - << "#define VK_CPP_H_" << std::endl - << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#include " << std::endl - << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl - << "# include " << std::endl - << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl - << std::endl; - - writeVersionCheck(ofs, vkData.version); - writeTypesafeCheck(ofs, vkData.typesafeCheck); - ofs << versionCheckHeader - << "namespace vk" << std::endl - << "{" << std::endl - << flagsHeader - << optionalClassHeader - << arrayProxyHeader; - - // first of all, write out vk::Result and the exception handling stuff - std::list::const_iterator it = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [](DependencyData const& dp) { return dp.name == "Result"; }); - assert(it != vkData.dependencies.end()); - writeTypeEnum(ofs, *it, vkData.enums.find(it->name)->second); - writeEnumsToString(ofs, *it, vkData.enums.find(it->name)->second); - vkData.dependencies.erase(it); - ofs << exceptionHeader; - - ofs << "} // namespace vk" << std::endl - << std::endl - << "namespace std" << std::endl - << "{" << std::endl - << " template <>" << std::endl - << " struct is_error_code_enum : public true_type" << std::endl - << " {};" << std::endl - << "}" << std::endl - << std::endl - << "namespace vk" << std::endl - << "{" << std::endl; - - writeTypes(ofs, vkData, defaultValues); - writeEnumsToString(ofs, vkData); - - ofs << "} // namespace vk" << std::endl - << std::endl - << "#endif" << std::endl; - } - catch (std::exception e) - { - std::cout << "caught exception: " << e.what() << std::endl; - } - catch (...) - { - std::cout << "caught unknown exception" << std::endl; - } -} +// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +const std::string nvidiaLicenseHeader( +"// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved.\n" +"//\n" +"// Redistribution and use in source and binary forms, with or without\n" +"// modification, are permitted provided that the following conditions\n" +"// are met:\n" +"// * Redistributions of source code must retain the above copyright\n" +"// notice, this list of conditions and the following disclaimer.\n" +"// * Redistributions in binary form must reproduce the above copyright\n" +"// notice, this list of conditions and the following disclaimer in the\n" +"// documentation and/or other materials provided with the distribution.\n" +"// * Neither the name of NVIDIA CORPORATION nor the names of its\n" +"// contributors may be used to endorse or promote products derived\n" +"// from this software without specific prior written permission.\n" +"//\n" +"// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY\n" +"// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" +"// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n" +"// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n" +"// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n" +"// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n" +"// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n" +"// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n" +"// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" +"// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" +"// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" +); + +const std::string exceptionHeader( + "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" + "# define noexcept _NOEXCEPT\n" + "#endif\n" + "\n" + " class ErrorCategoryImpl : public std::error_category\n" + " {\n" + " public:\n" + " virtual const char* name() const noexcept override { return \"vk::Result\"; }\n" + " virtual std::string message(int ev) const override { return to_string(static_cast(ev)); }\n" + " };\n" + "\n" + "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" + "# undef noexcept\n" + "#endif\n" + "\n" + " inline const std::error_category& errorCategory()\n" + " {\n" + " static ErrorCategoryImpl instance;\n" + " return instance;\n" + " }\n" + "\n" + " inline std::error_code make_error_code(Result e)\n" + " {\n" + " return std::error_code(static_cast(e), errorCategory());\n" + " }\n" + "\n" + " inline std::error_condition make_error_condition(Result e)\n" + " {\n" + " return std::error_condition(static_cast(e), errorCategory());\n" + " }\n" + "\n" + ); + +const std::string flagsHeader( +" template \n" +" class Flags\n" +" {\n" +" public:\n" +" Flags()\n" +" : m_mask(0)\n" +" {\n" +" }\n" +"\n" +" Flags(BitType bit)\n" +" : m_mask(static_cast(bit))\n" +" {\n" +" }\n" +"\n" +" Flags(Flags const& rhs)\n" +" : m_mask(rhs.m_mask)\n" +" {\n" +" }\n" +"\n" +" Flags & operator=(Flags const& rhs)\n" +" {\n" +" m_mask = rhs.m_mask;\n" +" return *this;\n" +" }\n" +"\n" +" Flags & operator|=(Flags const& rhs)\n" +" {\n" +" m_mask |= rhs.m_mask;\n" +" return *this;\n" +" }\n" +"\n" +" Flags & operator&=(Flags const& rhs)\n" +" {\n" +" m_mask &= rhs.m_mask;\n" +" return *this;\n" +" }\n" +"\n" +" Flags & operator^=(Flags const& rhs)\n" +" {\n" +" m_mask ^= rhs.m_mask;\n" +" return *this;\n" +" }\n" +"\n" +" Flags operator|(Flags const& rhs) const\n" +" {\n" +" Flags result(*this);\n" +" result |= rhs;\n" +" return result;\n" +" }\n" +"\n" +" Flags operator&(Flags const& rhs) const\n" +" {\n" +" Flags result(*this);\n" +" result &= rhs;\n" +" return result;\n" +" }\n" +"\n" +" Flags operator^(Flags const& rhs) const\n" +" {\n" +" Flags result(*this);\n" +" result ^= rhs;\n" +" return result;\n" +" }\n" +"\n" +" bool operator!() const\n" +" {\n" +" return !m_mask;\n" +" }\n" +"\n" +" bool operator==(Flags const& rhs) const\n" +" {\n" +" return m_mask == rhs.m_mask;\n" +" }\n" +"\n" +" bool operator!=(Flags const& rhs) const\n" +" {\n" +" return m_mask != rhs.m_mask;\n" +" }\n" +"\n" +" explicit operator bool() const\n" +" {\n" +" return !!m_mask;\n" +" }\n" +"\n" +" explicit operator MaskType() const\n" +" {\n" +" return m_mask;\n" +" }\n" +"\n" +" private:\n" +" MaskType m_mask;\n" +" };\n" +" \n" +" template \n" +" Flags operator|(BitType bit, Flags const& flags)\n" +" {\n" +" return flags | bit;\n" +" }\n" +" \n" +" template \n" +" Flags operator&(BitType bit, Flags const& flags)\n" +" {\n" +" return flags & bit;\n" +" }\n" +" \n" +" template \n" +" Flags operator^(BitType bit, Flags const& flags)\n" +" {\n" +" return flags ^ bit;\n" +" }\n" +"\n" +); + +std::string const optionalClassHeader = ( + " template \n" + " class Optional\n" + " {\n" + " public:\n" + " Optional(RefType & reference) { m_ptr = &reference; }\n" + " Optional(std::nullptr_t) { m_ptr = nullptr; }\n" + "\n" + " operator RefType*() const { return m_ptr; }\n" + " RefType const* operator->() const { return m_ptr; }\n" + " explicit operator bool() const { return !!m_ptr; }\n" + "\n" + " private:\n" + " RefType *m_ptr;\n" + " };\n" + "\n" +); + +std::string const arrayProxyHeader = ( + " template \n" + " class ArrayProxy\n" + " {\n" + " public:\n" + " ArrayProxy(std::nullptr_t)\n" + " : m_count(0)\n" + " , m_ptr(nullptr)\n" + " {}\n" + "\n" + " ArrayProxy(T & ptr)\n" + " : m_count(1)\n" + " , m_ptr(&ptr)\n" + " {}\n" + "\n" + " ArrayProxy(uint32_t count, T * ptr)\n" + " : m_count(count)\n" + " , m_ptr(ptr)\n" + " {}\n" + "\n" + " template \n" + " ArrayProxy(std::array::type, N> & data)\n" + " : m_count(N)\n" + " , m_ptr(data.data())\n" + " {}\n" + "\n" + " template \n" + " ArrayProxy(std::array::type, N> const& data)\n" + " : m_count(N)\n" + " , m_ptr(data.data())\n" + " {}\n" + "\n" + " template ::type>>\n" + " ArrayProxy(std::vector::type, Allocator> & data)\n" + " : m_count(static_cast(data.size()))\n" + " , m_ptr(data.data())\n" + " {}\n" + "\n" + " template ::type>>\n" + " ArrayProxy(std::vector::type, Allocator> const& data)\n" + " : m_count(static_cast(data.size()))\n" + " , m_ptr(data.data())\n" + " {}\n" + "\n" + " ArrayProxy(std::initializer_list const& data)\n" + " : m_count(static_cast(data.end() - data.begin()))\n" + " , m_ptr(data.begin())\n" + " {}\n" + "\n" + " uint32_t size() const\n" + " {\n" + " return m_count;\n" + " }\n" + "\n" + " T * data() const\n" + " {\n" + " return m_ptr;\n" + " }\n" + "\n" + " private:\n" + " uint32_t m_count;\n" + " T * m_ptr;\n" + " };\n" + "\n" +); + +std::string const versionCheckHeader = ( + "#if !defined(VK_CPP_HAS_UNRESTRICTED_UNIONS)\n" + "# if defined(__clang__)\n" + "# if __has_feature(cxx_unrestricted_unions)\n" + "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" + "# endif\n" + "# elif defined(__GNUC__)\n" + "# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)\n" + "# if 40600 <= GCC_VERSION\n" + "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" + "# endif\n" + "# elif defined(_MSC_VER)\n" + "# if 1900 <= _MSC_VER\n" + "# define VK_CPP_HAS_UNRESTRICTED_UNIONS\n" + "# endif\n" + "# endif\n" + "#endif\n" + "\n" + ); + +std::string const resultValueHeader = ( + " template \n" + " struct ResultValue\n" + " {\n" + " ResultValue( Result r, T & v )\n" + " : result( r )\n" + " , value( v )\n" + " {}\n" + "\n" + " Result result;\n" + " T value;\n" + " };\n" + "\n" + " template \n" + " struct ResultValueType\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " typedef ResultValue type;\n" + "#else\n" + " typedef T type;\n" + "#endif\n" + " };\n" + "\n" + " template <>" + " struct ResultValueType\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " typedef Result type;\n" + "#else\n" + " typedef void type;\n" + "#endif\n" + " };\n" + "\n" + ); + +std::string const createResultValueHeader = ( + " inline ResultValueType::type createResultValue( Result result, char const * message )\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " assert( result == Result::eSuccess );\n" + " return result;\n" + "#else\n" + " if ( result != Result::eSuccess )\n" + " {\n" + " throw std::system_error( result, message );\n" + " }\n" + "#endif\n" + " }\n" + "\n" + " template \n" + " inline typename ResultValueType::type createResultValue( Result result, T & data, char const * message )\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " assert( result == Result::eSuccess );\n" + " return ResultValue( result, data );\n" + "#else\n" + " if ( result != Result::eSuccess )\n" + " {\n" + " throw std::system_error( result, message );\n" + " }\n" + " return data;\n" + "#endif\n" + " }\n" + "\n" + " inline Result createResultValue( Result result, char const * message, std::initializer_list successCodes )\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() );\n" + "#else\n" + " if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )\n" + " {\n" + " throw std::system_error( result, message );\n" + " }\n" + "#endif\n" + " return result;\n" + " }\n" + "\n" + " template \n" + " inline ResultValue createResultValue( Result result, T & data, char const * message, std::initializer_list successCodes )\n" + " {\n" + "#ifdef VK_CPP_NO_EXCEPTIONS\n" + " assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() );\n" + "#else\n" + " if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )\n" + " {\n" + " throw std::system_error( result, message );\n" + " }\n" + "#endif\n" + " return ResultValue( result, data );\n" + " }\n" + "\n" + ); + +// trim from end +std::string trimEnd(std::string const& input) +{ + std::string result = input; + result.erase(std::find_if(result.rbegin(), result.rend(), std::not1(std::ptr_fun(std::isspace))).base(), result.end()); + return result; +} + +struct MemberData +{ + std::string type; + std::string name; + std::string arraySize; + std::string pureType; + std::string len; + bool optional; +}; + +struct CommandData +{ + CommandData() + : handleCommand(false) + , twoStep(false) + {} + + std::string returnType; + std::vector arguments; + std::vector successCodes; + std::string protect; + bool handleCommand; + bool twoStep; +}; + +struct DependencyData +{ + enum class Category + { + COMMAND, + ENUM, + FLAGS, + FUNC_POINTER, + HANDLE, + REQUIRED, + SCALAR, + STRUCT, + UNION + }; + + DependencyData(Category c, std::string const& n) + : category(c) + , name(n) + {} + + Category category; + std::string name; + std::set dependencies; +}; + +struct NameValue +{ + std::string name; + std::string value; +}; + +struct EnumData +{ + bool bitmask; + std::string prefix; + std::string postfix; + std::vector members; + std::string protect; + + void addEnum(std::string const & name, std::string const& tag, bool appendTag); +}; + +struct FlagData +{ + std::string protect; +}; + +struct HandleData +{ + std::vector commands; +}; + +struct ScalarData +{ + std::string protect; +}; + +struct StructData +{ + StructData() + : returnedOnly(false) + {} + + bool returnedOnly; + std::vector members; + std::string protect; +}; + +struct VkData +{ + std::map commands; + std::list dependencies; + std::map enums; + std::map flags; + std::map handles; + std::map scalars; + std::map structs; + std::set tags; + std::string typesafeCheck; + std::string version; + std::set vkTypes; + std::string vulkanLicenseHeader; +}; + +void createDefaults( VkData const& vkData, std::map & defaultValues ); +std::string determineFunctionName(std::string const& name, CommandData const& commandData); +std::string determineReturnType(CommandData const& commandData, size_t returnIndex, bool isVector = false); +void enterProtect(std::ofstream &ofs, std::string const& protect); +std::string extractTag(std::string const& name); +size_t findReturnIndex(CommandData const& commandData, std::map const& vectorParameters); +std::string findTag(std::string const& name, std::set const& tags); +size_t findTemplateIndex(CommandData const& commandData, std::map const& vectorParameters); +std::string generateEnumNameForFlags(std::string const& name); +std::map getVectorParameters(CommandData const& commandData); +bool hasPointerArguments(CommandData const& commandData); +bool isVectorSizeParameter(std::map const& vectorParameters, size_t idx); +void leaveProtect(std::ofstream &ofs, std::string const& protect); +bool noDependencies(std::set const& dependencies, std::map & listedTypes); +bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ); +std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData); +void readCommands( tinyxml2::XMLElement * element, VkData & vkData ); +void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData); +void readComment(tinyxml2::XMLElement * element, std::string & header); +void readEnums( tinyxml2::XMLElement * element, VkData & vkData ); +void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::string const& tag ); +void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag); +void readExtensions( tinyxml2::XMLElement * element, VkData & vkData ); +void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData); +void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ); +void readTypeBitmask( tinyxml2::XMLElement * element, VkData & vkData); +void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ); +void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ); +void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData); +void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ); +void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); +void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ); +void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); +void readTags(tinyxml2::XMLElement * element, std::set & tags); +void readTypes(tinyxml2::XMLElement * element, VkData & vkData); +void sortDependencies( std::list & dependencies ); +std::string reduceName(std::string const& name); +std::string strip(std::string const& value, std::string const& prefix, std::string const& tag = std::string()); +std::string stripCommand(std::string const& value); +std::string toCamelCase(std::string const& value); +std::string toUpperCase(std::string const& name); +void writeCall(std::ofstream & ofs, std::string const& name, size_t templateIndex, CommandData const& commandData, std::set const& vkTypes, std::map const& vectorParameters, size_t returnIndex, bool firstCall); +void writeEnumsToString(std::ofstream & ofs, VkData const& vkData); +void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::vector const& successCodes); +void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes, size_t returnIndex, std::map const& vectorParameters); +void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map const& vectorParameters); +void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set const& vkTypes); +void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set const& vkTypes, std::map const& defaultValues ); +void writeStructSetter( std::ofstream & ofs, std::string const& name, MemberData const& memberData, std::set const& vkTypes, std::map const& structs ); +void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes ); +void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes); +void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes); +void writeTypeEnum(std::ofstream & ofs, DependencyData const& dependencyData, EnumData const& enumData); +void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, FlagData const& flagData ); +void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies); +void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ); +void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ); +void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ); +void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues); +void writeVersionCheck(std::ofstream & ofs, std::string const& version); +void writeTypesafeCheck(std::ofstream & ofs, std::string const& typesafeCheck); + +void EnumData::addEnum(std::string const & name, std::string const& tag, bool appendTag) +{ + assert(tag.empty() || (name.find(tag) != std::string::npos)); + members.push_back(NameValue()); + members.back().name = "e" + toCamelCase(strip(name, prefix, tag)); + members.back().value = name; + if (!postfix.empty()) + { + size_t pos = members.back().name.find(postfix); + if (pos != std::string::npos) + { + members.back().name.erase(pos); + } + } + if (appendTag && !tag.empty()) + { + members.back().name += tag; + } +} + +void createDefaults( VkData const& vkData, std::map & defaultValues ) +{ + for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) + { + assert( defaultValues.find( it->name ) == defaultValues.end() ); + switch( it->category ) + { + case DependencyData::Category::COMMAND : // commands should never be asked for defaults + break; + case DependencyData::Category::ENUM : + { + assert(vkData.enums.find(it->name) != vkData.enums.end()); + EnumData const & enumData = vkData.enums.find(it->name)->second; + if (!enumData.members.empty()) + { + defaultValues[it->name] = it->name + "::" + vkData.enums.find(it->name)->second.members.front().name; + } + else + { + defaultValues[it->name] = it->name + "()"; + } + } + break; + case DependencyData::Category::FLAGS : + case DependencyData::Category::HANDLE: + case DependencyData::Category::STRUCT: + case DependencyData::Category::UNION : // just call the default constructor for flags, structs, and structs (which are mapped to classes) + defaultValues[it->name] = it->name + "()"; + break; + case DependencyData::Category::FUNC_POINTER : // func_pointers explicitly have no default! + defaultValues[it->name]; + break; + case DependencyData::Category::REQUIRED : // all required default to "0" + case DependencyData::Category::SCALAR : // all scalars default to "0" + defaultValues[it->name] = "0"; + break; + default : + assert( false ); + break; + } + } +} + +std::string determineFunctionName(std::string const& name, CommandData const& commandData) +{ + if (commandData.handleCommand) + { + std::string strippedName = name; + std::string searchName = commandData.arguments[0].pureType; + size_t pos = name.find(searchName); + if (pos == std::string::npos) + { + assert(isupper(searchName[0])); + searchName[0] = tolower(searchName[0]); + pos = name.find(searchName); + } + if (pos != std::string::npos) + { + strippedName.erase(pos, commandData.arguments[0].pureType.length()); + } + else if ((commandData.arguments[0].pureType == "CommandBuffer") && (name.find("cmd") == 0)) + { + strippedName.erase(0, 3); + pos = 0; + } + if (pos == 0) + { + assert(isupper(strippedName[0])); + strippedName[0] = tolower(strippedName[0]); + } + return strippedName; + } + return name; +} + +std::string determineReturnType(CommandData const& commandData, size_t returnIndex, bool isVector) +{ + std::string returnType; + if ( (returnIndex != ~0) + && ( (commandData.returnType == "void") + || ( (commandData.returnType == "Result") + && ( (commandData.successCodes.size() == 1) + || ( (commandData.successCodes.size() == 2) + && (commandData.successCodes[1] == "eIncomplete") + && commandData.twoStep))))) + { + if (isVector) + { + if (commandData.arguments[returnIndex].pureType == "void") + { + returnType = "std::vector"; + } + else + { + returnType = "std::vector<" + commandData.arguments[returnIndex].pureType + ",Allocator>"; + } + } + else + { + assert(commandData.arguments[returnIndex].type.back() == '*'); + assert(commandData.arguments[returnIndex].type.find("const") == std::string::npos); + returnType = commandData.arguments[returnIndex].type; + returnType.pop_back(); + } + } + else if ((commandData.returnType == "Result") && (commandData.successCodes.size() == 1)) + { + // an original return of type "Result" with less just one successCode is changed to void, errors throw an exception + returnType = "void"; + } + else + { + // the return type just stays the original return type + returnType = commandData.returnType; + } + return returnType; +} + +void enterProtect(std::ofstream &ofs, std::string const& protect) +{ + if (!protect.empty()) + { + ofs << "#ifdef " << protect << std::endl; + } +} + +std::string extractTag(std::string const& name) +{ + // the name is supposed to look like: VK__ + size_t start = name.find('_'); + assert(start != std::string::npos); + size_t end = name.find('_', start + 1); + assert(end != std::string::npos); + return name.substr(start + 1, end - start - 1); +} + +size_t findReturnIndex(CommandData const& commandData, std::map const& vectorParameters) +{ + if ((commandData.returnType == "Result") || (commandData.returnType == "void")) + { + for (size_t i = 0; i < commandData.arguments.size(); i++) + { + if ((commandData.arguments[i].type.find('*') != std::string::npos) && (commandData.arguments[i].type.find("const") == std::string::npos) && !isVectorSizeParameter(vectorParameters, i) + && ((vectorParameters.find(i) == vectorParameters.end()) || commandData.twoStep || (commandData.successCodes.size() == 1))) + { +#if !defined(NDEBUG) + for (size_t j = i + 1; j < commandData.arguments.size(); j++) + { + assert((commandData.arguments[j].type.find('*') == std::string::npos) || (commandData.arguments[j].type.find("const") != std::string::npos)); + } +#endif + return i; + } + } + } + return ~0; +} + +std::string findTag(std::string const& name, std::set const& tags) +{ + for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) + { + size_t pos = name.find(*it); + if ((pos != std::string::npos) && (pos == name.length() - it->length())) + { + return *it; + } + } + return ""; +} + +size_t findTemplateIndex(CommandData const& commandData, std::map const& vectorParameters) +{ + for (size_t i = 0; i < commandData.arguments.size(); i++) + { + if ((commandData.arguments[i].name == "pData") || (commandData.arguments[i].name == "pValues")) + { + assert(vectorParameters.find(i) != vectorParameters.end()); + return i; + } + } + return ~0; +} + +std::string getEnumName(std::string const& name) // get vkcpp enum name from vk enum name +{ + return strip(name, "Vk"); +} + +std::string generateEnumNameForFlags(std::string const& name) +{ + std::string generatedName = name; + size_t pos = generatedName.rfind("Flags"); + assert(pos != std::string::npos); + generatedName.replace(pos, 5, "FlagBits"); + return generatedName; +} + +std::map getVectorParameters(CommandData const& commandData) +{ + std::map lenParameters; + for (size_t i = 0; i < commandData.arguments.size(); i++) + { + if (!commandData.arguments[i].len.empty()) + { + lenParameters.insert(std::make_pair(i, ~0)); + for (size_t j = 0; j < commandData.arguments.size(); j++) + { + if (commandData.arguments[i].len == commandData.arguments[j].name) + { + lenParameters[i] = j; + } + } + assert( (lenParameters[i] != ~0) + || (commandData.arguments[i].len == "dataSize/4") + || (commandData.arguments[i].len == "latexmath:[$dataSize \\over 4$]") + || (commandData.arguments[i].len == "null-terminated") + || (commandData.arguments[i].len == "pAllocateInfo->descriptorSetCount") + || (commandData.arguments[i].len == "pAllocateInfo->commandBufferCount")); + assert((lenParameters[i] == ~0) || (lenParameters[i] < i)); + } + } + return lenParameters; +} + +bool hasPointerArguments(CommandData const& commandData) +{ + for (size_t i = 0; i < commandData.arguments.size(); i++) + { + size_t pos = commandData.arguments[i].type.find('*'); + if ((pos != std::string::npos) && (commandData.arguments[i].type.find('*', pos + 1) == std::string::npos)) + { + return true; + } + } + return false; +} + +bool isVectorSizeParameter(std::map const& vectorParameters, size_t idx) +{ + for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) + { + if (it->second == idx) + { + return true; + } + } + return false; +} + +void leaveProtect(std::ofstream &ofs, std::string const& protect) +{ + if (!protect.empty()) + { + ofs << "#endif /*" << protect << "*/" << std::endl; + } +} + +bool noDependencies(std::set const& dependencies, std::set & listedTypes) +{ + bool ok = true; + for ( std::set::const_iterator it = dependencies.begin() ; it != dependencies.end() && ok ; ++it ) + { + ok = ( listedTypes.find( *it ) != listedTypes.end() ); + } + return( ok ); +} + +bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ) +{ + arguments.push_back( MemberData() ); + MemberData & arg = arguments.back(); + + if (element->Attribute("len")) + { + arg.len = element->Attribute("len"); + } + + tinyxml2::XMLNode * child = element->FirstChild(); + assert( child ); + if ( child->ToText() ) + { + std::string value = trimEnd(child->Value()); + assert( (value == "const") || (value == "struct") ); + arg.type = value + " "; + child = child->NextSibling(); + assert( child ); + } + + assert( child->ToElement() ); + assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); + std::string type = strip( child->ToElement()->GetText(), "Vk" ); + typeData.dependencies.insert( type ); + arg.type += type; + arg.pureType = type; + + child = child->NextSibling(); + assert( child ); + if ( child->ToText() ) + { + std::string value = trimEnd(child->Value()); + assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); + arg.type += value; + child = child->NextSibling(); + } + + assert( child->ToElement() && ( strcmp( child->Value(), "name" ) == 0 ) ); + arg.name = child->ToElement()->GetText(); + + if ( arg.name.back() == ']' ) + { + assert( !child->NextSibling() ); + size_t pos = arg.name.find( '[' ); + assert( pos != std::string::npos ); + arg.arraySize = arg.name.substr( pos + 1, arg.name.length() - 2 - pos ); + arg.name.erase( pos ); + } + + child = child->NextSibling(); + if ( child ) + { + if ( child->ToText() ) + { + std::string value = child->Value(); + if ( value == "[" ) + { + child = child->NextSibling(); + assert( child ); + assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); + arg.arraySize = child->ToElement()->GetText(); + child = child->NextSibling(); + assert( child ); + assert( child->ToText() ); + assert( strcmp( child->Value(), "]" ) == 0 ); + assert( !child->NextSibling() ); + } + else + { + assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); + arg.arraySize = value.substr( 1, value.length() - 2 ); + assert( !child->NextSibling() ); + } + } + } + + arg.optional = element->Attribute("optional") && (strcmp(element->Attribute("optional"), "true") == 0); + + return element->Attribute("optional") && (strcmp(element->Attribute("optional"), "false,true") == 0); +} + +std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * typeElement = element->FirstChildElement(); + assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) ); + tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); + assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) ); + assert( !nameElement->NextSiblingElement() ); + + std::string type = strip( typeElement->GetText(), "Vk" ); + std::string name = stripCommand( nameElement->GetText() ); + + vkData.dependencies.push_back( DependencyData( DependencyData::Category::COMMAND, name ) ); + assert( vkData.commands.find( name ) == vkData.commands.end() ); + std::map::iterator it = vkData.commands.insert( std::make_pair( name, CommandData() ) ).first; + it->second.returnType = type; + + return it; +} + +void readCommands(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + assert( child ); + do + { + assert( strcmp( child->Value(), "command" ) == 0 ); + readCommandsCommand( child, vkData ); + } while ( child = child->NextSiblingElement() ); +} + +void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + assert( child && ( strcmp( child->Value(), "proto" ) == 0 ) ); + + std::map::iterator it = readCommandProto(child, vkData); + + if (element->Attribute("successcodes")) + { + std::string successCodes = element->Attribute("successcodes"); + size_t start = 0, end; + do + { + end = successCodes.find(',', start); + std::string code = successCodes.substr(start, end - start); + std::string tag = findTag(code, vkData.tags); + it->second.successCodes.push_back("e" + toCamelCase(strip(code, "VK_", tag)) + tag); + start = end + 1; + } while (end != std::string::npos); + } + + // HACK: the current vk.xml misses to specify successcodes on command vkCreateDebugReportCallbackEXT! + if (it->first == "createDebugReportCallbackEXT") + { + it->second.successCodes.clear(); + it->second.successCodes.push_back("eSuccess"); + } + + while ( child = child->NextSiblingElement() ) + { + std::string value = child->Value(); + if ( value == "param" ) + { + it->second.twoStep |= readCommandParam(child, vkData.dependencies.back(), it->second.arguments); + } + else + { + assert( ( value == "implicitexternsyncparams" ) || ( value == "validity" ) ); + } + } + + // HACK: the current vk.xml misses to specify on param pSparseMemoryRequirementCount on command vkGetImageSparseMemoryRequirements! + if (it->first == "getImageSparseMemoryRequirements") + { + it->second.twoStep = true; + } + + assert(!it->second.arguments.empty()); + std::map::iterator hit = vkData.handles.find(it->second.arguments[0].pureType); + if (hit != vkData.handles.end()) + { + hit->second.commands.push_back(it->first); + it->second.handleCommand = true; + DependencyData const& dep = vkData.dependencies.back(); + std::list::iterator dit = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [hit](DependencyData const& dd) { return dd.name == hit->first; }); + for (std::set::const_iterator depit = dep.dependencies.begin(); depit != dep.dependencies.end(); ++depit) + { + if (*depit != hit->first) + { + dit->dependencies.insert(*depit); + } + } + } +} + +void readComment(tinyxml2::XMLElement * element, std::string & header) +{ + assert(element->GetText()); + assert(header.empty()); + header = element->GetText(); + assert(header.find("\nCopyright") == 0); + + size_t pos = header.find("\n\n-----"); + assert(pos != std::string::npos); + header.erase(pos); + + for (size_t pos = header.find('\n'); pos != std::string::npos; pos = header.find('\n', pos + 1)) + { + header.replace(pos, 1, "\n// "); + } + + header += "\n\n// This header is generated from the Khronos Vulkan XML API Registry."; +} + +void readEnums( tinyxml2::XMLElement * element, VkData & vkData ) +{ + assert( element->Attribute( "name" ) ); + std::string name = getEnumName(element->Attribute("name")); + if ( name != "API Constants" ) + { + vkData.dependencies.push_back( DependencyData( DependencyData::Category::ENUM, name ) ); + std::map::iterator it = vkData.enums.insert( std::make_pair( name, EnumData() ) ).first; + std::string tag; + + if (name == "Result") + { + // special handling for VKResult, as its enums just have VK_ in common + it->second.prefix = "VK_"; + } + else + { + assert(element->Attribute("type")); + std::string type = element->Attribute("type"); + assert((type == "bitmask") || (type == "enum")); + it->second.bitmask = (type == "bitmask"); + std::string prefix, postfix; + if (it->second.bitmask) + { + size_t pos = name.find("FlagBits"); + assert(pos != std::string::npos); + it->second.prefix = "VK" + toUpperCase(name.substr(0, pos)) + "_"; + it->second.postfix = "Bit"; + } + else + { + it->second.prefix = "VK" + toUpperCase(name) + "_"; + } + + // if the enum name contains a tag remove it from the prefix to generate correct enum value names. + for (std::set::const_iterator tit = vkData.tags.begin(); tit != vkData.tags.end(); ++tit) + { + size_t pos = it->second.prefix.find(*tit); + if ((pos != std::string::npos) && (pos == it->second.prefix.length() - tit->length() - 1)) + { + it->second.prefix.erase(pos); + tag = *tit; + break; + } + } + } + + readEnumsEnum( element, it->second, tag ); + + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); + } +} + +void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::string const& tag ) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + if ( child->Attribute( "name" ) ) + { + enumData.addEnum(child->Attribute("name"), tag, false); + } + } while ( child = child->NextSiblingElement() ); +} + +void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + std::string value = child->Value(); + + if ( value == "command" ) + { + assert(child->Attribute("name")); + std::string name = stripCommand(child->Attribute("name")); + std::map::iterator cit = vkData.commands.find(name); + assert(cit != vkData.commands.end()); + cit->second.protect = protect; + } + else if (value == "type") + { + assert(child->Attribute("name")); + std::string name = strip(child->Attribute("name"), "Vk"); + std::map::iterator eit = vkData.enums.find(name); + if (eit != vkData.enums.end()) + { + eit->second.protect = protect; + } + else + { + std::map::iterator fit = vkData.flags.find(name); + if (fit != vkData.flags.end()) + { + fit->second.protect = protect; + + // if the enum of this flags is auto-generated, protect it as well + std::string enumName = generateEnumNameForFlags(name); + std::map::iterator eit = vkData.enums.find(enumName); + assert(eit != vkData.enums.end()); + if (eit->second.members.empty()) + { + eit->second.protect = protect; + } + } + else + { + std::map::iterator scit = vkData.scalars.find(name); + if (scit != vkData.scalars.end()) + { + scit->second.protect = protect; + } + else + { + std::map::iterator stit = vkData.structs.find(name); + assert(stit != vkData.structs.end() && stit->second.protect.empty()); + stit->second.protect = protect; + } + } + } + } + else if ( value == "enum") + { + // TODO process enums which don't extend existing enums + if (child->Attribute("extends")) + { + assert(child->Attribute("name")); + assert(vkData.enums.find(getEnumName(child->Attribute("extends"))) != vkData.enums.end()); + assert(!!child->Attribute("bitpos") + !!child->Attribute("offset") + !!child->Attribute("value") == 1); + vkData.enums[getEnumName(child->Attribute("extends"))].addEnum(child->Attribute("name"), child->Attribute("value") ? "" : tag, true ); + } + } + else + { + assert(value=="usage"); + } + } while ( child = child->NextSiblingElement() ); +} + +void readExtensions(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + assert( child ); + do + { + assert( strcmp( child->Value(), "extension" ) == 0 ); + readExtensionsExtension( child, vkData ); + } while ( child = child->NextSiblingElement() ); +} + +void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData) +{ + assert( element->Attribute( "name" ) ); + std::string tag = extractTag(element->Attribute("name")); + assert(vkData.tags.find(tag) != vkData.tags.end()); + + // don't parse disabled extensions + if (strcmp(element->Attribute("supported"), "disabled") == 0) + { + return; + } + + std::string protect; + if (element->Attribute("protect")) + { + protect = element->Attribute( "protect" ); + } + + tinyxml2::XMLElement * child = element->FirstChildElement(); + assert( child && ( strcmp( child->Value(), "require" ) == 0 ) && !child->NextSiblingElement() ); + readExtensionRequire( child, vkData, protect, tag ); +} + +void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ) +{ + tinyxml2::XMLElement * typeElement = element->FirstChildElement(); + assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() ); + std::string type = typeElement->GetText(); + assert( ( type == "uint32_t" ) || ( type == "uint64_t" ) ); + + tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); + assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); + std::string name = strip( nameElement->GetText(), "Vk" ); + + // skip "Flags", + if ( name != "Flags" ) + { + dependencies.push_back( DependencyData( DependencyData::Category::SCALAR, name ) ); + dependencies.back().dependencies.insert( type ); + } + else + { + assert( type == "uint32_t" ); + } +} + +void readTypeBitmask(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * typeElement = element->FirstChildElement(); + assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() && ( strcmp( typeElement->GetText(), "VkFlags" ) == 0 ) ); + std::string type = typeElement->GetText(); + + tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); + assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); + std::string name = strip( nameElement->GetText(), "Vk" ); + + assert( !nameElement->NextSiblingElement() ); + + std::string requires; + if (element->Attribute("requires")) + { + requires = strip(element->Attribute("requires"), "Vk"); + } + else { + // Generate FlagBits name + requires = generateEnumNameForFlags(name); + vkData.dependencies.push_back(DependencyData(DependencyData::Category::ENUM, requires)); + std::map::iterator it = vkData.enums.insert(std::make_pair(requires, EnumData())).first; + it->second.bitmask = true; + vkData.vkTypes.insert(requires); + } + + vkData.dependencies.push_back( DependencyData( DependencyData::Category::FLAGS, name ) ); + vkData.dependencies.back().dependencies.insert( requires ); + vkData.flags.insert(std::make_pair(name, FlagData())); + + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); +} + +void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + if (child && (strcmp(child->GetText(), "VK_HEADER_VERSION") == 0)) + { + vkData.version = element->LastChild()->ToText()->Value(); + } + else if (element->Attribute("name") && strcmp(element->Attribute("name"), "VK_DEFINE_NON_DISPATCHABLE_HANDLE") == 0) + { + std::string text = element->LastChild()->ToText()->Value(); + size_t start = text.find('#'); + size_t end = text.find_first_of("\r\n", start + 1); + vkData.typesafeCheck = text.substr(start, end - start); + } +} + +void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + assert( child && ( strcmp( child->Value(), "name" ) == 0 ) && child->GetText() ); + dependencies.push_back( DependencyData( DependencyData::Category::FUNC_POINTER, child->GetText() ) ); +} + +void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * typeElement = element->FirstChildElement(); + assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() ); +#if !defined(NDEBUG) + std::string type = typeElement->GetText(); + assert( type.find( "VK_DEFINE" ) == 0 ); +#endif + + tinyxml2::XMLElement * nameElement = typeElement->NextSiblingElement(); + assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); + std::string name = strip( nameElement->GetText(), "Vk" ); + + vkData.dependencies.push_back( DependencyData( DependencyData::Category::HANDLE, name ) ); + + assert(vkData.vkTypes.find(name) == vkData.vkTypes.end()); + vkData.vkTypes.insert(name); + assert(vkData.handles.find(name) == vkData.handles.end()); + vkData.handles[name]; // add this to the handles map +} + +void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) +{ + members.push_back( MemberData() ); + MemberData & member = members.back(); + + tinyxml2::XMLNode * child = element->FirstChild(); + assert( child ); + if ( child->ToText()) + { + std::string value = trimEnd(child->Value()); + assert( (value == "const") || (value == "struct") ); + member.type = value + " "; + child = child->NextSibling(); + assert( child ); + } + + assert( child->ToElement() ); + assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); + std::string type = strip( child->ToElement()->GetText(), "Vk" ); + dependencies.insert( type ); + member.type += type; + member.pureType = type; + + child = child->NextSibling(); + assert( child ); + if ( child->ToText()) + { + std::string value = trimEnd(child->Value()); + assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); + member.type += value; + child = child->NextSibling(); + } + + assert( ( child->ToElement() && strcmp( child->Value(), "name" ) == 0 )); + member.name = child->ToElement()->GetText(); + + if ( member.name.back() == ']' ) + { + assert( !child->NextSibling() ); + size_t pos = member.name.find( '[' ); + assert( pos != std::string::npos ); + member.arraySize = member.name.substr( pos + 1, member.name.length() - 2 - pos ); + member.name.erase( pos ); + } + + child = child->NextSibling(); + if ( child ) + { + assert( member.arraySize.empty() ); + if ( child->ToText() ) + { + std::string value = child->Value(); + if ( value == "[" ) + { + child = child->NextSibling(); + assert( child ); + assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); + member.arraySize = child->ToElement()->GetText(); + child = child->NextSibling(); + assert( child ); + assert( child->ToText() ); + assert( strcmp( child->Value(), "]" ) == 0 ); + assert( !child->NextSibling() ); + } + else + { + assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); + member.arraySize = value.substr( 1, value.length() - 2 ); + assert( !child->NextSibling() ); + } + } + } +} + +void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ) +{ + assert( !element->Attribute( "returnedonly" ) || ( strcmp( element->Attribute( "returnedonly" ), "true" ) == 0 ) ); + + assert( element->Attribute( "name" ) ); + std::string name = strip( element->Attribute( "name" ), "Vk" ); + + if ( name == "Rect3D" ) + { + return; + } + + vkData.dependencies.push_back( DependencyData( DependencyData::Category::STRUCT, name ) ); + + assert( vkData.structs.find( name ) == vkData.structs.end() ); + std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; + it->second.returnedOnly = !!element->Attribute( "returnedonly" ); + + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + assert( child->Value() ); + std::string value = child->Value(); + if ( value == "member" ) + { + readTypeStructMember( child, it->second.members, vkData.dependencies.back().dependencies ); + } + else + { + assert( value == "validity" ); + } + } while ( child = child->NextSiblingElement() ); + + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); +} + +void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) +{ + members.push_back( MemberData() ); + MemberData & member = members.back(); + + tinyxml2::XMLNode * child = element->FirstChild(); + assert( child ); + if ( child->ToText() ) + { + assert( ( strcmp( child->Value(), "const" ) == 0 ) || ( strcmp( child->Value(), "struct" ) == 0 ) ); + member.type = std::string( child->Value() ) + " "; + child = child->NextSibling(); + assert( child ); + } + + assert( child->ToElement() ); + assert( ( strcmp( child->Value(), "type" ) == 0 ) && child->ToElement() && child->ToElement()->GetText() ); + std::string type = strip( child->ToElement()->GetText(), "Vk" ); + dependencies.insert( type ); + member.type += type; + member.pureType = type; + + child = child->NextSibling(); + assert( child ); + if ( child->ToText() ) + { + std::string value = child->Value(); + assert( ( value == "*" ) || ( value == "**" ) || ( value == "* const*" ) ); + member.type += value; + child = child->NextSibling(); + } + + assert( child->ToElement() && ( strcmp( child->Value(), "name" ) == 0 ) ); + member.name = child->ToElement()->GetText(); + + if ( member.name.back() == ']' ) + { + assert( !child->NextSibling() ); + size_t pos = member.name.find( '[' ); + assert( pos != std::string::npos ); + member.arraySize = member.name.substr( pos + 1, member.name.length() - 2 - pos ); + member.name.erase( pos ); + } + + child = child->NextSibling(); + if ( child ) + { + if ( child->ToText() ) + { + std::string value = child->Value(); + if ( value == "[" ) + { + child = child->NextSibling(); + assert( child ); + assert( child->ToElement() && ( strcmp( child->Value(), "enum" ) == 0 ) ); + member.arraySize = child->ToElement()->GetText(); + child = child->NextSibling(); + assert( child ); + assert( child->ToText() ); + assert( strcmp( child->Value(), "]" ) == 0 ); + assert( !child->NextSibling() ); + } + else + { + assert( ( value.front() == '[' ) && ( value.back() == ']' ) ); + member.arraySize = value.substr( 1, value.length() - 2 ); + assert( !child->NextSibling() ); + } + } + } +} + +void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ) +{ + assert( element->Attribute( "name" ) ); + std::string name = strip( element->Attribute( "name" ), "Vk" ); + + vkData.dependencies.push_back( DependencyData( DependencyData::Category::UNION, name ) ); + + assert( vkData.structs.find( name ) == vkData.structs.end() ); + std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; + + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + assert( strcmp( child->Value(), "member" ) == 0 ); + readTypeUnionMember( child, it->second.members, vkData.dependencies.back().dependencies ); + } while ( child = child->NextSiblingElement() ); + + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); +} + +void readTags(tinyxml2::XMLElement * element, std::set & tags) +{ + tags.insert("EXT"); + tags.insert("KHR"); + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + assert(child->Attribute("name")); + tags.insert(child->Attribute("name")); + } while (child = child->NextSiblingElement()); +} + +void readTypes(tinyxml2::XMLElement * element, VkData & vkData) +{ + tinyxml2::XMLElement * child = element->FirstChildElement(); + do + { + assert( strcmp( child->Value(), "type" ) == 0 ); + std::string type = child->Value(); + assert( type == "type" ); + if ( child->Attribute( "category" ) ) + { + std::string category = child->Attribute( "category" ); + if ( category == "basetype" ) + { + readTypeBasetype( child, vkData.dependencies ); + } + else if ( category == "bitmask" ) + { + readTypeBitmask( child, vkData); + } + else if ( category == "define" ) + { + readTypeDefine( child, vkData ); + } + else if ( category == "funcpointer" ) + { + readTypeFuncpointer( child, vkData.dependencies ); + } + else if ( category == "handle" ) + { + readTypeHandle( child, vkData ); + } + else if ( category == "struct" ) + { + readTypeStruct( child, vkData ); + } + else if ( category == "union" ) + { + readTypeUnion( child, vkData ); + } + else + { + assert( ( category == "enum" ) || ( category == "include" ) ); + } + } + else + { + assert( child->Attribute( "requires" ) && child->Attribute( "name" ) ); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::REQUIRED, child->Attribute( "name" ) ) ); + } + } while ( child = child->NextSiblingElement() ); +} + +void sortDependencies( std::list & dependencies ) +{ + std::set listedTypes = { "VkFlags" }; + std::list sortedDependencies; + + while ( !dependencies.empty() ) + { +#if !defined(NDEBUG) + bool ok = false; +#endif + for ( std::list::iterator it = dependencies.begin() ; it != dependencies.end() ; ++it ) + { + if ( noDependencies( it->dependencies, listedTypes ) ) + { + sortedDependencies.push_back( *it ); + listedTypes.insert( it->name ); + dependencies.erase( it ); +#if !defined(NDEBUG) + ok = true; +#endif + break; + } + } + assert( ok ); + } + + dependencies.swap(sortedDependencies); +} + +std::string reduceName(std::string const& name) +{ + std::string reducedName; + if ((name[0] == 'p') && (1 < name.length()) && (isupper(name[1]) || name[1] == 'p')) + { + reducedName = strip(name, "p"); + reducedName[0] = tolower(reducedName[0]); + } + else + { + reducedName = name; + } + + return reducedName; +} + +std::string strip(std::string const& value, std::string const& prefix, std::string const& postfix) +{ + std::string strippedValue = value; + if (strippedValue.find(prefix) == 0) + { + strippedValue.erase(0, prefix.length()); + } + if (!postfix.empty()) + { + size_t pos = strippedValue.rfind(postfix); + assert(pos != std::string::npos); + strippedValue.erase(pos); + } + return strippedValue; +} + +std::string stripCommand(std::string const& value) +{ + std::string stripped = strip(value, "vk"); + assert(isupper(stripped[0])); + stripped[0] = tolower(stripped[0]); + return stripped; +} + +std::string toCamelCase(std::string const& value) +{ + assert(!value.empty() && (isupper(value[0]) || isdigit(value[0]))); + std::string result; + result.reserve(value.size()); + result.push_back(value[0]); + for (size_t i = 1; i < value.size(); i++) + { + if (value[i] != '_') + { + if ((value[i - 1] == '_') || isdigit(value[i-1])) + { + result.push_back(value[i]); + } + else + { + result.push_back(tolower(value[i])); + } + } + } + return result; +} + +std::string toUpperCase(std::string const& name) +{ + assert(isupper(name.front())); + std::string convertedName; + + for (size_t i = 0; i const& vkTypes, std::map const& vectorParameters, size_t returnIndex, bool firstCall) +{ + std::map countIndices; + for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) + { + countIndices.insert(std::make_pair(it->second, it->first)); + } + if ((vectorParameters.size() == 1) + && ((commandData.arguments[vectorParameters.begin()->first].len == "dataSize/4") || (commandData.arguments[vectorParameters.begin()->first].len == "latexmath:[$dataSize \\over 4$]"))) + { + assert(commandData.arguments[3].name == "dataSize"); + countIndices.insert(std::make_pair(3, vectorParameters.begin()->first)); + } + + assert(islower(name[0])); + ofs << "vk" << static_cast(toupper(name[0])) << name.substr(1) << "( "; + size_t i = 0; + if (commandData.handleCommand) + { + ofs << "m_" << commandData.arguments[0].name; + i++; + } + for (; i < commandData.arguments.size(); i++) + { + if (0 < i) + { + ofs << ", "; + } + std::map::const_iterator it = countIndices.find(i); + if (it != countIndices.end()) + { + if ((returnIndex == it->second) && commandData.twoStep) + { + ofs << "&" << reduceName(commandData.arguments[it->first].name); + } + else + { + ofs << reduceName(commandData.arguments[it->second].name) << ".size() "; + if (templateIndex == it->second) + { + ofs << "* sizeof( T ) "; + } + } + } + else + { + it = vectorParameters.find(i); + if (it != vectorParameters.end()) + { + assert(commandData.arguments[it->first].type.back() == '*'); + if ((returnIndex == it->first) && commandData.twoStep && firstCall) + { + ofs << "nullptr"; + } + else + { + std::set::const_iterator vkit = vkTypes.find(commandData.arguments[it->first].pureType); + if ((vkit != vkTypes.end()) || (it->first == templateIndex)) + { + ofs << "reinterpret_cast<"; + if (commandData.arguments[it->first].type.find("const") != std::string::npos) + { + ofs << "const "; + } + if (vkit != vkTypes.end()) + { + ofs << "Vk"; + } + ofs << commandData.arguments[it->first].pureType << "*>( " << reduceName(commandData.arguments[it->first].name) << ".data() )"; + } + else if (commandData.arguments[it->first].pureType == "char") + { + ofs << reduceName(commandData.arguments[it->first].name); + if (commandData.arguments[it->first].optional) + { + ofs << " ? " << reduceName(commandData.arguments[it->first].name) << "->c_str() : nullptr"; + } + else + { + ofs << ".c_str()"; + } + } + else + { + ofs << reduceName(commandData.arguments[it->first].name) << ".data()"; + } + } + } + else if (vkTypes.find(commandData.arguments[i].pureType) != vkTypes.end()) + { + if (commandData.arguments[i].type.back() == '*') + { + if (commandData.arguments[i].type.find("const") != std::string::npos) + { + ofs << "reinterpret_cast( "; + if (commandData.arguments[i].optional) + { + ofs << "static_cast( "; + } + else + { + ofs << "&"; + } + ofs << reduceName(commandData.arguments[i].name) << (commandData.arguments[i].optional ? "))" : " )"); + } + else + { + assert(!commandData.arguments[i].optional); + ofs << "reinterpret_cast( &" << reduceName(commandData.arguments[i].name) << " )"; + } + } + else + { + ofs << "static_cast( " << commandData.arguments[i].name << " )"; + } + } + else + { + if (commandData.arguments[i].type.back() == '*') + { + if (commandData.arguments[i].type.find("const") != std::string::npos) + { + assert(commandData.arguments[i].type.find("char") != std::string::npos); + ofs << reduceName(commandData.arguments[i].name); + if (commandData.arguments[i].optional) + { + ofs << " ? " << reduceName(commandData.arguments[i].name) << "->c_str() : nullptr"; + } + else + { + ofs << ".c_str()"; + } + } + else + { + assert(commandData.arguments[i].type.find("char") == std::string::npos); + ofs << "&" << reduceName(commandData.arguments[i].name); + } + } + else + { + ofs << commandData.arguments[i].name; + } + } + } + } + ofs << " )"; +} + +void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::vector const& successCodes) +{ + assert(!successCodes.empty()); + ofs << indentation << " if ("; + if (successCodes.size() == 1) + { + assert(successCodes.front() == "eSuccess"); + ofs << " result != Result::eSuccess"; + } + else + { + for (size_t i = 0; i < successCodes.size() - 1; i++) + { + ofs << " ( result != Result::" << successCodes[i] << " ) &&"; + } + ofs << " ( result != Result::" << successCodes.back() << " )"; + } + ofs << " )" << std::endl; + ofs << indentation << " {" << std::endl + << indentation << " throw std::system_error( result, \"vk::"; + if (!className.empty()) + { + ofs << className << "::"; + } + ofs << functionName << "\" );" << std::endl + << indentation << " }" << std::endl; +} + +void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes, size_t returnIndex, std::map const& vectorParameters) +{ + ofs << indentation << "{" << std::endl; + + // add a static_assert if a type is templated and its size needs to be some multiple of the original size + if ((templateIndex != ~0) && (commandData.arguments[templateIndex].pureType != "void")) + { + ofs << indentation << " static_assert( sizeof( T ) % sizeof( " << commandData.arguments[templateIndex].pureType << " ) == 0, \"wrong size of template type T\" );" << std::endl; + } + + // add some error checks if multiple vectors need to have the same size + if (1 < vectorParameters.size()) + { + for (std::map::const_iterator it0 = vectorParameters.begin(); it0 != vectorParameters.end(); ++it0) + { + if (it0->first != returnIndex) + { + for (std::map::const_iterator it1 = std::next(it0); it1 != vectorParameters.end(); ++it1) + { + if ((it1->first != returnIndex) && (it0->second == it1->second)) + { + ofs << "#ifdef VK_CPP_NO_EXCEPTIONS" << std::endl + << indentation << " assert( " << reduceName(commandData.arguments[it0->first].name) << ".size() == " << reduceName(commandData.arguments[it1->first].name) << ".size() );" << std::endl + << "#else" << std::endl + << indentation << " if ( " << reduceName(commandData.arguments[it0->first].name) << ".size() != " << reduceName(commandData.arguments[it1->first].name) << ".size() )" << std::endl + << indentation << " {" << std::endl + << indentation << " throw std::logic_error( \"vk::" << className << "::" << functionName << ": " << reduceName(commandData.arguments[it0->first].name) << ".size() != " << reduceName(commandData.arguments[it1->first].name) << ".size()\" );" << std::endl + << indentation << " }" << std::endl + << "#endif // VK_CPP_NO_EXCEPTIONS" << std::endl; + } + } + } + } + } + + // write the local variable to hold a returned value + if (returnIndex != ~0) + { + if (commandData.returnType != returnType) + { + ofs << indentation << " " << returnType << " " << reduceName(commandData.arguments[returnIndex].name); + + std::map::const_iterator it = vectorParameters.find(returnIndex); + if (it != vectorParameters.end() && !commandData.twoStep) + { + std::string size; + if ((it->second == ~0) && !commandData.arguments[returnIndex].len.empty()) + { + size = reduceName(commandData.arguments[returnIndex].len); + size_t pos = size.find("->"); + assert(pos != std::string::npos); + size.replace(pos, 2, "."); + } + else + { + for (std::map::const_iterator sit = vectorParameters.begin(); sit != vectorParameters.end(); ++sit) + { + if ((sit->first != returnIndex) && (sit->second == it->second)) + { + size = reduceName(commandData.arguments[sit->first].name) + ".size()"; + break; + } + } + } + assert(!size.empty()); + ofs << "( " << size << " )"; + } + ofs << ";" << std::endl; + } + else if (1 < commandData.successCodes.size()) + { + ofs << indentation << " " << commandData.arguments[returnIndex].pureType << " " << reduceName(commandData.arguments[returnIndex].name) << ";" << std::endl; + } + } + + // local count variable to hold the size of the vector to fill + if (commandData.twoStep) + { + assert(returnIndex != ~0); + + std::map::const_iterator returnit = vectorParameters.find(returnIndex); + assert(returnit != vectorParameters.end() && (returnit->second != ~0)); + assert((commandData.returnType == "Result") || (commandData.returnType == "void")); + + ofs << indentation << " " << commandData.arguments[returnit->second].pureType << " " << reduceName(commandData.arguments[returnit->second].name) << ";" << std::endl; + } + + // write the function call + ofs << indentation << " "; + std::string localIndentation = " "; + if (commandData.returnType == "Result") + { + ofs << "Result result"; + if (commandData.twoStep && (1 < commandData.successCodes.size())) + { + ofs << ";" << std::endl + << indentation << " do" << std::endl + << indentation << " {" << std::endl + << indentation << " result"; + localIndentation += " "; + } + ofs << " = static_cast( "; + } + else if (commandData.returnType != "void") + { + assert(!commandData.twoStep); + ofs << "return "; + } + writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, true); + if (commandData.returnType == "Result") + { + ofs << " )"; + } + ofs << ";" << std::endl; + + if (commandData.twoStep) + { + std::map::const_iterator returnit = vectorParameters.find(returnIndex); + + if (commandData.returnType == "Result") + { + ofs << indentation << localIndentation << "if ( ( result == Result::eSuccess ) && " << reduceName(commandData.arguments[returnit->second].name) << " )" << std::endl + << indentation << localIndentation << "{" << std::endl + << indentation << localIndentation << " "; + } + else + { + ofs << indentation << " "; + } + + // resize the vector to hold the data according to the result from the first call + ofs << reduceName(commandData.arguments[returnit->first].name) << ".resize( " << reduceName(commandData.arguments[returnit->second].name) << " );" << std::endl; + + // write the function call a second time + if (commandData.returnType == "Result") + { + ofs << indentation << localIndentation << " result = static_cast( "; + } + else + { + ofs << indentation << " "; + } + writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, false); + if (commandData.returnType == "Result") + { + ofs << " )"; + } + ofs << ";" << std::endl; + if (commandData.returnType == "Result") + { + ofs << indentation << localIndentation << "}" << std::endl; + if (1 < commandData.successCodes.size()) + { + ofs << indentation << " } while ( result == Result::eIncomplete );" << std::endl; + } + } + } + + if ((commandData.returnType == "Result") || !commandData.successCodes.empty()) + { + ofs << indentation << " return createResultValue( result, "; + if (returnIndex != ~0) + { + ofs << reduceName(commandData.arguments[returnIndex].name) << ", "; + } + ofs << "\"vk::" << (className.empty() ? "" : className + "::") << functionName << "\""; + if (1 < commandData.successCodes.size() && !commandData.twoStep) + { + ofs << ", { Result::" << commandData.successCodes[0]; + for (size_t i = 1; i < commandData.successCodes.size(); i++) + { + ofs << ", Result::" << commandData.successCodes[i]; + } + ofs << " }"; + } + ofs << " );" << std::endl; + } + else if ((returnIndex != ~0) && (commandData.returnType != returnType)) + { + ofs << indentation << " return " << reduceName(commandData.arguments[returnIndex].name) << ";" << std::endl; + } + + ofs << indentation << "}" << std::endl; +} + +void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map const& vectorParameters) +{ + std::set skippedArguments; + for (std::map::const_iterator it = vectorParameters.begin(); it != vectorParameters.end(); ++it) + { + if (it->second != ~0) + { + skippedArguments.insert(it->second); + } + } + if ((vectorParameters.size() == 1) + && ((commandData.arguments[vectorParameters.begin()->first].len == "dataSize/4") || (commandData.arguments[vectorParameters.begin()->first].len == "latexmath:[$dataSize \\over 4$]"))) + { + assert(commandData.arguments[3].name == "dataSize"); + skippedArguments.insert(3); + } + if (returnIndex != ~0) + { + skippedArguments.insert(returnIndex); + } + + ofs << indentation; + if ((templateIndex != ~0) && ((templateIndex != returnIndex) || (returnType == "Result"))) + { + assert(returnType.find("Allocator") == std::string::npos); + ofs << "template " << std::endl + << indentation; + } + else if (returnType.find("Allocator") != std::string::npos) + { + assert((returnType.substr(0, 12) == "std::vector<") && (returnType.find(',') != std::string::npos) && (12 < returnType.find(','))); + ofs << "template >" << std::endl + << indentation; + if ((returnType != commandData.returnType) && (commandData.returnType != "void")) + { + ofs << "typename "; + } + } + else if (!commandData.handleCommand) + { + ofs << "inline "; + } + if ((returnType != commandData.returnType) && (commandData.returnType != "void")) + { + assert(commandData.returnType == "Result"); + ofs << "ResultValueType<" << returnType << ">::type "; + } + else if ((returnIndex != ~0) && (1 < commandData.successCodes.size())) + { + assert(commandData.returnType == "Result"); + ofs << "ResultValue<" << commandData.arguments[returnIndex].pureType << "> "; + } + else + { + ofs << returnType << " "; + } + ofs << reduceName(name) << "("; + if (skippedArguments.size() + (commandData.handleCommand ? 1 : 0) < commandData.arguments.size()) + { + size_t lastArgument = ~0; + for (size_t i = commandData.arguments.size() - 1; i < commandData.arguments.size(); i--) + { + if (skippedArguments.find(i) == skippedArguments.end()) + { + lastArgument = i; + break; + } + } + + ofs << " "; + bool argEncountered = false; + for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) + { + if (skippedArguments.find(i) == skippedArguments.end()) + { + if (argEncountered) + { + ofs << ", "; + } + + std::map::const_iterator it = vectorParameters.find(i); + size_t pos = commandData.arguments[i].type.find('*'); + if (it == vectorParameters.end()) + { + if (pos == std::string::npos) + { + ofs << commandData.arguments[i].type << " " << reduceName(commandData.arguments[i].name); + if (!commandData.arguments[i].arraySize.empty()) + { + ofs << "[" << commandData.arguments[i].arraySize << "]"; + } + } + else + { + assert(commandData.arguments[i].type[pos] == '*'); + if (commandData.arguments[i].optional) + { + ofs << "Optional<" << trimEnd(commandData.arguments[i].type.substr(0, pos)) << "> " << reduceName(commandData.arguments[i].name) << " = nullptr"; + } + else if (commandData.arguments[i].type.find("char") == std::string::npos) + { + ofs << trimEnd(commandData.arguments[i].type.substr(0, pos)) << " & " << reduceName(commandData.arguments[i].name); + } + else + { + ofs << "const std::string & " << reduceName(commandData.arguments[i].name); + } + } + } + else + { + bool optional = commandData.arguments[i].optional && ((it == vectorParameters.end()) || (it->second == ~0)); + assert(pos != std::string::npos); + assert(commandData.arguments[i].type[pos] == '*'); + if (commandData.arguments[i].type.find("char") != std::string::npos) + { + if (optional) + { + ofs << "Optional " << reduceName(commandData.arguments[i].name) << " = nullptr"; + } + else + { + ofs << "const std::string & " << reduceName(commandData.arguments[i].name); + } + } + else + { + assert(!optional); + bool isConst = (commandData.arguments[i].type.find("const") != std::string::npos); + ofs << "ArrayProxy<" << ((templateIndex == i) ? (isConst ? "const T" : "T") : trimEnd(commandData.arguments[i].type.substr(0, pos))) << "> " << reduceName(commandData.arguments[i].name); + } + } + argEncountered = true; + } + } + ofs << " "; + } + ofs << ")"; + if (commandData.handleCommand) + { + ofs << " const"; + } + ofs << std::endl; +} + +void writeMemberData(std::ofstream & ofs, MemberData const& memberData, std::set const& vkTypes) +{ + if ( vkTypes.find( memberData.pureType ) != vkTypes.end() ) + { + if ( memberData.type.back() == '*' ) + { + ofs << "reinterpret_cast<"; + if ( memberData.type.find( "const" ) == 0 ) + { + ofs << "const "; + } + ofs << "Vk" << memberData.pureType << '*'; + } + else + { + ofs << "static_cast( " << memberData.name << " )"; + } + else + { + ofs << memberData.name; + } +} + +void writeStructConstructor( std::ofstream & ofs, std::string const& name, StructData const& structData, std::set const& vkTypes, std::map const& defaultValues ) +{ + // check if there is a member element with no default available + bool noDefault = false; + for (size_t i = 0; i < structData.members.size() && !noDefault; i++) + { + std::map::const_iterator it = defaultValues.find(structData.members[i].pureType); + assert(it != defaultValues.end()); + noDefault = it->second.empty(); + } + + if (!noDefault) + { + // if there's a default for all member, provide a default constructor + ofs << " " << name << "()" << std::endl + << " : " << name << "( "; + bool listedArgument = false; + for (size_t i = 0; i < structData.members.size(); i++) + { + if (listedArgument) + { + ofs << ", "; + } + if ((structData.members[i].name != "pNext") && (structData.members[i].name != "sType")) + { + if (structData.members[i].type.back() == '*') + { + ofs << "nullptr"; + } + else + { + std::map::const_iterator it = defaultValues.find(structData.members[i].pureType); + assert((it != defaultValues.end()) && !it->second.empty()); + + if (structData.members[i].arraySize.empty()) + { + ofs << it->second; + } + else + { + ofs << "{ " << it->second << " }"; + } + } + listedArgument = true; + } + } + ofs << " )" << std::endl + << " {}" << std::endl + << std::endl; + } + + // the constructor with all the elements as arguments + ofs << " " << name << "( "; + std::vector noDefaultArgs, defaultArgs; + bool listedArgument = false; + for (size_t i = 0; i const& " + structData.members[i].name << "_"; + } + listedArgument = true; + } + } + ofs << " )" << std::endl; + + // the body of the constructor, copying over data from argument list into wrapped struct + ofs << " {" << std::endl; + for ( size_t i=0 ; i const& vkTypes ) +{ + ofs << " " << name << "& set" << static_cast(toupper(memberData.name[0])) << memberData.name.substr(1) << "( "; + if ( memberData.arraySize.empty() ) + { + ofs << memberData.type << " "; + } + else + { + ofs << "std::array<" << memberData.type << "," << memberData.arraySize << "> "; + } + ofs << memberData.name << "_ )" << std::endl + << " {" << std::endl; + if ( !memberData.arraySize.empty() ) + { + ofs << " memcpy( &" << memberData.name << ", " << memberData.name << "_.data(), " << memberData.arraySize << " * sizeof( " << memberData.type << " ) )"; + } + else + { + ofs << " " << memberData.name << " = " << memberData.name << "_"; + } + ofs << ";" << std::endl + << " return *this;" << std::endl + << " }" << std::endl + << std::endl; +} + +void writeTypeCommand( std::ofstream & ofs, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes ) +{ + if (!commandData.handleCommand) + { + writeTypeCommandStandard(ofs, " ", dependencyData.name, dependencyData, commandData, vkTypes); + + ofs << std::endl + << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; + writeTypeCommandEnhanced(ofs, " ", "", dependencyData.name, dependencyData, commandData, vkTypes); + ofs << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl + << std::endl; + } +} + +void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes) +{ + enterProtect(ofs, commandData.protect); + std::map vectorParameters = getVectorParameters(commandData); + size_t returnIndex = findReturnIndex(commandData, vectorParameters); + size_t templateIndex = findTemplateIndex(commandData, vectorParameters); + std::map::const_iterator returnVector = vectorParameters.find(returnIndex); + std::string returnType = determineReturnType(commandData, returnIndex, returnVector != vectorParameters.end()); + + writeFunctionHeader(ofs, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters); + writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkTypes, returnIndex, vectorParameters); + leaveProtect(ofs, commandData.protect); +} + +void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes) +{ + enterProtect(ofs, commandData.protect); + ofs << indentation; + if (!commandData.handleCommand) + { + ofs << "inline "; + } + ofs << commandData.returnType << " " << functionName << "( "; + bool argEncountered = false; + for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) + { + if (argEncountered) + { + ofs << ", "; + } + ofs << commandData.arguments[i].type << " " << commandData.arguments[i].name; + if (!commandData.arguments[i].arraySize.empty()) + { + ofs << "[" << commandData.arguments[i].arraySize << "]"; + } + argEncountered = true; + } + ofs << " )"; + if (commandData.handleCommand) + { + ofs << " const"; + } + ofs << std::endl + << indentation << "{" << std::endl + << indentation << " "; + bool castReturn = false; + if (commandData.returnType != "void") + { + ofs << "return "; + castReturn = (vkTypes.find(commandData.returnType) != vkTypes.end()); + if (castReturn) + { + ofs << "static_cast<" << commandData.returnType << ">( "; + } + } + + std::string callName(dependencyData.name); + assert(islower(callName[0])); + callName[0] = toupper(callName[0]); + + ofs << "vk" << callName << "( "; + if (commandData.handleCommand) + { + ofs << "m_" << commandData.arguments[0].name; + } + argEncountered = false; + for (size_t i = commandData.handleCommand ? 1 : 0; i < commandData.arguments.size(); i++) + { + if (0 < i) + { + ofs << ", "; + } + writeMemberData(ofs, commandData.arguments[i], vkTypes); + } + ofs << " )"; + if (castReturn) + { + ofs << " )"; + } + ofs << ";" << std::endl + << indentation << "}" << std::endl; + leaveProtect(ofs, commandData.protect); +} + +void writeTypeEnum( std::ofstream & ofs, DependencyData const& dependencyData, EnumData const& enumData ) +{ + enterProtect(ofs, enumData.protect); + ofs << " enum class " << dependencyData.name << std::endl + << " {" << std::endl; + for ( size_t i=0 ; iname << ": return \"" << itMember->name.substr(1) << "\";" << std::endl; + } + ofs << " default: return \"invalid\";" << std::endl + << " }" << std::endl; + } + ofs << " }" << std::endl; + leaveProtect(ofs, enumData.protect); + ofs << std::endl; +} + +void writeFlagsToString(std::ofstream & ofs, DependencyData const& dependencyData, EnumData const &enumData) +{ + enterProtect(ofs, enumData.protect); + std::string enumPrefix = *dependencyData.dependencies.begin() + "::"; + ofs << " inline std::string to_string(" << dependencyData.name << (enumData.members.empty() ? ")" : " value)") << std::endl + << " {" << std::endl; + if (enumData.members.empty()) + { + ofs << " return \"{}\";" << std::endl; + } + else + { + ofs << " if (!value) return \"{}\";" << std::endl + << " std::string result;" << std::endl; + + for (auto itMember = enumData.members.begin(); itMember != enumData.members.end(); ++itMember) + { + ofs << " if (value & " << enumPrefix + itMember->name << ") result += \"" << itMember->name.substr(1) << " | \";" << std::endl; + } + ofs << " return \"{\" + result.substr(0, result.size() - 3) + \"}\";" << std::endl; + } + ofs << " }" << std::endl; + leaveProtect(ofs, enumData.protect); + ofs << std::endl; +} + +void writeEnumsToString(std::ofstream & ofs, VkData const& vkData) +{ + for (auto it = vkData.dependencies.begin(); it != vkData.dependencies.end(); ++it) + { + switch (it->category) + { + case DependencyData::Category::ENUM: + assert(vkData.enums.find(it->name) != vkData.enums.end()); + writeEnumsToString(ofs, *it, vkData.enums.find(it->name)->second); + break; + case DependencyData::Category::FLAGS: + writeFlagsToString(ofs, *it, vkData.enums.find(*it->dependencies.begin())->second); + break; + } + } +} + +void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, FlagData const& flagData ) +{ + assert( dependencyData.dependencies.size() == 1 ); + enterProtect(ofs, flagData.protect); + ofs << " using " << dependencyData.name << " = Flags<" << *dependencyData.dependencies.begin() << ", Vk" << dependencyData.name << ">;" << std::endl + << std::endl + << " inline " << dependencyData.name << " operator|( " << *dependencyData.dependencies.begin() << " bit0, " << *dependencyData.dependencies.begin() << " bit1 )" << std::endl + << " {" << std::endl + << " return " << dependencyData.name << "( bit0 ) | bit1;" << std::endl + << " }" << std::endl; + leaveProtect(ofs, flagData.protect); + ofs << std::endl; +} + +void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies) +{ + std::string memberName = dependencyData.name; + assert(isupper(memberName[0])); + memberName[0] = tolower(memberName[0]); + + ofs << " class " << dependencyData.name << std::endl + << " {" << std::endl + << " public:" << std::endl + << " " << dependencyData.name << "()" << std::endl + << " : m_" << memberName << "(VK_NULL_HANDLE)" << std::endl + << " {}" << std::endl + << std::endl + << "#if defined(VK_CPP_TYPESAFE_CONVERSION)" << std::endl + // construct from native handle + << " " << dependencyData.name << "(Vk" << dependencyData.name << " " << memberName << ")" << std::endl + << " : m_" << memberName << "(" << memberName << ")" << std::endl + << " {}" << std::endl + << std::endl + // assignment from native handle + << " " << dependencyData.name << "& operator=(Vk" << dependencyData.name << " " << memberName << ")" << std::endl + << " {" << std::endl + << " m_" << memberName << " = " << memberName << ";" << std::endl + << " return *this;" << std::endl + << " }" << std::endl + << "#endif\n" + << std::endl; + + if (!handle.commands.empty()) + { + for (size_t i = 0; i < handle.commands.size(); i++) + { + std::string commandName = handle.commands[i]; + std::map::const_iterator cit = vkData.commands.find(commandName); + assert((cit != vkData.commands.end()) && cit->second.handleCommand); + std::list::const_iterator dep = std::find_if(dependencies.begin(), dependencies.end(), [commandName](DependencyData const& dd) { return dd.name == commandName; }); + assert(dep != dependencies.end()); + std::string className = dependencyData.name; + std::string functionName = determineFunctionName(dep->name, cit->second); + + bool hasPointers = hasPointerArguments(cit->second); + if (!hasPointers) + { + ofs << "#ifdef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; + } + writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkData.vkTypes); + if (!hasPointers) + { + ofs << "#endif /*!VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl; + } + + ofs << std::endl + << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl; + writeTypeCommandEnhanced(ofs, " ", className, functionName, *dep, cit->second, vkData.vkTypes); + ofs << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl; + + if (i < handle.commands.size() - 1) + { + ofs << std::endl; + } + } + ofs << std::endl; + } + ofs << "#if !defined(VK_CPP_TYPESAFE_CONVERSION)" << std::endl + << " explicit" << std::endl + << "#endif" << std::endl + << " operator Vk" << dependencyData.name << "() const" << std::endl + << " {" << std::endl + << " return m_" << memberName << ";" << std::endl + << " }" << std::endl + << std::endl + << " explicit operator bool() const" << std::endl + << " {" << std::endl + << " return m_" << memberName << " != VK_NULL_HANDLE;" << std::endl + << " }" << std::endl + << std::endl + << " bool operator!() const" << std::endl + << " {" << std::endl + << " return m_" << memberName << " == VK_NULL_HANDLE;" << std::endl + << " }" << std::endl + << std::endl + << " private:" << std::endl + << " Vk" << dependencyData.name << " m_" << memberName << ";" << std::endl + << " };" << std::endl +#if 1 + << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"handle and wrapper have different size!\" );" << std::endl +#endif + << std::endl; +} + +void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ) +{ + assert( dependencyData.dependencies.size() == 1 ); + ofs << " using " << dependencyData.name << " = " << *dependencyData.dependencies.begin() << ";" << std::endl + << std::endl; +} + +void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ) +{ + std::map::const_iterator it = vkData.structs.find( dependencyData.name ); + assert( it != vkData.structs.end() ); + + enterProtect(ofs, it->second.protect); + ofs << " struct " << dependencyData.name << std::endl + << " {" << std::endl; + + // only structs that are not returnedOnly get a constructor! + if ( !it->second.returnedOnly ) + { + writeStructConstructor( ofs, dependencyData.name, it->second, vkData.vkTypes, defaultValues ); + } + + // create the setters + if (!it->second.returnedOnly) + { + for (size_t i = 0; isecond.members.size(); i++) + { + writeStructSetter( ofs, dependencyData.name, it->second.members[i], vkData.vkTypes ); + } + } + + // the cast-operator to the wrapped struct + ofs << " operator const Vk" << dependencyData.name << "&() const" << std::endl + << " {" << std::endl + << " return *reinterpret_cast(this);" << std::endl + << " }" << std::endl + << std::endl; + + // the member variables + for (size_t i = 0; i < it->second.members.size(); i++) + { + ofs << " " << it->second.members[i].type << " " << it->second.members[i].name; + if (!it->second.members[i].arraySize.empty()) + { + ofs << "[" << it->second.members[i].arraySize << "]"; + } + ofs << ";" << std::endl; + } + ofs << " };" << std::endl; +#if 1 + ofs << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"struct and wrapper have different size!\" );" << std::endl; +#endif + leaveProtect(ofs, it->second.protect); + ofs << std::endl; +} + +void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ) +{ + std::ostringstream oss; + ofs << " union " << dependencyData.name << std::endl + << " {" << std::endl; + + for ( size_t i=0 ; i& "; + } + ofs << unionData.members[i].name << "_"; + + // just the very first constructor gets default arguments + if ( i == 0 ) + { + std::map::const_iterator it = defaultValues.find( unionData.members[i].pureType ); + assert( it != defaultValues.end() ); + if ( unionData.members[i].arraySize.empty() ) + { + ofs << " = " << it->second; + } + else + { + ofs << " = { " << it->second << " }"; + } + } + ofs << " )" << std::endl + << " {" << std::endl + << " "; + if ( unionData.members[i].arraySize.empty() ) + { + ofs << unionData.members[i].name << " = " << unionData.members[i].name << "_"; + } + else + { + ofs << "memcpy( &" << unionData.members[i].name << ", " << unionData.members[i].name << "_.data(), " << unionData.members[i].arraySize << " * sizeof( " << unionData.members[i].type << " ) )"; + } + ofs << ";" << std::endl + << " }" << std::endl + << std::endl; + } + + for (size_t i = 0; i(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 = false; + for (size_t i = 0; i < unionData.members.size() && !needsUnrestrictedUnions; i++) + { + needsUnrestrictedUnions = (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end()); + } + if (needsUnrestrictedUnions) + { + ofs << "#ifdef VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl; + for (size_t i = 0; i < unionData.members.size(); i++) + { + ofs << " " << unionData.members[i].type << " " << unionData.members[i].name; + if (!unionData.members[i].arraySize.empty()) + { + ofs << "[" << unionData.members[i].arraySize << "]"; + } + ofs << ";" << std::endl; + } + ofs << "#else" << std::endl; + } + for (size_t i = 0; i < unionData.members.size(); i++) + { + ofs << " "; + if (vkData.vkTypes.find(unionData.members[i].type) != vkData.vkTypes.end()) + { + ofs << "Vk"; + } + ofs << unionData.members[i].type << " " << unionData.members[i].name; + if (!unionData.members[i].arraySize.empty()) + { + ofs << "[" << unionData.members[i].arraySize << "]"; + } + ofs << ";" << std::endl; + } + if (needsUnrestrictedUnions) + { + ofs << "#endif // VK_CPP_HAS_UNRESTRICTED_UNIONS" << std::endl; + } + ofs << " };" << std::endl + << std::endl; +} + +void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues) +{ + for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) + { + switch( it->category ) + { + case DependencyData::Category::COMMAND : + assert( vkData.commands.find( it->name ) != vkData.commands.end() ); + writeTypeCommand( ofs, *it, vkData.commands.find( it->name )->second, vkData.vkTypes ); + break; + case DependencyData::Category::ENUM : + assert( vkData.enums.find( it->name ) != vkData.enums.end() ); + writeTypeEnum( ofs, *it, vkData.enums.find( it->name )->second ); + break; + case DependencyData::Category::FLAGS : + assert(vkData.flags.find(it->name) != vkData.flags.end()); + writeTypeFlags( ofs, *it, vkData.flags.find( it->name)->second ); + break; + case DependencyData::Category::FUNC_POINTER : + case DependencyData::Category::REQUIRED : + // skip FUNC_POINTER and REQUIRED, they just needed to be in the dependencies list to resolve dependencies + break; + case DependencyData::Category::HANDLE : + assert(vkData.handles.find(it->name) != vkData.handles.end()); + writeTypeHandle(ofs, vkData, *it, vkData.handles.find(it->name)->second, vkData.dependencies); + break; + case DependencyData::Category::SCALAR : + writeTypeScalar( ofs, *it ); + break; + case DependencyData::Category::STRUCT : + writeTypeStruct( ofs, vkData, *it, defaultValues ); + break; + case DependencyData::Category::UNION : + assert( vkData.structs.find( it->name ) != vkData.structs.end() ); + writeTypeUnion( ofs, vkData, *it, vkData.structs.find( it->name )->second, defaultValues ); + break; + default : + assert( false ); + break; + } + } +} + +void writeVersionCheck(std::ofstream & ofs, std::string const& version) +{ + ofs << "static_assert( VK_HEADER_VERSION == " << version << " , \"Wrong VK_HEADER_VERSION!\" );" << std::endl + << std::endl; +} + +void writeTypesafeCheck(std::ofstream & ofs, std::string const& typesafeCheck) +{ + ofs << "// 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 VK_CPP_TYPESAFE_CONVERSION" << std::endl + << typesafeCheck << std::endl + << "#define VK_CPP_TYPESAFE_CONVERSION 1" << std::endl + << "#endif" << std::endl + << std::endl; +} + +int main( int argc, char **argv ) +{ + try { + tinyxml2::XMLDocument doc; + + std::string filename = (argc == 1) ? VK_SPEC : argv[1]; + std::cout << "Loading vk.xml from " << filename << std::endl; + std::cout << "Writing vk_cpp.hpp to " << VK_CPP << std::endl; + + tinyxml2::XMLError error = doc.LoadFile(filename.c_str()); + if (error != tinyxml2::XML_SUCCESS) + { + std::cout << "VkGenerate: failed to load file " << argv[1] << " . Error code: " << error << std::endl; + return -1; + } + + tinyxml2::XMLElement * registryElement = doc.FirstChildElement(); + assert(strcmp(registryElement->Value(), "registry") == 0); + assert(!registryElement->NextSiblingElement()); + + VkData vkData; + + tinyxml2::XMLElement * child = registryElement->FirstChildElement(); + do + { + assert(child->Value()); + const std::string value = child->Value(); + if (value == "commands") + { + readCommands(child, vkData); + } + else if (value == "comment") + { + readComment(child, vkData.vulkanLicenseHeader); + } + else if (value == "enums") + { + readEnums(child, vkData); + } + else if (value == "extensions") + { + readExtensions(child, vkData); + } + else if (value == "tags") + { + readTags(child, vkData.tags); + } + else if (value == "types") + { + readTypes(child, vkData); + } + else + { + assert((value == "feature") || (value == "vendorids")); + } + } while (child = child->NextSiblingElement()); + + sortDependencies(vkData.dependencies); + + std::map defaultValues; + createDefaults(vkData, defaultValues); + + std::ofstream ofs(VK_CPP); + ofs << nvidiaLicenseHeader << std::endl + << vkData.vulkanLicenseHeader << std::endl + << std::endl + << std::endl + << "#ifndef VK_CPP_H_" << std::endl + << "#define VK_CPP_H_" << std::endl + << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#include " << std::endl + << "#ifndef VKCPP_DISABLE_ENHANCED_MODE" << std::endl + << "# include " << std::endl + << "#endif /*VKCPP_DISABLE_ENHANCED_MODE*/" << std::endl + << std::endl; + + writeVersionCheck(ofs, vkData.version); + writeTypesafeCheck(ofs, vkData.typesafeCheck); + ofs << versionCheckHeader + << "namespace vk" << std::endl + << "{" << std::endl + << flagsHeader + << optionalClassHeader + << arrayProxyHeader; + + // first of all, write out vk::Result and the exception handling stuff + std::list::const_iterator it = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [](DependencyData const& dp) { return dp.name == "Result"; }); + assert(it != vkData.dependencies.end()); + writeTypeEnum(ofs, *it, vkData.enums.find(it->name)->second); + writeEnumsToString(ofs, *it, vkData.enums.find(it->name)->second); + vkData.dependencies.erase(it); + ofs << exceptionHeader; + + ofs << "} // namespace vk" << std::endl + << std::endl + << "namespace std" << std::endl + << "{" << std::endl + << " template <>" << std::endl + << " struct is_error_code_enum : public true_type" << std::endl + << " {};" << std::endl + << "}" << std::endl + << std::endl + << "namespace vk" << std::endl + << "{" << std::endl + << resultValueHeader + << createResultValueHeader; + + writeTypes(ofs, vkData, defaultValues); + writeEnumsToString(ofs, vkData); + + ofs << "} // namespace vk" << std::endl + << std::endl + << "#endif" << std::endl; + } + catch (std::exception e) + { + std::cout << "caught exception: " << e.what() << std::endl; + } + catch (...) + { + std::cout << "caught unknown exception" << std::endl; + } +} diff --git a/vulkan/vk_cpp.hpp b/vulkan/vk_cpp.hpp index 8a02f7b..5e4588e 100644 --- a/vulkan/vk_cpp.hpp +++ b/vulkan/vk_cpp.hpp @@ -381,6 +381,92 @@ namespace std namespace vk { + template + struct ResultValue + { + ResultValue( Result r, T & v ) + : result( r ) + , value( v ) + {} + + Result result; + T value; + }; + + template + struct ResultValueType + { +#ifdef VK_CPP_NO_EXCEPTIONS + typedef ResultValue type; +#else + typedef T type; +#endif + }; + + template <> struct ResultValueType + { +#ifdef VK_CPP_NO_EXCEPTIONS + typedef Result type; +#else + typedef void type; +#endif + }; + + inline ResultValueType::type createResultValue( Result result, char const * message ) + { +#ifdef VK_CPP_NO_EXCEPTIONS + assert( result == Result::eSuccess ); + return result; +#else + if ( result != Result::eSuccess ) + { + throw std::system_error( result, message ); + } +#endif + } + + template + inline typename ResultValueType::type createResultValue( Result result, T & data, char const * message ) + { +#ifdef VK_CPP_NO_EXCEPTIONS + assert( result == Result::eSuccess ); + return ResultValue( result, data ); +#else + if ( result != Result::eSuccess ) + { + throw std::system_error( result, message ); + } + return data; +#endif + } + + inline Result createResultValue( Result result, char const * message, std::initializer_list successCodes ) + { +#ifdef VK_CPP_NO_EXCEPTIONS + assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() ); +#else + if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() ) + { + throw std::system_error( result, message ); + } +#endif + return result; + } + + template + inline ResultValue createResultValue( Result result, T & data, char const * message, std::initializer_list successCodes ) + { +#ifdef VK_CPP_NO_EXCEPTIONS + assert( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() ); +#else + if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() ) + { + throw std::system_error( result, message ); + } +#endif + return ResultValue( result, data ); + } + using SampleMask = uint32_t; using Bool32 = uint32_t; @@ -11107,13 +11193,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void begin( const CommandBufferBeginInfo & beginInfo ) const + ResultValueType::type begin( const CommandBufferBeginInfo & beginInfo ) const { Result result = static_cast( vkBeginCommandBuffer( m_commandBuffer, reinterpret_cast( &beginInfo ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::CommandBuffer::begin" ); - } + return createResultValue( result, "vk::CommandBuffer::begin" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -11125,13 +11208,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void end() const + ResultValueType::type end() const { Result result = static_cast( vkEndCommandBuffer( m_commandBuffer ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::CommandBuffer::end" ); - } + return createResultValue( result, "vk::CommandBuffer::end" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -11143,13 +11223,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void reset( CommandBufferResetFlags flags ) const + ResultValueType::type reset( CommandBufferResetFlags flags ) const { Result result = static_cast( vkResetCommandBuffer( m_commandBuffer, static_cast( flags ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::CommandBuffer::reset" ); - } + return createResultValue( result, "vk::CommandBuffer::reset" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -11323,10 +11400,14 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE void bindVertexBuffers( uint32_t firstBinding, ArrayProxy buffers, ArrayProxy offsets ) const { +#ifdef VK_CPP_NO_EXCEPTIONS + assert( buffers.size() == offsets.size() ); +#else if ( buffers.size() != offsets.size() ) { throw std::logic_error( "vk::CommandBuffer::bindVertexBuffers: buffers.size() != offsets.size()" ); } +#endif // VK_CPP_NO_EXCEPTIONS vkCmdBindVertexBuffers( m_commandBuffer, firstBinding, buffers.size() , reinterpret_cast( buffers.data() ), offsets.data() ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12073,13 +12154,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void submit( ArrayProxy submits, Fence fence ) const + ResultValueType::type submit( ArrayProxy submits, Fence fence ) const { Result result = static_cast( vkQueueSubmit( m_queue, submits.size() , reinterpret_cast( submits.data() ), static_cast( fence ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Queue::submit" ); - } + return createResultValue( result, "vk::Queue::submit" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12091,13 +12169,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void waitIdle() const + ResultValueType::type waitIdle() const { Result result = static_cast( vkQueueWaitIdle( m_queue ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Queue::waitIdle" ); - } + return createResultValue( result, "vk::Queue::waitIdle" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12107,13 +12182,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void bindSparse( ArrayProxy bindInfo, Fence fence ) const + ResultValueType::type bindSparse( ArrayProxy bindInfo, Fence fence ) const { Result result = static_cast( vkQueueBindSparse( m_queue, bindInfo.size() , reinterpret_cast( bindInfo.data() ), static_cast( fence ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Queue::bindSparse" ); - } + return createResultValue( result, "vk::Queue::bindSparse" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12126,11 +12198,7 @@ namespace vk Result presentKHR( const PresentInfoKHR & presentInfo ) const { Result result = static_cast( vkQueuePresentKHR( m_queue, reinterpret_cast( &presentInfo ) ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eSuboptimalKHR ) ) - { - throw std::system_error( result, "vk::Queue::presentKHR" ); - } - return result; + return createResultValue( result, "vk::Queue::presentKHR", { Result::eSuccess, Result::eSuboptimalKHR } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12907,13 +12975,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void waitIdle() const + ResultValueType::type waitIdle() const { Result result = static_cast( vkDeviceWaitIdle( m_device ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::waitIdle" ); - } + return createResultValue( result, "vk::Device::waitIdle" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12923,15 +12988,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DeviceMemory allocateMemory( const MemoryAllocateInfo & allocateInfo, Optional allocator = nullptr ) const + ResultValueType::type allocateMemory( const MemoryAllocateInfo & allocateInfo, Optional allocator = nullptr ) const { DeviceMemory memory; Result result = static_cast( vkAllocateMemory( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &memory ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::allocateMemory" ); - } - return memory; + return createResultValue( result, memory, "vk::Device::allocateMemory" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12955,15 +13016,11 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void* mapMemory( DeviceMemory memory, DeviceSize offset, DeviceSize size, MemoryMapFlags flags ) const + ResultValueType::type mapMemory( DeviceMemory memory, DeviceSize offset, DeviceSize size, MemoryMapFlags flags ) const { void* pData; Result result = static_cast( vkMapMemory( m_device, static_cast( memory ), offset, size, static_cast( flags ), &pData ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::mapMemory" ); - } - return pData; + return createResultValue( result, pData, "vk::Device::mapMemory" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -12987,13 +13044,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void flushMappedMemoryRanges( ArrayProxy memoryRanges ) const + ResultValueType::type flushMappedMemoryRanges( ArrayProxy memoryRanges ) const { Result result = static_cast( vkFlushMappedMemoryRanges( m_device, memoryRanges.size() , reinterpret_cast( memoryRanges.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::flushMappedMemoryRanges" ); - } + return createResultValue( result, "vk::Device::flushMappedMemoryRanges" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13003,13 +13057,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void invalidateMappedMemoryRanges( ArrayProxy memoryRanges ) const + ResultValueType::type invalidateMappedMemoryRanges( ArrayProxy memoryRanges ) const { Result result = static_cast( vkInvalidateMappedMemoryRanges( m_device, memoryRanges.size() , reinterpret_cast( memoryRanges.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::invalidateMappedMemoryRanges" ); - } + return createResultValue( result, "vk::Device::invalidateMappedMemoryRanges" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13049,13 +13100,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void bindBufferMemory( Buffer buffer, DeviceMemory memory, DeviceSize memoryOffset ) const + ResultValueType::type bindBufferMemory( Buffer buffer, DeviceMemory memory, DeviceSize memoryOffset ) const { Result result = static_cast( vkBindBufferMemory( m_device, static_cast( buffer ), static_cast( memory ), memoryOffset ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::bindBufferMemory" ); - } + return createResultValue( result, "vk::Device::bindBufferMemory" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13081,13 +13129,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void bindImageMemory( Image image, DeviceMemory memory, DeviceSize memoryOffset ) const + ResultValueType::type bindImageMemory( Image image, DeviceMemory memory, DeviceSize memoryOffset ) const { Result result = static_cast( vkBindImageMemory( m_device, static_cast( image ), static_cast( memory ), memoryOffset ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::bindImageMemory" ); - } + return createResultValue( result, "vk::Device::bindImageMemory" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13115,15 +13160,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Fence createFence( const FenceCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createFence( const FenceCreateInfo & createInfo, Optional allocator = nullptr ) const { Fence fence; Result result = static_cast( vkCreateFence( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &fence ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createFence" ); - } - return fence; + return createResultValue( result, fence, "vk::Device::createFence" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13145,13 +13186,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void resetFences( ArrayProxy fences ) const + ResultValueType::type resetFences( ArrayProxy fences ) const { Result result = static_cast( vkResetFences( m_device, fences.size() , reinterpret_cast( fences.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::resetFences" ); - } + return createResultValue( result, "vk::Device::resetFences" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13166,11 +13204,7 @@ namespace vk Result getFenceStatus( Fence fence ) const { Result result = static_cast( vkGetFenceStatus( m_device, static_cast( fence ) ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eNotReady ) ) - { - throw std::system_error( result, "vk::Device::getFenceStatus" ); - } - return result; + return createResultValue( result, "vk::Device::getFenceStatus", { Result::eSuccess, Result::eNotReady } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13183,11 +13217,7 @@ namespace vk Result waitForFences( ArrayProxy fences, Bool32 waitAll, uint64_t timeout ) const { Result result = static_cast( vkWaitForFences( m_device, fences.size() , reinterpret_cast( fences.data() ), waitAll, timeout ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eTimeout ) ) - { - throw std::system_error( result, "vk::Device::waitForFences" ); - } - return result; + return createResultValue( result, "vk::Device::waitForFences", { Result::eSuccess, Result::eTimeout } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13197,15 +13227,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Semaphore createSemaphore( const SemaphoreCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createSemaphore( const SemaphoreCreateInfo & createInfo, Optional allocator = nullptr ) const { Semaphore semaphore; Result result = static_cast( vkCreateSemaphore( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &semaphore ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createSemaphore" ); - } - return semaphore; + return createResultValue( result, semaphore, "vk::Device::createSemaphore" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13227,15 +13253,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Event createEvent( const EventCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createEvent( const EventCreateInfo & createInfo, Optional allocator = nullptr ) const { Event event; Result result = static_cast( vkCreateEvent( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &event ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createEvent" ); - } - return event; + return createResultValue( result, event, "vk::Device::createEvent" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13262,11 +13284,7 @@ namespace vk Result getEventStatus( Event event ) const { Result result = static_cast( vkGetEventStatus( m_device, static_cast( event ) ) ); - if ( ( result != Result::eEventSet ) && ( result != Result::eEventReset ) ) - { - throw std::system_error( result, "vk::Device::getEventStatus" ); - } - return result; + return createResultValue( result, "vk::Device::getEventStatus", { Result::eEventSet, Result::eEventReset } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13278,13 +13296,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void setEvent( Event event ) const + ResultValueType::type setEvent( Event event ) const { Result result = static_cast( vkSetEvent( m_device, static_cast( event ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::setEvent" ); - } + return createResultValue( result, "vk::Device::setEvent" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13296,13 +13311,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void resetEvent( Event event ) const + ResultValueType::type resetEvent( Event event ) const { Result result = static_cast( vkResetEvent( m_device, static_cast( event ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::resetEvent" ); - } + return createResultValue( result, "vk::Device::resetEvent" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13312,15 +13324,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - QueryPool createQueryPool( const QueryPoolCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createQueryPool( const QueryPoolCreateInfo & createInfo, Optional allocator = nullptr ) const { QueryPool queryPool; Result result = static_cast( vkCreateQueryPool( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &queryPool ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createQueryPool" ); - } - return queryPool; + return createResultValue( result, queryPool, "vk::Device::createQueryPool" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13346,11 +13354,7 @@ namespace vk Result getQueryPoolResults( QueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, ArrayProxy data, DeviceSize stride, QueryResultFlags flags ) const { Result result = static_cast( vkGetQueryPoolResults( m_device, static_cast( queryPool ), firstQuery, queryCount, data.size() * sizeof( T ) , reinterpret_cast( data.data() ), stride, static_cast( flags ) ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eNotReady ) ) - { - throw std::system_error( result, "vk::Device::getQueryPoolResults" ); - } - return result; + return createResultValue( result, "vk::Device::getQueryPoolResults", { Result::eSuccess, Result::eNotReady } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13360,15 +13364,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Buffer createBuffer( const BufferCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createBuffer( const BufferCreateInfo & createInfo, Optional allocator = nullptr ) const { Buffer buffer; Result result = static_cast( vkCreateBuffer( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &buffer ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createBuffer" ); - } - return buffer; + return createResultValue( result, buffer, "vk::Device::createBuffer" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13390,15 +13390,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - BufferView createBufferView( const BufferViewCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createBufferView( const BufferViewCreateInfo & createInfo, Optional allocator = nullptr ) const { BufferView view; Result result = static_cast( vkCreateBufferView( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &view ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createBufferView" ); - } - return view; + return createResultValue( result, view, "vk::Device::createBufferView" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13420,15 +13416,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Image createImage( const ImageCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createImage( const ImageCreateInfo & createInfo, Optional allocator = nullptr ) const { Image image; Result result = static_cast( vkCreateImage( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &image ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createImage" ); - } - return image; + return createResultValue( result, image, "vk::Device::createImage" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13464,15 +13456,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - ImageView createImageView( const ImageViewCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createImageView( const ImageViewCreateInfo & createInfo, Optional allocator = nullptr ) const { ImageView view; Result result = static_cast( vkCreateImageView( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &view ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createImageView" ); - } - return view; + return createResultValue( result, view, "vk::Device::createImageView" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13494,15 +13482,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - ShaderModule createShaderModule( const ShaderModuleCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createShaderModule( const ShaderModuleCreateInfo & createInfo, Optional allocator = nullptr ) const { ShaderModule shaderModule; Result result = static_cast( vkCreateShaderModule( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &shaderModule ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createShaderModule" ); - } - return shaderModule; + return createResultValue( result, shaderModule, "vk::Device::createShaderModule" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13524,15 +13508,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - PipelineCache createPipelineCache( const PipelineCacheCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createPipelineCache( const PipelineCacheCreateInfo & createInfo, Optional allocator = nullptr ) const { PipelineCache pipelineCache; Result result = static_cast( vkCreatePipelineCache( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &pipelineCache ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createPipelineCache" ); - } - return pipelineCache; + return createResultValue( result, pipelineCache, "vk::Device::createPipelineCache" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13555,7 +13535,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getPipelineCacheData( PipelineCache pipelineCache ) const + typename ResultValueType>::type getPipelineCacheData( PipelineCache pipelineCache ) const { std::vector data; size_t dataSize; @@ -13565,11 +13545,7 @@ namespace vk data.resize( dataSize ); result = static_cast( vkGetPipelineCacheData( m_device, static_cast( pipelineCache ), &dataSize, reinterpret_cast( data.data() ) ) ); } - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::getPipelineCacheData" ); - } - return data; + return createResultValue( result, data, "vk::Device::getPipelineCacheData" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13579,13 +13555,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void mergePipelineCaches( PipelineCache dstCache, ArrayProxy srcCaches ) const + ResultValueType::type mergePipelineCaches( PipelineCache dstCache, ArrayProxy srcCaches ) const { Result result = static_cast( vkMergePipelineCaches( m_device, static_cast( dstCache ), srcCaches.size() , reinterpret_cast( srcCaches.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::mergePipelineCaches" ); - } + return createResultValue( result, "vk::Device::mergePipelineCaches" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13596,15 +13569,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector createGraphicsPipelines( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr ) const + typename ResultValueType>::type createGraphicsPipelines( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr ) const { std::vector pipelines( createInfos.size() ); Result result = static_cast( vkCreateGraphicsPipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( pipelines.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createGraphicsPipelines" ); - } - return pipelines; + return createResultValue( result, pipelines, "vk::Device::createGraphicsPipelines" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13615,15 +13584,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector createComputePipelines( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr ) const + typename ResultValueType>::type createComputePipelines( PipelineCache pipelineCache, ArrayProxy createInfos, Optional allocator = nullptr ) const { std::vector pipelines( createInfos.size() ); Result result = static_cast( vkCreateComputePipelines( m_device, static_cast( pipelineCache ), createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( pipelines.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createComputePipelines" ); - } - return pipelines; + return createResultValue( result, pipelines, "vk::Device::createComputePipelines" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13645,15 +13610,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - PipelineLayout createPipelineLayout( const PipelineLayoutCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createPipelineLayout( const PipelineLayoutCreateInfo & createInfo, Optional allocator = nullptr ) const { PipelineLayout pipelineLayout; Result result = static_cast( vkCreatePipelineLayout( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &pipelineLayout ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createPipelineLayout" ); - } - return pipelineLayout; + return createResultValue( result, pipelineLayout, "vk::Device::createPipelineLayout" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13675,15 +13636,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Sampler createSampler( const SamplerCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createSampler( const SamplerCreateInfo & createInfo, Optional allocator = nullptr ) const { Sampler sampler; Result result = static_cast( vkCreateSampler( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &sampler ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createSampler" ); - } - return sampler; + return createResultValue( result, sampler, "vk::Device::createSampler" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13705,15 +13662,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DescriptorSetLayout createDescriptorSetLayout( const DescriptorSetLayoutCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDescriptorSetLayout( const DescriptorSetLayoutCreateInfo & createInfo, Optional allocator = nullptr ) const { DescriptorSetLayout setLayout; Result result = static_cast( vkCreateDescriptorSetLayout( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &setLayout ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createDescriptorSetLayout" ); - } - return setLayout; + return createResultValue( result, setLayout, "vk::Device::createDescriptorSetLayout" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13735,15 +13688,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DescriptorPool createDescriptorPool( const DescriptorPoolCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDescriptorPool( const DescriptorPoolCreateInfo & createInfo, Optional allocator = nullptr ) const { DescriptorPool descriptorPool; Result result = static_cast( vkCreateDescriptorPool( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &descriptorPool ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createDescriptorPool" ); - } - return descriptorPool; + return createResultValue( result, descriptorPool, "vk::Device::createDescriptorPool" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13767,13 +13716,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void resetDescriptorPool( DescriptorPool descriptorPool, DescriptorPoolResetFlags flags ) const + ResultValueType::type resetDescriptorPool( DescriptorPool descriptorPool, DescriptorPoolResetFlags flags ) const { Result result = static_cast( vkResetDescriptorPool( m_device, static_cast( descriptorPool ), static_cast( flags ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::resetDescriptorPool" ); - } + return createResultValue( result, "vk::Device::resetDescriptorPool" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13784,15 +13730,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector allocateDescriptorSets( const DescriptorSetAllocateInfo & allocateInfo ) const + typename ResultValueType>::type allocateDescriptorSets( const DescriptorSetAllocateInfo & allocateInfo ) const { std::vector descriptorSets( allocateInfo.descriptorSetCount ); Result result = static_cast( vkAllocateDescriptorSets( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( descriptorSets.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::allocateDescriptorSets" ); - } - return descriptorSets; + return createResultValue( result, descriptorSets, "vk::Device::allocateDescriptorSets" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13802,13 +13744,10 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - void freeDescriptorSets( DescriptorPool descriptorPool, ArrayProxy descriptorSets ) const + ResultValueType::type freeDescriptorSets( DescriptorPool descriptorPool, ArrayProxy descriptorSets ) const { Result result = static_cast( vkFreeDescriptorSets( m_device, static_cast( descriptorPool ), descriptorSets.size() , reinterpret_cast( descriptorSets.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::freeDescriptorSets" ); - } + return createResultValue( result, "vk::Device::freeDescriptorSets" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13830,15 +13769,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Framebuffer createFramebuffer( const FramebufferCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createFramebuffer( const FramebufferCreateInfo & createInfo, Optional allocator = nullptr ) const { Framebuffer framebuffer; Result result = static_cast( vkCreateFramebuffer( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &framebuffer ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createFramebuffer" ); - } - return framebuffer; + return createResultValue( result, framebuffer, "vk::Device::createFramebuffer" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13860,15 +13795,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - RenderPass createRenderPass( const RenderPassCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createRenderPass( const RenderPassCreateInfo & createInfo, Optional allocator = nullptr ) const { RenderPass renderPass; Result result = static_cast( vkCreateRenderPass( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &renderPass ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createRenderPass" ); - } - return renderPass; + return createResultValue( result, renderPass, "vk::Device::createRenderPass" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13904,15 +13835,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - CommandPool createCommandPool( const CommandPoolCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createCommandPool( const CommandPoolCreateInfo & createInfo, Optional allocator = nullptr ) const { CommandPool commandPool; Result result = static_cast( vkCreateCommandPool( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &commandPool ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createCommandPool" ); - } - return commandPool; + return createResultValue( result, commandPool, "vk::Device::createCommandPool" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13936,13 +13863,10 @@ namespace vk #endif /*!VKCPP_DISABLE_ENHANCED_MODE*/ #ifndef VKCPP_DISABLE_ENHANCED_MODE - void resetCommandPool( CommandPool commandPool, CommandPoolResetFlags flags ) const + ResultValueType::type resetCommandPool( CommandPool commandPool, CommandPoolResetFlags flags ) const { Result result = static_cast( vkResetCommandPool( m_device, static_cast( commandPool ), static_cast( flags ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::resetCommandPool" ); - } + return createResultValue( result, "vk::Device::resetCommandPool" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13953,15 +13877,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector allocateCommandBuffers( const CommandBufferAllocateInfo & allocateInfo ) const + typename ResultValueType>::type allocateCommandBuffers( const CommandBufferAllocateInfo & allocateInfo ) const { std::vector commandBuffers( allocateInfo.commandBufferCount ); Result result = static_cast( vkAllocateCommandBuffers( m_device, reinterpret_cast( &allocateInfo ), reinterpret_cast( commandBuffers.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::allocateCommandBuffers" ); - } - return commandBuffers; + return createResultValue( result, commandBuffers, "vk::Device::allocateCommandBuffers" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -13984,15 +13904,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector createSharedSwapchainsKHR( ArrayProxy createInfos, Optional allocator = nullptr ) const + typename ResultValueType>::type createSharedSwapchainsKHR( ArrayProxy createInfos, Optional allocator = nullptr ) const { std::vector swapchains( createInfos.size() ); Result result = static_cast( vkCreateSharedSwapchainsKHR( m_device, createInfos.size() , reinterpret_cast( createInfos.data() ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( swapchains.data() ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createSharedSwapchainsKHR" ); - } - return swapchains; + return createResultValue( result, swapchains, "vk::Device::createSharedSwapchainsKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14002,15 +13918,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - SwapchainKHR createSwapchainKHR( const SwapchainCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createSwapchainKHR( const SwapchainCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SwapchainKHR swapchain; Result result = static_cast( vkCreateSwapchainKHR( m_device, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &swapchain ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::createSwapchainKHR" ); - } - return swapchain; + return createResultValue( result, swapchain, "vk::Device::createSwapchainKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14033,7 +13945,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getSwapchainImagesKHR( SwapchainKHR swapchain ) const + typename ResultValueType>::type getSwapchainImagesKHR( SwapchainKHR swapchain ) const { std::vector swapchainImages; uint32_t swapchainImageCount; @@ -14047,11 +13959,7 @@ namespace vk result = static_cast( vkGetSwapchainImagesKHR( m_device, static_cast( swapchain ), &swapchainImageCount, reinterpret_cast( swapchainImages.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Device::getSwapchainImagesKHR" ); - } - return swapchainImages; + return createResultValue( result, swapchainImages, "vk::Device::getSwapchainImagesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14061,14 +13969,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Result acquireNextImageKHR( SwapchainKHR swapchain, uint64_t timeout, Semaphore semaphore, Fence fence, uint32_t & imageIndex ) const + ResultValue acquireNextImageKHR( SwapchainKHR swapchain, uint64_t timeout, Semaphore semaphore, Fence fence ) const { + uint32_t imageIndex; Result result = static_cast( vkAcquireNextImageKHR( m_device, static_cast( swapchain ), timeout, static_cast( semaphore ), static_cast( fence ), &imageIndex ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eTimeout ) && ( result != Result::eNotReady ) && ( result != Result::eSuboptimalKHR ) ) - { - throw std::system_error( result, "vk::Device::acquireNextImageKHR" ); - } - return result; + return createResultValue( result, imageIndex, "vk::Device::acquireNextImageKHR", { Result::eSuccess, Result::eTimeout, Result::eNotReady, Result::eSuboptimalKHR } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14194,15 +14099,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - ImageFormatProperties getImageFormatProperties( Format format, ImageType type, ImageTiling tiling, ImageUsageFlags usage, ImageCreateFlags flags ) const + ResultValueType::type getImageFormatProperties( Format format, ImageType type, ImageTiling tiling, ImageUsageFlags usage, ImageCreateFlags flags ) const { ImageFormatProperties imageFormatProperties; Result result = static_cast( vkGetPhysicalDeviceImageFormatProperties( m_physicalDevice, static_cast( format ), static_cast( type ), static_cast( tiling ), static_cast( usage ), static_cast( flags ), reinterpret_cast( &imageFormatProperties ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getImageFormatProperties" ); - } - return imageFormatProperties; + return createResultValue( result, imageFormatProperties, "vk::PhysicalDevice::getImageFormatProperties" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14212,15 +14113,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Device createDevice( const DeviceCreateInfo & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDevice( const DeviceCreateInfo & createInfo, Optional allocator = nullptr ) const { Device device; Result result = static_cast( vkCreateDevice( m_physicalDevice, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &device ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::createDevice" ); - } - return device; + return createResultValue( result, device, "vk::PhysicalDevice::createDevice" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14231,7 +14128,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector enumerateDeviceLayerProperties() const + typename ResultValueType>::type enumerateDeviceLayerProperties() const { std::vector properties; uint32_t propertyCount; @@ -14245,11 +14142,7 @@ namespace vk result = static_cast( vkEnumerateDeviceLayerProperties( m_physicalDevice, &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::enumerateDeviceLayerProperties" ); - } - return properties; + return createResultValue( result, properties, "vk::PhysicalDevice::enumerateDeviceLayerProperties" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14260,7 +14153,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector enumerateDeviceExtensionProperties( Optional layerName = nullptr ) const + typename ResultValueType>::type enumerateDeviceExtensionProperties( Optional layerName = nullptr ) const { std::vector properties; uint32_t propertyCount; @@ -14274,11 +14167,7 @@ namespace vk result = static_cast( vkEnumerateDeviceExtensionProperties( m_physicalDevice, layerName ? layerName->c_str() : nullptr, &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::enumerateDeviceExtensionProperties" ); - } - return properties; + return createResultValue( result, properties, "vk::PhysicalDevice::enumerateDeviceExtensionProperties" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14307,7 +14196,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getDisplayPropertiesKHR() const + typename ResultValueType>::type getDisplayPropertiesKHR() const { std::vector properties; uint32_t propertyCount; @@ -14321,11 +14210,7 @@ namespace vk result = static_cast( vkGetPhysicalDeviceDisplayPropertiesKHR( m_physicalDevice, &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getDisplayPropertiesKHR" ); - } - return properties; + return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayPropertiesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14336,7 +14221,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getDisplayPlanePropertiesKHR() const + typename ResultValueType>::type getDisplayPlanePropertiesKHR() const { std::vector properties; uint32_t propertyCount; @@ -14350,11 +14235,7 @@ namespace vk result = static_cast( vkGetPhysicalDeviceDisplayPlanePropertiesKHR( m_physicalDevice, &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getDisplayPlanePropertiesKHR" ); - } - return properties; + return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayPlanePropertiesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14365,7 +14246,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getDisplayPlaneSupportedDisplaysKHR( uint32_t planeIndex ) const + typename ResultValueType>::type getDisplayPlaneSupportedDisplaysKHR( uint32_t planeIndex ) const { std::vector displays; uint32_t displayCount; @@ -14379,11 +14260,7 @@ namespace vk result = static_cast( vkGetDisplayPlaneSupportedDisplaysKHR( m_physicalDevice, planeIndex, &displayCount, reinterpret_cast( displays.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getDisplayPlaneSupportedDisplaysKHR" ); - } - return displays; + return createResultValue( result, displays, "vk::PhysicalDevice::getDisplayPlaneSupportedDisplaysKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14394,7 +14271,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getDisplayModePropertiesKHR( DisplayKHR display ) const + typename ResultValueType>::type getDisplayModePropertiesKHR( DisplayKHR display ) const { std::vector properties; uint32_t propertyCount; @@ -14408,11 +14285,7 @@ namespace vk result = static_cast( vkGetDisplayModePropertiesKHR( m_physicalDevice, static_cast( display ), &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getDisplayModePropertiesKHR" ); - } - return properties; + return createResultValue( result, properties, "vk::PhysicalDevice::getDisplayModePropertiesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14422,15 +14295,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DisplayModeKHR createDisplayModeKHR( DisplayKHR display, const DisplayModeCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDisplayModeKHR( DisplayKHR display, const DisplayModeCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { DisplayModeKHR mode; Result result = static_cast( vkCreateDisplayModeKHR( m_physicalDevice, static_cast( display ), reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &mode ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::createDisplayModeKHR" ); - } - return mode; + return createResultValue( result, mode, "vk::PhysicalDevice::createDisplayModeKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14440,15 +14309,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DisplayPlaneCapabilitiesKHR getDisplayPlaneCapabilitiesKHR( DisplayModeKHR mode, uint32_t planeIndex ) const + ResultValueType::type getDisplayPlaneCapabilitiesKHR( DisplayModeKHR mode, uint32_t planeIndex ) const { DisplayPlaneCapabilitiesKHR capabilities; Result result = static_cast( vkGetDisplayPlaneCapabilitiesKHR( m_physicalDevice, static_cast( mode ), planeIndex, reinterpret_cast( &capabilities ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getDisplayPlaneCapabilitiesKHR" ); - } - return capabilities; + return createResultValue( result, capabilities, "vk::PhysicalDevice::getDisplayPlaneCapabilitiesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14474,15 +14339,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Bool32 getSurfaceSupportKHR( uint32_t queueFamilyIndex, SurfaceKHR surface ) const + ResultValueType::type getSurfaceSupportKHR( uint32_t queueFamilyIndex, SurfaceKHR surface ) const { Bool32 supported; Result result = static_cast( vkGetPhysicalDeviceSurfaceSupportKHR( m_physicalDevice, queueFamilyIndex, static_cast( surface ), &supported ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getSurfaceSupportKHR" ); - } - return supported; + return createResultValue( result, supported, "vk::PhysicalDevice::getSurfaceSupportKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14492,14 +14353,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - Result getSurfaceCapabilitiesKHR( SurfaceKHR surface, SurfaceCapabilitiesKHR & surfaceCapabilities ) const + ResultValue getSurfaceCapabilitiesKHR( SurfaceKHR surface ) const { + SurfaceCapabilitiesKHR surfaceCapabilities; Result result = static_cast( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( m_physicalDevice, static_cast( surface ), reinterpret_cast( &surfaceCapabilities ) ) ); - if ( ( result != Result::eSuccess ) && ( result != Result::eIncomplete ) ) - { - throw std::system_error( result, "vk::PhysicalDevice::getSurfaceCapabilitiesKHR" ); - } - return result; + return createResultValue( result, surfaceCapabilities, "vk::PhysicalDevice::getSurfaceCapabilitiesKHR", { Result::eSuccess, Result::eIncomplete } ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14510,7 +14368,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getSurfaceFormatsKHR( SurfaceKHR surface ) const + typename ResultValueType>::type getSurfaceFormatsKHR( SurfaceKHR surface ) const { std::vector surfaceFormats; uint32_t surfaceFormatCount; @@ -14524,11 +14382,7 @@ namespace vk result = static_cast( vkGetPhysicalDeviceSurfaceFormatsKHR( m_physicalDevice, static_cast( surface ), &surfaceFormatCount, reinterpret_cast( surfaceFormats.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getSurfaceFormatsKHR" ); - } - return surfaceFormats; + return createResultValue( result, surfaceFormats, "vk::PhysicalDevice::getSurfaceFormatsKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14539,7 +14393,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector getSurfacePresentModesKHR( SurfaceKHR surface ) const + typename ResultValueType>::type getSurfacePresentModesKHR( SurfaceKHR surface ) const { std::vector presentModes; uint32_t presentModeCount; @@ -14553,11 +14407,7 @@ namespace vk result = static_cast( vkGetPhysicalDeviceSurfacePresentModesKHR( m_physicalDevice, static_cast( surface ), &presentModeCount, reinterpret_cast( presentModes.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::PhysicalDevice::getSurfacePresentModesKHR" ); - } - return presentModes; + return createResultValue( result, presentModes, "vk::PhysicalDevice::getSurfacePresentModesKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14802,7 +14652,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector enumeratePhysicalDevices() const + typename ResultValueType>::type enumeratePhysicalDevices() const { std::vector physicalDevices; uint32_t physicalDeviceCount; @@ -14816,11 +14666,7 @@ namespace vk result = static_cast( vkEnumeratePhysicalDevices( m_instance, &physicalDeviceCount, reinterpret_cast( physicalDevices.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::enumeratePhysicalDevices" ); - } - return physicalDevices; + return createResultValue( result, physicalDevices, "vk::Instance::enumeratePhysicalDevices" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14845,15 +14691,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_ANDROID_KHR - SurfaceKHR createAndroidSurfaceKHR( const AndroidSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createAndroidSurfaceKHR( const AndroidSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateAndroidSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createAndroidSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createAndroidSurfaceKHR" ); } #endif /*VK_USE_PLATFORM_ANDROID_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14864,15 +14706,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - SurfaceKHR createDisplayPlaneSurfaceKHR( const DisplaySurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDisplayPlaneSurfaceKHR( const DisplaySurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateDisplayPlaneSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createDisplayPlaneSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createDisplayPlaneSurfaceKHR" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14885,15 +14723,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_MIR_KHR - SurfaceKHR createMirSurfaceKHR( const MirSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createMirSurfaceKHR( const MirSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateMirSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createMirSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createMirSurfaceKHR" ); } #endif /*VK_USE_PLATFORM_MIR_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14919,15 +14753,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_WAYLAND_KHR - SurfaceKHR createWaylandSurfaceKHR( const WaylandSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createWaylandSurfaceKHR( const WaylandSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateWaylandSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createWaylandSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createWaylandSurfaceKHR" ); } #endif /*VK_USE_PLATFORM_WAYLAND_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14941,15 +14771,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_WIN32_KHR - SurfaceKHR createWin32SurfaceKHR( const Win32SurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createWin32SurfaceKHR( const Win32SurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateWin32SurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createWin32SurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createWin32SurfaceKHR" ); } #endif /*VK_USE_PLATFORM_WIN32_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14963,15 +14789,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_XLIB_KHR - SurfaceKHR createXlibSurfaceKHR( const XlibSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createXlibSurfaceKHR( const XlibSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateXlibSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createXlibSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createXlibSurfaceKHR" ); } #endif /*VK_USE_PLATFORM_XLIB_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -14985,15 +14807,11 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE #ifdef VK_USE_PLATFORM_XCB_KHR - SurfaceKHR createXcbSurfaceKHR( const XcbSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createXcbSurfaceKHR( const XcbSurfaceCreateInfoKHR & createInfo, Optional allocator = nullptr ) const { SurfaceKHR surface; Result result = static_cast( vkCreateXcbSurfaceKHR( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &surface ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createXcbSurfaceKHR" ); - } - return surface; + return createResultValue( result, surface, "vk::Instance::createXcbSurfaceKHR" ); } #endif /*VK_USE_PLATFORM_XCB_KHR*/ #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -15004,15 +14822,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - DebugReportCallbackEXT createDebugReportCallbackEXT( const DebugReportCallbackCreateInfoEXT & createInfo, Optional allocator = nullptr ) const + ResultValueType::type createDebugReportCallbackEXT( const DebugReportCallbackCreateInfoEXT & createInfo, Optional allocator = nullptr ) const { DebugReportCallbackEXT callback; Result result = static_cast( vkCreateDebugReportCallbackEXT( m_instance, reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &callback ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::Instance::createDebugReportCallbackEXT" ); - } - return callback; + return createResultValue( result, callback, "vk::Instance::createDebugReportCallbackEXT" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -15075,15 +14889,11 @@ namespace vk } #ifndef VKCPP_DISABLE_ENHANCED_MODE - inline Instance createInstance( const InstanceCreateInfo & createInfo, Optional allocator = nullptr ) + inline ResultValueType::type createInstance( const InstanceCreateInfo & createInfo, Optional allocator = nullptr ) { Instance instance; Result result = static_cast( vkCreateInstance( reinterpret_cast( &createInfo ), reinterpret_cast( static_cast( allocator)), reinterpret_cast( &instance ) ) ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::createInstance" ); - } - return instance; + return createResultValue( result, instance, "vk::createInstance" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -15094,7 +14904,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector enumerateInstanceLayerProperties() + typename ResultValueType>::type enumerateInstanceLayerProperties() { std::vector properties; uint32_t propertyCount; @@ -15108,11 +14918,7 @@ namespace vk result = static_cast( vkEnumerateInstanceLayerProperties( &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::enumerateInstanceLayerProperties" ); - } - return properties; + return createResultValue( result, properties, "vk::enumerateInstanceLayerProperties" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/ @@ -15123,7 +14929,7 @@ namespace vk #ifndef VKCPP_DISABLE_ENHANCED_MODE template > - std::vector enumerateInstanceExtensionProperties( Optional layerName = nullptr ) + typename ResultValueType>::type enumerateInstanceExtensionProperties( Optional layerName = nullptr ) { std::vector properties; uint32_t propertyCount; @@ -15137,11 +14943,7 @@ namespace vk result = static_cast( vkEnumerateInstanceExtensionProperties( layerName ? layerName->c_str() : nullptr, &propertyCount, reinterpret_cast( properties.data() ) ) ); } } while ( result == Result::eIncomplete ); - if ( result != Result::eSuccess ) - { - throw std::system_error( result, "vk::enumerateInstanceExtensionProperties" ); - } - return properties; + return createResultValue( result, properties, "vk::enumerateInstanceExtensionProperties" ); } #endif /*VKCPP_DISABLE_ENHANCED_MODE*/