2016-02-16 14:07:55 +00:00
// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2016-02-17 13:03:05 +00:00
# include <cassert>
# include <algorithm>
2016-02-16 14:07:55 +00:00
# include <fstream>
2016-02-17 13:03:05 +00:00
# include <functional>
2016-02-16 14:07:55 +00:00
# include <iostream>
# include <list>
# include <map>
# include <set>
# include <sstream>
# include <string>
# include <vector>
2016-02-17 13:03:05 +00:00
# include <tinyxml2.h>
2016-02-16 14:07:55 +00:00
2016-03-04 09:37:16 +00:00
const std : : string nvidiaLicenseHeader (
2016-02-16 14:07:55 +00:00
" // 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 "
) ;
2016-02-22 14:27:08 +00:00
const std : : string exceptionHeader (
2016-03-07 14:08:31 +00:00
" #if defined(_MSC_VER) && (_MSC_VER == 1800) \n "
" # define noexcept _NOEXCEPT \n "
" #endif \n "
2016-02-22 14:27:08 +00:00
" \n "
2016-03-07 14:08:31 +00:00
" class ErrorCategoryImpl : public std::error_category \n "
2016-02-22 14:27:08 +00:00
" { \n "
2016-03-07 14:08:31 +00:00
" public: \n "
" virtual const char* name() const noexcept override { return \" vk::Result \" ; } \n "
" virtual std::string message(int ev) const override { return getString(static_cast<vk::Result>(ev)); } \n "
2016-02-22 14:27:08 +00:00
" }; \n "
" \n "
2016-03-07 14:08:31 +00:00
" #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<int>(e), errorCategory()); \n "
" } \n "
" \n "
" inline std::error_condition make_error_condition(Result e) \n "
" { \n "
" return std::error_condition(static_cast<int>(e), errorCategory()); \n "
" } \n "
" \n "
2016-02-22 14:27:08 +00:00
) ;
2016-02-16 14:07:55 +00:00
const std : : string flagsHeader (
" template <typename BitType, typename MaskType = uint32_t> \n "
" class Flags \n "
" { \n "
" public: \n "
" Flags() \n "
" : m_mask(0) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags(BitType bit) \n "
" : m_mask(static_cast<uint32_t>(bit)) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags(Flags<BitType> const& rhs) \n "
" : m_mask(rhs.m_mask) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask = rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator|=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask |= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator&=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask &= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator^=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask ^= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator|(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result |= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator&(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result &= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator^(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result ^= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator!() const \n "
" { \n "
" return !m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator==(Flags<BitType> const& rhs) const \n "
" { \n "
" return m_mask == rhs.m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator!=(Flags<BitType> const& rhs) const \n "
" { \n "
" return m_mask != rhs.m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" operator bool() const \n "
" { \n "
" return !!m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
" explicit operator MaskType() const \n "
" { \n "
" return m_mask; \n "
" } \n "
" \n "
2016-02-16 14:07:55 +00:00
" private: \n "
" MaskType m_mask; \n "
" }; \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator|(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags | bit; \n "
" } \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator&(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags & bit; \n "
" } \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator^(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags ^ bit; \n "
" } \n "
" \n "
) ;
2016-03-14 16:51:10 +00:00
std : : string const optionalClassHeader = (
" template <typename RefType> \n "
" class Optional \n "
" { \n "
" public: \n "
" Optional(RefType & reference) { m_ptr = &reference; } \n "
" \n "
" operator RefType*() const { return m_ptr; } \n "
" \n "
" private: \n "
" Optional(std::nullptr_t) { m_ptr = nullptr; } \n "
" friend typename RefType; \n "
" RefType *m_ptr; \n "
" }; \n "
" \n "
) ;
2016-02-17 13:03:05 +00:00
// 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 < int , int > ( std : : isspace ) ) ) . base ( ) , result . end ( ) ) ;
return result ;
}
2016-02-16 14:07:55 +00:00
struct MemberData
{
std : : string type ;
std : : string name ;
std : : string arraySize ;
std : : string pureType ;
std : : string len ;
2016-03-14 16:51:10 +00:00
bool optional ;
2016-02-16 14:07:55 +00:00
} ;
2016-03-16 10:20:41 +00:00
struct CommandData
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
CommandData ( )
: handleCommand ( false )
, twoStep ( false )
2016-02-26 11:01:11 +00:00
{ }
2016-03-16 10:20:41 +00:00
std : : string returnType ;
std : : vector < MemberData > arguments ;
std : : vector < std : : string > 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 < std : : string > dependencies ;
2016-02-16 14:07:55 +00:00
} ;
struct NameValue
{
std : : string name ;
std : : string value ;
} ;
struct EnumData
{
bool bitmask ;
2016-02-18 08:45:18 +00:00
std : : string prefix ;
std : : string postfix ;
2016-02-16 14:07:55 +00:00
std : : vector < NameValue > members ;
2016-02-22 14:27:08 +00:00
std : : string protect ;
2016-02-18 08:45:18 +00:00
2016-02-25 13:25:23 +00:00
void addEnum ( std : : string const & name , std : : string const & tag ) ;
2016-02-16 14:07:55 +00:00
} ;
2016-03-16 10:20:41 +00:00
struct FlagData
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
std : : string protect ;
2016-02-16 14:07:55 +00:00
} ;
2016-02-22 14:27:08 +00:00
struct HandleData
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : vector < std : : string > commands ;
} ;
struct ScalarData
{
std : : string protect ;
2016-02-16 14:07:55 +00:00
} ;
2016-03-16 10:20:41 +00:00
struct StructData
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
StructData ( )
: returnedOnly ( false )
2016-02-16 14:07:55 +00:00
{ }
2016-03-16 10:20:41 +00:00
bool returnedOnly ;
std : : vector < MemberData > members ;
std : : string protect ;
} ;
struct VkData
{
std : : map < std : : string , CommandData > commands ;
std : : list < DependencyData > dependencies ;
std : : map < std : : string , EnumData > enums ;
std : : map < std : : string , FlagData > flags ;
std : : map < std : : string , HandleData > handles ;
std : : map < std : : string , ScalarData > scalars ;
std : : map < std : : string , StructData > structs ;
std : : set < std : : string > tags ;
std : : string typesafeCheck ;
std : : string version ;
std : : set < std : : string > vkTypes ;
std : : string vulkanLicenseHeader ;
2016-02-16 14:07:55 +00:00
} ;
2016-03-16 10:20:41 +00:00
void createDefaults ( VkData const & vkData , std : : map < std : : string , std : : string > & defaultValues ) ;
2016-02-22 14:27:08 +00:00
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 ) ;
2016-02-25 13:25:23 +00:00
std : : string extractTag ( std : : string const & name ) ;
2016-02-24 10:31:50 +00:00
size_t findReturnIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-25 13:25:23 +00:00
std : : string findTag ( std : : string const & name , std : : set < std : : string > const & tags ) ;
2016-02-24 10:31:50 +00:00
size_t findTemplateIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-22 14:27:08 +00:00
std : : string generateEnumNameForFlags ( std : : string const & name ) ;
std : : map < size_t , size_t > getVectorParameters ( CommandData const & commandData ) ;
bool hasPointerArguments ( CommandData const & commandData ) ;
bool isVectorSizeParameter ( std : : map < size_t , size_t > const & vectorParameters , size_t idx ) ;
void leaveProtect ( std : : ofstream & ofs , std : : string const & protect ) ;
2016-02-16 14:07:55 +00:00
bool noDependencies ( std : : set < std : : string > const & dependencies , std : : map < std : : string , std : : string > & listedTypes ) ;
2016-02-22 14:27:08 +00:00
bool readCommandParam ( tinyxml2 : : XMLElement * element , DependencyData & typeData , std : : vector < MemberData > & arguments ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , CommandData > : : iterator readCommandProto ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
void readCommands ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
void readCommandsCommand ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
2016-03-04 09:37:16 +00:00
void readComment ( tinyxml2 : : XMLElement * element , std : : string & header ) ;
2016-03-16 10:20:41 +00:00
void readEnums ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
2016-02-25 13:25:23 +00:00
void readEnumsEnum ( tinyxml2 : : XMLElement * element , EnumData & enumData , std : : string const & tag ) ;
2016-03-16 10:20:41 +00:00
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 ) ;
2016-02-17 13:03:05 +00:00
void readTypeBasetype ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies ) ;
2016-03-16 10:20:41 +00:00
void readTypeBitmask ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
void readTypeDefine ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
2016-02-17 13:03:05 +00:00
void readTypeFuncpointer ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies ) ;
2016-03-16 10:20:41 +00:00
void readTypeHandle ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
void readTypeStruct ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
2016-02-17 13:03:05 +00:00
void readTypeStructMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies ) ;
2016-03-16 10:20:41 +00:00
void readTypeUnion ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
2016-02-17 13:03:05 +00:00
void readTypeUnionMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies ) ;
2016-02-25 13:25:23 +00:00
void readTags ( tinyxml2 : : XMLElement * element , std : : set < std : : string > & tags ) ;
2016-03-16 10:20:41 +00:00
void readTypes ( tinyxml2 : : XMLElement * element , VkData & vkData ) ;
void sortDependencies ( std : : list < DependencyData > & dependencies ) ;
2016-02-16 14:07:55 +00:00
std : : string reduceName ( std : : string const & name ) ;
2016-02-25 13:25:23 +00:00
std : : string strip ( std : : string const & value , std : : string const & prefix , std : : string const & tag = std : : string ( ) ) ;
2016-02-22 14:27:08 +00:00
std : : string stripCommand ( std : : string const & value ) ;
2016-02-16 14:07:55 +00:00
std : : string toCamelCase ( std : : string const & value ) ;
std : : string toUpperCase ( std : : string const & name ) ;
2016-02-29 09:07:34 +00:00
void writeCall ( std : : ofstream & ofs , std : : string const & name , size_t templateIndex , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters , size_t returnIndex , bool firstCall ) ;
2016-03-16 10:20:41 +00:00
void writeEnumsToString ( std : : ofstream & ofs , VkData const & vkData ) ;
2016-02-22 14:27:08 +00:00
void writeExceptionCheck ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : vector < std : : string > const & successCodes ) ;
2016-02-29 09:07:34 +00:00
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 < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-24 10:31:50 +00:00
void writeFunctionHeader ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & returnType , std : : string const & name , CommandData const & commandData , size_t returnIndex , size_t templateIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-16 14:07:55 +00:00
void writeMemberData ( std : : ofstream & ofs , MemberData const & memberData , std : : set < std : : string > const & vkTypes ) ;
void writeStructConstructor ( std : : ofstream & ofs , std : : string const & name , std : : string const & memberName , StructData const & structData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , std : : string > const & defaultValues ) ;
2016-02-26 11:01:11 +00:00
void writeStructGetter ( std : : ofstream & ofs , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes , bool constVersion ) ;
2016-02-16 14:07:55 +00:00
void writeStructSetter ( std : : ofstream & ofs , std : : string const & name , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs ) ;
void writeTypeCommand ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
2016-03-01 11:14:18 +00:00
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
void writeTypeCommandStandard ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
2016-02-16 14:07:55 +00:00
void writeTypeEnum ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData ) ;
2016-02-22 14:27:08 +00:00
void writeTypeFlags ( std : : ofstream & ofs , DependencyData const & dependencyData , FlagData const & flagData ) ;
2016-03-16 10:20:41 +00:00
void writeTypeHandle ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , HandleData const & handle , std : : list < DependencyData > const & dependencies ) ;
2016-02-16 14:07:55 +00:00
void writeTypeScalar ( std : : ofstream & ofs , DependencyData const & dependencyData ) ;
2016-03-16 10:20:41 +00:00
void writeTypeStruct ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , std : : map < std : : string , std : : string > const & defaultValues ) ;
void writeTypeUnion ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , StructData const & unionData , std : : map < std : : string , std : : string > const & defaultValues ) ;
void writeTypes ( std : : ofstream & ofs , VkData const & vkData , std : : map < std : : string , std : : string > const & defaultValues ) ;
2016-02-22 14:27:08 +00:00
void writeVersionCheck ( std : : ofstream & ofs , std : : string const & version ) ;
2016-02-25 15:48:46 +00:00
void writeTypesafeCheck ( std : : ofstream & ofs , std : : string const & typesafeCheck ) ;
2016-02-16 14:07:55 +00:00
2016-02-25 13:25:23 +00:00
void EnumData : : addEnum ( std : : string const & name , std : : string const & tag )
2016-02-18 08:45:18 +00:00
{
2016-02-25 13:25:23 +00:00
assert ( tag . empty ( ) | | ( name . find ( tag ) ! = std : : string : : npos ) ) ;
2016-02-18 08:45:18 +00:00
members . push_back ( NameValue ( ) ) ;
2016-02-25 13:25:23 +00:00
members . back ( ) . name = " e " + toCamelCase ( strip ( name , prefix , tag ) ) ;
2016-02-18 08:45:18 +00:00
members . back ( ) . value = name ;
if ( ! postfix . empty ( ) )
{
size_t pos = members . back ( ) . name . find ( postfix ) ;
if ( pos ! = std : : string : : npos )
{
2016-02-25 13:25:23 +00:00
members . back ( ) . name . erase ( pos ) ;
2016-02-18 08:45:18 +00:00
}
}
2016-02-25 13:25:23 +00:00
if ( ! tag . empty ( ) )
{
members . back ( ) . name + = tag ;
}
2016-02-18 08:45:18 +00:00
}
2016-03-16 10:20:41 +00:00
void createDefaults ( VkData const & vkData , std : : map < std : : string , std : : string > & defaultValues )
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
for ( std : : list < DependencyData > : : const_iterator it = vkData . dependencies . begin ( ) ; it ! = vkData . dependencies . end ( ) ; + + it )
2016-02-16 14:07:55 +00:00
{
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 :
2016-02-19 11:56:38 +00:00
{
2016-03-16 10:20:41 +00:00
assert ( vkData . enums . find ( it - > name ) ! = vkData . enums . end ( ) ) ;
EnumData const & enumData = vkData . enums . find ( it - > name ) - > second ;
2016-02-19 11:56:38 +00:00
if ( ! enumData . members . empty ( ) )
{
2016-03-16 10:20:41 +00:00
defaultValues [ it - > name ] = it - > name + " :: " + vkData . enums . find ( it - > name ) - > second . members . front ( ) . name ;
2016-02-19 11:56:38 +00:00
}
else
{
defaultValues [ it - > name ] = it - > name + " () " ;
}
}
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : FLAGS :
2016-02-22 14:27:08 +00:00
case DependencyData : : Category : : HANDLE :
case DependencyData : : Category : : STRUCT :
2016-02-16 14:07:55 +00:00
case DependencyData : : Category : : UNION : // just call the default constructor for flags, structs, and structs (which are mapped to classes)
defaultValues [ it - > name ] = it - > name + " () " ;
break ;
case DependencyData : : Category : : FUNC_POINTER : // func_pointers explicitly have no default!
defaultValues [ it - > name ] ;
break ;
case DependencyData : : Category : : REQUIRED : // all required default to "0"
case DependencyData : : Category : : SCALAR : // all scalars default to "0"
defaultValues [ it - > name ] = " 0 " ;
break ;
default :
assert ( false ) ;
break ;
}
}
}
2016-02-22 14:27:08 +00:00
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 ;
2016-02-29 09:07:34 +00:00
if ( ( returnIndex ! = ~ 0 ) & & ( ( commandData . returnType = = " void " ) | | ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) < 2 ) ) ) )
2016-02-22 14:27:08 +00:00
{
2016-02-29 13:41:52 +00:00
if ( isVector )
2016-02-22 14:27:08 +00:00
{
if ( commandData . arguments [ returnIndex ] . pureType = = " void " )
{
returnType = " std::vector<uint8_t> " ;
}
else
{
returnType = " std::vector< " + commandData . arguments [ returnIndex ] . pureType + " > " ;
}
}
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 ( ) ;
}
}
2016-02-29 13:41:52 +00:00
else if ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) = = 1 ) )
2016-02-22 14:27:08 +00:00
{
2016-02-29 09:07:34 +00:00
// an original return of type "Result" with less just one successCode is changed to void, errors throw an exception
2016-02-22 14:27:08 +00:00
returnType = " void " ;
}
else
{
2016-02-29 13:41:52 +00:00
// the return type just stays the original return type
2016-02-22 14:27:08 +00:00
returnType = commandData . returnType ;
}
return std : : move ( returnType ) ;
}
void enterProtect ( std : : ofstream & ofs , std : : string const & protect )
{
if ( ! protect . empty ( ) )
{
ofs < < " #ifdef " < < protect < < std : : endl ;
}
}
2016-02-25 13:25:23 +00:00
std : : string extractTag ( std : : string const & name )
2016-02-22 14:27:08 +00:00
{
2016-02-25 13:25:23 +00:00
// the name is supposed to look like: VK_<tag>_<other>
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 ) ;
2016-02-22 14:27:08 +00:00
}
size_t findReturnIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters )
2016-02-16 14:07:55 +00:00
{
2016-02-29 09:07:34 +00:00
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
2016-02-16 14:07:55 +00:00
{
2016-02-29 09:07:34 +00:00
if ( ( commandData . arguments [ i ] . type . find ( ' * ' ) ! = std : : string : : npos ) & & ( commandData . arguments [ i ] . type . find ( " const " ) = = std : : string : : npos ) & & ! isVectorSizeParameter ( vectorParameters , i ) )
2016-02-16 14:07:55 +00:00
{
2016-02-29 13:41:52 +00:00
# if !defined(NDEBUG)
2016-02-29 09:07:34 +00:00
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 ) ) ;
2016-02-29 13:41:52 +00:00
}
2016-02-29 09:07:34 +00:00
# endif
return i ;
2016-02-16 14:07:55 +00:00
}
}
return ~ 0 ;
}
2016-02-25 13:25:23 +00:00
std : : string findTag ( std : : string const & name , std : : set < std : : string > const & tags )
{
for ( std : : set < std : : string > : : 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 " " ;
}
2016-02-24 10:31:50 +00:00
size_t findTemplateIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters )
{
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( commandData . arguments [ i ] . name = = " pData " )
{
assert ( vectorParameters . find ( i ) ! = vectorParameters . end ( ) ) ;
return i ;
}
}
return ~ 0 ;
}
2016-02-18 08:45:18 +00:00
std : : string getEnumName ( std : : string const & name ) // get vkcpp enum name from vk enum name
{
return strip ( name , " Vk " ) ;
}
2016-02-22 14:27:08 +00:00
std : : string generateEnumNameForFlags ( std : : string const & name )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : string generatedName = name ;
size_t pos = generatedName . rfind ( " Flags " ) ;
assert ( pos ! = std : : string : : npos ) ;
generatedName . replace ( pos , 5 , " FlagBits " ) ;
return generatedName ;
}
std : : map < size_t , size_t > getVectorParameters ( CommandData const & commandData )
{
std : : map < size_t , size_t > lenParameters ;
2016-02-16 14:07:55 +00:00
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( ! commandData . arguments [ i ] . len . empty ( ) )
{
2016-02-22 14:27:08 +00:00
lenParameters . insert ( std : : make_pair ( i , ~ 0 ) ) ;
2016-02-16 14:07:55 +00:00
for ( size_t j = 0 ; j < commandData . arguments . size ( ) ; j + + )
{
if ( commandData . arguments [ i ] . len = = commandData . arguments [ j ] . name )
{
2016-02-22 14:27:08 +00:00
lenParameters [ i ] = j ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-22 14:27:08 +00:00
assert ( ( lenParameters [ i ] ! = ~ 0 )
2016-02-16 14:07:55 +00:00
| | ( commandData . arguments [ i ] . len = = " dataSize/4 " )
2016-02-29 10:18:19 +00:00
| | ( commandData . arguments [ i ] . len = = " latexmath:[$dataSize \\ over 4$] " )
2016-02-16 14:07:55 +00:00
| | ( commandData . arguments [ i ] . len = = " null-terminated " )
| | ( commandData . arguments [ i ] . len = = " pAllocateInfo->descriptorSetCount " )
| | ( commandData . arguments [ i ] . len = = " pAllocateInfo->commandBufferCount " ) ) ;
2016-02-22 14:27:08 +00:00
assert ( ( lenParameters [ i ] = = ~ 0 ) | | ( lenParameters [ i ] < i ) ) ;
2016-02-16 14:07:55 +00:00
}
}
return std : : move ( lenParameters ) ;
}
2016-02-29 09:07:34 +00:00
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 ;
}
2016-02-22 14:27:08 +00:00
bool isVectorSizeParameter ( std : : map < size_t , size_t > const & vectorParameters , size_t idx )
{
for ( std : : map < size_t , size_t > : : 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 ;
}
}
2016-02-16 14:07:55 +00:00
bool noDependencies ( std : : set < std : : string > const & dependencies , std : : set < std : : string > & listedTypes )
{
bool ok = true ;
for ( std : : set < std : : string > : : const_iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) & & ok ; + + it )
{
ok = ( listedTypes . find ( * it ) ! = listedTypes . end ( ) ) ;
}
return ( ok ) ;
}
2016-02-22 14:27:08 +00:00
bool readCommandParam ( tinyxml2 : : XMLElement * element , DependencyData & typeData , std : : vector < MemberData > & arguments )
2016-02-16 14:07:55 +00:00
{
arguments . push_back ( MemberData ( ) ) ;
MemberData & arg = arguments . back ( ) ;
if ( element - > Attribute ( " len " ) )
{
arg . len = element - > Attribute ( " len " ) ;
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
assert ( ( value = = " const " ) | | ( value = = " struct " ) ) ;
arg . type = value + " " ;
2016-02-16 14:07:55 +00:00
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
arg . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
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 )
{
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
arg . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ( ) ) ;
}
}
}
2016-02-22 14:27:08 +00:00
2016-03-14 16:51:10 +00:00
arg . optional = element - > Attribute ( " optional " ) & & ( strcmp ( element - > Attribute ( " optional " ) , " true " ) = = 0 ) ;
2016-02-22 14:27:08 +00:00
return element - > Attribute ( " optional " ) & & ( strcmp ( element - > Attribute ( " optional " ) , " false,true " ) = = 0 ) ;
2016-02-16 14:07:55 +00:00
}
2016-03-16 10:20:41 +00:00
std : : map < std : : string , CommandData > : : iterator readCommandProto ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) ) ;
assert ( ! nameElement - > NextSiblingElement ( ) ) ;
std : : string type = strip ( typeElement - > GetText ( ) , " Vk " ) ;
2016-02-22 14:27:08 +00:00
std : : string name = stripCommand ( nameElement - > GetText ( ) ) ;
2016-02-16 14:07:55 +00:00
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : COMMAND , name ) ) ;
assert ( vkData . commands . find ( name ) = = vkData . commands . end ( ) ) ;
std : : map < std : : string , CommandData > : : iterator it = vkData . commands . insert ( std : : make_pair ( name , CommandData ( ) ) ) . first ;
2016-02-16 14:07:55 +00:00
it - > second . returnType = type ;
2016-02-22 14:27:08 +00:00
return it ;
2016-02-16 14:07:55 +00:00
}
2016-03-16 10:20:41 +00:00
void readCommands ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
do
{
assert ( strcmp ( child - > Value ( ) , " command " ) = = 0 ) ;
2016-03-16 10:20:41 +00:00
readCommandsCommand ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void readCommandsCommand ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " proto " ) = = 0 ) ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , CommandData > : : iterator it = readCommandProto ( child , vkData ) ;
2016-02-22 14:27:08 +00:00
if ( element - > Attribute ( " successcodes " ) )
{
std : : string successCodes = element - > Attribute ( " successcodes " ) ;
size_t start = 0 , end ;
do
{
end = successCodes . find ( ' , ' , start ) ;
2016-02-25 13:25:23 +00:00
std : : string code = successCodes . substr ( start , end - start ) ;
2016-03-16 10:20:41 +00:00
std : : string tag = findTag ( code , vkData . tags ) ;
2016-02-25 13:25:23 +00:00
it - > second . successCodes . push_back ( " e " + toCamelCase ( strip ( code , " VK_ " , tag ) ) + tag ) ;
2016-02-22 14:27:08 +00:00
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 ( ) ;
2016-02-25 13:25:23 +00:00
it - > second . successCodes . push_back ( " eSuccess " ) ;
2016-02-22 14:27:08 +00:00
}
2016-02-16 14:07:55 +00:00
while ( child = child - > NextSiblingElement ( ) )
{
std : : string value = child - > Value ( ) ;
if ( value = = " param " )
{
2016-03-16 10:20:41 +00:00
it - > second . twoStep | = readCommandParam ( child , vkData . dependencies . back ( ) , it - > second . arguments ) ;
2016-02-16 14:07:55 +00:00
}
else
{
assert ( ( value = = " implicitexternsyncparams " ) | | ( value = = " validity " ) ) ;
}
}
2016-02-22 14:27:08 +00:00
// HACK: the current vk.xml misses to specify <optional="false,true"> on param pSparseMemoryRequirementCount on command vkGetImageSparseMemoryRequirements!
if ( it - > first = = " getImageSparseMemoryRequirements " )
{
it - > second . twoStep = true ;
}
assert ( ! it - > second . arguments . empty ( ) ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , HandleData > : : iterator hit = vkData . handles . find ( it - > second . arguments [ 0 ] . pureType ) ;
if ( hit ! = vkData . handles . end ( ) )
2016-02-22 14:27:08 +00:00
{
hit - > second . commands . push_back ( it - > first ) ;
it - > second . handleCommand = true ;
2016-03-16 10:20:41 +00:00
DependencyData const & dep = vkData . dependencies . back ( ) ;
std : : list < DependencyData > : : iterator dit = std : : find_if ( vkData . dependencies . begin ( ) , vkData . dependencies . end ( ) , [ hit ] ( DependencyData const & dd ) { return dd . name = = hit - > first ; } ) ;
2016-02-22 14:27:08 +00:00
for ( std : : set < std : : string > : : const_iterator depit = dep . dependencies . begin ( ) ; depit ! = dep . dependencies . end ( ) ; + + depit )
{
if ( * depit ! = hit - > first )
{
dit - > dependencies . insert ( * depit ) ;
}
}
}
2016-02-16 14:07:55 +00:00
}
2016-03-04 09:37:16 +00:00
void readComment ( tinyxml2 : : XMLElement * element , std : : string & header )
{
assert ( element - > GetText ( ) ) ;
assert ( header . empty ( ) ) ;
header = element - > GetText ( ) ;
assert ( header . find ( " \n Copyright " ) = = 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. " ;
}
2016-03-16 10:20:41 +00:00
void readEnums ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
2016-02-18 08:45:18 +00:00
std : : string name = getEnumName ( element - > Attribute ( " name " ) ) ;
2016-02-16 14:07:55 +00:00
if ( name ! = " API Constants " )
{
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : ENUM , name ) ) ;
std : : map < std : : string , EnumData > : : iterator it = vkData . enums . insert ( std : : make_pair ( name , EnumData ( ) ) ) . first ;
2016-02-25 13:25:23 +00:00
std : : string tag ;
2016-02-16 14:07:55 +00:00
2016-02-25 13:25:23 +00:00
if ( name = = " Result " )
2016-02-16 14:07:55 +00:00
{
2016-02-25 13:25:23 +00:00
// special handling for VKResult, as its enums just have VK_ in common
it - > second . prefix = " VK_ " ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-02-25 13:25:23 +00:00
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.
2016-03-16 10:20:41 +00:00
for ( std : : set < std : : string > : : const_iterator tit = vkData . tags . begin ( ) ; tit ! = vkData . tags . end ( ) ; + + tit )
2016-02-25 13:25:23 +00:00
{
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 ;
}
}
2016-02-16 14:07:55 +00:00
}
2016-02-25 13:25:23 +00:00
readEnumsEnum ( element , it - > second , tag ) ;
2016-02-16 14:07:55 +00:00
2016-03-16 10:20:41 +00:00
assert ( vkData . vkTypes . find ( name ) = = vkData . vkTypes . end ( ) ) ;
vkData . vkTypes . insert ( name ) ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-25 13:25:23 +00:00
void readEnumsEnum ( tinyxml2 : : XMLElement * element , EnumData & enumData , std : : string const & tag )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
if ( child - > Attribute ( " name " ) )
{
2016-02-25 13:25:23 +00:00
enumData . addEnum ( child - > Attribute ( " name " ) , tag ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void readExtensionRequire ( tinyxml2 : : XMLElement * element , VkData & vkData , std : : string const & protect , std : : string const & tag )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
std : : string value = child - > Value ( ) ;
assert ( child - > Attribute ( " name " ) ) ;
2016-02-18 08:45:18 +00:00
2016-02-16 14:07:55 +00:00
if ( value = = " command " )
{
2016-02-22 14:27:08 +00:00
std : : string name = stripCommand ( child - > Attribute ( " name " ) ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , CommandData > : : iterator cit = vkData . commands . find ( name ) ;
assert ( cit ! = vkData . commands . end ( ) ) ;
2016-02-22 14:27:08 +00:00
cit - > second . protect = protect ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
else if ( value = = " type " )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : string name = strip ( child - > Attribute ( " name " ) , " Vk " ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , EnumData > : : iterator eit = vkData . enums . find ( name ) ;
if ( eit ! = vkData . enums . end ( ) )
2016-02-22 14:27:08 +00:00
{
eit - > second . protect = protect ;
}
else
{
2016-03-16 10:20:41 +00:00
std : : map < std : : string , FlagData > : : iterator fit = vkData . flags . find ( name ) ;
if ( fit ! = vkData . flags . end ( ) )
2016-02-22 14:27:08 +00:00
{
fit - > second . protect = protect ;
// if the enum of this flags is auto-generated, protect it as well
std : : string enumName = generateEnumNameForFlags ( name ) ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , EnumData > : : iterator eit = vkData . enums . find ( enumName ) ;
assert ( eit ! = vkData . enums . end ( ) ) ;
2016-02-22 14:27:08 +00:00
if ( eit - > second . members . empty ( ) )
{
eit - > second . protect = protect ;
}
}
else
{
2016-03-16 10:20:41 +00:00
std : : map < std : : string , ScalarData > : : iterator scit = vkData . scalars . find ( name ) ;
if ( scit ! = vkData . scalars . end ( ) )
2016-02-22 14:27:08 +00:00
{
scit - > second . protect = protect ;
}
else
{
2016-03-16 10:20:41 +00:00
std : : map < std : : string , StructData > : : iterator stit = vkData . structs . find ( name ) ;
assert ( stit ! = vkData . structs . end ( ) & & stit - > second . protect . empty ( ) ) ;
2016-02-22 14:27:08 +00:00
stit - > second . protect = protect ;
}
}
}
2016-02-16 14:07:55 +00:00
}
2016-02-18 08:45:18 +00:00
else if ( value = = " enum " )
{
// TODO process enums which don't extend existing enums
if ( child - > Attribute ( " extends " ) )
{
2016-03-16 10:20:41 +00:00
assert ( vkData . enums . find ( getEnumName ( child - > Attribute ( " extends " ) ) ) ! = vkData . enums . end ( ) ) ;
2016-02-29 10:18:19 +00:00
assert ( ! ! child - > Attribute ( " offset " ) ^ ! ! child - > Attribute ( " value " ) ) ; // either offset or value has to be defined; no both of them!
2016-03-16 10:20:41 +00:00
vkData . enums [ getEnumName ( child - > Attribute ( " extends " ) ) ] . addEnum ( child - > Attribute ( " name " ) , child - > Attribute ( " offset " ) ? tag : " " ) ;
2016-02-18 08:45:18 +00:00
}
}
2016-02-16 14:07:55 +00:00
else
{
2016-02-18 08:45:18 +00:00
assert ( " unknown attribute, check me " ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void readExtensions ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
do
{
assert ( strcmp ( child - > Value ( ) , " extension " ) = = 0 ) ;
2016-03-16 10:20:41 +00:00
readExtensionsExtension ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void readExtensionsExtension ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
2016-02-25 13:25:23 +00:00
std : : string tag = extractTag ( element - > Attribute ( " name " ) ) ;
2016-03-16 10:20:41 +00:00
assert ( vkData . tags . find ( tag ) ! = vkData . tags . end ( ) ) ;
2016-02-18 08:45:18 +00:00
// don't parse disabled extensions
if ( strcmp ( element - > Attribute ( " supported " ) , " disabled " ) = = 0 )
{
return ;
}
2016-02-22 14:27:08 +00:00
std : : string protect ;
if ( element - > Attribute ( " protect " ) )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
protect = element - > Attribute ( " protect " ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " require " ) = = 0 ) & & ! child - > NextSiblingElement ( ) ) ;
2016-03-16 10:20:41 +00:00
readExtensionRequire ( child , vkData , protect , tag ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeBasetype ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) ) ;
std : : string type = typeElement - > GetText ( ) ;
assert ( ( type = = " uint32_t " ) | | ( type = = " uint64_t " ) ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
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 " ) ;
}
}
2016-03-16 10:20:41 +00:00
void readTypeBitmask ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) & & ( strcmp ( typeElement - > GetText ( ) , " VkFlags " ) = = 0 ) ) ;
std : : string type = typeElement - > GetText ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) & & nameElement - > GetText ( ) ) ;
std : : string name = strip ( nameElement - > GetText ( ) , " Vk " ) ;
assert ( ! nameElement - > NextSiblingElement ( ) ) ;
2016-02-19 11:56:38 +00:00
std : : string requires ;
if ( element - > Attribute ( " requires " ) )
2016-02-16 14:07:55 +00:00
{
2016-02-19 11:56:38 +00:00
requires = strip ( element - > Attribute ( " requires " ) , " Vk " ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-19 11:56:38 +00:00
else {
// Generate FlagBits name
2016-02-22 14:27:08 +00:00
requires = generateEnumNameForFlags ( name ) ;
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : ENUM , requires ) ) ;
std : : map < std : : string , EnumData > : : iterator it = vkData . enums . insert ( std : : make_pair ( requires , EnumData ( ) ) ) . first ;
2016-02-19 11:56:38 +00:00
it - > second . bitmask = true ;
2016-03-16 10:20:41 +00:00
vkData . vkTypes . insert ( requires ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-19 11:56:38 +00:00
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : FLAGS , name ) ) ;
vkData . dependencies . back ( ) . dependencies . insert ( requires ) ;
vkData . flags . insert ( std : : make_pair ( name , FlagData ( ) ) ) ;
2016-02-19 11:56:38 +00:00
2016-03-16 10:20:41 +00:00
assert ( vkData . vkTypes . find ( name ) = = vkData . vkTypes . end ( ) ) ;
vkData . vkTypes . insert ( name ) ;
2016-02-16 14:07:55 +00:00
}
2016-03-16 10:20:41 +00:00
void readTypeDefine ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-25 15:48:46 +00:00
if ( child & & ( strcmp ( child - > GetText ( ) , " VK_API_VERSION " ) = = 0 ) )
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
vkData . version = element - > LastChild ( ) - > ToText ( ) - > Value ( ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-25 15:48:46 +00:00
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 ) ;
2016-03-16 10:20:41 +00:00
vkData . typesafeCheck = text . substr ( start , end - start ) ;
2016-02-25 15:48:46 +00:00
}
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeFuncpointer ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) & & child - > GetText ( ) ) ;
dependencies . push_back ( DependencyData ( DependencyData : : Category : : FUNC_POINTER , child - > GetText ( ) ) ) ;
}
2016-03-16 10:20:41 +00:00
void readTypeHandle ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) ) ;
# if !defined(NDEBUG)
std : : string type = typeElement - > GetText ( ) ;
assert ( type . find ( " VK_DEFINE " ) = = 0 ) ;
# endif
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) & & nameElement - > GetText ( ) ) ;
std : : string name = strip ( nameElement - > GetText ( ) , " Vk " ) ;
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : HANDLE , name ) ) ;
2016-02-22 14:27:08 +00:00
2016-03-16 10:20:41 +00:00
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
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeStructMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies )
2016-02-16 14:07:55 +00:00
{
members . push_back ( MemberData ( ) ) ;
MemberData & member = members . back ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
assert ( ( value = = " const " ) | | ( value = = " struct " ) ) ;
member . type = value + " " ;
2016-02-16 14:07:55 +00:00
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
member . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( ( child - > ToElement ( ) & & strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
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 ( ) ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ( ) ) ;
}
}
}
}
2016-03-16 10:20:41 +00:00
void readTypeStruct ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
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 ;
}
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : STRUCT , name ) ) ;
2016-02-16 14:07:55 +00:00
2016-03-16 10:20:41 +00:00
assert ( vkData . structs . find ( name ) = = vkData . structs . end ( ) ) ;
std : : map < std : : string , StructData > : : iterator it = vkData . structs . insert ( std : : make_pair ( name , StructData ( ) ) ) . first ;
2016-02-16 14:07:55 +00:00
it - > second . returnedOnly = ! ! element - > Attribute ( " returnedonly " ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( child - > Value ( ) ) ;
std : : string value = child - > Value ( ) ;
if ( value = = " member " )
{
2016-03-16 10:20:41 +00:00
readTypeStructMember ( child , it - > second . members , vkData . dependencies . back ( ) . dependencies ) ;
2016-02-16 14:07:55 +00:00
}
else
{
assert ( value = = " validity " ) ;
}
} while ( child = child - > NextSiblingElement ( ) ) ;
2016-03-16 10:20:41 +00:00
assert ( vkData . vkTypes . find ( name ) = = vkData . vkTypes . end ( ) ) ;
vkData . vkTypes . insert ( name ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeUnionMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies )
2016-02-16 14:07:55 +00:00
{
members . push_back ( MemberData ( ) ) ;
MemberData & member = members . back ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
assert ( ( strcmp ( child - > Value ( ) , " const " ) = = 0 ) | | ( strcmp ( child - > Value ( ) , " struct " ) = = 0 ) ) ;
member . type = std : : string ( child - > Value ( ) ) + " " ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
member . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
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 )
{
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
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 ( ) ) ;
}
}
}
}
2016-03-16 10:20:41 +00:00
void readTypeUnion ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
std : : string name = strip ( element - > Attribute ( " name " ) , " Vk " ) ;
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : UNION , name ) ) ;
2016-02-16 14:07:55 +00:00
2016-03-16 10:20:41 +00:00
assert ( vkData . structs . find ( name ) = = vkData . structs . end ( ) ) ;
std : : map < std : : string , StructData > : : iterator it = vkData . structs . insert ( std : : make_pair ( name , StructData ( ) ) ) . first ;
2016-02-16 14:07:55 +00:00
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( strcmp ( child - > Value ( ) , " member " ) = = 0 ) ;
2016-03-16 10:20:41 +00:00
readTypeUnionMember ( child , it - > second . members , vkData . dependencies . back ( ) . dependencies ) ;
2016-02-16 14:07:55 +00:00
} while ( child = child - > NextSiblingElement ( ) ) ;
2016-03-16 10:20:41 +00:00
assert ( vkData . vkTypes . find ( name ) = = vkData . vkTypes . end ( ) ) ;
vkData . vkTypes . insert ( name ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-25 13:25:23 +00:00
void readTags ( tinyxml2 : : XMLElement * element , std : : set < std : : string > & 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 ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void readTypes ( tinyxml2 : : XMLElement * element , VkData & vkData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
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 " )
{
2016-03-16 10:20:41 +00:00
readTypeBasetype ( child , vkData . dependencies ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " bitmask " )
{
2016-03-16 10:20:41 +00:00
readTypeBitmask ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " define " )
{
2016-03-16 10:20:41 +00:00
readTypeDefine ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " funcpointer " )
{
2016-03-16 10:20:41 +00:00
readTypeFuncpointer ( child , vkData . dependencies ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " handle " )
{
2016-03-16 10:20:41 +00:00
readTypeHandle ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " struct " )
{
2016-03-16 10:20:41 +00:00
readTypeStruct ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " union " )
{
2016-03-16 10:20:41 +00:00
readTypeUnion ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else
{
assert ( ( category = = " enum " ) | | ( category = = " include " ) ) ;
}
}
else
{
assert ( child - > Attribute ( " requires " ) & & child - > Attribute ( " name " ) ) ;
2016-03-16 10:20:41 +00:00
vkData . dependencies . push_back ( DependencyData ( DependencyData : : Category : : REQUIRED , child - > Attribute ( " name " ) ) ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-03-16 10:20:41 +00:00
void sortDependencies ( std : : list < DependencyData > & dependencies )
2016-02-16 14:07:55 +00:00
{
std : : set < std : : string > listedTypes = { " VkFlags " } ;
2016-03-16 10:20:41 +00:00
std : : list < DependencyData > sortedDependencies ;
2016-02-16 14:07:55 +00:00
while ( ! dependencies . empty ( ) )
{
# if !defined(NDEBUG)
bool ok = false ;
# endif
for ( std : : list < DependencyData > : : iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) ; + + it )
{
if ( noDependencies ( it - > dependencies , listedTypes ) )
{
2016-02-22 14:27:08 +00:00
sortedDependencies . push_back ( * it ) ;
2016-02-16 14:07:55 +00:00
listedTypes . insert ( it - > name ) ;
dependencies . erase ( it ) ;
# if !defined(NDEBUG)
ok = true ;
# endif
break ;
}
}
assert ( ok ) ;
}
2016-03-16 10:20:41 +00:00
dependencies . swap ( sortedDependencies ) ;
2016-02-16 14:07:55 +00:00
}
std : : string reduceName ( std : : string const & name )
{
2016-02-22 14:27:08 +00:00
assert ( 1 < name . length ( ) ) ;
if ( ( name [ 0 ] = = ' p ' ) & & ( isupper ( name [ 1 ] ) | | name [ 1 ] = = ' p ' ) )
{
std : : string reducedName = strip ( name , " p " ) ;
reducedName [ 0 ] = tolower ( reducedName [ 0 ] ) ;
return reducedName ;
}
return name ;
2016-02-16 14:07:55 +00:00
}
2016-02-25 13:25:23 +00:00
std : : string strip ( std : : string const & value , std : : string const & prefix , std : : string const & postfix )
2016-02-16 14:07:55 +00:00
{
2016-02-25 13:25:23 +00:00
std : : string strippedValue = value ;
if ( strippedValue . find ( prefix ) = = 0 )
{
strippedValue . erase ( 0 , prefix . length ( ) ) ;
}
if ( ! postfix . empty ( ) )
2016-02-16 14:07:55 +00:00
{
2016-03-14 10:52:28 +00:00
size_t pos = strippedValue . rfind ( postfix ) ;
2016-02-25 13:25:23 +00:00
assert ( pos ! = std : : string : : npos ) ;
strippedValue . erase ( pos ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-25 13:25:23 +00:00
return strippedValue ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
std : : string stripCommand ( std : : string const & value )
{
std : : string stripped = strip ( value , " vk " ) ;
assert ( isupper ( stripped [ 0 ] ) ) ;
stripped [ 0 ] = tolower ( stripped [ 0 ] ) ;
return stripped ;
}
2016-02-16 14:07:55 +00:00
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 < name . length ( ) ; i + + )
{
if ( isupper ( name [ i ] ) & & ( ( i = = 0 ) | | islower ( name [ i - 1 ] ) | | isdigit ( name [ i - 1 ] ) ) )
{
convertedName . push_back ( ' _ ' ) ;
}
convertedName . push_back ( toupper ( name [ i ] ) ) ;
}
return convertedName ;
}
2016-02-29 09:07:34 +00:00
void writeCall ( std : : ofstream & ofs , std : : string const & name , size_t templateIndex , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters , size_t returnIndex , bool firstCall )
2016-02-22 14:27:08 +00:00
{
std : : map < size_t , size_t > countIndices ;
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
{
countIndices . insert ( std : : make_pair ( it - > second , it - > first ) ) ;
}
2016-02-29 10:18:19 +00:00
if ( ( vectorParameters . size ( ) = = 1 )
& & ( ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " dataSize/4 " ) | | ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " latexmath:[$dataSize \\ over 4$] " ) ) )
2016-02-22 14:27:08 +00:00
{
assert ( commandData . arguments [ 3 ] . name = = " dataSize " ) ;
countIndices . insert ( std : : make_pair ( 3 , vectorParameters . begin ( ) - > first ) ) ;
}
assert ( islower ( name [ 0 ] ) ) ;
ofs < < " vk " < < static_cast < char > ( 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 < size_t , size_t > : : const_iterator it = countIndices . find ( i ) ;
if ( it ! = countIndices . end ( ) )
{
2016-02-29 09:07:34 +00:00
if ( ( returnIndex = = it - > second ) & & commandData . twoStep )
2016-02-22 14:27:08 +00:00
{
ofs < < " & " < < reduceName ( commandData . arguments [ it - > first ] . name ) ;
}
else
{
2016-02-24 10:31:50 +00:00
ofs < < " static_cast< " < < commandData . arguments [ it - > first ] . pureType < < " >( " < < reduceName ( commandData . arguments [ it - > second ] . name ) < < " .size() " ;
if ( templateIndex = = it - > second )
2016-02-22 14:27:08 +00:00
{
2016-02-24 10:31:50 +00:00
ofs < < " * sizeof( T ) " ;
2016-02-22 14:27:08 +00:00
}
2016-02-24 10:31:50 +00:00
ofs < < " ) " ;
2016-02-22 14:27:08 +00:00
}
}
else
{
it = vectorParameters . find ( i ) ;
if ( it ! = vectorParameters . end ( ) )
{
assert ( commandData . arguments [ it - > first ] . type . back ( ) = = ' * ' ) ;
2016-02-29 09:07:34 +00:00
if ( ( returnIndex = = it - > first ) & & commandData . twoStep & & firstCall )
2016-02-22 14:27:08 +00:00
{
2016-02-29 09:07:34 +00:00
ofs < < " nullptr " ;
}
else
{
std : : set < std : : string > : : const_iterator vkit = vkTypes . find ( commandData . arguments [ it - > first ] . pureType ) ;
if ( ( vkit ! = vkTypes . end ( ) ) | | ( it - > first = = templateIndex ) )
2016-02-22 14:27:08 +00:00
{
2016-02-29 09:07:34 +00:00
ofs < < " reinterpret_cast< " ;
if ( commandData . arguments [ it - > first ] . type . find ( " const " ) ! = std : : string : : npos )
{
ofs < < " const " ;
}
if ( vkit ! = vkTypes . end ( ) )
{
ofs < < " Vk " ;
}
ofs < < commandData . arguments [ it - > first ] . pureType < < " *>( " < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .data() ) " ;
2016-02-22 14:27:08 +00:00
}
2016-02-29 09:07:34 +00:00
else if ( commandData . arguments [ it - > first ] . pureType = = " char " )
2016-02-22 14:27:08 +00:00
{
2016-02-29 09:07:34 +00:00
ofs < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .c_str() " ;
}
else
{
ofs < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .data() " ;
2016-02-22 14:27:08 +00:00
}
}
}
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 )
{
2016-03-14 16:51:10 +00:00
ofs < < " reinterpret_cast<const Vk " < < commandData . arguments [ i ] . pureType < < " *>( " ;
if ( commandData . arguments [ i ] . optional )
{
ofs < < " static_cast<const " < < commandData . arguments [ i ] . pureType < < " *>( " ;
}
else
{
ofs < < " & " ;
}
ofs < < reduceName ( commandData . arguments [ i ] . name )
< < ( commandData . arguments [ i ] . optional ? " )) " : " ) " ) ;
2016-02-22 14:27:08 +00:00
}
else
{
ofs < < " reinterpret_cast<Vk " < < commandData . arguments [ i ] . pureType < < " *>( & " < < reduceName ( commandData . arguments [ i ] . name ) < < " ) " ;
}
}
else
{
ofs < < " static_cast<Vk " < < commandData . arguments [ i ] . pureType < < " >( " < < 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 ) < < " .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 < std : : string > const & successCodes )
{
if ( successCodes . size ( ) = = 1 )
{
2016-02-25 13:25:23 +00:00
assert ( successCodes . front ( ) = = " eSuccess " ) ;
ofs < < indentation < < " if ( result != Result::eSuccess ) " < < std : : endl ;
2016-02-22 14:27:08 +00:00
}
else
{
assert ( successCodes . size ( ) = = 2 ) ;
2016-02-25 13:25:23 +00:00
ofs < < indentation < < " if ( ( result != Result:: " < < successCodes [ 0 ] < < " ) && ( result != Result:: " < < successCodes [ 1 ] < < " ) ) " < < std : : endl ;
2016-02-22 14:27:08 +00:00
}
ofs < < indentation < < " { " < < std : : endl
2016-03-07 14:08:31 +00:00
< < indentation < < " throw std::system_error( result, \" vk:: " ;
2016-02-22 14:27:08 +00:00
if ( ! className . empty ( ) )
{
ofs < < className < < " :: " ;
}
ofs < < functionName < < " \" ); " < < std : : endl
< < indentation < < " } " < < std : : endl ;
}
2016-02-29 09:07:34 +00:00
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 < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters )
{
ofs < < indentation < < " { " < < std : : endl ;
// add a static_assert if a type is templated and its size needs to be some multiple of the original size
if ( ( templateIndex ! = ~ 0 ) & & ( commandData . arguments [ templateIndex ] . pureType ! = " void " ) )
{
ofs < < indentation < < " static_assert( sizeof( T ) % sizeof( " < < commandData . arguments [ templateIndex ] . pureType < < " ) == 0, \" wrong size of template type T \" ); " < < std : : endl ;
}
// add some error checks if multiple vectors need to have the same size
if ( 1 < vectorParameters . size ( ) )
{
for ( std : : map < size_t , size_t > : : const_iterator it0 = vectorParameters . begin ( ) ; it0 ! = vectorParameters . end ( ) ; + + it0 )
{
if ( it0 - > first ! = returnIndex )
{
for ( std : : map < size_t , size_t > : : const_iterator it1 = std : : next ( it0 ) ; it1 ! = vectorParameters . end ( ) ; + + it1 )
{
if ( ( it1 - > first ! = returnIndex ) & & ( it0 - > second = = it1 - > second ) )
{
ofs < < indentation < < " if ( " < < reduceName ( commandData . arguments [ it0 - > first ] . name ) < < " .size() != " < < reduceName ( commandData . arguments [ it1 - > first ] . name ) < < " .size() ) " < < std : : endl
< < indentation < < " { " < < std : : endl
< < indentation < < " throw std::logic_error( \" vk:: " < < className < < " :: " < < functionName < < " : " < < reduceName ( commandData . arguments [ it0 - > first ] . name ) < < " .size() != " < < reduceName ( commandData . arguments [ it1 - > first ] . name ) < < " .size() \" ); " < < std : : endl
< < indentation < < " } " < < std : : endl ;
}
}
}
}
}
// write the local variable to hold a returned value
if ( ( returnIndex ! = ~ 0 ) & & ( ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) < 2 ) ) | | ( commandData . returnType = = " void " ) ) )
{
ofs < < indentation < < " " < < returnType < < " " < < reduceName ( commandData . arguments [ returnIndex ] . name ) ;
std : : map < size_t , size_t > : : 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 , " . " ) ;
size + = " () " ;
}
else
{
for ( std : : map < size_t , size_t > : : const_iterator sit = vectorParameters . begin ( ) ; sit ! = vectorParameters . end ( ) ; + + sit )
{
if ( ( sit - > first ! = returnIndex ) & & ( sit - > second = = it - > second ) )
{
size = reduceName ( commandData . arguments [ sit - > first ] . name ) + " .size() " ;
break ;
}
}
}
assert ( ! size . empty ( ) ) ;
ofs < < " ( " < < size < < " ) " ;
}
ofs < < " ; " < < std : : endl ;
}
// local count variable to hold the size of the vector to fill
if ( commandData . twoStep )
{
assert ( returnIndex ! = ~ 0 ) ;
std : : map < size_t , size_t > : : 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 < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " Result result = static_cast<Result>( " ;
}
else if ( commandData . returnType ! = " void " )
{
ofs < < " return " ;
}
writeCall ( ofs , dependencyData . name , templateIndex , commandData , vkTypes , vectorParameters , returnIndex , true ) ;
if ( commandData . returnType = = " Result " )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl ;
// add an exception check
if ( ( commandData . returnType = = " Result " ) | | ! commandData . successCodes . empty ( ) )
{
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
}
if ( commandData . twoStep )
{
std : : map < size_t , size_t > : : const_iterator returnit = vectorParameters . find ( returnIndex ) ;
// resize the vector to hold the data according to the result from the first call
ofs < < indentation < < " " < < reduceName ( commandData . arguments [ returnit - > first ] . name ) < < " .resize( " < < reduceName ( commandData . arguments [ returnit - > second ] . name ) < < " ); " < < std : : endl ;
// write the function call a second time
ofs < < indentation < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " result = static_cast<Result>( " ;
}
writeCall ( ofs , dependencyData . name , templateIndex , commandData , vkTypes , vectorParameters , returnIndex , false ) ;
if ( commandData . returnType = = " Result " )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl ;
// add a second exception check
if ( ( commandData . returnType = = " Result " ) | | ! commandData . successCodes . empty ( ) )
{
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
}
}
// return the returned value
if ( ( returnIndex ! = ~ 0 ) & & ( ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) < 2 ) ) | | ( commandData . returnType = = " void " ) ) )
{
ofs < < indentation < < " return " ;
if ( vectorParameters . find ( returnIndex ) ! = vectorParameters . end ( ) )
{
ofs < < " std::move( " ;
ofs < < reduceName ( commandData . arguments [ returnIndex ] . name ) ;
ofs < < " ) " ;
}
else
{
ofs < < reduceName ( commandData . arguments [ returnIndex ] . name ) ;
}
ofs < < " ; " < < std : : endl ;
}
else if ( returnType = = " Result " )
{
ofs < < indentation < < " return result; " < < std : : endl ;
}
ofs < < indentation < < " } " < < std : : endl ;
}
2016-02-24 10:31:50 +00:00
void writeFunctionHeader ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & returnType , std : : string const & name , CommandData const & commandData , size_t returnIndex , size_t templateIndex , std : : map < size_t , size_t > const & vectorParameters )
2016-02-22 14:27:08 +00:00
{
std : : set < size_t > skippedArguments ;
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
{
skippedArguments . insert ( it - > second ) ;
}
2016-02-29 10:18:19 +00:00
if ( ( vectorParameters . size ( ) = = 1 )
& & ( ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " dataSize/4 " ) | | ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " latexmath:[$dataSize \\ over 4$] " ) ) )
2016-02-22 14:27:08 +00:00
{
assert ( commandData . arguments [ 3 ] . name = = " dataSize " ) ;
skippedArguments . insert ( 3 ) ;
}
2016-02-29 09:07:34 +00:00
if ( ( returnIndex ! = ~ 0 ) & & ( ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) < 2 ) ) | | ( commandData . returnType = = " void " ) ) )
2016-02-22 14:27:08 +00:00
{
skippedArguments . insert ( returnIndex ) ;
}
ofs < < indentation ;
2016-02-24 10:31:50 +00:00
if ( ( templateIndex ! = ~ 0 ) & & ( ( templateIndex ! = returnIndex ) | | ( returnType = = " Result " ) ) )
{
ofs < < " template <typename T> " < < std : : endl
< < indentation ;
}
else if ( ! commandData . handleCommand )
2016-02-22 14:27:08 +00:00
{
ofs < < " inline " ;
}
ofs < < returnType < < " " < < name < < " ( " ;
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 < < " , " ;
}
if ( vectorParameters . find ( i ) = = vectorParameters . end ( ) )
{
size_t pos = commandData . arguments [ i ] . type . find ( ' * ' ) ;
if ( pos = = std : : string : : npos )
{
ofs < < commandData . arguments [ i ] . type < < " " < < commandData . arguments [ i ] . name ;
if ( ! commandData . arguments [ i ] . arraySize . empty ( ) )
{
ofs < < " [ " < < commandData . arguments [ i ] . arraySize < < " ] " ;
}
}
else
{
std : : string type = commandData . arguments [ i ] . type ;
if ( type . find ( " char " ) ! = std : : string : : npos )
{
type = " std::string const& " ;
}
else
{
assert ( type [ pos ] = = ' * ' ) ;
2016-03-14 16:51:10 +00:00
if ( commandData . arguments [ i ] . optional )
{
type [ pos ] = ' ' ;
type = " vk::Optional< " + trimEnd ( type ) + " > const & " ;
}
else
{
type [ pos ] = ' & ' ;
}
2016-02-22 14:27:08 +00:00
}
ofs < < type < < " " < < reduceName ( commandData . arguments [ i ] . name ) ;
}
}
else
{
2016-02-24 10:31:50 +00:00
if ( templateIndex = = i )
{
ofs < < " std::vector<T> " ;
}
else if ( commandData . arguments [ i ] . pureType = = " char " )
2016-02-22 14:27:08 +00:00
{
ofs < < " std::string " ;
}
else if ( commandData . arguments [ i ] . pureType = = " void " )
{
ofs < < " std::vector<uint8_t> " ;
}
else
{
ofs < < " std::vector< " < < commandData . arguments [ i ] . pureType < < " > " ;
}
if ( commandData . arguments [ i ] . type . find ( " const " ) ! = std : : string : : npos )
{
ofs < < " const " ;
}
ofs < < " & " < < reduceName ( commandData . arguments [ i ] . name ) ;
}
argEncountered = true ;
}
}
ofs < < " ) " ;
if ( commandData . handleCommand )
{
ofs < < " const " ;
}
ofs < < std : : endl ;
}
2016-02-16 14:07:55 +00:00
void writeMemberData ( std : : ofstream & ofs , MemberData const & memberData , std : : set < std : : string > const & vkTypes )
{
if ( vkTypes . find ( memberData . pureType ) ! = vkTypes . end ( ) )
{
if ( memberData . type . back ( ) = = ' * ' )
{
ofs < < " reinterpret_cast< " ;
if ( memberData . type . find ( " const " ) = = 0 )
{
ofs < < " const " ;
}
2016-02-22 14:27:08 +00:00
ofs < < " Vk " < < memberData . pureType < < ' * ' ;
2016-02-16 14:07:55 +00:00
}
else
{
ofs < < " static_cast<Vk " < < memberData . pureType ;
}
ofs < < " >( " < < memberData . name < < " ) " ;
}
else
{
ofs < < memberData . name ;
}
}
void writeStructConstructor ( std : : ofstream & ofs , std : : string const & name , std : : string const & memberName , StructData const & structData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , std : : string > const & defaultValues )
{
// check if there is a member element with no default available
bool noDefault = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) & & ! noDefault ; i + + )
{
std : : map < std : : string , std : : string > : : const_iterator it = defaultValues . find ( structData . members [ i ] . pureType ) ;
assert ( it ! = defaultValues . end ( ) ) ;
noDefault = it - > second . empty ( ) ;
}
if ( ! noDefault )
{
// if there's a default for all memeber, provide a default constructor
ofs < < " " < < name < < " () " < < std : : endl
< < " : " < < name < < " ( " ;
bool listedArgument = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( listedArgument )
{
ofs < < " , " ;
}
if ( ( structData . members [ i ] . name ! = " pNext " ) & & ( structData . members [ i ] . name ! = " sType " ) )
{
if ( structData . members [ i ] . type . back ( ) = = ' * ' )
{
ofs < < " nullptr " ;
}
else
{
std : : map < std : : string , std : : string > : : const_iterator it = defaultValues . find ( structData . members [ i ] . pureType ) ;
assert ( ( it ! = defaultValues . end ( ) ) & & ! it - > second . empty ( ) ) ;
if ( structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < it - > second ;
}
else
{
ofs < < " { " < < it - > second < < " } " ;
}
}
listedArgument = true ;
}
}
ofs < < " ) " < < std : : endl
< < " {} " < < std : : endl
< < std : : endl ;
}
// the constructor with all the elements as arguments
ofs < < " " < < name < < " ( " ;
std : : vector < std : : string > noDefaultArgs , defaultArgs ;
bool listedArgument = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( listedArgument )
{
ofs < < " , " ;
}
if ( ( structData . members [ i ] . name ! = " pNext " ) & & ( structData . members [ i ] . name ! = " sType " ) )
{
if ( structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < structData . members [ i ] . type + " " + structData . members [ i ] . name ;
}
else
{
ofs < < " std::array< " + structData . members [ i ] . type + " , " + structData . members [ i ] . arraySize + " > const& " + structData . members [ i ] . name ;
}
listedArgument = true ;
}
}
ofs < < " ) " < < std : : endl ;
// now the body of the constructor, copying over data from argument list into wrapped struct
ofs < < " { " < < std : : endl ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( ! structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < " memcpy( & " < < memberName < < " . " < < structData . members [ i ] . name < < " , " < < structData . members [ i ] . name < < " .data(), " < < structData . members [ i ] . arraySize < < " * sizeof( " < < structData . members [ i ] . type < < " ) ) " ;
}
else
{
ofs < < " " < < memberName < < " . " < < structData . members [ i ] . name < < " = " ;
if ( structData . members [ i ] . name = = " pNext " )
{
ofs < < " nullptr " ;
}
else if ( structData . members [ i ] . name = = " sType " )
{
2016-02-22 14:27:08 +00:00
// HACK: we need to read <enum extends="VkStructureType"> here for the correct name. In this case the 'generic' rule to create the enums doesn't work
2016-02-16 14:07:55 +00:00
if ( name = = " DebugReportCallbackCreateInfoEXT " )
{
ofs < < " VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT " ;
}
else
{
ofs < < " VK_STRUCTURE_TYPE " < < toUpperCase ( name ) ;
}
}
else
{
writeMemberData ( ofs , structData . members [ i ] , vkTypes ) ;
}
}
ofs < < " ; " < < std : : endl ;
}
ofs < < " } " < < std : : endl
< < std : : endl ;
2016-02-25 15:48:46 +00:00
// now write the copy constructor
ofs < < " " < < name < < " (Vk " < < name < < " const & rhs) " < < std : : endl
< < " : " < < memberName < < " (rhs) " < < std : : endl
< < " { " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
// now write the assignment operator
ofs < < " " < < name < < " & operator=(Vk " < < name < < " const & rhs) " < < std : : endl
< < " { " < < std : : endl
< < " " < < memberName < < " = rhs; " < < std : : endl
< < " return *this; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-26 11:01:11 +00:00
void writeStructGetter ( std : : ofstream & ofs , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes , bool constVersion )
2016-02-16 14:07:55 +00:00
{
ofs < < " " ;
if ( memberData . type . back ( ) = = ' * ' )
{
2016-02-26 11:01:11 +00:00
if ( constVersion & & ( memberData . type . find ( " const " ) ! = 0 ) )
2016-02-16 14:07:55 +00:00
{
ofs < < " const " ;
}
ofs < < memberData . type ;
}
else
{
2016-02-26 11:01:11 +00:00
if ( constVersion )
{
ofs < < " const " ;
}
ofs < < memberData . type < < ( memberData . arraySize . empty ( ) ? ' & ' : ' * ' ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-26 11:01:11 +00:00
ofs < < " " < < memberData . name < < " () " ;
if ( constVersion )
{
ofs < < " const " ;
}
ofs < < std : : endl
2016-02-16 14:07:55 +00:00
< < " { " < < std : : endl
< < " return " ;
if ( ! memberData . arraySize . empty ( ) )
{
2016-02-26 11:01:11 +00:00
ofs < < " reinterpret_cast< " ;
if ( constVersion )
{
ofs < < " const " ;
}
ofs < < memberData . type < < " *>( " < < memberName < < " . " < < memberData . name < < " ) " ;
2016-02-16 14:07:55 +00:00
}
else if ( memberData . type . back ( ) = = ' * ' )
{
2016-02-26 11:01:11 +00:00
ofs < < " reinterpret_cast< " ;
if ( constVersion & & ( memberData . type . find ( " const " ) ! = 0 ) )
{
ofs < < " const " ;
}
ofs < < memberData . type < < " >( " < < memberName < < " . " < < memberData . name < < " ) " ;
2016-02-16 14:07:55 +00:00
}
else if ( vkTypes . find ( memberData . pureType ) ! = vkTypes . end ( ) )
{
2016-02-26 11:01:11 +00:00
ofs < < " reinterpret_cast< " ;
if ( constVersion )
{
ofs < < " const " ;
}
ofs < < memberData . pureType < < " &>( " < < memberName < < " . " < < memberData . name < < " ) " ;
2016-02-16 14:07:55 +00:00
}
else
{
ofs < < memberName < < " . " < < memberData . name ;
}
ofs < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
}
void writeStructSetter ( std : : ofstream & ofs , std : : string const & name , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes )
{
ofs < < " " < < name < < " & " < < memberData . name < < " ( " ;
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( & " < < memberName < < " . " < < memberData . name < < " , " < < memberData . name < < " .data(), " < < memberData . arraySize < < " * sizeof( " < < memberData . type < < " ) ) " ;
}
else
{
ofs < < " " < < memberName < < " . " < < memberData . name < < " = " ;
writeMemberData ( ofs , memberData , vkTypes ) ;
}
ofs < < " ; " < < std : : endl
< < " return *this; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
}
void writeTypeCommand ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
{
2016-02-22 14:27:08 +00:00
if ( ! commandData . handleCommand )
{
2016-03-01 11:14:18 +00:00
writeTypeCommandStandard ( ofs , " " , dependencyData . name , dependencyData , commandData , vkTypes ) ;
ofs < < std : : endl
< < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl ;
writeTypeCommandEnhanced ( ofs , " " , " " , dependencyData . name , dependencyData , commandData , vkTypes ) ;
ofs < < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl
< < std : : endl ;
2016-02-22 14:27:08 +00:00
}
2016-02-16 14:07:55 +00:00
}
2016-03-01 11:14:18 +00:00
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , commandData . protect ) ;
std : : map < size_t , size_t > vectorParameters = getVectorParameters ( commandData ) ;
size_t returnIndex = findReturnIndex ( commandData , vectorParameters ) ;
2016-02-24 10:31:50 +00:00
size_t templateIndex = findTemplateIndex ( commandData , vectorParameters ) ;
2016-02-22 14:27:08 +00:00
std : : map < size_t , size_t > : : const_iterator returnVector = vectorParameters . find ( returnIndex ) ;
std : : string returnType = determineReturnType ( commandData , returnIndex , returnVector ! = vectorParameters . end ( ) ) ;
2016-02-24 10:31:50 +00:00
writeFunctionHeader ( ofs , indentation , returnType , functionName , commandData , returnIndex , templateIndex , vectorParameters ) ;
2016-02-29 09:07:34 +00:00
writeFunctionBody ( ofs , indentation , className , functionName , returnType , templateIndex , dependencyData , commandData , vkTypes , returnIndex , vectorParameters ) ;
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , commandData . protect ) ;
2016-02-16 14:07:55 +00:00
}
2016-03-01 11:14:18 +00:00
void writeTypeCommandStandard ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
2016-02-16 14:07:55 +00:00
{
2016-03-01 11:14:18 +00:00
enterProtect ( ofs , commandData . protect ) ;
ofs < < indentation ;
if ( ! commandData . handleCommand )
2016-02-16 14:07:55 +00:00
{
2016-03-01 11:14:18 +00:00
ofs < < " inline " ;
}
ofs < < commandData . returnType < < " " < < functionName < < " ( " ;
bool argEncountered = false ;
for ( size_t i = commandData . handleCommand ? 1 : 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( argEncountered )
2016-02-16 14:07:55 +00:00
{
ofs < < " , " ;
}
ofs < < commandData . arguments [ i ] . type < < " " < < commandData . arguments [ i ] . name ;
if ( ! commandData . arguments [ i ] . arraySize . empty ( ) )
{
ofs < < " [ " < < commandData . arguments [ i ] . arraySize < < " ] " ;
}
2016-03-01 11:14:18 +00:00
argEncountered = true ;
2016-02-16 14:07:55 +00:00
}
2016-03-02 10:56:09 +00:00
ofs < < " ) " ;
if ( commandData . handleCommand )
{
ofs < < " const " ;
}
ofs < < std : : endl
2016-03-01 11:14:18 +00:00
< < indentation < < " { " < < std : : endl
< < indentation < < " " ;
2016-02-16 14:07:55 +00:00
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 < < " ( " ;
2016-03-01 11:14:18 +00:00
if ( commandData . handleCommand )
{
ofs < < " m_ " < < commandData . arguments [ 0 ] . name ;
}
argEncountered = false ;
for ( size_t i = commandData . handleCommand ? 1 : 0 ; i < commandData . arguments . size ( ) ; i + + )
2016-02-16 14:07:55 +00:00
{
if ( 0 < i )
{
ofs < < " , " ;
}
writeMemberData ( ofs , commandData . arguments [ i ] , vkTypes ) ;
}
ofs < < " ) " ;
if ( castReturn )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl
2016-03-01 11:14:18 +00:00
< < indentation < < " } " < < std : : endl ;
leaveProtect ( ofs , commandData . protect ) ;
2016-02-16 14:07:55 +00:00
}
void writeTypeEnum ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-16 14:07:55 +00:00
ofs < < " enum class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl ;
for ( size_t i = 0 ; i < enumData . members . size ( ) ; i + + )
{
ofs < < " " < < enumData . members [ i ] . name < < " = " < < enumData . members [ i ] . value ;
if ( i < enumData . members . size ( ) - 1 )
{
ofs < < " , " ;
}
ofs < < std : : endl ;
}
2016-02-22 14:27:08 +00:00
ofs < < " }; " < < std : : endl ;
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-26 09:25:04 +00:00
void writeEnumGetString ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
2016-02-18 11:12:55 +00:00
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-26 09:25:04 +00:00
ofs < < " inline std::string getString( " < < dependencyData . name < < ( enumData . members . empty ( ) ? " ) " : " value) " ) < < std : : endl
2016-02-22 14:27:08 +00:00
< < " { " < < std : : endl ;
if ( enumData . members . empty ( ) )
2016-02-18 11:12:55 +00:00
{
2016-02-26 09:25:04 +00:00
ofs < < " return std::string(); " < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
2016-02-22 14:27:08 +00:00
else
{
ofs < < " switch (value) " < < std : : endl
< < " { " < < std : : endl ;
for ( auto itMember = enumData . members . begin ( ) ; itMember ! = enumData . members . end ( ) ; + + itMember )
{
ofs < < " case " < < dependencyData . name < < " :: " < < itMember - > name < < " : return \" " < < itMember - > name . substr ( 1 ) < < " \" ; " < < std : : endl ;
}
ofs < < " default: return \" unknown \" ; " < < std : : endl
< < " } " < < std : : endl ;
}
ofs < < " } " < < std : : endl ;
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
2016-02-26 09:25:04 +00:00
void writeFlagsGetString ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
2016-02-18 11:12:55 +00:00
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-18 11:12:55 +00:00
std : : string enumPrefix = " vk:: " + * dependencyData . dependencies . begin ( ) + " :: " ;
2016-02-26 09:25:04 +00:00
ofs < < " inline std::string getString( " < < dependencyData . name < < ( enumData . members . empty ( ) ? " ) " : " value) " ) < < std : : endl
< < " { " < < std : : endl ;
if ( enumData . members . empty ( ) )
2016-02-18 11:12:55 +00:00
{
2016-02-26 09:25:04 +00:00
ofs < < " return std::string(); " < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
2016-02-26 09:25:04 +00:00
else
{
ofs < < " if (!value) return std::string(); " < < 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 ;
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
2016-03-16 10:20:41 +00:00
void writeEnumsToString ( std : : ofstream & ofs , VkData const & vkData )
2016-02-18 11:12:55 +00:00
{
2016-03-16 10:20:41 +00:00
for ( auto it = vkData . dependencies . begin ( ) ; it ! = vkData . dependencies . end ( ) ; + + it )
2016-02-18 11:12:55 +00:00
{
switch ( it - > category )
{
case DependencyData : : Category : : ENUM :
2016-03-16 10:20:41 +00:00
assert ( vkData . enums . find ( it - > name ) ! = vkData . enums . end ( ) ) ;
writeEnumGetString ( ofs , * it , vkData . enums . find ( it - > name ) - > second ) ;
2016-02-18 11:12:55 +00:00
break ;
case DependencyData : : Category : : FLAGS :
2016-03-16 10:20:41 +00:00
writeFlagsGetString ( ofs , * it , vkData . enums . find ( * it - > dependencies . begin ( ) ) - > second ) ;
2016-02-18 11:12:55 +00:00
break ;
}
}
}
2016-02-22 14:27:08 +00:00
void writeTypeFlags ( std : : ofstream & ofs , DependencyData const & dependencyData , FlagData const & flagData )
2016-02-16 14:07:55 +00:00
{
assert ( dependencyData . dependencies . size ( ) = = 1 ) ;
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , flagData . protect ) ;
2016-02-17 16:45:27 +00:00
ofs < < " typedef Flags< " < < * dependencyData . dependencies . begin ( ) < < " , Vk " < < dependencyData . name < < " > " < < dependencyData . name < < " ; " < < std : : endl
2016-02-16 14:07:55 +00:00
< < 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
2016-02-22 14:27:08 +00:00
< < " } " < < std : : endl ;
leaveProtect ( ofs , flagData . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-03-16 10:20:41 +00:00
void writeTypeHandle ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , HandleData const & handle , std : : list < DependencyData > const & dependencies )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
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
2016-02-26 08:59:27 +00:00
< < " : m_ " < < memberName < < " (VK_NULL_HANDLE) " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " {} " < < std : : endl
2016-02-25 15:48:46 +00:00
< < std : : endl
< < " #if defined(VK_CPP_TYPESAFE_CONVERSION) " < < std : : endl
// construct from native handle
< < " " < < dependencyData . name < < " (Vk " < < dependencyData . name < < " " < < memberName < < " ) " < < std : : endl
< < " : m_ " < < memberName < < " ( " < < memberName < < " ) " < < std : : endl
< < " {} " < < std : : endl
< < std : : endl
< < " " < < dependencyData . name < < " & operator=(Vk " < < dependencyData . name < < " " < < memberName < < " ) " < < std : : endl
< < " { " < < std : : endl
< < " m_ " < < memberName < < " = " < < memberName < < " ; " < < std : : endl
< < " return *this; " < < std : : endl
< < " } " < < std : : endl
< < " #endif \n "
2016-02-22 14:27:08 +00:00
< < std : : endl ;
2016-03-01 11:14:18 +00:00
2016-02-22 14:27:08 +00:00
if ( ! handle . commands . empty ( ) )
{
for ( size_t i = 0 ; i < handle . commands . size ( ) ; i + + )
{
std : : string commandName = handle . commands [ i ] ;
2016-03-16 10:20:41 +00:00
std : : map < std : : string , CommandData > : : const_iterator cit = vkData . commands . find ( commandName ) ;
assert ( ( cit ! = vkData . commands . end ( ) ) & & cit - > second . handleCommand ) ;
std : : list < DependencyData > : : const_iterator dep = std : : find_if ( dependencies . begin ( ) , dependencies . end ( ) , [ commandName ] ( DependencyData const & dd ) { return dd . name = = commandName ; } ) ;
2016-02-22 14:27:08 +00:00
assert ( dep ! = dependencies . end ( ) ) ;
2016-03-01 11:14:18 +00:00
std : : string className = dependencyData . name ;
std : : string functionName = determineFunctionName ( dep - > name , cit - > second ) ;
2016-03-02 10:56:09 +00:00
bool hasPointers = hasPointerArguments ( cit - > second ) ;
if ( ! hasPointers )
{
ofs < < " #ifndef VKCPP_ENHANCED_MODE " < < std : : endl ;
}
2016-03-16 10:20:41 +00:00
writeTypeCommandStandard ( ofs , " " , functionName , * dep , cit - > second , vkData . vkTypes ) ;
2016-03-02 10:56:09 +00:00
if ( ! hasPointers )
{
ofs < < " #endif /*!VKCPP_ENHANCED_MODE*/ " < < std : : endl ;
}
2016-03-01 11:14:18 +00:00
ofs < < std : : endl
< < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl ;
2016-03-16 10:20:41 +00:00
writeTypeCommandEnhanced ( ofs , " " , className , functionName , * dep , cit - > second , vkData . vkTypes ) ;
2016-03-01 11:14:18 +00:00
ofs < < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl ;
2016-02-22 14:27:08 +00:00
if ( i < handle . commands . size ( ) - 1 )
{
ofs < < std : : endl ;
}
}
2016-03-01 11:14:18 +00:00
ofs < < std : : endl ;
2016-02-22 14:27:08 +00:00
}
2016-02-25 15:48:46 +00:00
ofs < < " #if !defined(VK_CPP_TYPESAFE_CONVERSION) " < < std : : endl
< < " explicit " < < std : : endl
< < " #endif " < < std : : endl
< < " operator Vk " < < dependencyData . name < < " () const " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " { " < < std : : endl
< < " return m_ " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
2016-02-26 08:59:27 +00:00
< < " 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
2016-02-22 14:27:08 +00:00
< < " 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 ;
2016-02-16 14:07:55 +00:00
}
void writeTypeScalar ( std : : ofstream & ofs , DependencyData const & dependencyData )
{
assert ( dependencyData . dependencies . size ( ) = = 1 ) ;
ofs < < " typedef " < < * dependencyData . dependencies . begin ( ) < < " " < < dependencyData . name < < " ; " < < std : : endl ;
}
2016-03-16 10:20:41 +00:00
void writeTypeStruct ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , std : : map < std : : string , std : : string > const & defaultValues )
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
std : : map < std : : string , StructData > : : const_iterator it = vkData . structs . find ( dependencyData . name ) ;
assert ( it ! = vkData . structs . end ( ) ) ;
2016-02-16 14:07:55 +00:00
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , it - > second . protect ) ;
2016-02-16 14:07:55 +00:00
ofs < < " class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl ;
std : : string memberName ( dependencyData . name ) ;
assert ( isupper ( memberName [ 0 ] ) ) ;
memberName [ 0 ] = tolower ( memberName [ 0 ] ) ;
memberName = " m_ " + memberName ;
// only structs that are not returnedOnly get a constructor!
if ( ! it - > second . returnedOnly )
{
2016-03-16 10:20:41 +00:00
writeStructConstructor ( ofs , dependencyData . name , memberName , it - > second , vkData . vkTypes , defaultValues ) ;
2016-02-16 14:07:55 +00:00
}
// create the getters and setters
for ( size_t i = 0 ; i < it - > second . members . size ( ) ; i + + )
{
2016-03-16 10:20:41 +00:00
writeStructGetter ( ofs , it - > second . members [ i ] , memberName , vkData . vkTypes , true ) ;
2016-02-26 11:01:11 +00:00
if ( ! it - > second . returnedOnly )
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
writeStructGetter ( ofs , it - > second . members [ i ] , memberName , vkData . vkTypes , false ) ;
writeStructSetter ( ofs , dependencyData . name , it - > second . members [ i ] , memberName , vkData . vkTypes ) ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-26 10:41:21 +00:00
// null handle
2016-03-14 16:51:10 +00:00
ofs < < " static Optional<const " < < dependencyData . name < < " > null() " < < std : : endl
2016-02-26 10:41:21 +00:00
< < " { " < < std : : endl
2016-03-14 16:51:10 +00:00
< < " return Optional<const " < < dependencyData . name < < " >(nullptr); " < < std : : endl
2016-02-26 10:41:21 +00:00
< < " } " < < std : : endl
< < std : : endl ;
2016-02-16 14:07:55 +00:00
// the cast-operator to the wrapped struct, and the struct itself as a private member variable
ofs < < " operator const Vk " < < dependencyData . name < < " &() const " < < std : : endl
< < " { " < < std : : endl
< < " return " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " private: " < < std : : endl
< < " Vk " < < dependencyData . name < < " " < < memberName < < " ; " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " }; " < < std : : endl ;
# if 1
ofs < < " static_assert( sizeof( " < < dependencyData . name < < " ) == sizeof( Vk " < < dependencyData . name < < " ), \" struct and wrapper have different size! \" ); " < < std : : endl ;
2016-02-16 14:07:55 +00:00
# endif
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , it - > second . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-03-16 10:20:41 +00:00
void writeTypeUnion ( std : : ofstream & ofs , VkData const & vkData , DependencyData const & dependencyData , StructData const & unionData , std : : map < std : : string , std : : string > const & defaultValues )
2016-02-16 14:07:55 +00:00
{
std : : ostringstream oss ;
ofs < < " class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl ;
std : : string memberName ( dependencyData . name ) ;
assert ( isupper ( memberName [ 0 ] ) ) ;
memberName [ 0 ] = tolower ( memberName [ 0 ] ) ;
memberName = " m_ " + memberName ;
for ( size_t i = 0 ; i < unionData . members . size ( ) ; i + + )
{
// one constructor per union element
ofs < < " " < < dependencyData . name < < " ( " ;
if ( unionData . members [ i ] . arraySize . empty ( ) )
{
ofs < < unionData . members [ i ] . type < < " " ;
}
else
{
ofs < < " const std::array< " < < unionData . members [ i ] . type < < " , " < < unionData . members [ i ] . arraySize < < " >& " ;
}
ofs < < unionData . members [ i ] . name ;
// just the very first constructor gets default arguments
if ( i = = 0 )
{
std : : map < std : : string , std : : string > : : 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 < < memberName < < " . " < < unionData . members [ i ] . name < < " = " < < unionData . members [ i ] . name ;
}
else
{
ofs < < " memcpy( & " < < memberName < < " . " < < 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 ;
// one getter/setter per union element
2016-03-16 10:20:41 +00:00
writeStructGetter ( ofs , unionData . members [ i ] , memberName , vkData . vkTypes , true ) ;
2016-02-26 11:01:11 +00:00
assert ( ! unionData . returnedOnly ) ;
2016-03-16 10:20:41 +00:00
writeStructGetter ( ofs , unionData . members [ i ] , memberName , vkData . vkTypes , false ) ;
writeStructSetter ( ofs , dependencyData . name , unionData . members [ i ] , memberName , vkData . vkTypes ) ;
2016-02-16 14:07:55 +00:00
}
ofs < < " operator Vk " < < dependencyData . name < < " const& () const " < < std : : endl
< < " { " < < std : : endl
< < " return " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " private: " < < std : : endl
< < " Vk " < < dependencyData . name < < " " < < memberName < < " ; " < < std : : endl
< < " }; " < < std : : endl
< < std : : endl ;
}
2016-03-16 10:20:41 +00:00
void writeTypes ( std : : ofstream & ofs , VkData const & vkData , std : : map < std : : string , std : : string > const & defaultValues )
2016-02-16 14:07:55 +00:00
{
2016-03-16 10:20:41 +00:00
for ( std : : list < DependencyData > : : const_iterator it = vkData . dependencies . begin ( ) ; it ! = vkData . dependencies . end ( ) ; + + it )
2016-02-16 14:07:55 +00:00
{
switch ( it - > category )
{
case DependencyData : : Category : : COMMAND :
2016-03-16 10:20:41 +00:00
assert ( vkData . commands . find ( it - > name ) ! = vkData . commands . end ( ) ) ;
writeTypeCommand ( ofs , * it , vkData . commands . find ( it - > name ) - > second , vkData . vkTypes ) ;
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : ENUM :
2016-03-16 10:20:41 +00:00
assert ( vkData . enums . find ( it - > name ) ! = vkData . enums . end ( ) ) ;
writeTypeEnum ( ofs , * it , vkData . enums . find ( it - > name ) - > second ) ;
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : FLAGS :
2016-03-16 10:20:41 +00:00
assert ( vkData . flags . find ( it - > name ) ! = vkData . flags . end ( ) ) ;
writeTypeFlags ( ofs , * it , vkData . flags . find ( it - > name ) - > second ) ;
2016-02-16 14:07:55 +00:00
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 :
2016-03-16 10:20:41 +00:00
assert ( vkData . handles . find ( it - > name ) ! = vkData . handles . end ( ) ) ;
writeTypeHandle ( ofs , vkData , * it , vkData . handles . find ( it - > name ) - > second , vkData . dependencies ) ;
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : SCALAR :
writeTypeScalar ( ofs , * it ) ;
break ;
case DependencyData : : Category : : STRUCT :
2016-03-16 10:20:41 +00:00
writeTypeStruct ( ofs , vkData , * it , defaultValues ) ;
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : UNION :
2016-03-16 10:20:41 +00:00
assert ( vkData . structs . find ( it - > name ) ! = vkData . structs . end ( ) ) ;
writeTypeUnion ( ofs , vkData , * it , vkData . structs . find ( it - > name ) - > second , defaultValues ) ;
2016-02-16 14:07:55 +00:00
break ;
default :
assert ( false ) ;
break ;
}
}
}
2016-02-22 14:27:08 +00:00
void writeVersionCheck ( std : : ofstream & ofs , std : : string const & version )
2016-02-16 14:07:55 +00:00
{
ofs < < " static_assert( VK_MAKE_VERSION " < < version < < " == VK_API_VERSION, \" Wrong VK_API_VERSION! \" ); " < < std : : endl
< < std : : endl ;
}
2016-02-25 15:48:46 +00:00
void writeTypesafeCheck ( std : : ofstream & ofs , std : : string const & typesafeCheck )
{
ofs < < " // 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default. " < < std : : endl
< < " // To enable this feature on 32-bit platforms please define VK_CPP_TYPESAFE_CONVERSION " < < std : : endl
< < typesafeCheck < < std : : endl
< < " #define VK_CPP_TYPESAFE_CONVERSION 1 " < < std : : endl
< < " #endif " < < std : : endl
< < std : : endl ;
}
2016-02-16 14:07:55 +00:00
int main ( int argc , char * * argv )
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLDocument doc ;
2016-02-16 14:07:55 +00:00
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLError error = doc . LoadFile ( argv [ 1 ] ) ;
if ( error ! = tinyxml2 : : XML_SUCCESS )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : cout < < " VkGenerate: failed to load file " < < argv [ 1 ] < < " . Error code: " < < error < < std : : endl ;
2016-02-16 14:07:55 +00:00
return - 1 ;
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * registryElement = doc . FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( strcmp ( registryElement - > Value ( ) , " registry " ) = = 0 ) ;
assert ( ! registryElement - > NextSiblingElement ( ) ) ;
2016-03-16 10:20:41 +00:00
VkData vkData ;
2016-02-16 14:07:55 +00:00
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = registryElement - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( child - > Value ( ) ) ;
const std : : string value = child - > Value ( ) ;
if ( value = = " commands " )
{
2016-03-16 10:20:41 +00:00
readCommands ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
2016-03-04 09:37:16 +00:00
else if ( value = = " comment " )
{
2016-03-16 10:20:41 +00:00
readComment ( child , vkData . vulkanLicenseHeader ) ;
2016-03-04 09:37:16 +00:00
}
2016-02-16 14:07:55 +00:00
else if ( value = = " enums " )
{
2016-03-16 10:20:41 +00:00
readEnums ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else if ( value = = " extensions " )
{
2016-03-16 10:20:41 +00:00
readExtensions ( child , vkData ) ;
2016-02-25 13:25:23 +00:00
}
else if ( value = = " tags " )
{
2016-03-16 10:20:41 +00:00
readTags ( child , vkData . tags ) ;
2016-02-16 14:07:55 +00:00
}
else if ( value = = " types " )
{
2016-03-16 10:20:41 +00:00
readTypes ( child , vkData ) ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-03-04 09:37:16 +00:00
assert ( ( value = = " feature " ) | | ( value = = " vendorids " ) ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
2016-03-16 10:20:41 +00:00
sortDependencies ( vkData . dependencies ) ;
2016-02-16 14:07:55 +00:00
std : : map < std : : string , std : : string > defaultValues ;
2016-03-16 10:20:41 +00:00
createDefaults ( vkData , defaultValues ) ;
2016-02-16 14:07:55 +00:00
std : : ofstream ofs ( " vk_cpp.h " ) ;
2016-03-04 09:37:16 +00:00
ofs < < nvidiaLicenseHeader < < std : : endl
2016-03-16 10:20:41 +00:00
< < vkData . vulkanLicenseHeader < < std : : endl
2016-03-04 09:37:16 +00:00
< < std : : endl
< < std : : endl
< < " #ifndef VK_CPP_H_ " < < std : : endl
< < " #define VK_CPP_H_ " < < std : : endl
< < std : : endl
< < " #include <array> " < < std : : endl
2016-02-17 18:40:01 +00:00
< < " #include <cassert> " < < std : : endl
2016-02-16 14:07:55 +00:00
< < " #include <cstdint> " < < std : : endl
< < " #include <cstring> " < < std : : endl
2016-03-07 14:08:31 +00:00
< < " #include <string> " < < std : : endl
< < " #include <system_error> " < < std : : endl
2016-02-16 14:07:55 +00:00
< < " #include <vulkan/vulkan.h> " < < std : : endl
< < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl
< < " # include <vector> " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl
2016-02-16 14:07:55 +00:00
< < std : : endl ;
2016-03-04 09:37:16 +00:00
2016-03-16 10:20:41 +00:00
writeVersionCheck ( ofs , vkData . version ) ;
writeTypesafeCheck ( ofs , vkData . typesafeCheck ) ;
2016-02-16 14:07:55 +00:00
ofs < < " namespace vk " < < std : : endl
2016-03-07 14:08:31 +00:00
< < " { " < < std : : endl
2016-03-14 16:51:10 +00:00
< < flagsHeader
< < optionalClassHeader ;
2016-03-07 14:08:31 +00:00
// first of all, write out vk::Result and the exception handling stuff
2016-03-16 10:20:41 +00:00
std : : list < DependencyData > : : 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 ) ;
writeEnumGetString ( ofs , * it , vkData . enums . find ( it - > name ) - > second ) ;
vkData . dependencies . erase ( it ) ;
2016-02-22 14:27:08 +00:00
ofs < < exceptionHeader ;
2016-03-07 14:08:31 +00:00
ofs < < " } // namespace vk " < < std : : endl
< < std : : endl
< < " namespace std " < < std : : endl
< < " { " < < std : : endl
< < " template <> " < < std : : endl
< < " struct is_error_code_enum<vk::Result> : public true_type " < < std : : endl
< < " {}; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " namespace vk " < < std : : endl
< < " { " < < std : : endl ;
2016-02-16 14:07:55 +00:00
2016-03-16 10:20:41 +00:00
writeTypes ( ofs , vkData , defaultValues ) ;
writeEnumsToString ( ofs , vkData ) ;
2016-02-16 14:07:55 +00:00
2016-02-22 14:27:08 +00:00
ofs < < " } // namespace vk " < < std : : endl
< < std : : endl
< < " #endif " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}