diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index c353918..727e1b3 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1,3089 +1,3142 @@ -// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#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" - " const T * begin() const\n" - " {\n" - " return m_ptr;\n" - " }\n" - "\n" - " const T * end() const\n" - " {\n" - " return m_ptr + m_count;\n" - " }\n" - "\n" - " const T & front() const\n" - " {\n" - " assert(m_count && m_ptr);\n" - " return *m_ptr;\n" - " }\n" - "\n" - " const T & back() const\n" - " {\n" - " assert(m_count && m_ptr);\n" - " return *(m_ptr + m_count - 1);\n" - " }\n" - "\n" - " bool empty() const\n" - " {\n" - " return (m_count == 0);\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(VULKAN_HPP_HAS_UNRESTRICTED_UNIONS)\n" - "# if defined(__clang__)\n" - "# if __has_feature(cxx_unrestricted_unions)\n" - "# define VULKAN_HPP_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 VULKAN_HPP_HAS_UNRESTRICTED_UNIONS\n" - "# endif\n" - "# elif defined(_MSC_VER)\n" - "# if 1900 <= _MSC_VER\n" - "# define VULKAN_HPP_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 VULKAN_HPP_NO_EXCEPTIONS\n" - " typedef ResultValue type;\n" - "#else\n" - " typedef T type;\n" - "#endif\n" - " };\n" - "\n" - " template <>" - " struct ResultValueType\n" - " {\n" - "#ifdef VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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) +// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#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" + " const T * begin() const\n" + " {\n" + " return m_ptr;\n" + " }\n" + "\n" + " const T * end() const\n" + " {\n" + " return m_ptr + m_count;\n" + " }\n" + "\n" + " const T & front() const\n" + " {\n" + " assert(m_count && m_ptr);\n" + " return *m_ptr;\n" + " }\n" + "\n" + " const T & back() const\n" + " {\n" + " assert(m_count && m_ptr);\n" + " return *(m_ptr + m_count - 1);\n" + " }\n" + "\n" + " bool empty() const\n" + " {\n" + " return (m_count == 0);\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(VULKAN_HPP_HAS_UNRESTRICTED_UNIONS)\n" + "# if defined(__clang__)\n" + "# if __has_feature(cxx_unrestricted_unions)\n" + "# define VULKAN_HPP_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 VULKAN_HPP_HAS_UNRESTRICTED_UNIONS\n" + "# endif\n" + "# elif defined(_MSC_VER)\n" + "# if 1900 <= _MSC_VER\n" + "# define VULKAN_HPP_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 VULKAN_HPP_NO_EXCEPTIONS\n" + " typedef ResultValue type;\n" + "#else\n" + " typedef T type;\n" + "#endif\n" + " };\n" + "\n" + " template <>" + " struct ResultValueType\n" + " {\n" + "#ifdef VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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 VULKAN_HPP_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; + bool isUnion; + 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, bool singular = false); +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, bool singular); +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, bool singular); +void writeFunctionHeader(std::ofstream & ofs, VkData const& vkData, 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, bool singular); +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, VkData const& vkData, DependencyData const& dependencyData); +void writeTypeCommandEnhanced(std::ofstream & ofs, VkData const& vkData, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData); +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 default to nullptr + defaultValues[it->name] = "nullptr"; + 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 vulkan.hpp 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" ); + it->second.isUnion = false; + + 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; + it->second.isUnion = true; + + 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, bool singular) +{ + 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; + } + if (singular) + { + size_t pos = reducedName.rfind('s'); + assert(pos != std::string::npos); + reducedName.erase(pos, 1); + } + + 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, bool singular) +{ + 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 + { + if (singular) + { + ofs << "1 "; + } + 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 << "*>( " << (singular ? "&" : "") << reduceName(commandData.arguments[it->first].name, singular) << (singular ? "" : ".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, bool singular) +{ + 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 VULKAN_HPP_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 // VULKAN_HPP_NO_EXCEPTIONS" << std::endl; + } + } + } + } + } + + // write the local variable to hold a returned value + if (returnIndex != ~0) + { + if (commandData.returnType != returnType) + { + ofs << indentation << " " << (singular ? commandData.arguments[returnIndex].pureType : returnType) << " " << reduceName(commandData.arguments[returnIndex].name, singular); + + if ( !singular) + { + 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, singular); + 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 << " "; + } + assert(!singular); + writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, false, singular); + 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, singular) << ", "; + } + ofs << "\"vk::" << (className.empty() ? "" : className + "::") << reduceName(functionName, singular) << "\""; + 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, VkData const& vkData, 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, bool singular) +{ + 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 ( !singular && (templateIndex != ~0) && ((templateIndex != returnIndex) || (returnType == "Result"))) + { + assert(returnType.find("Allocator") == std::string::npos); + ofs << "template " << std::endl + << indentation; + } + else if (!singular && (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<" << (singular ? commandData.arguments[returnIndex].pureType : 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, singular) << "("; + 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 << "]"; + } + if (lastArgument == i) + { + std::map::const_iterator flagIt = vkData.flags.find(commandData.arguments[i].pureType); + if (flagIt != vkData.flags.end()) + { + std::list::const_iterator depIt = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [&flagIt](DependencyData const& dd) { return(dd.name == flagIt->first); }); + assert(depIt != vkData.dependencies.end()); + assert(depIt->dependencies.size() == 1); + std::map::const_iterator enumIt = vkData.enums.find(*depIt->dependencies.begin()); + assert(enumIt != vkData.enums.end()); + if (enumIt->second.members.empty()) + { + ofs << " = " << commandData.arguments[i].pureType << "()"; + } + } + } + } + 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); + if (singular) + { + ofs << trimEnd(commandData.arguments[i].type.substr(0, pos)) << " & " << reduceName(commandData.arguments[i].name, true); + } + else + { + 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 ) +{ + // the constructor with all the elements as arguments, with defaults + ofs << " " << name << "( "; + bool listedArgument = false; + for (size_t i = 0; i::const_iterator defaultIt = defaultValues.find(structData.members[i].pureType); + assert(defaultIt != defaultValues.end()); + if (structData.members[i].arraySize.empty()) + { + ofs << structData.members[i].type + " " + structData.members[i].name << "_ = " << (structData.members[i].type.back() == '*' ? "nullptr" : defaultIt->second); + } + else + { + ofs << "std::array<" + structData.members[i].type + "," + structData.members[i].arraySize + "> const& " + structData.members[i].name << "_ = { " << defaultIt->second; + size_t n = atoi(structData.members[i].arraySize.c_str()); + assert(0 < n); + for (size_t j = 1; j < n; j++) + { + ofs << ", " << defaultIt->second; + } + ofs << " }"; + } + listedArgument = true; + } + } + ofs << " )" << std::endl; + + // copy over the simple arguments + bool firstArgument = true; + for (size_t i = 0; i < structData.members.size(); i++) + { + if (structData.members[i].arraySize.empty()) + { + ofs << " " << (firstArgument ? ":" : ",") << " " << structData.members[i].name << "( "; + if (structData.members[i].name == "pNext") + { + ofs << "nullptr"; + } + else if (structData.members[i].name == "sType") + { + ofs << "StructureType::e" << name; + } + else + { + ofs << structData.members[i].name << "_"; + } + ofs << " )" << std::endl; + firstArgument = false; + } + } + + // 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, VkData const& vkData, DependencyData const& dependencyData) +{ + assert(vkData.commands.find(dependencyData.name) != vkData.commands.end()); + CommandData const& commandData = vkData.commands.find(dependencyData.name)->second; + if (!commandData.handleCommand) + { + writeTypeCommandStandard(ofs, " ", dependencyData.name, dependencyData, commandData, vkData.vkTypes); + + ofs << std::endl + << "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; + writeTypeCommandEnhanced(ofs, vkData, " ", "", dependencyData.name, dependencyData, commandData); + ofs << "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl + << std::endl; + } +} + +void writeTypeCommandEnhanced(std::ofstream & ofs, VkData const& vkData, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData) +{ + 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, vkData, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters, false); + writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkData.vkTypes, returnIndex, vectorParameters, false); + + // determine candidates for singular version of function + if ((returnVector != vectorParameters.end()) && (returnVector->second != ~0) && (commandData.arguments[returnVector->second].type.back() != '*')) + { + ofs << std::endl; + writeFunctionHeader(ofs, vkData, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters, true); + writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkData.vkTypes, returnIndex, vectorParameters, true); + } + 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(VULKAN_HPP_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 VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; + } + writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkData.vkTypes); + if (!hasPointers) + { + ofs << "#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl; + } + + ofs << std::endl + << "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; + writeTypeCommandEnhanced(ofs, vkData, " ", className, functionName, *dep, cit->second); + ofs << "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl; + + if (i < handle.commands.size() - 1) + { + ofs << std::endl; + } + } + ofs << std::endl; + } + ofs << "#if !defined(VULKAN_HPP_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; +} + +bool containsUnion(std::string const& type, std::map const& structs) { - 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 + std::map::const_iterator sit = structs.find(type); + bool found = (sit != structs.end()); + if (found) { - 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, bool singular = false); -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, bool singular); -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, bool singular); -void writeFunctionHeader(std::ofstream & ofs, VkData const& vkData, 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, bool singular); -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, VkData const& vkData, DependencyData const& dependencyData); -void writeTypeCommandEnhanced(std::ofstream & ofs, VkData const& vkData, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData); -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) + found = sit->second.isUnion; + for (std::vector::const_iterator mit = sit->second.members.begin(); mit != sit->second.members.end() && !found; ++mit) { - members.back().name.erase(pos); + found = (mit->type == mit->pureType) && containsUnion(mit->type, structs); } } - if (appendTag && !tag.empty()) - { - members.back().name += tag; - } + return found; } -void createDefaults( VkData const& vkData, std::map & defaultValues ) -{ - for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) +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; + + // operator==() and operator!=() + // only structs without a union as a member can have a meaningfull == and != operation; we filter them out + if (!containsUnion(dependencyData.name, vkData.structs)) { - assert( defaultValues.find( it->name ) == defaultValues.end() ); - switch( it->category ) + ofs << " bool operator==( " << dependencyData.name << " const& rhs ) const" << std::endl + << " {" << std::endl + << " return "; + for (size_t i = 0; i < it->second.members.size(); i++) { - 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 default to nullptr - defaultValues[it->name] = "nullptr"; - 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") + if (i != 0) { - returnType = "std::vector"; + ofs << std::endl << " && "; } - 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 vulkan.hpp 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, bool singular) -{ - 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; - } - if (singular) - { - size_t pos = reducedName.rfind('s'); - assert(pos != std::string::npos); - reducedName.erase(pos, 1); - } - - 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, bool singular) -{ - 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 - { - if (singular) - { - ofs << "1 "; - } - 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 << "*>( " << (singular ? "&" : "") << reduceName(commandData.arguments[it->first].name, singular) << (singular ? "" : ".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, bool singular) -{ - 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 VULKAN_HPP_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 // VULKAN_HPP_NO_EXCEPTIONS" << std::endl; - } - } - } - } - } - - // write the local variable to hold a returned value - if (returnIndex != ~0) - { - if (commandData.returnType != returnType) - { - ofs << indentation << " " << (singular ? commandData.arguments[returnIndex].pureType : returnType) << " " << reduceName(commandData.arguments[returnIndex].name, singular); - - if ( !singular) - { - 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, singular); - 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 << " "; - } - assert(!singular); - writeCall(ofs, dependencyData.name, templateIndex, commandData, vkTypes, vectorParameters, returnIndex, false, singular); - 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, singular) << ", "; - } - ofs << "\"vk::" << (className.empty() ? "" : className + "::") << reduceName(functionName, singular) << "\""; - 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, VkData const& vkData, 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, bool singular) -{ - 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 ( !singular && (templateIndex != ~0) && ((templateIndex != returnIndex) || (returnType == "Result"))) - { - assert(returnType.find("Allocator") == std::string::npos); - ofs << "template " << std::endl - << indentation; - } - else if (!singular && (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<" << (singular ? commandData.arguments[returnIndex].pureType : 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, singular) << "("; - 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 << "]"; - } - if (lastArgument == i) - { - std::map::const_iterator flagIt = vkData.flags.find(commandData.arguments[i].pureType); - if (flagIt != vkData.flags.end()) - { - std::list::const_iterator depIt = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [&flagIt](DependencyData const& dd) { return(dd.name == flagIt->first); }); - assert(depIt != vkData.dependencies.end()); - assert(depIt->dependencies.size() == 1); - std::map::const_iterator enumIt = vkData.enums.find(*depIt->dependencies.begin()); - assert(enumIt != vkData.enums.end()); - if (enumIt->second.members.empty()) - { - ofs << " = " << commandData.arguments[i].pureType << "()"; - } - } - } - } - 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); - if (singular) - { - ofs << trimEnd(commandData.arguments[i].type.substr(0, pos)) << " & " << reduceName(commandData.arguments[i].name, true); - } - else - { - 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 ) -{ - // the constructor with all the elements as arguments, with defaults - ofs << " " << name << "( "; - bool listedArgument = false; - for (size_t i = 0; i::const_iterator defaultIt = defaultValues.find(structData.members[i].pureType); - assert(defaultIt != defaultValues.end()); - if (structData.members[i].arraySize.empty()) - { - ofs << structData.members[i].type + " " + structData.members[i].name << "_ = " << (structData.members[i].type.back() == '*' ? "nullptr" : defaultIt->second); - } - else - { - ofs << "std::array<" + structData.members[i].type + "," + structData.members[i].arraySize + "> const& " + structData.members[i].name << "_ = { " << defaultIt->second; - size_t n = atoi(structData.members[i].arraySize.c_str()); - assert(0 < n); - for (size_t j = 1; j < n; j++) - { - ofs << ", " << defaultIt->second; - } - ofs << " }"; - } - listedArgument = true; - } - } - ofs << " )" << std::endl; - - // copy over the simple arguments - bool firstArgument = true; - for (size_t i = 0; i < structData.members.size(); i++) - { - if (structData.members[i].arraySize.empty()) - { - ofs << " " << (firstArgument ? ":" : ",") << " " << structData.members[i].name << "( "; - if (structData.members[i].name == "pNext") - { - ofs << "nullptr"; - } - else if (structData.members[i].name == "sType") - { - ofs << "StructureType::e" << name; - } - else - { - ofs << structData.members[i].name << "_"; - } - ofs << " )" << std::endl; - firstArgument = false; - } - } - - // 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, VkData const& vkData, DependencyData const& dependencyData) -{ - assert(vkData.commands.find(dependencyData.name) != vkData.commands.end()); - CommandData const& commandData = vkData.commands.find(dependencyData.name)->second; - if (!commandData.handleCommand) - { - writeTypeCommandStandard(ofs, " ", dependencyData.name, dependencyData, commandData, vkData.vkTypes); - - ofs << std::endl - << "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; - writeTypeCommandEnhanced(ofs, vkData, " ", "", dependencyData.name, dependencyData, commandData); - ofs << "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl - << std::endl; - } -} - -void writeTypeCommandEnhanced(std::ofstream & ofs, VkData const& vkData, std::string const& indentation, std::string const& className, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData) -{ - 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, vkData, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters, false); - writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkData.vkTypes, returnIndex, vectorParameters, false); - - // determine candidates for singular version of function - if ((returnVector != vectorParameters.end()) && (returnVector->second != ~0) && (commandData.arguments[returnVector->second].type.back() != '*')) - { - ofs << std::endl; - writeFunctionHeader(ofs, vkData, indentation, returnType, functionName, commandData, returnIndex, templateIndex, vectorParameters, true); - writeFunctionBody(ofs, indentation, className, functionName, returnType, templateIndex, dependencyData, commandData, vkData.vkTypes, returnIndex, vectorParameters, true); - } - 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(VULKAN_HPP_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 VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; - } - writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkData.vkTypes); - if (!hasPointers) - { - ofs << "#endif /*!VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl; - } - - ofs << std::endl - << "#ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl; - writeTypeCommandEnhanced(ofs, vkData, " ", className, functionName, *dep, cit->second); - ofs << "#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/" << std::endl; - - if (i < handle.commands.size() - 1) - { - ofs << std::endl; - } - } - ofs << std::endl; - } - ofs << "#if !defined(VULKAN_HPP_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++) - { - if (it->second.members[i].type == "StructureType") - { - assert((i == 0) && (it->second.members[i].name == "sType")); - ofs << " private:" << std::endl - << " StructureType sType;" << std::endl - << std::endl - << " public:" << std::endl; - } - else - { - 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; + ofs << "( memcmp( " << it->second.members[i].name << ", rhs." << it->second.members[i].name << ", " << it->second.members[i].arraySize << " * sizeof( " << it->second.members[i].type << " ) ) == 0 )"; } else { - ofs << " = { " << it->second << " }"; + ofs << "( " << it->second.members[i].name << " == rhs." << it->second.members[i].name << " )"; } } - 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 + << " bool operator!=( " << dependencyData.name << " const& rhs ) const" << std::endl + << " {" << std::endl + << " return !operator==( rhs );" << 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 VULKAN_HPP_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 // VULKAN_HPP_HAS_UNRESTRICTED_UNIONS" << std::endl; - } + // the member variables + for (size_t i = 0; i < it->second.members.size(); i++) + { + if (it->second.members[i].type == "StructureType") + { + assert((i == 0) && (it->second.members[i].name == "sType")); + ofs << " private:" << std::endl + << " StructureType sType;" << std::endl + << std::endl + << " public:" << std::endl; + } + else + { + 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 - << std::endl; -} + << " static_assert( sizeof( " << dependencyData.name << " ) == sizeof( Vk" << dependencyData.name << " ), \"struct and wrapper have different size!\" );" << 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 : - writeTypeCommand( ofs, vkData, *it ); - 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 VULKAN_HPP_TYPESAFE_CONVERSION" << std::endl - << typesafeCheck << std::endl - << "#define VULKAN_HPP_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 vulkan.hpp to " << VULKAN_HPP << 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(VULKAN_HPP); - ofs << nvidiaLicenseHeader << std::endl - << vkData.vulkanLicenseHeader << std::endl - << std::endl - << std::endl - << "#ifndef VULKAN_HPP" << std::endl - << "#define VULKAN_HPP" << 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 VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl - << "# include " << std::endl - << "#endif /*VULKAN_HPP_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; - } -} + 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 VULKAN_HPP_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 // VULKAN_HPP_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 : + writeTypeCommand( ofs, vkData, *it ); + 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 VULKAN_HPP_TYPESAFE_CONVERSION" << std::endl + << typesafeCheck << std::endl + << "#define VULKAN_HPP_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 vulkan.hpp to " << VULKAN_HPP << 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(VULKAN_HPP); + ofs << nvidiaLicenseHeader << std::endl + << vkData.vulkanLicenseHeader << std::endl + << std::endl + << std::endl + << "#ifndef VULKAN_HPP" << std::endl + << "#define VULKAN_HPP" << 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 VULKAN_HPP_DISABLE_ENHANCED_MODE" << std::endl + << "# include " << std::endl + << "#endif /*VULKAN_HPP_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/vulkan.hpp b/vulkan/vulkan.hpp index 97075d7..950b44e 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -2017,6 +2017,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Offset2D const& rhs ) const + { + return ( x == rhs.x ) + && ( y == rhs.y ); + } + + bool operator!=( Offset2D const& rhs ) const + { + return !operator==( rhs ); + } + int32_t x; int32_t y; }; @@ -2065,6 +2076,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Offset3D const& rhs ) const + { + return ( x == rhs.x ) + && ( y == rhs.y ) + && ( z == rhs.z ); + } + + bool operator!=( Offset3D const& rhs ) const + { + return !operator==( rhs ); + } + int32_t x; int32_t y; int32_t z; @@ -2107,6 +2130,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Extent2D const& rhs ) const + { + return ( width == rhs.width ) + && ( height == rhs.height ); + } + + bool operator!=( Extent2D const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t width; uint32_t height; }; @@ -2155,6 +2189,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Extent3D const& rhs ) const + { + return ( width == rhs.width ) + && ( height == rhs.height ) + && ( depth == rhs.depth ); + } + + bool operator!=( Extent3D const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t width; uint32_t height; uint32_t depth; @@ -2225,6 +2271,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Viewport const& rhs ) const + { + return ( x == rhs.x ) + && ( y == rhs.y ) + && ( width == rhs.width ) + && ( height == rhs.height ) + && ( minDepth == rhs.minDepth ) + && ( maxDepth == rhs.maxDepth ); + } + + bool operator!=( Viewport const& rhs ) const + { + return !operator==( rhs ); + } + float x; float y; float width; @@ -2270,6 +2331,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Rect2D const& rhs ) const + { + return ( offset == rhs.offset ) + && ( extent == rhs.extent ); + } + + bool operator!=( Rect2D const& rhs ) const + { + return !operator==( rhs ); + } + Offset2D offset; Extent2D extent; }; @@ -2318,6 +2390,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ClearRect const& rhs ) const + { + return ( rect == rhs.rect ) + && ( baseArrayLayer == rhs.baseArrayLayer ) + && ( layerCount == rhs.layerCount ); + } + + bool operator!=( ClearRect const& rhs ) const + { + return !operator==( rhs ); + } + Rect2D rect; uint32_t baseArrayLayer; uint32_t layerCount; @@ -2331,6 +2415,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ExtensionProperties const& rhs ) const + { + return ( memcmp( extensionName, rhs.extensionName, VK_MAX_EXTENSION_NAME_SIZE * sizeof( char ) ) == 0 ) + && ( specVersion == rhs.specVersion ); + } + + bool operator!=( ExtensionProperties const& rhs ) const + { + return !operator==( rhs ); + } + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; uint32_t specVersion; }; @@ -2343,6 +2438,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( LayerProperties const& rhs ) const + { + return ( memcmp( layerName, rhs.layerName, VK_MAX_EXTENSION_NAME_SIZE * sizeof( char ) ) == 0 ) + && ( specVersion == rhs.specVersion ) + && ( implementationVersion == rhs.implementationVersion ) + && ( memcmp( description, rhs.description, VK_MAX_DESCRIPTION_SIZE * sizeof( char ) ) == 0 ); + } + + bool operator!=( LayerProperties const& rhs ) const + { + return !operator==( rhs ); + } + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; uint32_t specVersion; uint32_t implementationVersion; @@ -2414,6 +2522,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( AllocationCallbacks const& rhs ) const + { + return ( pUserData == rhs.pUserData ) + && ( pfnAllocation == rhs.pfnAllocation ) + && ( pfnReallocation == rhs.pfnReallocation ) + && ( pfnFree == rhs.pfnFree ) + && ( pfnInternalAllocation == rhs.pfnInternalAllocation ) + && ( pfnInternalFree == rhs.pfnInternalFree ); + } + + bool operator!=( AllocationCallbacks const& rhs ) const + { + return !operator==( rhs ); + } + void* pUserData; PFN_vkAllocationFunction pfnAllocation; PFN_vkReallocationFunction pfnReallocation; @@ -2430,6 +2553,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MemoryRequirements const& rhs ) const + { + return ( size == rhs.size ) + && ( alignment == rhs.alignment ) + && ( memoryTypeBits == rhs.memoryTypeBits ); + } + + bool operator!=( MemoryRequirements const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize size; DeviceSize alignment; uint32_t memoryTypeBits; @@ -2479,6 +2614,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorBufferInfo const& rhs ) const + { + return ( buffer == rhs.buffer ) + && ( offset == rhs.offset ) + && ( range == rhs.range ); + } + + bool operator!=( DescriptorBufferInfo const& rhs ) const + { + return !operator==( rhs ); + } + Buffer buffer; DeviceSize offset; DeviceSize range; @@ -2492,6 +2639,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SubresourceLayout const& rhs ) const + { + return ( offset == rhs.offset ) + && ( size == rhs.size ) + && ( rowPitch == rhs.rowPitch ) + && ( arrayPitch == rhs.arrayPitch ) + && ( depthPitch == rhs.depthPitch ); + } + + bool operator!=( SubresourceLayout const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize offset; DeviceSize size; DeviceSize rowPitch; @@ -2543,6 +2704,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BufferCopy const& rhs ) const + { + return ( srcOffset == rhs.srcOffset ) + && ( dstOffset == rhs.dstOffset ) + && ( size == rhs.size ); + } + + bool operator!=( BufferCopy const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize srcOffset; DeviceSize dstOffset; DeviceSize size; @@ -2592,6 +2765,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SpecializationMapEntry const& rhs ) const + { + return ( constantID == rhs.constantID ) + && ( offset == rhs.offset ) + && ( size == rhs.size ); + } + + bool operator!=( SpecializationMapEntry const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t constantID; uint32_t offset; size_t size; @@ -2648,6 +2833,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SpecializationInfo const& rhs ) const + { + return ( mapEntryCount == rhs.mapEntryCount ) + && ( pMapEntries == rhs.pMapEntries ) + && ( dataSize == rhs.dataSize ) + && ( pData == rhs.pData ); + } + + bool operator!=( SpecializationInfo const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t mapEntryCount; const SpecializationMapEntry* pMapEntries; size_t dataSize; @@ -2736,6 +2934,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ClearDepthStencilValue const& rhs ) const + { + return ( depth == rhs.depth ) + && ( stencil == rhs.stencil ); + } + + bool operator!=( ClearDepthStencilValue const& rhs ) const + { + return !operator==( rhs ); + } + float depth; uint32_t stencil; }; @@ -3186,6 +3395,70 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PhysicalDeviceFeatures const& rhs ) const + { + return ( robustBufferAccess == rhs.robustBufferAccess ) + && ( fullDrawIndexUint32 == rhs.fullDrawIndexUint32 ) + && ( imageCubeArray == rhs.imageCubeArray ) + && ( independentBlend == rhs.independentBlend ) + && ( geometryShader == rhs.geometryShader ) + && ( tessellationShader == rhs.tessellationShader ) + && ( sampleRateShading == rhs.sampleRateShading ) + && ( dualSrcBlend == rhs.dualSrcBlend ) + && ( logicOp == rhs.logicOp ) + && ( multiDrawIndirect == rhs.multiDrawIndirect ) + && ( drawIndirectFirstInstance == rhs.drawIndirectFirstInstance ) + && ( depthClamp == rhs.depthClamp ) + && ( depthBiasClamp == rhs.depthBiasClamp ) + && ( fillModeNonSolid == rhs.fillModeNonSolid ) + && ( depthBounds == rhs.depthBounds ) + && ( wideLines == rhs.wideLines ) + && ( largePoints == rhs.largePoints ) + && ( alphaToOne == rhs.alphaToOne ) + && ( multiViewport == rhs.multiViewport ) + && ( samplerAnisotropy == rhs.samplerAnisotropy ) + && ( textureCompressionETC2 == rhs.textureCompressionETC2 ) + && ( textureCompressionASTC_LDR == rhs.textureCompressionASTC_LDR ) + && ( textureCompressionBC == rhs.textureCompressionBC ) + && ( occlusionQueryPrecise == rhs.occlusionQueryPrecise ) + && ( pipelineStatisticsQuery == rhs.pipelineStatisticsQuery ) + && ( vertexPipelineStoresAndAtomics == rhs.vertexPipelineStoresAndAtomics ) + && ( fragmentStoresAndAtomics == rhs.fragmentStoresAndAtomics ) + && ( shaderTessellationAndGeometryPointSize == rhs.shaderTessellationAndGeometryPointSize ) + && ( shaderImageGatherExtended == rhs.shaderImageGatherExtended ) + && ( shaderStorageImageExtendedFormats == rhs.shaderStorageImageExtendedFormats ) + && ( shaderStorageImageMultisample == rhs.shaderStorageImageMultisample ) + && ( shaderStorageImageReadWithoutFormat == rhs.shaderStorageImageReadWithoutFormat ) + && ( shaderStorageImageWriteWithoutFormat == rhs.shaderStorageImageWriteWithoutFormat ) + && ( shaderUniformBufferArrayDynamicIndexing == rhs.shaderUniformBufferArrayDynamicIndexing ) + && ( shaderSampledImageArrayDynamicIndexing == rhs.shaderSampledImageArrayDynamicIndexing ) + && ( shaderStorageBufferArrayDynamicIndexing == rhs.shaderStorageBufferArrayDynamicIndexing ) + && ( shaderStorageImageArrayDynamicIndexing == rhs.shaderStorageImageArrayDynamicIndexing ) + && ( shaderClipDistance == rhs.shaderClipDistance ) + && ( shaderCullDistance == rhs.shaderCullDistance ) + && ( shaderFloat64 == rhs.shaderFloat64 ) + && ( shaderInt64 == rhs.shaderInt64 ) + && ( shaderInt16 == rhs.shaderInt16 ) + && ( shaderResourceResidency == rhs.shaderResourceResidency ) + && ( shaderResourceMinLod == rhs.shaderResourceMinLod ) + && ( sparseBinding == rhs.sparseBinding ) + && ( sparseResidencyBuffer == rhs.sparseResidencyBuffer ) + && ( sparseResidencyImage2D == rhs.sparseResidencyImage2D ) + && ( sparseResidencyImage3D == rhs.sparseResidencyImage3D ) + && ( sparseResidency2Samples == rhs.sparseResidency2Samples ) + && ( sparseResidency4Samples == rhs.sparseResidency4Samples ) + && ( sparseResidency8Samples == rhs.sparseResidency8Samples ) + && ( sparseResidency16Samples == rhs.sparseResidency16Samples ) + && ( sparseResidencyAliased == rhs.sparseResidencyAliased ) + && ( variableMultisampleRate == rhs.variableMultisampleRate ) + && ( inheritedQueries == rhs.inheritedQueries ); + } + + bool operator!=( PhysicalDeviceFeatures const& rhs ) const + { + return !operator==( rhs ); + } + Bool32 robustBufferAccess; Bool32 fullDrawIndexUint32; Bool32 imageCubeArray; @@ -3251,6 +3524,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PhysicalDeviceSparseProperties const& rhs ) const + { + return ( residencyStandard2DBlockShape == rhs.residencyStandard2DBlockShape ) + && ( residencyStandard2DMultisampleBlockShape == rhs.residencyStandard2DMultisampleBlockShape ) + && ( residencyStandard3DBlockShape == rhs.residencyStandard3DBlockShape ) + && ( residencyAlignedMipSize == rhs.residencyAlignedMipSize ) + && ( residencyNonResidentStrict == rhs.residencyNonResidentStrict ); + } + + bool operator!=( PhysicalDeviceSparseProperties const& rhs ) const + { + return !operator==( rhs ); + } + Bool32 residencyStandard2DBlockShape; Bool32 residencyStandard2DMultisampleBlockShape; Bool32 residencyStandard3DBlockShape; @@ -3309,6 +3596,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DrawIndirectCommand const& rhs ) const + { + return ( vertexCount == rhs.vertexCount ) + && ( instanceCount == rhs.instanceCount ) + && ( firstVertex == rhs.firstVertex ) + && ( firstInstance == rhs.firstInstance ); + } + + bool operator!=( DrawIndirectCommand const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t vertexCount; uint32_t instanceCount; uint32_t firstVertex; @@ -3373,6 +3673,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DrawIndexedIndirectCommand const& rhs ) const + { + return ( indexCount == rhs.indexCount ) + && ( instanceCount == rhs.instanceCount ) + && ( firstIndex == rhs.firstIndex ) + && ( vertexOffset == rhs.vertexOffset ) + && ( firstInstance == rhs.firstInstance ); + } + + bool operator!=( DrawIndexedIndirectCommand const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t indexCount; uint32_t instanceCount; uint32_t firstIndex; @@ -3424,6 +3738,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DispatchIndirectCommand const& rhs ) const + { + return ( x == rhs.x ) + && ( y == rhs.y ) + && ( z == rhs.z ); + } + + bool operator!=( DispatchIndirectCommand const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t x; uint32_t y; uint32_t z; @@ -3466,6 +3792,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayPlanePropertiesKHR const& rhs ) const + { + return ( currentDisplay == rhs.currentDisplay ) + && ( currentStackIndex == rhs.currentStackIndex ); + } + + bool operator!=( DisplayPlanePropertiesKHR const& rhs ) const + { + return !operator==( rhs ); + } + DisplayKHR currentDisplay; uint32_t currentStackIndex; }; @@ -3507,6 +3844,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayModeParametersKHR const& rhs ) const + { + return ( visibleRegion == rhs.visibleRegion ) + && ( refreshRate == rhs.refreshRate ); + } + + bool operator!=( DisplayModeParametersKHR const& rhs ) const + { + return !operator==( rhs ); + } + Extent2D visibleRegion; uint32_t refreshRate; }; @@ -3548,6 +3896,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayModePropertiesKHR const& rhs ) const + { + return ( displayMode == rhs.displayMode ) + && ( parameters == rhs.parameters ); + } + + bool operator!=( DisplayModePropertiesKHR const& rhs ) const + { + return !operator==( rhs ); + } + DisplayModeKHR displayMode; DisplayModeParametersKHR parameters; }; @@ -3610,6 +3969,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorImageInfo const& rhs ) const + { + return ( sampler == rhs.sampler ) + && ( imageView == rhs.imageView ) + && ( imageLayout == rhs.imageLayout ); + } + + bool operator!=( DescriptorImageInfo const& rhs ) const + { + return !operator==( rhs ); + } + Sampler sampler; ImageView imageView; ImageLayout imageLayout; @@ -3652,6 +4023,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( AttachmentReference const& rhs ) const + { + return ( attachment == rhs.attachment ) + && ( layout == rhs.layout ); + } + + bool operator!=( AttachmentReference const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t attachment; ImageLayout layout; }; @@ -3761,6 +4143,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ComponentMapping const& rhs ) const + { + return ( r == rhs.r ) + && ( g == rhs.g ) + && ( b == rhs.b ) + && ( a == rhs.a ); + } + + bool operator!=( ComponentMapping const& rhs ) const + { + return !operator==( rhs ); + } + ComponentSwizzle r; ComponentSwizzle g; ComponentSwizzle b; @@ -3819,6 +4214,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorPoolSize const& rhs ) const + { + return ( type == rhs.type ) + && ( descriptorCount == rhs.descriptorCount ); + } + + bool operator!=( DescriptorPoolSize const& rhs ) const + { + return !operator==( rhs ); + } + DescriptorType type; uint32_t descriptorCount; }; @@ -3939,6 +4345,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SubpassDescription const& rhs ) const + { + return ( flags == rhs.flags ) + && ( pipelineBindPoint == rhs.pipelineBindPoint ) + && ( inputAttachmentCount == rhs.inputAttachmentCount ) + && ( pInputAttachments == rhs.pInputAttachments ) + && ( colorAttachmentCount == rhs.colorAttachmentCount ) + && ( pColorAttachments == rhs.pColorAttachments ) + && ( pResolveAttachments == rhs.pResolveAttachments ) + && ( pDepthStencilAttachment == rhs.pDepthStencilAttachment ) + && ( preserveAttachmentCount == rhs.preserveAttachmentCount ) + && ( pPreserveAttachments == rhs.pPreserveAttachments ); + } + + bool operator!=( SubpassDescription const& rhs ) const + { + return !operator==( rhs ); + } + SubpassDescriptionFlags flags; PipelineBindPoint pipelineBindPoint; uint32_t inputAttachmentCount; @@ -4161,6 +4586,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( StencilOpState const& rhs ) const + { + return ( failOp == rhs.failOp ) + && ( passOp == rhs.passOp ) + && ( depthFailOp == rhs.depthFailOp ) + && ( compareOp == rhs.compareOp ) + && ( compareMask == rhs.compareMask ) + && ( writeMask == rhs.writeMask ) + && ( reference == rhs.reference ); + } + + bool operator!=( StencilOpState const& rhs ) const + { + return !operator==( rhs ); + } + StencilOp failOp; StencilOp passOp; StencilOp depthFailOp; @@ -4263,6 +4704,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( VertexInputBindingDescription const& rhs ) const + { + return ( binding == rhs.binding ) + && ( stride == rhs.stride ) + && ( inputRate == rhs.inputRate ); + } + + bool operator!=( VertexInputBindingDescription const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t binding; uint32_t stride; VertexInputRate inputRate; @@ -4508,6 +4961,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( VertexInputAttributeDescription const& rhs ) const + { + return ( location == rhs.location ) + && ( binding == rhs.binding ) + && ( format == rhs.format ) + && ( offset == rhs.offset ); + } + + bool operator!=( VertexInputAttributeDescription const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t location; uint32_t binding; Format format; @@ -4655,6 +5121,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ApplicationInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( pApplicationName == rhs.pApplicationName ) + && ( applicationVersion == rhs.applicationVersion ) + && ( pEngineName == rhs.pEngineName ) + && ( engineVersion == rhs.engineVersion ) + && ( apiVersion == rhs.apiVersion ); + } + + bool operator!=( ApplicationInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -4732,6 +5214,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DeviceQueueCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( queueFamilyIndex == rhs.queueFamilyIndex ) + && ( queueCount == rhs.queueCount ) + && ( pQueuePriorities == rhs.pQueuePriorities ); + } + + bool operator!=( DeviceQueueCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -4836,6 +5333,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DeviceCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( queueCreateInfoCount == rhs.queueCreateInfoCount ) + && ( pQueueCreateInfos == rhs.pQueueCreateInfos ) + && ( enabledLayerCount == rhs.enabledLayerCount ) + && ( ppEnabledLayerNames == rhs.ppEnabledLayerNames ) + && ( enabledExtensionCount == rhs.enabledExtensionCount ) + && ( ppEnabledExtensionNames == rhs.ppEnabledExtensionNames ) + && ( pEnabledFeatures == rhs.pEnabledFeatures ); + } + + bool operator!=( DeviceCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -4930,6 +5446,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( InstanceCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( pApplicationInfo == rhs.pApplicationInfo ) + && ( enabledLayerCount == rhs.enabledLayerCount ) + && ( ppEnabledLayerNames == rhs.ppEnabledLayerNames ) + && ( enabledExtensionCount == rhs.enabledExtensionCount ) + && ( ppEnabledExtensionNames == rhs.ppEnabledExtensionNames ); + } + + bool operator!=( InstanceCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -4994,6 +5527,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MemoryAllocateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( allocationSize == rhs.allocationSize ) + && ( memoryTypeIndex == rhs.memoryTypeIndex ); + } + + bool operator!=( MemoryAllocateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5061,6 +5607,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MappedMemoryRange const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( memory == rhs.memory ) + && ( offset == rhs.offset ) + && ( size == rhs.size ); + } + + bool operator!=( MappedMemoryRange const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5164,6 +5724,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( WriteDescriptorSet const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( dstSet == rhs.dstSet ) + && ( dstBinding == rhs.dstBinding ) + && ( dstArrayElement == rhs.dstArrayElement ) + && ( descriptorCount == rhs.descriptorCount ) + && ( descriptorType == rhs.descriptorType ) + && ( pImageInfo == rhs.pImageInfo ) + && ( pBufferInfo == rhs.pBufferInfo ) + && ( pTexelBufferView == rhs.pTexelBufferView ); + } + + bool operator!=( WriteDescriptorSet const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5265,6 +5844,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( CopyDescriptorSet const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( srcSet == rhs.srcSet ) + && ( srcBinding == rhs.srcBinding ) + && ( srcArrayElement == rhs.srcArrayElement ) + && ( dstSet == rhs.dstSet ) + && ( dstBinding == rhs.dstBinding ) + && ( dstArrayElement == rhs.dstArrayElement ) + && ( descriptorCount == rhs.descriptorCount ); + } + + bool operator!=( CopyDescriptorSet const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5351,6 +5948,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BufferViewCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( buffer == rhs.buffer ) + && ( format == rhs.format ) + && ( offset == rhs.offset ) + && ( range == rhs.range ); + } + + bool operator!=( BufferViewCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5421,6 +6034,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ShaderModuleCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( codeSize == rhs.codeSize ) + && ( pCode == rhs.pCode ); + } + + bool operator!=( ShaderModuleCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5489,6 +6116,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorSetAllocateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( descriptorPool == rhs.descriptorPool ) + && ( descriptorSetCount == rhs.descriptorSetCount ) + && ( pSetLayouts == rhs.pSetLayouts ); + } + + bool operator!=( DescriptorSetAllocateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5571,6 +6212,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineVertexInputStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( vertexBindingDescriptionCount == rhs.vertexBindingDescriptionCount ) + && ( pVertexBindingDescriptions == rhs.pVertexBindingDescriptions ) + && ( vertexAttributeDescriptionCount == rhs.vertexAttributeDescriptionCount ) + && ( pVertexAttributeDescriptions == rhs.pVertexAttributeDescriptions ); + } + + bool operator!=( PipelineVertexInputStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5641,6 +6298,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineInputAssemblyStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( topology == rhs.topology ) + && ( primitiveRestartEnable == rhs.primitiveRestartEnable ); + } + + bool operator!=( PipelineInputAssemblyStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5702,6 +6373,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineTessellationStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( patchControlPoints == rhs.patchControlPoints ); + } + + bool operator!=( PipelineTessellationStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5783,6 +6467,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineViewportStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( viewportCount == rhs.viewportCount ) + && ( pViewports == rhs.pViewports ) + && ( scissorCount == rhs.scissorCount ) + && ( pScissors == rhs.pScissors ); + } + + bool operator!=( PipelineViewportStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -5909,6 +6609,28 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineRasterizationStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( depthClampEnable == rhs.depthClampEnable ) + && ( rasterizerDiscardEnable == rhs.rasterizerDiscardEnable ) + && ( polygonMode == rhs.polygonMode ) + && ( cullMode == rhs.cullMode ) + && ( frontFace == rhs.frontFace ) + && ( depthBiasEnable == rhs.depthBiasEnable ) + && ( depthBiasConstantFactor == rhs.depthBiasConstantFactor ) + && ( depthBiasClamp == rhs.depthBiasClamp ) + && ( depthBiasSlopeFactor == rhs.depthBiasSlopeFactor ) + && ( lineWidth == rhs.lineWidth ); + } + + bool operator!=( PipelineRasterizationStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6034,6 +6756,27 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineDepthStencilStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( depthTestEnable == rhs.depthTestEnable ) + && ( depthWriteEnable == rhs.depthWriteEnable ) + && ( depthCompareOp == rhs.depthCompareOp ) + && ( depthBoundsTestEnable == rhs.depthBoundsTestEnable ) + && ( stencilTestEnable == rhs.stencilTestEnable ) + && ( front == rhs.front ) + && ( back == rhs.back ) + && ( minDepthBounds == rhs.minDepthBounds ) + && ( maxDepthBounds == rhs.maxDepthBounds ); + } + + bool operator!=( PipelineDepthStencilStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6109,6 +6852,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineCacheCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( initialDataSize == rhs.initialDataSize ) + && ( pInitialData == rhs.pInitialData ); + } + + bool operator!=( PipelineCacheCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6268,6 +7025,33 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SamplerCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( magFilter == rhs.magFilter ) + && ( minFilter == rhs.minFilter ) + && ( mipmapMode == rhs.mipmapMode ) + && ( addressModeU == rhs.addressModeU ) + && ( addressModeV == rhs.addressModeV ) + && ( addressModeW == rhs.addressModeW ) + && ( mipLodBias == rhs.mipLodBias ) + && ( anisotropyEnable == rhs.anisotropyEnable ) + && ( maxAnisotropy == rhs.maxAnisotropy ) + && ( compareEnable == rhs.compareEnable ) + && ( compareOp == rhs.compareOp ) + && ( minLod == rhs.minLod ) + && ( maxLod == rhs.maxLod ) + && ( borderColor == rhs.borderColor ) + && ( unnormalizedCoordinates == rhs.unnormalizedCoordinates ); + } + + bool operator!=( SamplerCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6349,6 +7133,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( CommandBufferAllocateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( commandPool == rhs.commandPool ) + && ( level == rhs.level ) + && ( commandBufferCount == rhs.commandBufferCount ); + } + + bool operator!=( CommandBufferAllocateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6431,6 +7229,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( RenderPassBeginInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( renderPass == rhs.renderPass ) + && ( framebuffer == rhs.framebuffer ) + && ( renderArea == rhs.renderArea ) + && ( clearValueCount == rhs.clearValueCount ) + && ( pClearValues == rhs.pClearValues ); + } + + bool operator!=( RenderPassBeginInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6487,6 +7301,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( EventCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ); + } + + bool operator!=( EventCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6539,6 +7365,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SemaphoreCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ); + } + + bool operator!=( SemaphoreCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6633,6 +7471,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( FramebufferCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( renderPass == rhs.renderPass ) + && ( attachmentCount == rhs.attachmentCount ) + && ( pAttachments == rhs.pAttachments ) + && ( width == rhs.width ) + && ( height == rhs.height ) + && ( layers == rhs.layers ); + } + + bool operator!=( FramebufferCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6698,6 +7554,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayModeCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( parameters == rhs.parameters ); + } + + bool operator!=( DisplayModeCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6765,6 +7634,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayPresentInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( srcRect == rhs.srcRect ) + && ( dstRect == rhs.dstRect ) + && ( persistent == rhs.persistent ); + } + + bool operator!=( DisplayPresentInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6827,6 +7710,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( AndroidSurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( window == rhs.window ); + } + + bool operator!=( AndroidSurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6896,6 +7792,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MirSurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( connection == rhs.connection ) + && ( mirSurface == rhs.mirSurface ); + } + + bool operator!=( MirSurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -6966,6 +7876,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( WaylandSurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( display == rhs.display ) + && ( surface == rhs.surface ); + } + + bool operator!=( WaylandSurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7036,6 +7960,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( Win32SurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( hinstance == rhs.hinstance ) + && ( hwnd == rhs.hwnd ); + } + + bool operator!=( Win32SurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7106,6 +8044,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( XlibSurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( dpy == rhs.dpy ) + && ( window == rhs.window ); + } + + bool operator!=( XlibSurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7176,6 +8128,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( XcbSurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( connection == rhs.connection ) + && ( window == rhs.window ); + } + + bool operator!=( XcbSurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7238,6 +8204,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DebugMarkerMarkerInfoEXT const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( pMarkerName == rhs.pMarkerName ) + && ( memcmp( color, rhs.color, 4 * sizeof( float ) ) == 0 ); + } + + bool operator!=( DebugMarkerMarkerInfoEXT const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7332,6 +8311,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PresentInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( waitSemaphoreCount == rhs.waitSemaphoreCount ) + && ( pWaitSemaphores == rhs.pWaitSemaphores ) + && ( swapchainCount == rhs.swapchainCount ) + && ( pSwapchains == rhs.pSwapchains ) + && ( pImageIndices == rhs.pImageIndices ) + && ( pResults == rhs.pResults ); + } + + bool operator!=( PresentInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7416,6 +8412,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineDynamicStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( dynamicStateCount == rhs.dynamicStateCount ) + && ( pDynamicStates == rhs.pDynamicStates ); + } + + bool operator!=( PipelineDynamicStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7449,6 +8459,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( QueueFamilyProperties const& rhs ) const + { + return ( queueFlags == rhs.queueFlags ) + && ( queueCount == rhs.queueCount ) + && ( timestampValidBits == rhs.timestampValidBits ) + && ( minImageTransferGranularity == rhs.minImageTransferGranularity ); + } + + bool operator!=( QueueFamilyProperties const& rhs ) const + { + return !operator==( rhs ); + } + QueueFlags queueFlags; uint32_t queueCount; uint32_t timestampValidBits; @@ -7479,6 +8502,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MemoryType const& rhs ) const + { + return ( propertyFlags == rhs.propertyFlags ) + && ( heapIndex == rhs.heapIndex ); + } + + bool operator!=( MemoryType const& rhs ) const + { + return !operator==( rhs ); + } + MemoryPropertyFlags propertyFlags; uint32_t heapIndex; }; @@ -7503,6 +8537,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MemoryHeap const& rhs ) const + { + return ( size == rhs.size ) + && ( flags == rhs.flags ); + } + + bool operator!=( MemoryHeap const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize size; MemoryHeapFlags flags; }; @@ -7515,6 +8560,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PhysicalDeviceMemoryProperties const& rhs ) const + { + return ( memoryTypeCount == rhs.memoryTypeCount ) + && ( memcmp( memoryTypes, rhs.memoryTypes, VK_MAX_MEMORY_TYPES * sizeof( MemoryType ) ) == 0 ) + && ( memoryHeapCount == rhs.memoryHeapCount ) + && ( memcmp( memoryHeaps, rhs.memoryHeaps, VK_MAX_MEMORY_HEAPS * sizeof( MemoryHeap ) ) == 0 ); + } + + bool operator!=( PhysicalDeviceMemoryProperties const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t memoryTypeCount; MemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; uint32_t memoryHeapCount; @@ -7600,6 +8658,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( MemoryBarrier const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( srcAccessMask == rhs.srcAccessMask ) + && ( dstAccessMask == rhs.dstAccessMask ); + } + + bool operator!=( MemoryBarrier const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7695,6 +8766,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BufferMemoryBarrier const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( srcAccessMask == rhs.srcAccessMask ) + && ( dstAccessMask == rhs.dstAccessMask ) + && ( srcQueueFamilyIndex == rhs.srcQueueFamilyIndex ) + && ( dstQueueFamilyIndex == rhs.dstQueueFamilyIndex ) + && ( buffer == rhs.buffer ) + && ( offset == rhs.offset ) + && ( size == rhs.size ); + } + + bool operator!=( BufferMemoryBarrier const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7822,6 +8911,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BufferCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( size == rhs.size ) + && ( usage == rhs.usage ) + && ( sharingMode == rhs.sharingMode ) + && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount ) + && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices ); + } + + bool operator!=( BufferCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -7912,6 +9018,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorSetLayoutBinding const& rhs ) const + { + return ( binding == rhs.binding ) + && ( descriptorType == rhs.descriptorType ) + && ( descriptorCount == rhs.descriptorCount ) + && ( stageFlags == rhs.stageFlags ) + && ( pImmutableSamplers == rhs.pImmutableSamplers ); + } + + bool operator!=( DescriptorSetLayoutBinding const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t binding; DescriptorType descriptorType; uint32_t descriptorCount; @@ -7977,6 +9097,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorSetLayoutCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( bindingCount == rhs.bindingCount ) + && ( pBindings == rhs.pBindings ); + } + + bool operator!=( DescriptorSetLayoutCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8059,6 +9193,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineShaderStageCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( stage == rhs.stage ) + && ( module == rhs.module ) + && ( pName == rhs.pName ) + && ( pSpecializationInfo == rhs.pSpecializationInfo ); + } + + bool operator!=( PipelineShaderStageCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8115,6 +9265,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PushConstantRange const& rhs ) const + { + return ( stageFlags == rhs.stageFlags ) + && ( offset == rhs.offset ) + && ( size == rhs.size ); + } + + bool operator!=( PushConstantRange const& rhs ) const + { + return !operator==( rhs ); + } + ShaderStageFlags stageFlags; uint32_t offset; uint32_t size; @@ -8192,6 +9354,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineLayoutCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( setLayoutCount == rhs.setLayoutCount ) + && ( pSetLayouts == rhs.pSetLayouts ) + && ( pushConstantRangeCount == rhs.pushConstantRangeCount ) + && ( pPushConstantRanges == rhs.pPushConstantRanges ); + } + + bool operator!=( PipelineLayoutCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8325,6 +9503,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ComputePipelineCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( stage == rhs.stage ) + && ( layout == rhs.layout ) + && ( basePipelineHandle == rhs.basePipelineHandle ) + && ( basePipelineIndex == rhs.basePipelineIndex ); + } + + bool operator!=( ComputePipelineCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8431,6 +9625,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineColorBlendAttachmentState const& rhs ) const + { + return ( blendEnable == rhs.blendEnable ) + && ( srcColorBlendFactor == rhs.srcColorBlendFactor ) + && ( dstColorBlendFactor == rhs.dstColorBlendFactor ) + && ( colorBlendOp == rhs.colorBlendOp ) + && ( srcAlphaBlendFactor == rhs.srcAlphaBlendFactor ) + && ( dstAlphaBlendFactor == rhs.dstAlphaBlendFactor ) + && ( alphaBlendOp == rhs.alphaBlendOp ) + && ( colorWriteMask == rhs.colorWriteMask ); + } + + bool operator!=( PipelineColorBlendAttachmentState const& rhs ) const + { + return !operator==( rhs ); + } + Bool32 blendEnable; BlendFactor srcColorBlendFactor; BlendFactor dstColorBlendFactor; @@ -8520,6 +9731,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineColorBlendStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( logicOpEnable == rhs.logicOpEnable ) + && ( logicOp == rhs.logicOp ) + && ( attachmentCount == rhs.attachmentCount ) + && ( pAttachments == rhs.pAttachments ) + && ( memcmp( blendConstants, rhs.blendConstants, 4 * sizeof( float ) ) == 0 ); + } + + bool operator!=( PipelineColorBlendStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8589,6 +9817,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( FenceCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ); + } + + bool operator!=( FenceCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8630,6 +9870,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( FormatProperties const& rhs ) const + { + return ( linearTilingFeatures == rhs.linearTilingFeatures ) + && ( optimalTilingFeatures == rhs.optimalTilingFeatures ) + && ( bufferFeatures == rhs.bufferFeatures ); + } + + bool operator!=( FormatProperties const& rhs ) const + { + return !operator==( rhs ); + } + FormatFeatureFlags linearTilingFeatures; FormatFeatureFlags optimalTilingFeatures; FormatFeatureFlags bufferFeatures; @@ -8777,6 +10029,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( CommandBufferInheritanceInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( renderPass == rhs.renderPass ) + && ( subpass == rhs.subpass ) + && ( framebuffer == rhs.framebuffer ) + && ( occlusionQueryEnable == rhs.occlusionQueryEnable ) + && ( queryFlags == rhs.queryFlags ) + && ( pipelineStatistics == rhs.pipelineStatistics ); + } + + bool operator!=( CommandBufferInheritanceInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8841,6 +10110,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( CommandBufferBeginInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( pInheritanceInfo == rhs.pInheritanceInfo ); + } + + bool operator!=( CommandBufferBeginInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8915,6 +10197,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( QueryPoolCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( queryType == rhs.queryType ) + && ( queryCount == rhs.queryCount ) + && ( pipelineStatistics == rhs.pipelineStatistics ); + } + + bool operator!=( QueryPoolCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -8985,6 +10282,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageSubresource const& rhs ) const + { + return ( aspectMask == rhs.aspectMask ) + && ( mipLevel == rhs.mipLevel ) + && ( arrayLayer == rhs.arrayLayer ); + } + + bool operator!=( ImageSubresource const& rhs ) const + { + return !operator==( rhs ); + } + ImageAspectFlags aspectMask; uint32_t mipLevel; uint32_t arrayLayer; @@ -9041,6 +10350,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageSubresourceLayers const& rhs ) const + { + return ( aspectMask == rhs.aspectMask ) + && ( mipLevel == rhs.mipLevel ) + && ( baseArrayLayer == rhs.baseArrayLayer ) + && ( layerCount == rhs.layerCount ); + } + + bool operator!=( ImageSubresourceLayers const& rhs ) const + { + return !operator==( rhs ); + } + ImageAspectFlags aspectMask; uint32_t mipLevel; uint32_t baseArrayLayer; @@ -9105,6 +10427,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageSubresourceRange const& rhs ) const + { + return ( aspectMask == rhs.aspectMask ) + && ( baseMipLevel == rhs.baseMipLevel ) + && ( levelCount == rhs.levelCount ) + && ( baseArrayLayer == rhs.baseArrayLayer ) + && ( layerCount == rhs.layerCount ); + } + + bool operator!=( ImageSubresourceRange const& rhs ) const + { + return !operator==( rhs ); + } + ImageAspectFlags aspectMask; uint32_t baseMipLevel; uint32_t levelCount; @@ -9205,6 +10541,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageMemoryBarrier const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( srcAccessMask == rhs.srcAccessMask ) + && ( dstAccessMask == rhs.dstAccessMask ) + && ( oldLayout == rhs.oldLayout ) + && ( newLayout == rhs.newLayout ) + && ( srcQueueFamilyIndex == rhs.srcQueueFamilyIndex ) + && ( dstQueueFamilyIndex == rhs.dstQueueFamilyIndex ) + && ( image == rhs.image ) + && ( subresourceRange == rhs.subresourceRange ); + } + + bool operator!=( ImageMemoryBarrier const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -9299,6 +10654,23 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageViewCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( image == rhs.image ) + && ( viewType == rhs.viewType ) + && ( format == rhs.format ) + && ( components == rhs.components ) + && ( subresourceRange == rhs.subresourceRange ); + } + + bool operator!=( ImageViewCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -9370,6 +10742,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageCopy const& rhs ) const + { + return ( srcSubresource == rhs.srcSubresource ) + && ( srcOffset == rhs.srcOffset ) + && ( dstSubresource == rhs.dstSubresource ) + && ( dstOffset == rhs.dstOffset ) + && ( extent == rhs.extent ); + } + + bool operator!=( ImageCopy const& rhs ) const + { + return !operator==( rhs ); + } + ImageSubresourceLayers srcSubresource; Offset3D srcOffset; ImageSubresourceLayers dstSubresource; @@ -9428,6 +10814,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageBlit const& rhs ) const + { + return ( srcSubresource == rhs.srcSubresource ) + && ( memcmp( srcOffsets, rhs.srcOffsets, 2 * sizeof( Offset3D ) ) == 0 ) + && ( dstSubresource == rhs.dstSubresource ) + && ( memcmp( dstOffsets, rhs.dstOffsets, 2 * sizeof( Offset3D ) ) == 0 ); + } + + bool operator!=( ImageBlit const& rhs ) const + { + return !operator==( rhs ); + } + ImageSubresourceLayers srcSubresource; Offset3D srcOffsets[2]; ImageSubresourceLayers dstSubresource; @@ -9499,6 +10898,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BufferImageCopy const& rhs ) const + { + return ( bufferOffset == rhs.bufferOffset ) + && ( bufferRowLength == rhs.bufferRowLength ) + && ( bufferImageHeight == rhs.bufferImageHeight ) + && ( imageSubresource == rhs.imageSubresource ) + && ( imageOffset == rhs.imageOffset ) + && ( imageExtent == rhs.imageExtent ); + } + + bool operator!=( BufferImageCopy const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize bufferOffset; uint32_t bufferRowLength; uint32_t bufferImageHeight; @@ -9565,6 +10979,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageResolve const& rhs ) const + { + return ( srcSubresource == rhs.srcSubresource ) + && ( srcOffset == rhs.srcOffset ) + && ( dstSubresource == rhs.dstSubresource ) + && ( dstOffset == rhs.dstOffset ) + && ( extent == rhs.extent ); + } + + bool operator!=( ImageResolve const& rhs ) const + { + return !operator==( rhs ); + } + ImageSubresourceLayers srcSubresource; Offset3D srcOffset; ImageSubresourceLayers dstSubresource; @@ -9643,6 +11071,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseImageFormatProperties const& rhs ) const + { + return ( aspectMask == rhs.aspectMask ) + && ( imageGranularity == rhs.imageGranularity ) + && ( flags == rhs.flags ); + } + + bool operator!=( SparseImageFormatProperties const& rhs ) const + { + return !operator==( rhs ); + } + ImageAspectFlags aspectMask; Extent3D imageGranularity; SparseImageFormatFlags flags; @@ -9656,6 +11096,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseImageMemoryRequirements const& rhs ) const + { + return ( formatProperties == rhs.formatProperties ) + && ( imageMipTailFirstLod == rhs.imageMipTailFirstLod ) + && ( imageMipTailSize == rhs.imageMipTailSize ) + && ( imageMipTailOffset == rhs.imageMipTailOffset ) + && ( imageMipTailStride == rhs.imageMipTailStride ); + } + + bool operator!=( SparseImageMemoryRequirements const& rhs ) const + { + return !operator==( rhs ); + } + SparseImageFormatProperties formatProperties; uint32_t imageMipTailFirstLod; DeviceSize imageMipTailSize; @@ -9733,6 +11187,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseMemoryBind const& rhs ) const + { + return ( resourceOffset == rhs.resourceOffset ) + && ( size == rhs.size ) + && ( memory == rhs.memory ) + && ( memoryOffset == rhs.memoryOffset ) + && ( flags == rhs.flags ); + } + + bool operator!=( SparseMemoryBind const& rhs ) const + { + return !operator==( rhs ); + } + DeviceSize resourceOffset; DeviceSize size; DeviceMemory memory; @@ -9805,6 +11273,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseImageMemoryBind const& rhs ) const + { + return ( subresource == rhs.subresource ) + && ( offset == rhs.offset ) + && ( extent == rhs.extent ) + && ( memory == rhs.memory ) + && ( memoryOffset == rhs.memoryOffset ) + && ( flags == rhs.flags ); + } + + bool operator!=( SparseImageMemoryBind const& rhs ) const + { + return !operator==( rhs ); + } + ImageSubresource subresource; Offset3D offset; Extent3D extent; @@ -9857,6 +11340,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseBufferMemoryBindInfo const& rhs ) const + { + return ( buffer == rhs.buffer ) + && ( bindCount == rhs.bindCount ) + && ( pBinds == rhs.pBinds ); + } + + bool operator!=( SparseBufferMemoryBindInfo const& rhs ) const + { + return !operator==( rhs ); + } + Buffer buffer; uint32_t bindCount; const SparseMemoryBind* pBinds; @@ -9906,6 +11401,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseImageOpaqueMemoryBindInfo const& rhs ) const + { + return ( image == rhs.image ) + && ( bindCount == rhs.bindCount ) + && ( pBinds == rhs.pBinds ); + } + + bool operator!=( SparseImageOpaqueMemoryBindInfo const& rhs ) const + { + return !operator==( rhs ); + } + Image image; uint32_t bindCount; const SparseMemoryBind* pBinds; @@ -9955,6 +11462,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SparseImageMemoryBindInfo const& rhs ) const + { + return ( image == rhs.image ) + && ( bindCount == rhs.bindCount ) + && ( pBinds == rhs.pBinds ); + } + + bool operator!=( SparseImageMemoryBindInfo const& rhs ) const + { + return !operator==( rhs ); + } + Image image; uint32_t bindCount; const SparseImageMemoryBind* pBinds; @@ -10067,6 +11586,27 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( BindSparseInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( waitSemaphoreCount == rhs.waitSemaphoreCount ) + && ( pWaitSemaphores == rhs.pWaitSemaphores ) + && ( bufferBindCount == rhs.bufferBindCount ) + && ( pBufferBinds == rhs.pBufferBinds ) + && ( imageOpaqueBindCount == rhs.imageOpaqueBindCount ) + && ( pImageOpaqueBinds == rhs.pImageOpaqueBinds ) + && ( imageBindCount == rhs.imageBindCount ) + && ( pImageBinds == rhs.pImageBinds ) + && ( signalSemaphoreCount == rhs.signalSemaphoreCount ) + && ( pSignalSemaphores == rhs.pSignalSemaphores ); + } + + bool operator!=( BindSparseInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -10176,6 +11716,19 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( CommandPoolCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( queueFamilyIndex == rhs.queueFamilyIndex ); + } + + bool operator!=( CommandPoolCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -10235,6 +11788,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageFormatProperties const& rhs ) const + { + return ( maxExtent == rhs.maxExtent ) + && ( maxMipLevels == rhs.maxMipLevels ) + && ( maxArrayLayers == rhs.maxArrayLayers ) + && ( sampleCounts == rhs.sampleCounts ) + && ( maxResourceSize == rhs.maxResourceSize ); + } + + bool operator!=( ImageFormatProperties const& rhs ) const + { + return !operator==( rhs ); + } + Extent3D maxExtent; uint32_t maxMipLevels; uint32_t maxArrayLayers; @@ -10370,6 +11937,30 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( ImageCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( imageType == rhs.imageType ) + && ( format == rhs.format ) + && ( extent == rhs.extent ) + && ( mipLevels == rhs.mipLevels ) + && ( arrayLayers == rhs.arrayLayers ) + && ( samples == rhs.samples ) + && ( tiling == rhs.tiling ) + && ( usage == rhs.usage ) + && ( sharingMode == rhs.sharingMode ) + && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount ) + && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices ) + && ( initialLayout == rhs.initialLayout ); + } + + bool operator!=( ImageCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -10476,6 +12067,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineMultisampleStateCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( rasterizationSamples == rhs.rasterizationSamples ) + && ( sampleShadingEnable == rhs.sampleShadingEnable ) + && ( minSampleShading == rhs.minSampleShading ) + && ( pSampleMask == rhs.pSampleMask ) + && ( alphaToCoverageEnable == rhs.alphaToCoverageEnable ) + && ( alphaToOneEnable == rhs.alphaToOneEnable ); + } + + bool operator!=( PipelineMultisampleStateCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -10646,6 +12255,34 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( GraphicsPipelineCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( stageCount == rhs.stageCount ) + && ( pStages == rhs.pStages ) + && ( pVertexInputState == rhs.pVertexInputState ) + && ( pInputAssemblyState == rhs.pInputAssemblyState ) + && ( pTessellationState == rhs.pTessellationState ) + && ( pViewportState == rhs.pViewportState ) + && ( pRasterizationState == rhs.pRasterizationState ) + && ( pMultisampleState == rhs.pMultisampleState ) + && ( pDepthStencilState == rhs.pDepthStencilState ) + && ( pColorBlendState == rhs.pColorBlendState ) + && ( pDynamicState == rhs.pDynamicState ) + && ( layout == rhs.layout ) + && ( renderPass == rhs.renderPass ) + && ( subpass == rhs.subpass ) + && ( basePipelineHandle == rhs.basePipelineHandle ) + && ( basePipelineIndex == rhs.basePipelineIndex ); + } + + bool operator!=( GraphicsPipelineCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -10678,6 +12315,121 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PhysicalDeviceLimits const& rhs ) const + { + return ( maxImageDimension1D == rhs.maxImageDimension1D ) + && ( maxImageDimension2D == rhs.maxImageDimension2D ) + && ( maxImageDimension3D == rhs.maxImageDimension3D ) + && ( maxImageDimensionCube == rhs.maxImageDimensionCube ) + && ( maxImageArrayLayers == rhs.maxImageArrayLayers ) + && ( maxTexelBufferElements == rhs.maxTexelBufferElements ) + && ( maxUniformBufferRange == rhs.maxUniformBufferRange ) + && ( maxStorageBufferRange == rhs.maxStorageBufferRange ) + && ( maxPushConstantsSize == rhs.maxPushConstantsSize ) + && ( maxMemoryAllocationCount == rhs.maxMemoryAllocationCount ) + && ( maxSamplerAllocationCount == rhs.maxSamplerAllocationCount ) + && ( bufferImageGranularity == rhs.bufferImageGranularity ) + && ( sparseAddressSpaceSize == rhs.sparseAddressSpaceSize ) + && ( maxBoundDescriptorSets == rhs.maxBoundDescriptorSets ) + && ( maxPerStageDescriptorSamplers == rhs.maxPerStageDescriptorSamplers ) + && ( maxPerStageDescriptorUniformBuffers == rhs.maxPerStageDescriptorUniformBuffers ) + && ( maxPerStageDescriptorStorageBuffers == rhs.maxPerStageDescriptorStorageBuffers ) + && ( maxPerStageDescriptorSampledImages == rhs.maxPerStageDescriptorSampledImages ) + && ( maxPerStageDescriptorStorageImages == rhs.maxPerStageDescriptorStorageImages ) + && ( maxPerStageDescriptorInputAttachments == rhs.maxPerStageDescriptorInputAttachments ) + && ( maxPerStageResources == rhs.maxPerStageResources ) + && ( maxDescriptorSetSamplers == rhs.maxDescriptorSetSamplers ) + && ( maxDescriptorSetUniformBuffers == rhs.maxDescriptorSetUniformBuffers ) + && ( maxDescriptorSetUniformBuffersDynamic == rhs.maxDescriptorSetUniformBuffersDynamic ) + && ( maxDescriptorSetStorageBuffers == rhs.maxDescriptorSetStorageBuffers ) + && ( maxDescriptorSetStorageBuffersDynamic == rhs.maxDescriptorSetStorageBuffersDynamic ) + && ( maxDescriptorSetSampledImages == rhs.maxDescriptorSetSampledImages ) + && ( maxDescriptorSetStorageImages == rhs.maxDescriptorSetStorageImages ) + && ( maxDescriptorSetInputAttachments == rhs.maxDescriptorSetInputAttachments ) + && ( maxVertexInputAttributes == rhs.maxVertexInputAttributes ) + && ( maxVertexInputBindings == rhs.maxVertexInputBindings ) + && ( maxVertexInputAttributeOffset == rhs.maxVertexInputAttributeOffset ) + && ( maxVertexInputBindingStride == rhs.maxVertexInputBindingStride ) + && ( maxVertexOutputComponents == rhs.maxVertexOutputComponents ) + && ( maxTessellationGenerationLevel == rhs.maxTessellationGenerationLevel ) + && ( maxTessellationPatchSize == rhs.maxTessellationPatchSize ) + && ( maxTessellationControlPerVertexInputComponents == rhs.maxTessellationControlPerVertexInputComponents ) + && ( maxTessellationControlPerVertexOutputComponents == rhs.maxTessellationControlPerVertexOutputComponents ) + && ( maxTessellationControlPerPatchOutputComponents == rhs.maxTessellationControlPerPatchOutputComponents ) + && ( maxTessellationControlTotalOutputComponents == rhs.maxTessellationControlTotalOutputComponents ) + && ( maxTessellationEvaluationInputComponents == rhs.maxTessellationEvaluationInputComponents ) + && ( maxTessellationEvaluationOutputComponents == rhs.maxTessellationEvaluationOutputComponents ) + && ( maxGeometryShaderInvocations == rhs.maxGeometryShaderInvocations ) + && ( maxGeometryInputComponents == rhs.maxGeometryInputComponents ) + && ( maxGeometryOutputComponents == rhs.maxGeometryOutputComponents ) + && ( maxGeometryOutputVertices == rhs.maxGeometryOutputVertices ) + && ( maxGeometryTotalOutputComponents == rhs.maxGeometryTotalOutputComponents ) + && ( maxFragmentInputComponents == rhs.maxFragmentInputComponents ) + && ( maxFragmentOutputAttachments == rhs.maxFragmentOutputAttachments ) + && ( maxFragmentDualSrcAttachments == rhs.maxFragmentDualSrcAttachments ) + && ( maxFragmentCombinedOutputResources == rhs.maxFragmentCombinedOutputResources ) + && ( maxComputeSharedMemorySize == rhs.maxComputeSharedMemorySize ) + && ( memcmp( maxComputeWorkGroupCount, rhs.maxComputeWorkGroupCount, 3 * sizeof( uint32_t ) ) == 0 ) + && ( maxComputeWorkGroupInvocations == rhs.maxComputeWorkGroupInvocations ) + && ( memcmp( maxComputeWorkGroupSize, rhs.maxComputeWorkGroupSize, 3 * sizeof( uint32_t ) ) == 0 ) + && ( subPixelPrecisionBits == rhs.subPixelPrecisionBits ) + && ( subTexelPrecisionBits == rhs.subTexelPrecisionBits ) + && ( mipmapPrecisionBits == rhs.mipmapPrecisionBits ) + && ( maxDrawIndexedIndexValue == rhs.maxDrawIndexedIndexValue ) + && ( maxDrawIndirectCount == rhs.maxDrawIndirectCount ) + && ( maxSamplerLodBias == rhs.maxSamplerLodBias ) + && ( maxSamplerAnisotropy == rhs.maxSamplerAnisotropy ) + && ( maxViewports == rhs.maxViewports ) + && ( memcmp( maxViewportDimensions, rhs.maxViewportDimensions, 2 * sizeof( uint32_t ) ) == 0 ) + && ( memcmp( viewportBoundsRange, rhs.viewportBoundsRange, 2 * sizeof( float ) ) == 0 ) + && ( viewportSubPixelBits == rhs.viewportSubPixelBits ) + && ( minMemoryMapAlignment == rhs.minMemoryMapAlignment ) + && ( minTexelBufferOffsetAlignment == rhs.minTexelBufferOffsetAlignment ) + && ( minUniformBufferOffsetAlignment == rhs.minUniformBufferOffsetAlignment ) + && ( minStorageBufferOffsetAlignment == rhs.minStorageBufferOffsetAlignment ) + && ( minTexelOffset == rhs.minTexelOffset ) + && ( maxTexelOffset == rhs.maxTexelOffset ) + && ( minTexelGatherOffset == rhs.minTexelGatherOffset ) + && ( maxTexelGatherOffset == rhs.maxTexelGatherOffset ) + && ( minInterpolationOffset == rhs.minInterpolationOffset ) + && ( maxInterpolationOffset == rhs.maxInterpolationOffset ) + && ( subPixelInterpolationOffsetBits == rhs.subPixelInterpolationOffsetBits ) + && ( maxFramebufferWidth == rhs.maxFramebufferWidth ) + && ( maxFramebufferHeight == rhs.maxFramebufferHeight ) + && ( maxFramebufferLayers == rhs.maxFramebufferLayers ) + && ( framebufferColorSampleCounts == rhs.framebufferColorSampleCounts ) + && ( framebufferDepthSampleCounts == rhs.framebufferDepthSampleCounts ) + && ( framebufferStencilSampleCounts == rhs.framebufferStencilSampleCounts ) + && ( framebufferNoAttachmentsSampleCounts == rhs.framebufferNoAttachmentsSampleCounts ) + && ( maxColorAttachments == rhs.maxColorAttachments ) + && ( sampledImageColorSampleCounts == rhs.sampledImageColorSampleCounts ) + && ( sampledImageIntegerSampleCounts == rhs.sampledImageIntegerSampleCounts ) + && ( sampledImageDepthSampleCounts == rhs.sampledImageDepthSampleCounts ) + && ( sampledImageStencilSampleCounts == rhs.sampledImageStencilSampleCounts ) + && ( storageImageSampleCounts == rhs.storageImageSampleCounts ) + && ( maxSampleMaskWords == rhs.maxSampleMaskWords ) + && ( timestampComputeAndGraphics == rhs.timestampComputeAndGraphics ) + && ( timestampPeriod == rhs.timestampPeriod ) + && ( maxClipDistances == rhs.maxClipDistances ) + && ( maxCullDistances == rhs.maxCullDistances ) + && ( maxCombinedClipAndCullDistances == rhs.maxCombinedClipAndCullDistances ) + && ( discreteQueuePriorities == rhs.discreteQueuePriorities ) + && ( memcmp( pointSizeRange, rhs.pointSizeRange, 2 * sizeof( float ) ) == 0 ) + && ( memcmp( lineWidthRange, rhs.lineWidthRange, 2 * sizeof( float ) ) == 0 ) + && ( pointSizeGranularity == rhs.pointSizeGranularity ) + && ( lineWidthGranularity == rhs.lineWidthGranularity ) + && ( strictLines == rhs.strictLines ) + && ( standardSampleLocations == rhs.standardSampleLocations ) + && ( optimalBufferCopyOffsetAlignment == rhs.optimalBufferCopyOffsetAlignment ) + && ( optimalBufferCopyRowPitchAlignment == rhs.optimalBufferCopyRowPitchAlignment ) + && ( nonCoherentAtomSize == rhs.nonCoherentAtomSize ); + } + + bool operator!=( PhysicalDeviceLimits const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t maxImageDimension1D; uint32_t maxImageDimension2D; uint32_t maxImageDimension3D; @@ -10794,6 +12546,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PhysicalDeviceProperties const& rhs ) const + { + return ( apiVersion == rhs.apiVersion ) + && ( driverVersion == rhs.driverVersion ) + && ( vendorID == rhs.vendorID ) + && ( deviceID == rhs.deviceID ) + && ( deviceType == rhs.deviceType ) + && ( memcmp( deviceName, rhs.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE * sizeof( char ) ) == 0 ) + && ( memcmp( pipelineCacheUUID, rhs.pipelineCacheUUID, VK_UUID_SIZE * sizeof( uint8_t ) ) == 0 ) + && ( limits == rhs.limits ) + && ( sparseProperties == rhs.sparseProperties ); + } + + bool operator!=( PhysicalDeviceProperties const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t apiVersion; uint32_t driverVersion; uint32_t vendorID; @@ -10903,6 +12673,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( AttachmentDescription const& rhs ) const + { + return ( flags == rhs.flags ) + && ( format == rhs.format ) + && ( samples == rhs.samples ) + && ( loadOp == rhs.loadOp ) + && ( storeOp == rhs.storeOp ) + && ( stencilLoadOp == rhs.stencilLoadOp ) + && ( stencilStoreOp == rhs.stencilStoreOp ) + && ( initialLayout == rhs.initialLayout ) + && ( finalLayout == rhs.finalLayout ); + } + + bool operator!=( AttachmentDescription const& rhs ) const + { + return !operator==( rhs ); + } + AttachmentDescriptionFlags flags; Format format; SampleCountFlagBits samples; @@ -11005,6 +12793,21 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DescriptorPoolCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( maxSets == rhs.maxSets ) + && ( poolSizeCount == rhs.poolSizeCount ) + && ( pPoolSizes == rhs.pPoolSizes ); + } + + bool operator!=( DescriptorPoolCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -11816,6 +13619,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SubpassDependency const& rhs ) const + { + return ( srcSubpass == rhs.srcSubpass ) + && ( dstSubpass == rhs.dstSubpass ) + && ( srcStageMask == rhs.srcStageMask ) + && ( dstStageMask == rhs.dstStageMask ) + && ( srcAccessMask == rhs.srcAccessMask ) + && ( dstAccessMask == rhs.dstAccessMask ) + && ( dependencyFlags == rhs.dependencyFlags ); + } + + bool operator!=( SubpassDependency const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t srcSubpass; uint32_t dstSubpass; PipelineStageFlags srcStageMask; @@ -11911,6 +13730,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( RenderPassCreateInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( attachmentCount == rhs.attachmentCount ) + && ( pAttachments == rhs.pAttachments ) + && ( subpassCount == rhs.subpassCount ) + && ( pSubpasses == rhs.pSubpasses ) + && ( dependencyCount == rhs.dependencyCount ) + && ( pDependencies == rhs.pDependencies ); + } + + bool operator!=( RenderPassCreateInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -12011,6 +13848,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SubmitInfo const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( waitSemaphoreCount == rhs.waitSemaphoreCount ) + && ( pWaitSemaphores == rhs.pWaitSemaphores ) + && ( pWaitDstStageMask == rhs.pWaitDstStageMask ) + && ( commandBufferCount == rhs.commandBufferCount ) + && ( pCommandBuffers == rhs.pCommandBuffers ) + && ( signalSemaphoreCount == rhs.signalSemaphoreCount ) + && ( pSignalSemaphores == rhs.pSignalSemaphores ); + } + + bool operator!=( SubmitInfo const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -12171,6 +14026,17 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SurfaceFormatKHR const& rhs ) const + { + return ( format == rhs.format ) + && ( colorSpace == rhs.colorSpace ); + } + + bool operator!=( SurfaceFormatKHR const& rhs ) const + { + return !operator==( rhs ); + } + Format format; ColorSpaceKHR colorSpace; }; @@ -12276,6 +14142,24 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayPlaneCapabilitiesKHR const& rhs ) const + { + return ( supportedAlpha == rhs.supportedAlpha ) + && ( minSrcPosition == rhs.minSrcPosition ) + && ( maxSrcPosition == rhs.maxSrcPosition ) + && ( minSrcExtent == rhs.minSrcExtent ) + && ( maxSrcExtent == rhs.maxSrcExtent ) + && ( minDstPosition == rhs.minDstPosition ) + && ( maxDstPosition == rhs.maxDstPosition ) + && ( minDstExtent == rhs.minDstExtent ) + && ( maxDstExtent == rhs.maxDstExtent ); + } + + bool operator!=( DisplayPlaneCapabilitiesKHR const& rhs ) const + { + return !operator==( rhs ); + } + DisplayPlaneAlphaFlagsKHR supportedAlpha; Offset2D minSrcPosition; Offset2D maxSrcPosition; @@ -12394,6 +14278,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplayPropertiesKHR const& rhs ) const + { + return ( display == rhs.display ) + && ( displayName == rhs.displayName ) + && ( physicalDimensions == rhs.physicalDimensions ) + && ( physicalResolution == rhs.physicalResolution ) + && ( supportedTransforms == rhs.supportedTransforms ) + && ( planeReorderPossible == rhs.planeReorderPossible ) + && ( persistentContent == rhs.persistentContent ); + } + + bool operator!=( DisplayPropertiesKHR const& rhs ) const + { + return !operator==( rhs ); + } + DisplayKHR display; const char* displayName; Extent2D physicalDimensions; @@ -12496,6 +14396,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DisplaySurfaceCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( displayMode == rhs.displayMode ) + && ( planeIndex == rhs.planeIndex ) + && ( planeStackIndex == rhs.planeStackIndex ) + && ( transform == rhs.transform ) + && ( globalAlpha == rhs.globalAlpha ) + && ( alphaMode == rhs.alphaMode ) + && ( imageExtent == rhs.imageExtent ); + } + + bool operator!=( DisplaySurfaceCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -12604,6 +14523,25 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SurfaceCapabilitiesKHR const& rhs ) const + { + return ( minImageCount == rhs.minImageCount ) + && ( maxImageCount == rhs.maxImageCount ) + && ( currentExtent == rhs.currentExtent ) + && ( minImageExtent == rhs.minImageExtent ) + && ( maxImageExtent == rhs.maxImageExtent ) + && ( maxImageArrayLayers == rhs.maxImageArrayLayers ) + && ( supportedTransforms == rhs.supportedTransforms ) + && ( currentTransform == rhs.currentTransform ) + && ( supportedCompositeAlpha == rhs.supportedCompositeAlpha ) + && ( supportedUsageFlags == rhs.supportedUsageFlags ); + } + + bool operator!=( SurfaceCapabilitiesKHR const& rhs ) const + { + return !operator==( rhs ); + } + uint32_t minImageCount; uint32_t maxImageCount; Extent2D currentExtent; @@ -12765,6 +14703,33 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( SwapchainCreateInfoKHR const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( surface == rhs.surface ) + && ( minImageCount == rhs.minImageCount ) + && ( imageFormat == rhs.imageFormat ) + && ( imageColorSpace == rhs.imageColorSpace ) + && ( imageExtent == rhs.imageExtent ) + && ( imageArrayLayers == rhs.imageArrayLayers ) + && ( imageUsage == rhs.imageUsage ) + && ( imageSharingMode == rhs.imageSharingMode ) + && ( queueFamilyIndexCount == rhs.queueFamilyIndexCount ) + && ( pQueueFamilyIndices == rhs.pQueueFamilyIndices ) + && ( preTransform == rhs.preTransform ) + && ( compositeAlpha == rhs.compositeAlpha ) + && ( presentMode == rhs.presentMode ) + && ( clipped == rhs.clipped ) + && ( oldSwapchain == rhs.oldSwapchain ); + } + + bool operator!=( SwapchainCreateInfoKHR const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -12862,6 +14827,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DebugReportCallbackCreateInfoEXT const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( flags == rhs.flags ) + && ( pfnCallback == rhs.pfnCallback ) + && ( pUserData == rhs.pUserData ); + } + + bool operator!=( DebugReportCallbackCreateInfoEXT const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -12963,6 +14942,20 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DebugMarkerObjectNameInfoEXT const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( objectType == rhs.objectType ) + && ( object == rhs.object ) + && ( pObjectName == rhs.pObjectName ); + } + + bool operator!=( DebugMarkerObjectNameInfoEXT const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -13045,6 +15038,22 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( DebugMarkerObjectTagInfoEXT const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( objectType == rhs.objectType ) + && ( object == rhs.object ) + && ( tagName == rhs.tagName ) + && ( tagSize == rhs.tagSize ) + && ( pTag == rhs.pTag ); + } + + bool operator!=( DebugMarkerObjectTagInfoEXT const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType; @@ -15015,6 +17024,18 @@ namespace vk return *reinterpret_cast(this); } + bool operator==( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const + { + return ( sType == rhs.sType ) + && ( pNext == rhs.pNext ) + && ( rasterizationOrder == rhs.rasterizationOrder ); + } + + bool operator!=( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const + { + return !operator==( rhs ); + } + private: StructureType sType;