2020-01-03 09:59:59 +00:00
// Copyright(c) 2015-2020, NVIDIA CORPORATION. All rights reserved.
2018-09-25 09:23:27 +00:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2020-04-12 19:49:12 +00:00
# include "VulkanHppGenerator.hpp"
2018-09-25 09:23:27 +00:00
# include <algorithm>
2020-04-12 19:49:12 +00:00
# include <cassert>
# include <exception>
2018-09-25 09:23:27 +00:00
# include <fstream>
# include <functional>
# include <iterator>
# include <regex>
2020-04-12 19:49:12 +00:00
void appendArgumentCount ( std : : string & str ,
size_t vectorIndex ,
std : : string const & vectorName ,
std : : string const & counterName ,
size_t returnParamIndex ,
size_t templateParamIndex ,
bool twoStep ,
bool singular ) ;
std : : string appendFunctionBodyEnhancedLocalReturnVariableSingular ( std : : string & str ,
std : : string const & indentation ,
std : : string const & returnName ,
std : : string const & typeName ,
bool isStructureChain ) ;
void appendReinterpretCast ( std : : string & str ,
bool leadingConst ,
std : : string const & type ,
bool trailingPointerToConst ) ;
void appendTypesafeStuff ( std : : string & str , std : : string const & typesafeCheck ) ;
void appendVersionCheck ( std : : string & str , std : : string const & version ) ;
bool beginsWith ( std : : string const & text , std : : string const & prefix ) ;
bool endsWith ( std : : string const & text , std : : string const & postfix ) ;
void check ( bool condition , int line , std : : string const & message ) ;
void checkAttributes ( int line ,
std : : map < std : : string , std : : string > const & attributes ,
std : : map < std : : string , std : : set < std : : string > > const & required ,
std : : map < std : : string , std : : set < std : : string > > const & optional ) ;
void checkElements ( int line ,
std : : vector < tinyxml2 : : XMLElement const * > const & elements ,
std : : map < std : : string , bool > const & required ,
std : : set < std : : string > const & optional = { } ) ;
void cleanup ( std : : stringstream & ss ) ;
std : : string constructArraySize ( std : : vector < std : : string > const & sizes ) ;
std : : string constructStandardArray ( std : : string const & type , std : : vector < std : : string > const & sizes ) ;
std : : string createEnumValueName ( std : : string const & name ,
std : : string const & prefix ,
std : : string const & postfix ,
bool bitmask ,
std : : string const & tag ) ;
std : : string createSuccessCode ( std : : string const & code , std : : set < std : : string > const & tags ) ;
std : : string determineCommandName ( std : : string const & vulkanCommandName , std : : string const & firstArgumentType ) ;
std : : set < size_t > determineSkippedParams ( size_t returnParamIndex , std : : map < size_t , size_t > const & vectorParamIndices ) ;
bool determineStructureChaining ( std : : string const & structType ,
std : : set < std : : string > const & extendedStructs ,
std : : map < std : : string , std : : string > const & structureAliases ) ;
std : : string extractTag ( int line , std : : string const & name , std : : set < std : : string > const & tags ) ;
std : : string findTag ( std : : set < std : : string > const & tags , std : : string const & name , std : : string const & postfix = " " ) ;
std : : pair < bool , std : : string > generateFunctionBodyStandardReturn ( std : : string const & returnType ) ;
std : : map < std : : string , std : : string > getAttributes ( tinyxml2 : : XMLElement const * element ) ;
template < typename ElementContainer >
std : : vector < tinyxml2 : : XMLElement const * > getChildElements ( ElementContainer const * element ) ;
std : : string getEnumPostfix ( std : : string const & name , std : : set < std : : string > const & tags , std : : string & prefix ) ;
std : : string getEnumPrefix ( int line , std : : string const & name , bool bitmask ) ;
std : : string readTypePostfix ( tinyxml2 : : XMLNode const * node ) ;
std : : string readTypePrefix ( tinyxml2 : : XMLNode const * node ) ;
std : : string replaceWithMap ( std : : string const & input , std : : map < std : : string , std : : string > replacements ) ;
std : : string startLowerCase ( std : : string const & input ) ;
std : : string startUpperCase ( std : : string const & input ) ;
std : : string stripPostfix ( std : : string const & value , std : : string const & postfix ) ;
std : : string stripPluralS ( std : : string const & name ) ;
std : : string stripPrefix ( std : : string const & value , std : : string const & prefix ) ;
std : : string toCamelCase ( std : : string const & value ) ;
std : : string toUpperCase ( std : : string const & name ) ;
std : : vector < std : : string > tokenize ( std : : string const & tokenString , std : : string const & separator ) ;
std : : string trim ( std : : string const & input ) ;
std : : string trimEnd ( std : : string const & input ) ;
void warn ( bool condition , int line , std : : string const & message ) ;
2019-08-27 07:02:49 +00:00
2019-11-07 07:22:47 +00:00
const std : : set < std : : string > nonConstSTypeStructs = { " VkBaseInStructure " , " VkBaseOutStructure " } ;
2020-04-12 19:49:12 +00:00
void appendArgumentCount ( std : : string & str ,
size_t vectorIndex ,
std : : string const & vectorName ,
std : : string const & counterName ,
size_t returnParamIndex ,
size_t templateParamIndex ,
bool twoStep ,
bool singular )
2019-08-27 07:02:49 +00:00
{
// this parameter is a count parameter for a vector parameter
2020-04-12 19:49:12 +00:00
if ( ( returnParamIndex = = vectorIndex ) & & twoStep )
2019-08-27 07:02:49 +00:00
{
// the corresponding vector parameter is the return parameter and it's a two-step algorithm
// -> use the pointer to a local variable named like the counter parameter without leading 'p'
2020-04-12 19:49:12 +00:00
assert ( ( counterName [ 0 ] = = ' p ' ) & & isupper ( counterName [ 1 ] ) ) ;
str + = " & " + startLowerCase ( stripPrefix ( counterName , " p " ) ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// the corresponding vector parameter is not the return parameter, or it's not a two-step algorithm
2020-04-12 19:49:12 +00:00
if ( singular )
2019-08-27 07:02:49 +00:00
{
// for the singular version, the count is just 1.
str + = " 1 " ;
}
else
{
// for the non-singular version, the count is the size of the vector parameter
// -> use the vector parameter name without leading 'p' to get the size (in number of elements, not in bytes)
2020-04-12 19:49:12 +00:00
assert ( vectorName [ 0 ] = = ' p ' ) ;
str + = startLowerCase ( stripPrefix ( vectorName , " p " ) ) + " .size() " ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( templateParamIndex = = vectorIndex )
2019-08-27 07:02:49 +00:00
{
// if the vector parameter is templatized -> multiply by the size of that type to get the size in bytes
str + = " * sizeof( T ) " ;
}
}
}
2020-04-12 19:49:12 +00:00
std : : string appendFunctionBodyEnhancedLocalReturnVariableSingular ( std : : string & str ,
std : : string const & indentation ,
std : : string const & returnName ,
std : : string const & typeName ,
bool isStructureChain )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string strippedReturnName = stripPluralS ( returnName ) ;
if ( isStructureChain )
2019-08-27 07:02:49 +00:00
{
// For StructureChains use the template parameters
2020-04-12 19:49:12 +00:00
str + = " StructureChain<X, Y, Z...> structureChain; \n " + indentation + " " + typeName + " & " + strippedReturnName +
" = structureChain.template get< " + typeName + " >() " ;
2019-08-27 07:02:49 +00:00
strippedReturnName = " structureChain " ;
}
else
{
// in singular case, just use the return parameters pure type for the return variable
str + = typeName + " " + strippedReturnName ;
}
return strippedReturnName ;
}
2020-04-12 19:49:12 +00:00
void appendReinterpretCast ( std : : string & str ,
bool leadingConst ,
std : : string const & type ,
bool trailingPointerToConst )
2019-08-27 07:02:49 +00:00
{
str + = " reinterpret_cast< " ;
2020-04-12 19:49:12 +00:00
if ( leadingConst )
2019-08-27 07:02:49 +00:00
{
str + = " const " ;
}
str + = type ;
2020-04-12 19:49:12 +00:00
if ( trailingPointerToConst )
2019-08-27 07:02:49 +00:00
{
str + = " * const " ;
}
str + = " *> " ;
}
2020-04-12 19:49:12 +00:00
void appendTypesafeStuff ( std : : string & str , std : : string const & typesafeCheck )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" // 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default. \n "
" // To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION \n " +
typesafeCheck +
" \n "
2019-08-27 07:02:49 +00:00
" # if !defined( VULKAN_HPP_TYPESAFE_CONVERSION ) \n "
" # define VULKAN_HPP_TYPESAFE_CONVERSION \n "
" # endif \n "
" #endif \n " ;
}
2020-04-12 19:49:12 +00:00
void appendVersionCheck ( std : : string & str , std : : string const & version )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " static_assert( VK_HEADER_VERSION == " + version +
" , \" Wrong VK_HEADER_VERSION! \" ); \n "
" \n " ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
bool beginsWith ( std : : string const & text , std : : string const & prefix )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
return prefix . empty ( ) | | text . substr ( 0 , prefix . length ( ) ) = = prefix ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
bool endsWith ( std : : string const & text , std : : string const & postfix )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
return postfix . empty ( ) | |
( ( postfix . length ( ) < = text . length ( ) ) & & ( text . substr ( text . length ( ) - postfix . length ( ) ) = = postfix ) ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void check ( bool condition , int line , std : : string const & message )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! condition )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
throw std : : runtime_error ( " Spec error on line " + std : : to_string ( line ) + " : " + message ) ;
2019-01-09 10:55:11 +00:00
}
}
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
// check the validity of an attributes map
// line : the line in the xml file where the attributes are listed
2020-02-11 13:37:22 +00:00
// attributes : the map of name/value pairs of the encountered attributes
2019-01-09 10:55:11 +00:00
// required : the required attributes, with a set of allowed values per attribute
// optional : the optional attributes, with a set of allowed values per attribute
2020-04-12 19:49:12 +00:00
void checkAttributes ( int line ,
std : : map < std : : string , std : : string > const & attributes ,
std : : map < std : : string , std : : set < std : : string > > const & required ,
std : : map < std : : string , std : : set < std : : string > > const & optional )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
// check if all required attributes are included and if there is a set of allowed values, check if the actual value is
// part of that set
for ( auto const & r : required )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
auto attributesIt = attributes . find ( r . first ) ;
check ( attributesIt ! = attributes . end ( ) , line , " missing attribute < " + r . first + " > " ) ;
check ( r . second . empty ( ) | | ( r . second . find ( attributesIt - > second ) ! = r . second . end ( ) ) ,
line ,
" unexpected attribute value < " + attributesIt - > second + " > in attribute < " + r . first + " > " ) ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
// check if all not required attributes or optional, and if there is a set of allowed values, check if the actual
// value is part of that set
for ( auto const & a : attributes )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( required . find ( a . first ) = = required . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto optionalIt = optional . find ( a . first ) ;
if ( optionalIt = = optional . end ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
warn ( false , line , " unknown attribute < " + a . first + " > " ) ;
2019-01-09 10:55:11 +00:00
continue ;
}
2020-04-12 19:49:12 +00:00
if ( ! optionalIt - > second . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
std : : vector < std : : string > values = tokenize ( a . second , " , " ) ;
for ( auto const & v : values )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
warn ( optionalIt - > second . find ( v ) ! = optionalIt - > second . end ( ) ,
line ,
" unexpected attribute value < " + v + " > in attribute < " + a . first + " > " ) ;
2019-01-09 10:55:11 +00:00
}
}
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void checkElements ( int line ,
std : : vector < tinyxml2 : : XMLElement const * > const & elements ,
std : : map < std : : string , bool > const & required ,
std : : set < std : : string > const & optional )
2019-01-09 10:55:11 +00:00
{
2020-02-11 13:37:22 +00:00
std : : map < std : : string , size_t > encountered ;
2020-04-12 19:49:12 +00:00
for ( auto const & e : elements )
2019-01-09 10:55:11 +00:00
{
2020-02-04 09:35:33 +00:00
std : : string value = e - > Value ( ) ;
2020-02-11 13:37:22 +00:00
encountered [ value ] + + ;
2020-04-12 19:49:12 +00:00
warn ( ( required . find ( value ) ! = required . end ( ) ) | | ( optional . find ( value ) ! = optional . end ( ) ) ,
e - > GetLineNum ( ) ,
" unknown element < " + value + " > " ) ;
2020-02-04 09:35:33 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & r : required )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
auto encounteredIt = encountered . find ( r . first ) ;
check ( encounteredIt ! = encountered . end ( ) , line , " missing required element < " + r . first + " > " ) ;
2020-02-11 13:37:22 +00:00
// check: r.second (means: required excactly once) => (encouteredIt->second == 1)
2020-04-12 19:49:12 +00:00
check ( ! r . second | | ( encounteredIt - > second = = 1 ) ,
line ,
" required element < " + r . first + " > is supposed to be listed exactly once, but is listed " +
std : : to_string ( encounteredIt - > second ) ) ;
2019-01-09 10:55:11 +00:00
}
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void cleanup ( std : : string & str )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
std : : map < std : : string , std : : string > replacements = { { " \n \n \n " , " \n \n " } ,
{ " { \n \n " , " { \n " } ,
{ " \n \n } " , " \n } " } } ;
for ( auto const & repl : replacements )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string : : size_type pos = str . find ( repl . first ) ;
while ( pos ! = std : : string : : npos )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
str . replace ( pos , repl . first . length ( ) , repl . second ) ;
pos = str . find ( repl . first , pos ) ;
2019-07-23 07:28:14 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
std : : string constructArraySize ( std : : vector < std : : string > const & sizes )
2020-01-13 14:00:59 +00:00
{
std : : string arraySize ;
2020-04-12 19:49:12 +00:00
for ( auto const & s : sizes )
2020-01-13 14:00:59 +00:00
{
arraySize + = s + " * " ;
}
2020-04-12 19:49:12 +00:00
return arraySize . substr ( 0 , arraySize . length ( ) - 3 ) ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string constructCArraySizes ( std : : vector < std : : string > const & sizes )
2020-01-13 14:00:59 +00:00
{
std : : string arraySizes ;
2020-04-12 19:49:12 +00:00
for ( auto const & s : sizes )
2020-01-13 14:00:59 +00:00
{
arraySizes + = " [ " + s + " ] " ;
}
return arraySizes ;
}
2020-04-12 19:49:12 +00:00
std : : string constructStandardArray ( std : : string const & type , std : : vector < std : : string > const & sizes )
2020-01-13 14:00:59 +00:00
{
std : : string arrayString = " std::array< " + type + " , " + sizes . back ( ) + " > " ;
2020-04-12 19:49:12 +00:00
for ( size_t i = sizes . size ( ) - 2 ; i < sizes . size ( ) ; i - - )
2020-01-13 14:00:59 +00:00
{
arrayString = " std::array< " + arrayString + " , " + sizes [ i ] + " > " ;
}
return arrayString ;
}
2020-04-12 19:49:12 +00:00
std : : string constructStandardArrayWrapper ( std : : string const & type , std : : vector < std : : string > const & sizes )
2020-03-23 13:59:37 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string arrayString = " VULKAN_HPP_NAMESPACE::ArrayWrapper " + std : : to_string ( sizes . size ( ) ) + " D< " + type ;
for ( auto const & size : sizes )
2020-03-23 13:59:37 +00:00
{
arrayString + = " , " + size ;
}
arrayString + = " > " ;
return arrayString ;
}
2020-04-12 19:49:12 +00:00
std : : string createEnumValueName ( std : : string const & name ,
std : : string const & prefix ,
std : : string const & postfix ,
bool bitmask ,
std : : string const & tag )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string result = " e " + toCamelCase ( stripPostfix ( stripPrefix ( name , prefix ) , postfix ) ) ;
if ( bitmask )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
size_t pos = result . find ( " Bit " ) ;
if ( pos ! = std : : string : : npos )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
result . erase ( pos , 3 ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! tag . empty ( ) & & ( result . substr ( result . length ( ) - tag . length ( ) ) = = toCamelCase ( tag ) ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
result = result . substr ( 0 , result . length ( ) - tag . length ( ) ) + tag ;
2019-01-09 10:55:11 +00:00
}
return result ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string createSuccessCode ( std : : string const & code , std : : set < std : : string > const & tags )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string tag = findTag ( tags , code ) ;
2020-02-11 13:37:22 +00:00
// on each success code: prepend 'e', strip "VK_" and a tag, convert it to camel case, and add the tag again
2020-04-12 19:49:12 +00:00
return " e " + toCamelCase ( stripPostfix ( stripPrefix ( code , " VK_ " ) , tag ) ) + tag ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string determineCommandName ( std : : string const & vulkanCommandName , std : : string const & firstArgumentType )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string commandName ( startLowerCase ( stripPrefix ( vulkanCommandName , " vk " ) ) ) ;
std : : string searchName = stripPrefix ( firstArgumentType , " Vk " ) ;
size_t pos = commandName . find ( searchName ) ;
if ( ( pos = = std : : string : : npos ) & & isupper ( searchName [ 0 ] ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
searchName [ 0 ] = static_cast < char > ( tolower ( searchName [ 0 ] ) ) ;
pos = commandName . find ( searchName ) ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
if ( pos ! = std : : string : : npos )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
commandName . erase ( pos , searchName . length ( ) ) ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( ( searchName = = " commandBuffer " ) & & beginsWith ( commandName , " cmd " ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
commandName . erase ( 0 , 3 ) ;
2019-01-09 10:55:11 +00:00
pos = 0 ;
}
2020-04-12 19:49:12 +00:00
if ( ( pos = = 0 ) & & isupper ( commandName [ 0 ] ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
commandName [ 0 ] = static_cast < char > ( tolower ( commandName [ 0 ] ) ) ;
2019-01-09 10:55:11 +00:00
}
return commandName ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : set < size_t > determineSkippedParams ( size_t returnParamIndex , std : : map < size_t , size_t > const & vectorParamIndices )
2019-01-09 10:55:11 +00:00
{
std : : set < size_t > skippedParams ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
// the size-parameters of vector parameters are not explicitly used in the enhanced API
2020-04-12 19:49:12 +00:00
std : : for_each (
vectorParamIndices . begin ( ) , vectorParamIndices . end ( ) , [ & skippedParams ] ( std : : pair < size_t , size_t > const & vp ) {
if ( vp . second ! = INVALID_INDEX )
skippedParams . insert ( vp . second ) ;
} ) ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
// and the return parameter is also skipped
2020-04-12 19:49:12 +00:00
if ( returnParamIndex ! = INVALID_INDEX )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
skippedParams . insert ( returnParamIndex ) ;
2019-01-09 10:55:11 +00:00
}
return skippedParams ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
bool determineStructureChaining ( std : : string const & structType ,
std : : set < std : : string > const & extendedStructs ,
std : : map < std : : string , std : : string > const & structureAliases )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
bool isStructureChained = ( extendedStructs . find ( structType ) ! = extendedStructs . end ( ) ) ;
if ( ! isStructureChained )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto aliasIt = structureAliases . find ( structType ) ;
if ( ( aliasIt ! = structureAliases . end ( ) ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
isStructureChained = ( extendedStructs . find ( aliasIt - > second ) ! = extendedStructs . end ( ) ) ;
2019-01-09 10:55:11 +00:00
}
}
return isStructureChained ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string findTag ( std : : set < std : : string > const & tags , std : : string const & name , std : : string const & postfix )
2019-02-13 11:18:49 +00:00
{
2020-04-12 19:49:12 +00:00
auto tagIt = std : : find_if (
tags . begin ( ) , tags . end ( ) , [ & name , & postfix ] ( std : : string const & t ) { return endsWith ( name , t + postfix ) ; } ) ;
return ( tagIt ! = tags . end ( ) ) ? * tagIt : " " ;
2019-02-13 11:18:49 +00:00
}
2020-04-12 19:49:12 +00:00
std : : pair < bool , std : : string > generateFunctionBodyStandardReturn ( std : : string const & returnType )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
bool castReturn = false ;
2019-08-27 07:02:49 +00:00
std : : string ret ;
2020-04-12 19:49:12 +00:00
if ( returnType ! = " void " )
2019-07-23 07:28:14 +00:00
{
2019-08-27 07:02:49 +00:00
// there's something to return...
ret = " return " ;
2020-04-12 19:49:12 +00:00
castReturn = beginsWith ( returnType , " Vk " ) ;
if ( castReturn )
2019-07-23 07:28:14 +00:00
{
2019-12-02 09:06:44 +00:00
// the return-type is a vulkan type -> need to cast to VULKAN_HPP_NAMESPACE-type
2020-04-12 19:49:12 +00:00
ret + = " static_cast< " + stripPrefix ( returnType , " Vk " ) + " >( " ;
2019-07-23 07:28:14 +00:00
}
}
2020-04-12 19:49:12 +00:00
return std : : make_pair ( castReturn , ret ) ;
2019-07-23 07:28:14 +00:00
}
2020-04-12 19:49:12 +00:00
std : : map < std : : string , std : : string > getAttributes ( tinyxml2 : : XMLElement const * element )
2019-01-09 10:55:11 +00:00
{
std : : map < std : : string , std : : string > attributes ;
2020-04-12 19:49:12 +00:00
for ( auto attribute = element - > FirstAttribute ( ) ; attribute ; attribute = attribute - > Next ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( attributes . find ( attribute - > Name ( ) ) = = attributes . end ( ) ) ;
2019-01-09 10:55:11 +00:00
attributes [ attribute - > Name ( ) ] = attribute - > Value ( ) ;
}
return attributes ;
}
2018-09-25 09:23:27 +00:00
2020-02-11 13:37:22 +00:00
template < typename ElementContainer >
2020-04-12 19:49:12 +00:00
std : : vector < tinyxml2 : : XMLElement const * > getChildElements ( ElementContainer const * element )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
std : : vector < tinyxml2 : : XMLElement const * > childElements ;
for ( tinyxml2 : : XMLElement const * childElement = element - > FirstChildElement ( ) ; childElement ;
childElement = childElement - > NextSiblingElement ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
childElements . push_back ( childElement ) ;
2019-01-09 10:55:11 +00:00
}
return childElements ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string getEnumPostfix ( std : : string const & name , std : : set < std : : string > const & tags , std : : string & prefix )
2019-01-09 10:55:11 +00:00
{
std : : string postfix ;
2020-04-12 19:49:12 +00:00
if ( name ! = " VkResult " )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
// if the enum name contains a tag move it from the prefix to the postfix to generate correct enum value names.
2020-04-12 19:49:12 +00:00
for ( auto const & tag : tags )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( endsWith ( prefix , tag + " _ " ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
prefix . erase ( prefix . length ( ) - tag . length ( ) - 1 ) ;
2019-01-09 10:55:11 +00:00
postfix = " _ " + tag ;
break ;
}
2020-04-12 19:49:12 +00:00
else if ( endsWith ( name , tag ) )
2019-01-09 10:55:11 +00:00
{
postfix = " _ " + tag ;
break ;
}
}
}
return postfix ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string getEnumPrefix ( int line , std : : string const & name , bool bitmask )
2019-01-09 10:55:11 +00:00
{
std : : string prefix ;
2020-04-12 19:49:12 +00:00
if ( name = = " VkResult " )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
prefix = " VK_ " ;
}
2020-04-12 19:49:12 +00:00
else if ( bitmask )
2019-01-09 10:55:11 +00:00
{
// for a bitmask enum, start with "VK", cut off the trailing "FlagBits", and convert that name to upper case
// end that with "Bit"
2020-04-12 19:49:12 +00:00
size_t pos = name . find ( " FlagBits " ) ;
check ( pos ! = std : : string : : npos , line , " bitmask < " + name + " > does not contain <FlagBits> " ) ;
prefix = toUpperCase ( name . substr ( 0 , pos ) ) + " _ " ;
2019-01-09 10:55:11 +00:00
}
else
{
// for a non-bitmask enum, convert the name to upper case
2020-04-12 19:49:12 +00:00
prefix = toUpperCase ( name ) + " _ " ;
2019-01-09 10:55:11 +00:00
}
return prefix ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string extractTag ( int line , std : : string const & name , std : : set < std : : string > const & tags )
2019-01-09 10:55:11 +00:00
{
// extract the tag from the name, which is supposed to look like VK_<tag>_<other>
2020-04-12 19:49:12 +00:00
size_t tagStart = name . find ( ' _ ' ) ;
check ( tagStart ! = std : : string : : npos , line , " name < " + name + " > is missing an underscore '_' " ) ;
size_t tagEnd = name . find ( ' _ ' , tagStart + 1 ) ;
check ( tagEnd ! = std : : string : : npos , line , " name < " + name + " > is missing an underscore '_' " ) ;
std : : string tag = name . substr ( tagStart + 1 , tagEnd - tagStart - 1 ) ;
check ( tags . find ( tag ) ! = tags . end ( ) , line , " name < " + name + " > is using an unknown tag < " + tag + " > " ) ;
2019-01-09 10:55:11 +00:00
return tag ;
}
2018-12-03 13:30:36 +00:00
2020-04-12 19:49:12 +00:00
std : : pair < std : : vector < std : : string > , std : : string > readModifiers ( tinyxml2 : : XMLNode const * node )
2019-01-09 10:55:11 +00:00
{
2020-01-13 14:00:59 +00:00
std : : vector < std : : string > arraySizes ;
2020-04-12 19:49:12 +00:00
std : : string bitCount ;
if ( node & & node - > ToText ( ) )
2018-09-25 09:23:27 +00:00
{
2019-01-14 09:09:19 +00:00
// following the name there might be some array size
2020-01-13 14:00:59 +00:00
std : : string value = node - > Value ( ) ;
2020-04-12 19:49:12 +00:00
assert ( ! value . empty ( ) ) ;
if ( value [ 0 ] = = ' [ ' )
2018-09-25 09:23:27 +00:00
{
2020-01-13 14:00:59 +00:00
std : : string : : size_type endPos = 0 ;
2020-04-12 19:49:12 +00:00
while ( endPos + 1 ! = value . length ( ) )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string : : size_type startPos = value . find ( ' [ ' , endPos ) ;
check ( startPos ! = std : : string : : npos , node - > GetLineNum ( ) , " could not find '[' in < " + value + " > " ) ;
endPos = value . find ( ' ] ' , startPos ) ;
check ( endPos ! = std : : string : : npos , node - > GetLineNum ( ) , " could not find ']' in < " + value + " > " ) ;
check ( startPos + 2 < = endPos , node - > GetLineNum ( ) , " missing content between '[' and ']' in < " + value + " > " ) ;
arraySizes . push_back ( value . substr ( startPos + 1 , endPos - startPos - 1 ) ) ;
2020-01-13 14:00:59 +00:00
}
}
2020-04-12 19:49:12 +00:00
else if ( value [ 0 ] = = ' : ' )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
bitCount = value . substr ( 1 ) ;
2018-09-25 09:23:27 +00:00
}
2020-02-11 13:37:22 +00:00
else
{
2020-04-12 19:49:12 +00:00
check ( ( value [ 0 ] = = ' ; ' ) | | ( value [ 0 ] = = ' ) ' ) , node - > GetLineNum ( ) , " unknown modifier < " + value + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
return std : : make_pair ( arraySizes , bitCount ) ;
;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string readTypePostfix ( tinyxml2 : : XMLNode const * node )
2019-01-14 09:09:19 +00:00
{
std : : string postfix ;
2020-04-12 19:49:12 +00:00
if ( node & & node - > ToText ( ) )
2019-01-14 09:09:19 +00:00
{
2020-04-12 19:49:12 +00:00
postfix = trimEnd ( node - > Value ( ) ) ;
2019-01-14 09:09:19 +00:00
}
return postfix ;
}
2020-04-12 19:49:12 +00:00
std : : string readTypePrefix ( tinyxml2 : : XMLNode const * node )
2019-01-14 09:09:19 +00:00
{
std : : string prefix ;
2020-04-12 19:49:12 +00:00
if ( node & & node - > ToText ( ) )
2019-01-14 09:09:19 +00:00
{
2020-04-12 19:49:12 +00:00
prefix = trim ( node - > Value ( ) ) ;
2019-01-14 09:09:19 +00:00
}
return prefix ;
}
2020-04-12 19:49:12 +00:00
std : : string replaceWithMap ( std : : string const & input , std : : map < std : : string , std : : string > replacements )
2019-01-09 10:55:11 +00:00
{
// This will match ${someVariable} and contain someVariable in match group 1
2020-04-12 19:49:12 +00:00
std : : regex re ( R " ( \ $ \ {([^ \ }]+) \ }) " ) ;
auto it = std : : sregex_iterator ( input . begin ( ) , input . end ( ) , re ) ;
auto end = std : : sregex_iterator ( ) ;
2019-01-09 10:55:11 +00:00
// No match, just return the original string
2020-04-12 19:49:12 +00:00
if ( it = = end )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return input ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
std : : string result = " " ;
2020-04-12 19:49:12 +00:00
while ( it ! = end )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : smatch match = * it ;
auto itReplacement = replacements . find ( match [ 1 ] . str ( ) ) ;
assert ( itReplacement ! = replacements . end ( ) ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
result + =
match . prefix ( ) . str ( ) + ( ( itReplacement ! = replacements . end ( ) ) ? itReplacement - > second : match [ 0 ] . str ( ) ) ;
2019-01-09 10:55:11 +00:00
+ + it ;
// we've passed the last match. Append the rest of the orignal string
2020-04-12 19:49:12 +00:00
if ( it = = end )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
result + = match . suffix ( ) . str ( ) ;
2018-09-25 09:23:27 +00:00
}
}
2019-01-09 10:55:11 +00:00
return result ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string startLowerCase ( std : : string const & input )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
return input . empty ( ) ? " " : static_cast < char > ( tolower ( input [ 0 ] ) ) + input . substr ( 1 ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string startUpperCase ( std : : string const & input )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
return input . empty ( ) ? " " : static_cast < char > ( toupper ( input [ 0 ] ) ) + input . substr ( 1 ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string stripPostfix ( std : : string const & value , std : : string const & postfix )
2019-01-09 10:55:11 +00:00
{
std : : string strippedValue = value ;
2020-04-12 19:49:12 +00:00
if ( endsWith ( strippedValue , postfix ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
strippedValue . erase ( strippedValue . length ( ) - postfix . length ( ) ) ;
2019-01-09 10:55:11 +00:00
}
return strippedValue ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string stripPluralS ( std : : string const & name )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string strippedName ( name ) ;
size_t pos = strippedName . rfind ( ' s ' ) ;
assert ( pos ! = std : : string : : npos ) ;
strippedName . erase ( pos , 1 ) ;
2019-01-09 10:55:11 +00:00
return strippedName ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string stripPrefix ( std : : string const & value , std : : string const & prefix )
2019-01-09 10:55:11 +00:00
{
std : : string strippedValue = value ;
2020-04-12 19:49:12 +00:00
if ( beginsWith ( strippedValue , prefix ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
strippedValue . erase ( 0 , prefix . length ( ) ) ;
2019-01-09 10:55:11 +00:00
}
return strippedValue ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string toCamelCase ( std : : string const & value )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ! value . empty ( ) & & ( isupper ( value [ 0 ] ) | | isdigit ( value [ 0 ] ) ) ) ;
2019-01-09 10:55:11 +00:00
std : : string result ;
2020-04-12 19:49:12 +00:00
result . reserve ( value . size ( ) ) ;
2019-01-09 10:55:11 +00:00
bool keepUpper = true ;
2020-04-12 19:49:12 +00:00
for ( auto c : value )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( c = = ' _ ' )
2019-01-09 10:55:11 +00:00
{
keepUpper = true ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( isdigit ( c ) )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
keepUpper = true ;
2020-04-12 19:49:12 +00:00
result . push_back ( c ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( keepUpper )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
result . push_back ( c ) ;
2019-01-09 10:55:11 +00:00
keepUpper = false ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
else
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
result . push_back ( static_cast < char > ( tolower ( c ) ) ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
return result ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string toUpperCase ( std : : string const & name )
2019-01-09 10:55:11 +00:00
{
std : : string convertedName ;
2020-04-12 19:49:12 +00:00
convertedName . reserve ( name . size ( ) ) ;
2019-01-09 10:55:11 +00:00
bool lowerOrDigit = false ;
2020-04-12 19:49:12 +00:00
for ( auto c : name )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( islower ( c ) | | isdigit ( c ) )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
lowerOrDigit = true ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( lowerOrDigit )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
convertedName . push_back ( ' _ ' ) ;
2019-01-09 10:55:11 +00:00
lowerOrDigit = false ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
convertedName . push_back ( static_cast < char > ( toupper ( c ) ) ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
return convertedName ;
}
2020-04-12 19:49:12 +00:00
std : : vector < std : : string > tokenize ( std : : string const & tokenString , std : : string const & separator )
2019-01-09 10:55:11 +00:00
{
std : : vector < std : : string > tokens ;
2020-04-12 19:49:12 +00:00
size_t start = 0 , end ;
2019-01-09 10:55:11 +00:00
do
{
2020-04-12 19:49:12 +00:00
end = tokenString . find ( separator , start ) ;
if ( start ! = end )
2020-02-11 13:37:22 +00:00
{
2020-05-04 15:19:44 +00:00
tokens . push_back ( trim ( tokenString . substr ( start , end - start ) ) ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-17 18:17:45 +00:00
start = end + separator . length ( ) ;
2020-04-12 19:49:12 +00:00
} while ( end ! = std : : string : : npos ) ;
2019-01-09 10:55:11 +00:00
return tokens ;
}
2020-04-12 19:49:12 +00:00
std : : string trim ( std : : string const & input )
2019-01-09 10:55:11 +00:00
{
std : : string result = input ;
2020-04-12 19:49:12 +00:00
result . erase ( result . begin ( ) ,
std : : find_if ( result . begin ( ) , result . end ( ) , [ ] ( char c ) { return ! std : : isspace ( c ) ; } ) ) ;
result . erase ( std : : find_if ( result . rbegin ( ) , result . rend ( ) , [ ] ( char c ) { return ! std : : isspace ( c ) ; } ) . base ( ) ,
result . end ( ) ) ;
2019-01-09 10:55:11 +00:00
return result ;
}
2020-04-12 19:49:12 +00:00
std : : string trimEnd ( std : : string const & input )
2019-01-09 10:55:11 +00:00
{
std : : string result = input ;
2020-04-12 19:49:12 +00:00
result . erase ( std : : find_if ( result . rbegin ( ) , result . rend ( ) , [ ] ( char c ) { return ! std : : isspace ( c ) ; } ) . base ( ) ,
result . end ( ) ) ;
2019-01-09 10:55:11 +00:00
return result ;
}
2020-04-12 19:49:12 +00:00
void warn ( bool condition , int line , std : : string const & message )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! condition )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
std : : cerr < < " Spec warning on line " < < std : : to_string ( line ) < < " " < < message < < " ! " < < std : : endl ;
2020-02-04 09:35:33 +00:00
}
}
2020-04-12 19:49:12 +00:00
VulkanHppGenerator : : VulkanHppGenerator ( tinyxml2 : : XMLDocument const & document )
2019-03-19 14:34:00 +00:00
{
2020-04-12 19:49:12 +00:00
m_handles . insert ( std : : make_pair (
" " , HandleData ( { } , 0 ) ) ) ; // insert the default "handle" without class (for createInstance, and such)
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
int line = document . GetLineNum ( ) ;
std : : vector < tinyxml2 : : XMLElement const * > elements = getChildElements ( & document ) ;
checkElements ( line , elements , { { " registry " , true } } ) ;
check ( elements . size ( ) = = 1 ,
line ,
" encountered " + std : : to_string ( elements . size ( ) ) + " elments named <registry> but only one is allowed " ) ;
readRegistry ( elements [ 0 ] ) ;
2020-02-11 13:37:22 +00:00
checkCorrectness ( ) ;
2019-03-19 14:34:00 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendArgumentPlainType ( std : : string & str , ParamData const & paramData ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// this parameter is just a plain type
2020-04-12 19:49:12 +00:00
if ( ! paramData . type . postfix . empty ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( paramData . type . postfix . back ( ) = = ' * ' ) ;
2019-08-27 07:02:49 +00:00
// it's a pointer
2020-04-12 19:49:12 +00:00
std : : string parameterName = startLowerCase ( stripPrefix ( paramData . name , " p " ) ) ;
if ( paramData . type . prefix . find ( " const " ) ! = std : : string : : npos )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// it's a const pointer
2020-04-12 19:49:12 +00:00
if ( paramData . type . type = = " char " )
2019-08-27 07:02:49 +00:00
{
// it's a const pointer to char -> it's a string -> get the data via c_str()
2020-04-12 19:49:12 +00:00
str + = parameterName + ( paramData . optional ? ( " ? " + parameterName + " ->c_str() : nullptr " ) : " .c_str() " ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// it's const pointer to something else -> just use the name
2020-04-12 19:49:12 +00:00
assert ( ! paramData . optional ) ;
2019-08-27 07:02:49 +00:00
str + = paramData . name ;
}
}
else
{
// it's a non-const pointer, and char is the only type that occurs -> use the address of the parameter
2020-04-12 19:49:12 +00:00
assert ( paramData . type . type . find ( " char " ) = = std : : string : : npos ) ;
2019-08-27 07:02:49 +00:00
str + = " & " + parameterName ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
else
{
// it's a plain parameter -> just use its name
str + = paramData . name ;
}
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendArguments ( std : : string & str ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
bool firstCall ,
bool singular ,
size_t from ,
size_t to ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( from < = to ) ;
2019-08-27 07:02:49 +00:00
bool encounteredArgument = false ;
2020-04-12 19:49:12 +00:00
for ( size_t i = from ; i < to ; i + + )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( encounteredArgument )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " , " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
auto it = vectorParamIndices . find ( i ) ;
if ( it ! = vectorParamIndices . end ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
appendArgumentVector ( str ,
it - > first ,
commandData . params [ it - > first ] ,
returnParamIndex ,
templateParamIndex ,
twoStep ,
firstCall ,
singular ) ;
2019-01-09 10:55:11 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
it = find_if ( vectorParamIndices . begin ( ) , vectorParamIndices . end ( ) , [ i ] ( std : : pair < size_t , size_t > const & vpi ) {
return vpi . second = = i ;
} ) ;
if ( it ! = vectorParamIndices . end ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
appendArgumentCount ( str ,
it - > first ,
commandData . params [ it - > first ] . name ,
commandData . params [ it - > second ] . name ,
returnParamIndex ,
templateParamIndex ,
twoStep ,
singular ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( beginsWith ( commandData . params [ i ] . type . type , " Vk " ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendArgumentVulkanType ( str , commandData . params [ i ] ) ;
2019-01-09 10:55:11 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
appendArgumentPlainType ( str , commandData . params [ i ] ) ;
2019-01-09 10:55:11 +00:00
}
}
2019-08-27 07:02:49 +00:00
encounteredArgument = true ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendArgumentVector ( std : : string & str ,
size_t paramIndex ,
ParamData const & paramData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
bool twoStep ,
bool firstCall ,
bool singular ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// this parameter is a vector parameter
2020-04-12 19:49:12 +00:00
assert ( paramData . type . postfix . back ( ) = = ' * ' ) ;
if ( ( returnParamIndex = = paramIndex ) & & twoStep & & firstCall )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// this parameter is the return parameter, and it's the first call of a two-step algorithm -> just just nullptr
str + = " nullptr " ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
else
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string parameterName = startLowerCase ( stripPrefix ( paramData . name , " p " ) ) ;
if ( beginsWith ( paramData . type . type , " Vk " ) | | ( paramIndex = = templateParamIndex ) )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// CHECK for !commandData.params[it->first].optional
// this parameter is a vulkan type or a templated type -> need to reinterpret cast
2020-04-12 19:49:12 +00:00
appendReinterpretCast ( str ,
paramData . type . prefix . find ( " const " ) = = 0 ,
paramData . type . type ,
paramData . type . postfix . rfind ( " * const " ) ! = std : : string : : npos ) ;
str + = " ( " + ( singular ? ( " & " + stripPluralS ( parameterName ) ) : ( parameterName + " .data() " ) ) + " ) " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( paramData . type . type = = " char " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// the parameter is a vector to char -> it might be optional
// besides that, the parameter now is a std::string -> get the pointer via c_str()
2020-04-12 19:49:12 +00:00
str + = parameterName + ( paramData . optional ? ( " ? " + parameterName + " ->c_str() : nullptr " ) : " .c_str() " ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// this parameter is just a vetor -> get the pointer to its data
str + = parameterName + " .data() " ;
2018-09-25 09:23:27 +00:00
}
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendArgumentVulkanType ( std : : string & str , ParamData const & paramData ) const
2019-08-27 07:02:49 +00:00
{
// this parameter is a vulkan type
2020-04-12 19:49:12 +00:00
if ( ! paramData . type . postfix . empty ( ) | | ! paramData . arraySizes . empty ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( paramData . type . postfix . empty ( ) | | ( paramData . type . postfix . back ( ) = = ' * ' ) ) & &
( paramData . arraySizes . empty ( ) | | ( paramData . arraySizes . size ( ) = = 1 ) ) ) ;
2019-08-27 07:02:49 +00:00
// it's a pointer -> needs a reinterpret cast to the vulkan type
2020-04-12 19:49:12 +00:00
std : : string parameterName = startLowerCase ( stripPrefix ( paramData . name , " p " ) ) ;
appendReinterpretCast (
str , paramData . type . prefix . find ( " const " ) ! = std : : string : : npos , paramData . type . type , false ) ;
2019-08-27 07:02:49 +00:00
str + = " ( " ;
2020-04-12 19:49:12 +00:00
if ( paramData . optional )
2019-08-27 07:02:49 +00:00
{
// for an optional parameter, we need also a static_cast from optional type to const-pointer to pure type
2020-04-12 19:49:12 +00:00
str + = " static_cast<const " + stripPrefix ( paramData . type . type , " Vk " ) + " *>( " + parameterName + " ) " ;
2019-08-27 07:02:49 +00:00
}
else
{
// other parameters can just use the pointer
2020-04-12 19:49:12 +00:00
str + = ( paramData . arraySizes . empty ( ) ? " & " : " " ) + parameterName ;
2019-08-27 07:02:49 +00:00
}
str + = " ) " ;
2019-01-09 10:55:11 +00:00
}
else
{
2019-12-02 09:06:44 +00:00
// a non-pointer parameter needs a static_cast from VULKAN_HPP_NAMESPACE-type to vulkan type
2019-08-27 07:02:49 +00:00
str + = " static_cast< " + paramData . type . type + " >( " + paramData . name + " ) " ;
2019-01-09 10:55:11 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendBaseTypes ( std : : string & str ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ! m_baseTypes . empty ( ) ) ;
for ( auto const & baseType : m_baseTypes )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( baseType . first ! = " VkFlags " ) & &
( baseType . first ! =
" VkFlags64 " ) ) // filter out VkFlags and VkFlags64, as they are mapped to our own Flags class
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " using " + stripPrefix ( baseType . first , " Vk " ) + " = " + baseType . second . type + " ; \n " ;
2018-09-25 09:23:27 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendBitmasks ( std : : string & str ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & bitmask : m_bitmasks )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto bitmaskBits = m_enums . find ( bitmask . second . requirements ) ;
bool hasBits = ( bitmaskBits ! = m_enums . end ( ) ) ;
check ( bitmask . second . requirements . empty ( ) | | hasBits ,
bitmask . second . xmlLine ,
" bitmask < " + bitmask . first + " > references the undefined requires < " + bitmask . second . requirements + " > " ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : string strippedBitmaskName = stripPrefix ( bitmask . first , " Vk " ) ;
std : : string strippedEnumName = hasBits ? stripPrefix ( bitmaskBits - > first , " Vk " ) : " " ;
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! bitmask . second . alias . empty ( ) , bitmask . second . platform ) ;
appendBitmask ( str ,
strippedBitmaskName ,
bitmask . second . type ,
bitmask . second . alias ,
strippedEnumName ,
hasBits ? bitmaskBits - > second . values : std : : vector < EnumValueData > ( ) ) ;
appendBitmaskToStringFunction (
str , strippedBitmaskName , strippedEnumName , hasBits ? bitmaskBits - > second . values : std : : vector < EnumValueData > ( ) ) ;
appendPlatformLeave ( str , ! bitmask . second . alias . empty ( ) , bitmask . second . platform ) ;
}
}
void VulkanHppGenerator : : appendBitmask ( std : : string & str ,
std : : string const & bitmaskName ,
std : : string const & bitmaskType ,
std : : string const & bitmaskAlias ,
std : : string const & enumName ,
std : : vector < EnumValueData > const & enumValues ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter
2020-01-13 14:00:59 +00:00
// if there's no enum for the FlagBits, introduce an artificial empty one
std : : string emptyEnumName ;
2020-04-12 19:49:12 +00:00
if ( enumName . empty ( ) )
2020-01-13 14:00:59 +00:00
{
emptyEnumName = bitmaskName ;
2020-04-12 19:49:12 +00:00
size_t pos = emptyEnumName . rfind ( " Flags " ) ;
assert ( pos ! = std : : string : : npos ) ;
emptyEnumName . replace ( pos , 5 , " FlagBits " ) ;
2020-01-13 14:00:59 +00:00
// if this emptyEnumName is not in the list of enums, list it here
2020-04-12 19:49:12 +00:00
if ( m_enums . find ( " Vk " + emptyEnumName ) = = m_enums . end ( ) )
2020-01-13 14:00:59 +00:00
{
2020-03-04 12:33:52 +00:00
const std : : string templateString = R " x( enum class ${enumName} : ${bitmaskType}
2020-01-13 14:00:59 +00:00
{ } ;
VULKAN_HPP_INLINE std : : string to_string ( $ { enumName } )
{
return " (void) " ;
}
) x " ;
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( templateString , { { " enumName " , emptyEnumName } , { " bitmaskType " , bitmaskType } } ) ;
2020-01-13 14:00:59 +00:00
}
}
2020-04-12 19:49:12 +00:00
std : : string name = ( enumName . empty ( ) ? emptyEnumName : enumName ) ;
str + =
" \n "
" using " +
bitmaskName + " = Flags< " + name + " >; \n " ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
if ( ! enumValues . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string allFlags ;
2020-04-12 19:49:12 +00:00
for ( auto const & value : enumValues )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! allFlags . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
allFlags + = " | " ;
2019-01-09 10:55:11 +00:00
}
2020-03-04 12:33:52 +00:00
allFlags + = bitmaskType + " ( " + enumName + " :: " + value . vkValue + " ) " ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
static const std : : string bitmaskOperatorsTemplate = R " (
2019-10-10 11:29:59 +00:00
template < > struct FlagTraits < $ { enumName } >
{
2020-03-04 12:33:52 +00:00
enum : $ { bitmaskType }
2019-10-10 11:29:59 +00:00
{
allFlags = $ { allFlags }
} ;
} ;
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR $ { bitmaskName } operator | ( $ { enumName } bit0 , $ { enumName } bit1 ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
return $ { bitmaskName } ( bit0 ) | bit1 ;
2019-01-09 10:55:11 +00:00
}
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR $ { bitmaskName } operator & ( $ { enumName } bit0 , $ { enumName } bit1 ) VULKAN_HPP_NOEXCEPT
2019-10-10 11:29:59 +00:00
{
return $ { bitmaskName } ( bit0 ) & bit1 ;
}
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR $ { bitmaskName } operator ^ ( $ { enumName } bit0 , $ { enumName } bit1 ) VULKAN_HPP_NOEXCEPT
2019-10-10 11:29:59 +00:00
{
return $ { bitmaskName } ( bit0 ) ^ bit1 ;
}
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR $ { bitmaskName } operator ~ ( $ { enumName } bits ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
return ~ ( $ { bitmaskName } ( bits ) ) ;
}
) " ;
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( bitmaskOperatorsTemplate ,
{ { " bitmaskName " , bitmaskName } ,
{ " bitmaskType " , bitmaskType } ,
{ " enumName " , enumName } ,
{ " allFlags " , allFlags } } ) ;
2019-07-23 07:28:14 +00:00
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( ! bitmaskAlias . empty ( ) )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
" using " +
stripPrefix ( bitmaskAlias , " Vk " ) + " = " + bitmaskName + " ; \n " ;
2019-07-23 07:28:14 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendBitmaskToStringFunction ( std : : string & str ,
std : : string const & bitmaskName ,
std : : string const & enumName ,
std : : vector < EnumValueData > const & enumValues ) const
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
" VULKAN_HPP_INLINE std::string to_string( " +
bitmaskName + ( enumValues . empty ( ) ? " " : " value " ) +
" ) \n "
2019-08-27 07:02:49 +00:00
" { \n " ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
if ( enumValues . empty ( ) )
2019-07-23 07:28:14 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " \n return \" {} \" ; \n " ;
2019-07-23 07:28:14 +00:00
}
else
{
2019-08-27 07:02:49 +00:00
// 'or' together all the bits in the value
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-08-27 07:02:49 +00:00
" if ( !value ) return \" {} \" ; \n "
" std::string result; \n " ;
2020-04-12 19:49:12 +00:00
for ( auto const & evd : enumValues )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( evd . singleBit )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
" if ( value & " +
enumName + " :: " + evd . vkValue + " ) result += \" " + evd . vkValue . substr ( 1 ) + " | \" ; " ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-08-27 07:02:49 +00:00
" return \" { \" + result.substr(0, result.size() - 3) + \" } \" ; \n " ;
2019-07-23 07:28:14 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " } \n " ;
2019-07-23 07:28:14 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendCall ( std : : string & str ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
bool firstCall ,
bool singular ) const
2019-01-09 10:55:11 +00:00
{
// the original function call
2020-03-25 10:00:02 +00:00
str + = " d. " + name + " ( " ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
if ( ! handle . empty ( ) )
2019-01-09 10:55:11 +00:00
{
// if it's member of a class -> the first argument is the member variable, starting with "m_"
2020-04-12 19:49:12 +00:00
assert ( handle = = commandData . params [ 0 ] . type . type ) ;
str + = " m_ " + startLowerCase ( stripPrefix ( handle , " Vk " ) ) ;
if ( 1 < commandData . params . size ( ) )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " , " ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
appendArguments ( str ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
firstCall ,
singular ,
handle . empty ( ) ? 0 : 1 ,
commandData . params . size ( ) ) ;
2019-08-27 07:02:49 +00:00
str + = " ) " ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendCommand ( std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
bool definition ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
bool twoStep = isTwoStepAlgorithm ( commandData . params ) ;
std : : map < size_t , size_t > vectorParamIndices = determineVectorParamIndices ( commandData . params ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
size_t returnParamIndex = determineReturnParamIndex ( commandData , vectorParamIndices , twoStep ) ;
bool isStructureChain =
( returnParamIndex ! = INVALID_INDEX ) & &
determineStructureChaining ( commandData . params [ returnParamIndex ] . type . type , m_extendedStructs , m_structureAliases ) ;
std : : string enhancedReturnType =
determineEnhancedReturnType ( commandData ,
returnParamIndex ,
vectorParamIndices ,
false ) ; // get the enhanced return type without structureChain
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
size_t templateParamIndex = determineTemplateParamIndex ( commandData . params , vectorParamIndices ) ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// first create the standard version of the function
std : : string standard ;
2020-04-12 19:49:12 +00:00
appendFunction ( standard ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
false ,
false ,
false ,
false ,
false ) ;
2019-07-23 07:28:14 +00:00
2019-08-27 07:02:49 +00:00
// then the enhanced version, composed by up to eight parts
std : : string enhanced ;
2020-04-12 19:49:12 +00:00
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
false ,
false ,
false ,
false ) ;
if ( enhancedReturnType . find ( " Allocator " ) ! = std : : string : : npos )
{
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
false ,
false ,
false ,
true ) ;
}
if ( isStructureChain )
{
std : : string enhancedReturnTypeWithStructureChain =
determineEnhancedReturnType ( commandData , returnParamIndex , vectorParamIndices , true ) ;
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnTypeWithStructureChain ,
definition ,
true ,
false ,
false ,
true ,
false ) ;
if ( enhancedReturnTypeWithStructureChain . find ( " Allocator " ) ! = std : : string : : npos )
{
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnTypeWithStructureChain ,
definition ,
true ,
false ,
false ,
true ,
true ) ;
2019-07-23 07:28:14 +00:00
}
}
2019-08-27 07:02:49 +00:00
// then a singular version, if a sized vector would be returned
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator returnVector = vectorParamIndices . find ( returnParamIndex ) ;
bool singular = ( returnVector ! = vectorParamIndices . end ( ) ) & & ( returnVector - > second ! = INVALID_INDEX ) & &
( commandData . params [ returnVector - > first ] . type . type ! = " void " ) & &
( commandData . params [ returnVector - > second ] . type . postfix . empty ( ) | |
( commandData . params [ returnVector - > second ] . type . postfix . back ( ) ! = ' * ' ) ) ;
if ( singular )
{
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
true ,
false ,
false ,
false ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// special handling for createDevice and createInstance !
2020-04-12 19:49:12 +00:00
bool specialWriteUnique = ( name = = " vkCreateDevice " ) | | ( name = = " vkCreateInstance " ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
// and then the same for the Unique* versions (a deleteCommand is available for the commandData's class, and the
// function starts with 'allocate' or 'create')
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
auto handleIt = m_handles . find ( m_commandToHandle . find ( name ) - > second ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
if ( ( ! handleIt - > second . deleteCommand . empty ( ) | | specialWriteUnique ) & &
( ( name . substr ( 2 , 8 ) = = " Allocate " ) | | ( name . substr ( 2 , 6 ) = = " Create " ) | |
( ( name . substr ( 2 , 8 ) = = " Register " ) & & ( returnParamIndex + 1 = = commandData . params . size ( ) ) ) ) )
2019-08-27 07:02:49 +00:00
{
enhanced + = " #ifndef VULKAN_HPP_NO_SMART_HANDLE \n " ;
2020-04-12 19:49:12 +00:00
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
false ,
true ,
false ,
false ) ;
if ( enhancedReturnType . find ( " Allocator " ) ! = std : : string : : npos )
{
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
false ,
true ,
false ,
true ) ;
}
if ( singular )
{
appendFunction ( enhanced ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
definition ,
true ,
true ,
true ,
false ,
false ) ;
2019-08-27 07:02:49 +00:00
}
enhanced + = " #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ \n " ;
}
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// and append one or both of them
2020-04-12 19:49:12 +00:00
if ( standard = = enhanced )
2019-08-27 07:02:49 +00:00
{
// standard and enhanced string are equal -> just use one of them and we're done
str + = standard ;
}
else
{
// standard and enhanced string differ -> use both, wrapping the enhanced by !VULKAN_HPP_DISABLE_ENHANCED_MODE
// determine the argument list of that standard, and compare it with that of the enhanced
// if they are equal -> need to have just one; if they differ -> need to have both
2020-04-12 19:49:12 +00:00
size_t standardStart = standard . find ( ' ( ' ) ;
size_t standardCount = standard . find ( ' ) ' , standardStart ) - standardStart ;
size_t enhancedStart = enhanced . find ( ' ( ' ) ;
bool unchangedInterface =
( standard . substr ( standardStart , standardCount ) = = enhanced . substr ( enhancedStart , standardCount ) ) ;
if ( unchangedInterface )
2019-08-27 07:02:49 +00:00
{
str + = " #ifdef VULKAN_HPP_DISABLE_ENHANCED_MODE \n " ;
}
2020-04-12 19:49:12 +00:00
str + = standard + ( unchangedInterface ? " #else " : " #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE " ) + " \n " + enhanced +
" #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/ \n " ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendDispatchLoaderDynamic ( std : : string & str )
2018-09-25 09:23:27 +00:00
{
2019-09-24 10:12:49 +00:00
str + = R " (
2019-10-01 01:14:22 +00:00
# if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL
2019-09-24 10:12:49 +00:00
class DynamicLoader
{
public :
2019-10-23 08:52:29 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
2019-10-25 11:21:49 +00:00
DynamicLoader ( ) VULKAN_HPP_NOEXCEPT : m_success ( false )
2019-10-23 08:52:29 +00:00
# else
2019-09-24 10:12:49 +00:00
DynamicLoader ( ) : m_success ( false )
2019-10-23 08:52:29 +00:00
# endif
2019-09-24 10:12:49 +00:00
{
# if defined(__linux__)
m_library = dlopen ( " libvulkan.so " , RTLD_NOW | RTLD_LOCAL ) ;
2019-10-17 07:59:35 +00:00
# elif defined(__APPLE__)
m_library = dlopen ( " libvulkan.dylib " , RTLD_NOW | RTLD_LOCAL ) ;
2019-09-24 10:12:49 +00:00
# elif defined(_WIN32)
2019-11-06 13:44:33 +00:00
m_library = LoadLibrary ( TEXT ( " vulkan-1.dll " ) ) ;
2019-09-24 10:12:49 +00:00
# else
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( false & & " unsupported platform " ) ;
2019-09-24 10:12:49 +00:00
# endif
m_success = m_library ! = 0 ;
# ifndef VULKAN_HPP_NO_EXCEPTIONS
if ( ! m_success )
{
// NOTE there should be an InitializationFailedError, but msvc insists on the symbol does not exist within the scope of this function.
throw std : : runtime_error ( " Failed to load vulkan library! " ) ;
}
# endif
}
2020-02-16 02:57:27 +00:00
DynamicLoader ( DynamicLoader const & ) = delete ;
DynamicLoader ( DynamicLoader & & other ) VULKAN_HPP_NOEXCEPT
: m_success ( other . m_success )
, m_library ( other . m_library )
{
other . m_library = nullptr ;
}
DynamicLoader & operator = ( DynamicLoader const & ) = delete ;
DynamicLoader & operator = ( DynamicLoader & & other ) VULKAN_HPP_NOEXCEPT
{
m_success = other . m_success ;
2020-02-22 06:08:03 +00:00
std : : swap ( m_library , other . m_library ) ;
2020-02-16 02:57:27 +00:00
return * this ;
}
2019-10-23 08:52:29 +00:00
~ DynamicLoader ( ) VULKAN_HPP_NOEXCEPT
2019-09-24 10:12:49 +00:00
{
if ( m_library )
{
2019-10-17 07:59:35 +00:00
# if defined(__linux__) || defined(__APPLE__)
2019-09-24 10:12:49 +00:00
dlclose ( m_library ) ;
# elif defined(_WIN32)
FreeLibrary ( m_library ) ;
# endif
}
}
template < typename T >
2019-10-23 08:52:29 +00:00
T getProcAddress ( const char * function ) const VULKAN_HPP_NOEXCEPT
2019-09-24 10:12:49 +00:00
{
2019-10-17 07:59:35 +00:00
# if defined(__linux__) || defined(__APPLE__)
2019-09-24 10:12:49 +00:00
return ( T ) dlsym ( m_library , function ) ;
# elif defined(_WIN32)
return ( T ) GetProcAddress ( m_library , function ) ;
# endif
}
2019-10-23 08:52:29 +00:00
bool success ( ) const VULKAN_HPP_NOEXCEPT { return m_success ; }
2019-09-24 10:12:49 +00:00
private :
bool m_success ;
2019-10-17 07:59:35 +00:00
# if defined(__linux__) || defined(__APPLE__)
2019-09-24 10:12:49 +00:00
void * m_library ;
# elif defined(_WIN32)
HMODULE m_library ;
# else
# error unsupported platform
# endif
} ;
2019-10-01 01:14:22 +00:00
# endif
2019-09-24 10:12:49 +00:00
) " ;
2019-08-27 07:02:49 +00:00
str + = R " (
class DispatchLoaderDynamic
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
public :
) " ;
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & command : handle . second . commands )
2019-08-27 07:02:49 +00:00
{
std : : string enter , leave ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( enter , ! command . second . aliases . empty ( ) , command . second . platform ) ;
appendPlatformLeave ( leave , ! command . second . aliases . empty ( ) , command . second . platform ) ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
str + = enter + " PFN_ " + command . first + " " + command . first + " = 0; \n " + leave ;
2020-04-12 19:49:12 +00:00
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( enter . empty ( ) & & leave . empty ( ) ) ;
2020-03-02 11:32:42 +00:00
str + = " PFN_ " + alias + " " + alias + " = 0; \n " ;
}
2019-08-27 07:02:49 +00:00
}
}
2018-09-25 09:23:27 +00:00
2019-09-26 07:55:15 +00:00
std : : string emptyFunctions ;
std : : string strDeviceFunctions ;
std : : string strDeviceFunctionsInstance ;
std : : string strInstanceFunctions ;
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2019-09-26 07:55:15 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & command : handle . second . commands )
2019-09-26 07:55:15 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( command . first ! = " vkGetInstanceProcAddr " ) )
2019-09-26 07:55:15 +00:00
{
std : : string enter , leave ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( enter , ! command . second . aliases . empty ( ) , command . second . platform ) ;
appendPlatformLeave ( leave , ! command . second . aliases . empty ( ) , command . second . platform ) ;
2019-09-26 07:55:15 +00:00
2020-04-12 19:49:12 +00:00
if ( handle . first . empty ( ) )
2019-09-26 07:55:15 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( command . second . aliases . empty ( ) ) ;
2019-09-26 07:55:15 +00:00
emptyFunctions + = enter ;
2020-04-12 19:49:12 +00:00
emptyFunctions + = " " + command . first + " = PFN_ " + command . first + " ( vkGetInstanceProcAddr( NULL, \" " +
command . first + " \" ) ); \n " ;
2019-09-26 07:55:15 +00:00
emptyFunctions + = leave ;
}
2020-04-12 19:49:12 +00:00
else if ( ! command . second . params . empty ( ) & &
m_handles . find ( command . second . params [ 0 ] . type . type ) ! = m_handles . end ( ) & &
command . second . params [ 0 ] . type . type ! = " VkInstance " & &
command . second . params [ 0 ] . type . type ! = " VkPhysicalDevice " )
2019-09-26 07:55:15 +00:00
{
strDeviceFunctions + = enter ;
2020-04-12 19:49:12 +00:00
strDeviceFunctions + = " " + command . first + " = PFN_ " + command . first +
" ( vkGetDeviceProcAddr( device, \" " + command . first + " \" ) ); \n " ;
2019-09-26 07:55:15 +00:00
strDeviceFunctions + = leave ;
strDeviceFunctionsInstance + = enter ;
2020-04-12 19:49:12 +00:00
strDeviceFunctionsInstance + = " " + command . first + " = PFN_ " + command . first +
" ( vkGetInstanceProcAddr( instance, \" " + command . first + " \" ) ); \n " ;
2019-09-26 07:55:15 +00:00
strDeviceFunctionsInstance + = leave ;
2020-03-02 11:32:42 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( enter . empty ( ) & & leave . empty ( ) ) ;
strDeviceFunctions + =
" " + alias + " = PFN_ " + alias + " ( vkGetDeviceProcAddr( device, \" " + alias + " \" ) ); \n " ;
strDeviceFunctionsInstance + =
" " + alias + " = PFN_ " + alias + " ( vkGetInstanceProcAddr( instance, \" " + alias + " \" ) ); \n " ;
2020-03-02 11:32:42 +00:00
}
2019-09-26 07:55:15 +00:00
}
else
{
strInstanceFunctions + = enter ;
2020-04-12 19:49:12 +00:00
strInstanceFunctions + = " " + command . first + " = PFN_ " + command . first +
" ( vkGetInstanceProcAddr( instance, \" " + command . first + " \" ) ); \n " ;
2019-09-26 07:55:15 +00:00
strInstanceFunctions + = leave ;
2020-03-02 11:32:42 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( enter . empty ( ) & & leave . empty ( ) ) ;
strInstanceFunctions + =
" " + alias + " = PFN_ " + alias + " ( vkGetInstanceProcAddr( instance, \" " + alias + " \" ) ); \n " ;
2020-03-02 11:32:42 +00:00
}
2019-09-26 07:55:15 +00:00
}
}
}
}
2019-08-27 07:02:49 +00:00
// append initialization function to fetch function pointers
str + = R " (
public :
2019-10-23 08:52:29 +00:00
DispatchLoaderDynamic ( ) VULKAN_HPP_NOEXCEPT = default ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
# if !defined(VK_NO_PROTOTYPES)
// This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
2020-02-03 14:52:53 +00:00
template < typename DynamicLoader >
void init ( VULKAN_HPP_NAMESPACE : : Instance const & instance , VULKAN_HPP_NAMESPACE : : Device const & device , DynamicLoader const & dl ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-02-03 14:52:53 +00:00
PFN_vkGetInstanceProcAddr getInstanceProcAddr = dl . template getProcAddress < PFN_vkGetInstanceProcAddr > ( " vkGetInstanceProcAddr " ) ;
PFN_vkGetDeviceProcAddr getDeviceProcAddr = dl . template getProcAddress < PFN_vkGetDeviceProcAddr > ( " vkGetDeviceProcAddr " ) ;
init ( static_cast < VkInstance > ( instance ) , getInstanceProcAddr , static_cast < VkDevice > ( device ) , device ? getDeviceProcAddr : nullptr ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
2020-02-03 14:52:53 +00:00
template < typename DynamicLoader
# if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL
= vk : : DynamicLoader
# endif
>
2019-12-02 09:06:44 +00:00
void init ( VULKAN_HPP_NAMESPACE : : Instance const & instance , VULKAN_HPP_NAMESPACE : : Device const & device ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
2020-02-03 14:52:53 +00:00
static DynamicLoader dl ;
init ( instance , device , dl ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
# endif // !defined(VK_NO_PROTOTYPES)
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
DispatchLoaderDynamic ( PFN_vkGetInstanceProcAddr getInstanceProcAddr ) VULKAN_HPP_NOEXCEPT
2019-09-24 10:12:49 +00:00
{
init ( getInstanceProcAddr ) ;
}
2019-10-23 08:52:29 +00:00
void init ( PFN_vkGetInstanceProcAddr getInstanceProcAddr ) VULKAN_HPP_NOEXCEPT
2019-09-24 10:12:49 +00:00
{
VULKAN_HPP_ASSERT ( getInstanceProcAddr ) ;
vkGetInstanceProcAddr = getInstanceProcAddr ;
2019-09-26 07:55:15 +00:00
) " ;
str + = emptyFunctions ;
str + = R " ( }
2019-09-24 10:12:49 +00:00
2019-08-27 07:02:49 +00:00
// This interface does not require a linked vulkan library.
2019-10-23 08:52:29 +00:00
DispatchLoaderDynamic ( VkInstance instance , PFN_vkGetInstanceProcAddr getInstanceProcAddr , VkDevice device = VK_NULL_HANDLE , PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
init ( instance , getInstanceProcAddr , device , getDeviceProcAddr ) ;
}
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// This interface does not require a linked vulkan library.
2019-10-23 08:52:29 +00:00
void init ( VkInstance instance , PFN_vkGetInstanceProcAddr getInstanceProcAddr , VkDevice device = VK_NULL_HANDLE , PFN_vkGetDeviceProcAddr /*getDeviceProcAddr*/ = nullptr ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
VULKAN_HPP_ASSERT ( instance & & getInstanceProcAddr ) ;
vkGetInstanceProcAddr = getInstanceProcAddr ;
2019-12-02 09:06:44 +00:00
init ( VULKAN_HPP_NAMESPACE : : Instance ( instance ) ) ;
2019-09-25 09:59:39 +00:00
if ( device ) {
2019-12-02 09:06:44 +00:00
init ( VULKAN_HPP_NAMESPACE : : Device ( device ) ) ;
2019-09-25 09:59:39 +00:00
}
}
2019-12-02 09:06:44 +00:00
void init ( VULKAN_HPP_NAMESPACE : : Instance instanceCpp ) VULKAN_HPP_NOEXCEPT
2019-09-25 09:59:39 +00:00
{
2019-11-06 12:52:41 +00:00
VkInstance instance = static_cast < VkInstance > ( instanceCpp ) ;
2019-08-27 07:02:49 +00:00
) " ;
2019-01-09 10:55:11 +00:00
2019-09-25 09:59:39 +00:00
str + = strInstanceFunctions ;
str + = strDeviceFunctionsInstance ;
str + = " } \n \n " ;
2019-12-02 09:06:44 +00:00
str + = " void init( VULKAN_HPP_NAMESPACE::Device deviceCpp ) VULKAN_HPP_NOEXCEPT \n { \n " ;
2019-11-06 12:52:41 +00:00
str + = " VkDevice device = static_cast<VkDevice>(deviceCpp); \n " ;
2019-09-25 09:59:39 +00:00
str + = strDeviceFunctions ;
str + = R " ( }
} ;
) " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendDispatchLoaderStatic ( std : : string & str )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = R " (
2019-09-25 09:59:39 +00:00
# if !defined(VK_NO_PROTOTYPES)
2019-08-27 07:02:49 +00:00
class DispatchLoaderStatic
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
public : ) " ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & command : handle . second . commands )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string parameterList , parameters ;
2020-04-12 19:49:12 +00:00
bool firstParam = true ;
for ( auto param : command . second . params )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! firstParam )
2019-08-27 07:02:49 +00:00
{
parameterList + = " , " ;
parameters + = " , " ;
}
2020-04-12 19:49:12 +00:00
parameterList + = param . type . prefix + ( param . type . prefix . empty ( ) ? " " : " " ) + param . type . type +
param . type . postfix + " " + param . name + constructCArraySizes ( param . arraySizes ) ;
2019-08-27 07:02:49 +00:00
parameters + = param . name ;
firstParam = false ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string commandName = stripPrefix ( command . first , " vk " ) ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
str + = " " + command . second . returnType + " vk " + commandName + " ( " + parameterList +
" ) const VULKAN_HPP_NOEXCEPT \n "
" { \n "
" return ::vk " +
commandName + " ( " + parameters +
" ); \n "
" } \n " ;
appendPlatformLeave ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
commandName = stripPrefix ( alias , " vk " ) ;
str + =
" \n "
" " +
command . second . returnType + " vk " + commandName + " ( " + parameterList +
" ) const VULKAN_HPP_NOEXCEPT \n "
2020-03-02 11:32:42 +00:00
" { \n "
2020-04-12 19:49:12 +00:00
" return ::vk " +
commandName + " ( " + parameters +
" ); \n "
2020-03-02 11:32:42 +00:00
" } \n " ;
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-09-25 09:59:39 +00:00
str + = " }; \n #endif \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendDispatchLoaderDefault ( std : : string & str )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-09-25 09:59:39 +00:00
R " ( class DispatchLoaderDynamic;
# if !defined(VULKAN_HPP_DISPATCH_LOADER_DYNAMIC)
# if defined(VK_NO_PROTOTYPES)
# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
2019-10-23 08:52:29 +00:00
# else
2019-09-25 09:59:39 +00:00
# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 0
# endif
# endif
# if !defined(VULKAN_HPP_DEFAULT_DISPATCHER)
# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
2019-12-02 09:06:44 +00:00
# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::defaultDispatchLoaderDynamic
# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE namespace VULKAN_HPP_NAMESPACE { DispatchLoaderDynamic defaultDispatchLoaderDynamic; }
2019-09-25 13:01:29 +00:00
extern DispatchLoaderDynamic defaultDispatchLoaderDynamic ;
2019-10-23 08:52:29 +00:00
# else
2019-12-02 09:06:44 +00:00
# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic()
2019-09-25 13:01:29 +00:00
# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
2019-09-25 09:59:39 +00:00
# endif
# endif
# if !defined(VULKAN_HPP_DEFAULT_DISPATCHER_TYPE)
# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
2019-12-02 09:06:44 +00:00
# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderDynamic
2019-10-23 08:52:29 +00:00
# else
2019-12-02 09:06:44 +00:00
# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic
2019-09-25 09:59:39 +00:00
# endif
2019-08-27 07:02:49 +00:00
# endif
) " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendEnum ( std : : string & str , std : : pair < std : : string , EnumData > const & enumData ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " enum class " + stripPrefix ( enumData . first , " Vk " ) ;
if ( enumData . second . isBitmask )
2020-02-20 11:04:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto bitmaskIt = std : : find_if ( m_bitmasks . begin ( ) , m_bitmasks . end ( ) , [ & enumData ] ( auto const & bitmask ) {
return bitmask . second . requirements = = enumData . first ;
} ) ;
assert ( bitmaskIt ! = m_bitmasks . end ( ) ) ;
2020-02-20 11:04:27 +00:00
str + = " : " + bitmaskIt - > first ;
}
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-08-27 07:02:49 +00:00
" { " ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
bool first = true ;
2020-04-12 19:49:12 +00:00
for ( auto const & value : enumData . second . values )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! first )
2019-01-14 09:09:19 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " , " ;
2019-01-14 09:09:19 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " \n " + value . vkValue + " = " + value . vulkanValue ;
first = false ;
}
2020-04-30 09:30:17 +00:00
for ( auto const & alias : enumData . second . aliases )
2019-08-27 07:02:49 +00:00
{
// make sure to only list alias values that differ from all non-alias values
2020-04-12 19:49:12 +00:00
if ( std : : find_if (
2020-04-30 09:30:17 +00:00
enumData . second . values . begin ( ) , enumData . second . values . end ( ) , [ & alias ] ( EnumValueData const & evd ) {
return alias . second . second = = evd . vkValue ;
2020-04-12 19:49:12 +00:00
} ) = = enumData . second . values . end ( ) )
2019-01-14 09:09:19 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! first )
2019-08-27 07:02:49 +00:00
{
str + = " , " ;
}
2020-04-30 09:30:17 +00:00
str + = " \n " + alias . second . second + " = " + alias . first ;
2019-08-27 07:02:49 +00:00
first = false ;
2019-01-14 09:09:19 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! first )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " }; \n " ;
2020-01-13 14:00:59 +00:00
2020-04-12 19:49:12 +00:00
if ( ! enumData . second . alias . empty ( ) )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" using " + stripPrefix ( enumData . second . alias , " Vk " ) + " = " + stripPrefix ( enumData . first , " Vk " ) + " ; \n " ;
2020-01-13 14:00:59 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendEnums ( std : : string & str ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & e : m_enums )
2019-08-27 07:02:49 +00:00
{
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! e . second . alias . empty ( ) , e . second . platform ) ;
appendEnum ( str , e ) ;
appendEnumToString ( str , e ) ;
2020-04-21 12:26:32 +00:00
if ( e . first = = " VkObjectType " )
{
str + = R " (
template < ObjectType value >
2020-04-25 22:10:16 +00:00
struct VULKAN_HPP_DEPRECATED ( " vk::cpp_type is deprecated. Use vk::CppType instead. " ) cpp_type
2020-04-21 12:26:32 +00:00
{ } ;
) " ;
}
2020-04-12 19:49:12 +00:00
if ( e . second . alias . empty ( ) ) // enums with an alias are not protected anymore !
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! e . second . alias . empty ( ) , e . second . platform ) ;
2020-03-02 11:32:42 +00:00
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendEnumInitializer ( std : : string & str ,
TypeData const & type ,
std : : vector < std : : string > const & arraySizes ,
2020-04-29 09:45:10 +00:00
std : : vector < EnumValueData > const & values ) const
2020-03-10 08:47:59 +00:00
{
// enum arguments might need special initialization
2020-04-12 19:49:12 +00:00
assert ( type . prefix . empty ( ) & & ! values . empty ( ) ) ;
std : : string value = " VULKAN_HPP_NAMESPACE:: " + stripPrefix ( type . type , " Vk " ) + " :: " + values . front ( ) . vkValue ;
if ( arraySizes . empty ( ) )
2020-03-10 08:47:59 +00:00
{
str + = value ;
}
else
{
2020-04-12 19:49:12 +00:00
assert ( arraySizes . size ( ) = = 1 ) ;
int count = std : : stoi ( arraySizes [ 0 ] ) ;
assert ( 1 < count ) ;
2020-04-29 09:45:10 +00:00
str + = " { { " + value ;
2020-04-12 19:49:12 +00:00
for ( int i = 1 ; i < count ; i + + )
2020-03-10 08:47:59 +00:00
{
str + = " , " + value ;
}
2020-04-29 09:45:10 +00:00
str + = " } } " ;
2020-03-10 08:47:59 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendEnumToString ( std : : string & str ,
std : : pair < std : : string , EnumData > const & enumData ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string enumName = stripPrefix ( enumData . first , " Vk " ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
str + =
" \n "
" VULKAN_HPP_INLINE std::string to_string( " +
enumName + ( enumData . second . values . empty ( ) ? " " : " value " ) +
" ) \n "
2019-08-27 07:02:49 +00:00
" { " ;
2020-04-12 19:49:12 +00:00
if ( enumData . second . values . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-08-27 07:02:49 +00:00
" return \" (void) \" ; \n " ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
else
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-08-27 07:02:49 +00:00
" switch ( value ) \n "
" { \n " ;
2020-04-12 19:49:12 +00:00
for ( auto const & value : enumData . second . values )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " case " + enumName + " :: " + value . vkValue + " : return \" " + value . vkValue . substr ( 1 ) + " \" ; \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
str + =
" default: return \" invalid \" ; \n "
2019-08-27 07:02:49 +00:00
" } \n " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " } \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendForwardDeclarations ( std : : string & str ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2020-04-12 19:49:12 +00:00
for ( auto const & structure : m_structures )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
str + = std : : string ( " " ) + ( structure . second . isUnion ? " union " : " struct " ) + " " +
stripPrefix ( structure . first , " Vk " ) + " ; \n " ;
for ( std : : string const & alias : structure . second . aliases )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " using " + stripPrefix ( alias , " Vk " ) + " = " + stripPrefix ( structure . first , " Vk " ) + " ; \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
bool needsMultiVectorSizeCheck ( size_t returnParamIndex , std : : map < size_t , size_t > const & vectorParamIndices )
2019-10-30 09:10:32 +00:00
{
2020-04-12 19:49:12 +00:00
for ( std : : map < size_t , size_t > : : const_iterator it0 = vectorParamIndices . begin ( ) ; it0 ! = vectorParamIndices . end ( ) ;
+ + it0 )
2019-10-30 09:10:32 +00:00
{
2020-04-12 19:49:12 +00:00
if ( it0 - > first ! = returnParamIndex )
2019-10-30 09:10:32 +00:00
{
2020-04-12 19:49:12 +00:00
for ( std : : map < size_t , size_t > : : const_iterator it1 = std : : next ( it0 ) ; it1 ! = vectorParamIndices . end ( ) ; + + it1 )
2019-10-30 09:10:32 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( it1 - > first ! = returnParamIndex ) & & ( it0 - > second = = it1 - > second ) )
2019-10-30 09:10:32 +00:00
{
return true ;
}
}
}
}
return false ;
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunction ( std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
std : : string const & enhancedReturnType ,
bool definition ,
bool enhanced ,
bool singular ,
bool unique ,
bool isStructureChain ,
bool withAllocator ) const
{
appendFunctionHeaderTemplate ( str ,
indentation ,
returnParamIndex ,
templateParamIndex ,
enhancedReturnType ,
enhanced ,
singular ,
unique ,
! definition ,
isStructureChain ) ;
str + = indentation + ( definition ? " VULKAN_HPP_INLINE " : " " ) ;
appendFunctionHeaderReturnType ( str ,
commandData ,
returnParamIndex ,
vectorParamIndices ,
enhancedReturnType ,
enhanced ,
twoStep ,
singular ,
unique ,
isStructureChain ) ;
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
if ( definition & & ! handle . empty ( ) )
{
str + = stripPrefix ( handle , " Vk " ) + " :: " ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
// append the function header name
2020-04-12 19:49:12 +00:00
std : : string commandName = determineCommandName ( name , commandData . params [ 0 ] . type . type ) ;
str + = ( singular ? stripPluralS ( commandName ) : commandName ) ;
if ( unique )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " Unique " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
appendFunctionHeaderArguments ( str ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
enhanced ,
singular ,
! definition ,
withAllocator ) ;
2019-10-23 08:52:29 +00:00
// Any function that originally does not return VkResult can be marked noexcept,
2020-01-14 09:37:54 +00:00
// if it is enhanced it must not include anything with an Allocator or needs size checks on multiple vectors
2020-04-12 19:49:12 +00:00
bool hasAllocator = enhancedReturnType . find ( " Allocator " ) ! = std : : string : : npos ;
if ( ! enhanced | |
( commandData . returnType ! = " VkResult " & &
! ( enhanced & & ( hasAllocator | | needsMultiVectorSizeCheck ( returnParamIndex , vectorParamIndices ) ) ) ) )
2019-10-23 08:52:29 +00:00
{
str + = " VULKAN_HPP_NOEXCEPT " ;
}
2020-04-12 19:49:12 +00:00
str + = std : : string ( definition ? " " : " ; " ) + " \n " ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( definition )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// append the function body
str + = indentation + " { \n " ;
2020-04-12 19:49:12 +00:00
if ( enhanced )
{
appendFunctionBodyEnhanced ( str ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
singular ,
unique ,
isStructureChain ,
withAllocator ) ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
else
{
2020-04-12 19:49:12 +00:00
appendFunctionBodyStandard ( str , indentation , name , commandData ) ;
2019-08-27 07:02:49 +00:00
}
str + = indentation + " } \n " ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhanced ( std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
std : : string const & enhancedReturnType ,
bool singular ,
bool unique ,
bool isStructureChain ,
bool withAllocator ) const
{
if ( unique & & ! singular & &
( vectorParamIndices . find ( returnParamIndex ) ! = vectorParamIndices . end ( ) ) ) // returns a vector of UniqueStuff
{
appendFunctionBodyEnhancedVectorOfUniqueHandles ( str ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
singular ,
withAllocator ) ;
}
else if ( isStructureChain & & ( vectorParamIndices . find ( returnParamIndex ) ! = vectorParamIndices . end ( ) ) )
{
appendFunctionBodyEnhancedVectorOfStructureChain (
str , indentation , name , commandData , returnParamIndex , vectorParamIndices , withAllocator ) ;
2019-11-13 09:04:50 +00:00
}
2019-01-09 10:55:11 +00:00
else
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( 1 < vectorParamIndices . size ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendFunctionBodyEnhancedMultiVectorSizeCheck (
str , indentation , name , commandData , returnParamIndex , vectorParamIndices ) ;
2019-08-27 07:02:49 +00:00
}
std : : string returnName ;
2020-04-12 19:49:12 +00:00
if ( returnParamIndex ! = INVALID_INDEX )
{
returnName = appendFunctionBodyEnhancedLocalReturnVariable ( str ,
indentation ,
commandData ,
returnParamIndex ,
vectorParamIndices ,
twoStep ,
enhancedReturnType ,
singular ,
isStructureChain ,
withAllocator ) ;
}
if ( twoStep )
{
appendFunctionBodyEnhancedTwoStep ( str ,
indentation ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
singular ,
returnName ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
appendFunctionBodyEnhancedSingleStep (
str , indentation , name , commandData , returnParamIndex , templateParamIndex , vectorParamIndices , singular ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ( commandData . returnType = = " VkResult " ) | | ! commandData . successCodes . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendFunctionBodyEnhancedReturnResultValue (
str , indentation , returnName , name , commandData , returnParamIndex , twoStep , singular , unique ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( ( returnParamIndex ! = INVALID_INDEX ) & &
( stripPrefix ( commandData . returnType , " Vk " ) ! = enhancedReturnType ) )
2019-08-27 07:02:49 +00:00
{
// for the other returning cases, when the return type is somhow enhanced, just return the local returnVariable
str + = indentation + " return " + returnName + " ; \n " ;
}
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
std : : string VulkanHppGenerator : : appendFunctionBodyEnhancedLocalReturnVariable (
std : : string & str ,
std : : string const & indentation ,
CommandData const & commandData ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
std : : string const & enhancedReturnType ,
bool singular ,
bool isStructureChain ,
bool withAllocator ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string pureReturnType = stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) ;
std : : string returnName = startLowerCase ( stripPrefix ( commandData . params [ returnParamIndex ] . name , " p " ) ) ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// there is a returned parameter -> we need a local variable to hold that value
2020-04-12 19:49:12 +00:00
if ( stripPrefix ( commandData . returnType , " Vk " ) ! = enhancedReturnType )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// the returned parameter is somehow enhanced by us
str + = indentation + " " ;
2020-04-12 19:49:12 +00:00
if ( singular )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
returnName = appendFunctionBodyEnhancedLocalReturnVariableSingular (
str , indentation , returnName , pureReturnType , isStructureChain ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// in non-singular case, use the enhanced type for the return variable (like vector<...>)
2020-04-12 19:49:12 +00:00
if ( isStructureChain & & vectorParamIndices . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// For StructureChains use the template parameters
2020-04-12 19:49:12 +00:00
str + = " StructureChain<X, Y, Z...> structureChain; \n " + indentation + " " + enhancedReturnType + " & " +
returnName + " = structureChain.template get< " + enhancedReturnType + " >() " ;
2019-08-27 07:02:49 +00:00
returnName = " structureChain " ;
2019-01-09 10:55:11 +00:00
}
else
{
2019-08-27 07:02:49 +00:00
str + = enhancedReturnType + " " + returnName ;
}
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator vpiIt = vectorParamIndices . find ( returnParamIndex ) ;
if ( vpiIt ! = vectorParamIndices . end ( ) & & ! twoStep )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendFunctionBodyEnhancedLocalReturnVariableVectorSize (
str , commandData . params , * vpiIt , returnParamIndex , vectorParamIndices , withAllocator ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( withAllocator )
2019-08-27 07:02:49 +00:00
{
str + = " ( vectorAllocator ) " ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " ; \n " ;
}
else
{
2020-04-12 19:49:12 +00:00
// the return parameter is not enhanced -> the type is supposed to be a Result and there are more than one success
// codes!
assert ( ( commandData . returnType = = " VkResult " ) & & ( 1 < commandData . successCodes . size ( ) ) ) ;
2019-08-27 07:02:49 +00:00
str + = indentation + " " + pureReturnType + " " + returnName + " ; \n " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
return returnName ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhancedLocalReturnVariableVectorSize (
std : : string & str ,
std : : vector < ParamData > const & params ,
std : : pair < size_t , size_t > const & vectorParamIndex ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool withAllocator ) const
2018-10-15 12:27:42 +00:00
{
2019-08-27 07:02:49 +00:00
// if the return parameter is a vector parameter, and not part of a two-step algorithm, initialize its size
std : : string size ;
2020-04-12 19:49:12 +00:00
if ( vectorParamIndex . second = = INVALID_INDEX )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ! params [ returnParamIndex ] . len . empty ( ) ) ;
// the size of the vector is not given by an other parameter, but by some member of a parameter, described as
// 'parameter->member'
2020-04-17 18:17:45 +00:00
// -> replace the '->' by '.' and filter out the leading 'p' to access that value
2020-04-12 19:49:12 +00:00
size = startLowerCase ( stripPrefix ( params [ returnParamIndex ] . len , " p " ) ) ;
size_t pos = size . find ( " -> " ) ;
2020-04-17 18:17:45 +00:00
// older versions of the vk.xml used the notation parameter::member !
2020-04-12 19:49:12 +00:00
if ( pos = = std : : string : : npos )
2020-04-17 18:17:45 +00:00
{
2020-04-12 19:49:12 +00:00
pos = size . find ( " :: " ) ;
2020-04-17 18:17:45 +00:00
}
2020-04-12 19:49:12 +00:00
assert ( pos ! = std : : string : : npos ) ;
size . replace ( pos , 2 , " . " ) ;
2019-01-09 10:55:11 +00:00
}
else
2018-10-15 12:27:42 +00:00
{
2019-08-27 07:02:49 +00:00
// the size of the vector is given by an other parameter
// first check, if that size has become the size of some other vector parameter
// -> look for it and get it's actual size
2020-04-12 19:49:12 +00:00
for ( auto const & vpi : vectorParamIndices )
2018-10-15 12:27:42 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( vpi . first ! = vectorParamIndex . first ) & & ( vpi . second = = vectorParamIndex . second ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
size = startLowerCase ( stripPrefix ( params [ vpi . first ] . name , " p " ) ) + " .size() " ;
2019-08-27 07:02:49 +00:00
break ;
}
}
2020-04-12 19:49:12 +00:00
if ( size . empty ( ) )
2019-08-27 07:02:49 +00:00
{
// otherwise, just use that parameter
size = params [ vectorParamIndex . second ] . name ;
2018-10-15 12:27:42 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! size . empty ( ) ) ;
str + = " ( " + size + ( withAllocator ? " , vectorAllocator " : " " ) + " ) " ;
2018-10-15 12:27:42 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhancedMultiVectorSizeCheck (
std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string const sizeCheckTemplate =
R " #(#ifdef VULKAN_HPP_NO_EXCEPTIONS
$ { i } VULKAN_HPP_ASSERT ( $ { firstVectorName } . size ( ) = = $ { secondVectorName } . size ( ) ) ;
# else
$ { i } if ( $ { firstVectorName } . size ( ) ! = $ { secondVectorName } . size ( ) )
$ { i } {
$ { i } throw LogicError ( VULKAN_HPP_NAMESPACE_STRING " ::${className}::${commandName}: ${firstVectorName}.size() ! = $ { secondVectorName } . size ( ) " );
$ { i } }
# endif /*VULKAN_HPP_NO_EXCEPTIONS*/
) # " ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// add some error checks if multiple vectors need to have the same size
2020-04-12 19:49:12 +00:00
std : : string commandName = determineCommandName ( name , commandData . params [ 0 ] . type . type ) ;
for ( std : : map < size_t , size_t > : : const_iterator it0 = vectorParamIndices . begin ( ) ; it0 ! = vectorParamIndices . end ( ) ;
+ + it0 )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( it0 - > first ! = returnParamIndex )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
for ( std : : map < size_t , size_t > : : const_iterator it1 = std : : next ( it0 ) ; it1 ! = vectorParamIndices . end ( ) ; + + it1 )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( it1 - > first ! = returnParamIndex ) & & ( it0 - > second = = it1 - > second ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + = replaceWithMap (
sizeCheckTemplate ,
std : : map < std : : string , std : : string > (
{ { " firstVectorName " , startLowerCase ( stripPrefix ( commandData . params [ it0 - > first ] . name , " p " ) ) } ,
{ " secondVectorName " , startLowerCase ( stripPrefix ( commandData . params [ it1 - > first ] . name , " p " ) ) } ,
{ " className " , handle } ,
{ " commandName " , commandName } ,
{ " i " , indentation } } ) ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhancedReturnResultValue ( std : : string & str ,
std : : string const & indentation ,
std : : string const & returnName ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
bool twoStep ,
bool singular ,
bool unique ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string type = ( returnParamIndex ! = INVALID_INDEX ) ? commandData . params [ returnParamIndex ] . type . type : " " ;
std : : string returnVectorName = ( returnParamIndex ! = INVALID_INDEX )
? stripPostfix ( stripPrefix ( commandData . params [ returnParamIndex ] . name , " p " ) , " s " )
: " " ;
std : : string commandName = determineCommandName ( name , commandData . params [ 0 ] . type . type ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
if ( commandData . returnType = = " void " )
2020-03-25 10:00:02 +00:00
{
2020-04-12 19:49:12 +00:00
std : : cerr < < " warning: skipping appendFunctionBodyEnhancedReturnResultValue for function " < < commandName
< < " because the returnType is void " ;
2019-08-27 07:02:49 +00:00
return ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
if ( unique )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// the unique version needs a Deleter object for destruction of the newly created stuff
// get the DeleterData corresponding to the returned type
// special handling for "createDevice", as Device is created from PhysicalDevice, but destroyed on its own
2020-04-12 19:49:12 +00:00
bool noParent = handle . empty ( ) | | ( name = = " vkCreateDevice " ) ;
str + = " \n " + indentation + ( ( name = = " vkAllocateMemory " ) ? " ObjectFree< " : " ObjectDestroy< " ) +
( noParent ? " NoParent " : stripPrefix ( handle , " Vk " ) ) + " ,Dispatch> deleter( " +
( noParent ? " " : " *this, " ) + " allocator, d ); \n " + indentation + " return createResultValue< " +
stripPrefix ( type , " Vk " ) + " ,Dispatch>( result, " ;
2019-08-27 07:02:49 +00:00
}
else
{
str + = indentation + " return createResultValue( result, " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
// if the return type is "Result" or there is at least one success code, create the Result/Value construct to return
2020-04-12 19:49:12 +00:00
if ( returnParamIndex ! = INVALID_INDEX )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// if there's a return parameter, list it in the Result/Value constructor
str + = returnName + " , " ;
}
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// now the function name (with full namespace) as a string
2020-04-12 19:49:12 +00:00
str + = " VULKAN_HPP_NAMESPACE_STRING \" :: " + ( handle . empty ( ) ? " " : stripPrefix ( handle , " Vk " ) + " :: " ) +
( singular ? stripPluralS ( commandName ) : commandName ) + ( unique ? " Unique " : " " ) + " \" " ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( ! twoStep & & ( 1 < commandData . successCodes . size ( ) ) )
2019-08-27 07:02:49 +00:00
{
// and for the single-step algorithms with more than one success code list them all
2020-04-12 19:49:12 +00:00
str + = " , { Result:: " + createSuccessCode ( commandData . successCodes [ 0 ] , m_tags ) ;
for ( size_t i = 1 ; i < commandData . successCodes . size ( ) ; i + + )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " , Result:: " + createSuccessCode ( commandData . successCodes [ i ] , m_tags ) ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " } " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
if ( unique )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " , deleter " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " ); \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhancedSingleStep ( std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool singular ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = indentation + " " ;
2020-04-12 19:49:12 +00:00
if ( commandData . returnType = = " VkResult " )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " Result result = static_cast<Result>( " ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( commandData . returnType ! = " void " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " return " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
appendCall ( str , name , commandData , returnParamIndex , templateParamIndex , vectorParamIndices , false , true , singular ) ;
if ( commandData . returnType = = " VkResult " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " ) " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " ; \n " ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyEnhancedTwoStep ( std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool singular ,
std : : string const & returnName ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ! singular ) ;
assert ( ( commandData . returnType = = " VkResult " ) | | ( commandData . returnType = = " void " ) ) ;
assert ( returnParamIndex ! = INVALID_INDEX ) ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// local count variable to hold the size of the vector to fill
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator returnit = vectorParamIndices . find ( returnParamIndex ) ;
assert ( returnit ! = vectorParamIndices . end ( ) & & ( returnit - > second ! = INVALID_INDEX ) ) ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// take the pure type of the size parameter; strip the leading 'p' from its name for its local name
2020-04-12 19:49:12 +00:00
std : : string sizeName = startLowerCase ( stripPrefix ( commandData . params [ returnit - > second ] . name , " p " ) ) ;
str + =
indentation + " " + stripPrefix ( commandData . params [ returnit - > second ] . type . type , " Vk " ) + " " + sizeName + " ; \n " ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
std : : string const multiSuccessTemplate =
R " (${i} Result result;
$ { i } do
$ { i } {
$ { i } result = static_cast < Result > ( $ { call1 } ) ;
$ { i } if ( ( result = = Result : : eSuccess ) & & $ { sizeName } )
$ { i } {
$ { i } $ { returnName } . resize ( $ { sizeName } ) ;
$ { i } result = static_cast < Result > ( $ { call2 } ) ;
$ { i } }
$ { i } } while ( result = = Result : : eIncomplete ) ;
$ { i } if ( result = = Result : : eSuccess )
$ { i } {
$ { i } VULKAN_HPP_ASSERT ( $ { sizeName } < = $ { returnName } . size ( ) ) ;
$ { i } $ { returnName } . resize ( $ { sizeName } ) ;
$ { i } }
) " ;
std : : string const singleSuccessTemplate =
R " (${i} Result result = static_cast<Result>( ${call1} );
$ { i } if ( ( result = = Result : : eSuccess ) & & $ { sizeName } )
$ { i } {
$ { i } $ { returnName } . resize ( $ { sizeName } ) ;
$ { i } result = static_cast < Result > ( $ { call2 } ) ;
$ { i } }
) " ;
std : : string const voidMultiCallTemplate =
R " (${i} ${call1};
$ { i } $ { returnName } . resize ( $ { sizeName } ) ;
$ { i } $ { call2 } ;
) " ;
2020-04-12 19:49:12 +00:00
std : : string const & selectedTemplate =
( commandData . returnType = = " VkResult " )
? ( ( 1 < commandData . successCodes . size ( ) ) ? multiSuccessTemplate : singleSuccessTemplate )
: voidMultiCallTemplate ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
std : : string call1 , call2 ;
2020-04-12 19:49:12 +00:00
appendCall ( call1 , name , commandData , returnParamIndex , templateParamIndex , vectorParamIndices , true , true , false ) ;
appendCall ( call2 , name , commandData , returnParamIndex , templateParamIndex , vectorParamIndices , true , false , false ) ;
str + = replaceWithMap ( selectedTemplate ,
{ { " sizeName " , sizeName } ,
{ " returnName " , returnName } ,
{ " call1 " , call1 } ,
{ " call2 " , call2 } ,
{ " i " , indentation } } ) ;
}
void VulkanHppGenerator : : appendFunctionBodyEnhancedVectorOfStructureChain (
std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool withAllocator ) const
2019-11-13 09:04:50 +00:00
{
std : : string const stringTemplate =
R " (${i} std::vector<StructureChain,Allocator> ${returnName}${vectorAllocator};
$ { i } uint32_t $ { sizeName } ;
$ { i } d . $ { commandName } ( m_ $ { handleName } , & $ { sizeName } , nullptr ) ;
$ { i } $ { returnName } . resize ( $ { sizeName } ) ;
2019-12-02 09:06:44 +00:00
$ { i } std : : vector < VULKAN_HPP_NAMESPACE : : $ { returnType } > localVector ( $ { sizeName } ) ;
2019-11-13 09:04:50 +00:00
$ { i } for ( uint32_t i = 0 ; i < $ { sizeName } ; i + + )
$ { i } {
2019-12-02 09:06:44 +00:00
$ { i } localVector [ i ] . pNext = $ { returnName } [ i ] . template get < VULKAN_HPP_NAMESPACE : : $ { returnType } > ( ) . pNext ;
2019-11-13 09:04:50 +00:00
$ { i } }
$ { i } d . $ { commandName } ( m_ $ { handleName } , & $ { sizeName } , reinterpret_cast < $ { VkReturnType } * > ( localVector . data ( ) ) ) ;
$ { i } for ( uint32_t i = 0 ; i < $ { sizeName } ; i + + )
$ { i } {
2019-12-02 09:06:44 +00:00
$ { i } $ { returnName } [ i ] . template get < VULKAN_HPP_NAMESPACE : : $ { returnType } > ( ) = localVector [ i ] ;
2019-11-13 09:04:50 +00:00
$ { i } }
$ { i } return $ { returnName } ;
) " ;
// local count variable to hold the size of the vector to fill
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator returnit = vectorParamIndices . find ( returnParamIndex ) ;
assert ( returnit ! = vectorParamIndices . end ( ) & & ( returnit - > second ! = INVALID_INDEX ) ) ;
2019-11-13 09:04:50 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) - > second = =
commandData . params [ 0 ] . type . type ) ; // make sure, the first argument is the handle
assert ( commandData . params . size ( ) = =
3 ) ; // make sure, there are three args: the handle, the pointer to size, and the data pointer
2019-11-13 09:04:50 +00:00
2020-04-12 19:49:12 +00:00
str + =
replaceWithMap ( stringTemplate ,
{ { " commandName " , name } ,
{ " handleName " , startLowerCase ( stripPrefix ( commandData . params [ 0 ] . type . type , " Vk " ) ) } ,
{ " i " , indentation } ,
{ " returnName " , startLowerCase ( stripPrefix ( commandData . params [ returnParamIndex ] . name , " p " ) ) } ,
{ " returnType " , stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) } ,
{ " sizeName " , startLowerCase ( stripPrefix ( commandData . params [ returnit - > second ] . name , " p " ) ) } ,
{ " vectorAllocator " , withAllocator ? " ( vectorAllocator ) " : " " } ,
{ " VkReturnType " , commandData . params [ returnParamIndex ] . type . type } } ) ;
}
void VulkanHppGenerator : : appendFunctionBodyEnhancedVectorOfUniqueHandles (
std : : string & str ,
std : : string const & indentation ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ,
bool singular ,
bool withAllocator ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string const stringTemplate =
2020-03-31 07:26:02 +00:00
R " (${i} std::vector<UniqueHandle<${type}, Dispatch>, Allocator> ${uniqueTypeVariable}s${allocator};
$ { i } std : : vector < $ { type } > $ { typeVariable } s ( $ { vectorSize } ) ;
$ { i } Result result = static_cast < Result > ( d . vk $ { command } ( m_device , $ { arguments } , reinterpret_cast < Vk $ { type } * > ( $ { typeVariable } s . data ( ) ) ) ) ;
2020-01-15 15:54:55 +00:00
$ { i } if ( $ { successChecks } )
2019-08-27 07:02:49 +00:00
$ { i } {
2020-03-31 07:26:02 +00:00
$ { i } $ { uniqueTypeVariable } s . reserve ( $ { vectorSize } ) ;
2019-08-27 07:02:49 +00:00
$ { i } $ { Deleter } < $ { DeleterTemplate } , Dispatch > deleter ( * this , $ { deleterArg } , d ) ;
$ { i } for ( size_t i = 0 ; i < $ { vectorSize } ; i + + )
$ { i } {
2020-03-31 07:26:02 +00:00
$ { i } $ { uniqueTypeVariable } s . push_back ( UniqueHandle < $ { type } , Dispatch > ( $ { typeVariable } s [ i ] , deleter ) ) ;
2019-08-27 07:02:49 +00:00
$ { i } }
$ { i } }
2018-09-25 09:23:27 +00:00
2020-03-31 07:26:02 +00:00
$ { i } return createResultValue ( result , $ { uniqueTypeVariable } s , VULKAN_HPP_NAMESPACE_STRING " ::${class}::${commandName}Unique " $ { successCodes } ) ;
2019-08-27 07:02:49 +00:00
) " ;
2020-04-12 19:49:12 +00:00
std : : string type = ( returnParamIndex ! = INVALID_INDEX ) ? commandData . params [ returnParamIndex ] . type . type : " " ;
std : : string typeVariable = startLowerCase ( stripPrefix ( type , " Vk " ) ) ;
std : : string uniqueTypeVariable = " unique " + stripPrefix ( type , " Vk " ) ;
2019-08-27 07:02:49 +00:00
std : : string arguments ;
2020-04-12 19:49:12 +00:00
appendArguments ( arguments ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
twoStep ,
true ,
singular ,
1 ,
commandData . params . size ( ) - 1 ) ;
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
auto handleIt = m_handles . find ( type ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
assert ( ! commandData . successCodes . empty ( ) ) ;
std : : string successChecks =
" result == VULKAN_HPP_NAMESPACE::Result:: " + createSuccessCode ( commandData . successCodes [ 0 ] , m_tags ) ;
2020-01-15 15:54:55 +00:00
std : : string successCodes ;
2020-04-12 19:49:12 +00:00
if ( 1 < commandData . successCodes . size ( ) )
2020-01-15 15:54:55 +00:00
{
successChecks = " ( " + successChecks + " ) " ;
2020-04-12 19:49:12 +00:00
successCodes = " , { VULKAN_HPP_NAMESPACE::Result:: " + createSuccessCode ( commandData . successCodes [ 0 ] , m_tags ) ;
for ( size_t i = 1 ; i < commandData . successCodes . size ( ) ; i + + )
2020-01-15 15:54:55 +00:00
{
2020-04-12 19:49:12 +00:00
successChecks + =
" || ( result == VULKAN_HPP_NAMESPACE::Result:: " + createSuccessCode ( commandData . successCodes [ i ] , m_tags ) +
" ) " ;
successCodes + = " , VULKAN_HPP_NAMESPACE::Result:: " + createSuccessCode ( commandData . successCodes [ i ] , m_tags ) ;
2020-01-15 15:54:55 +00:00
}
successCodes + = " } " ;
}
2020-04-12 19:49:12 +00:00
std : : string commandName = determineCommandName ( name , commandData . params [ 0 ] . type . type ) ;
bool isCreateFunction = ( name . substr ( 2 , 6 ) = = " Create " ) ;
str + = replaceWithMap (
stringTemplate ,
std : : map < std : : string , std : : string > {
{ " allocator " , withAllocator ? " ( vectorAllocator ) " : " " } ,
{ " arguments " , arguments } ,
{ " class " , stripPrefix ( handle , " Vk " ) } ,
{ " command " , stripPrefix ( name , " vk " ) } ,
{ " commandName " , commandName } ,
{ " Deleter " , handleIt - > second . deletePool . empty ( ) ? " ObjectDestroy " : " PoolFree " } ,
{ " deleterArg " ,
handleIt - > second . deletePool . empty ( )
? " allocator "
: " allocateInfo. " + startLowerCase ( stripPrefix ( handleIt - > second . deletePool , " Vk " ) ) } ,
{ " DeleterTemplate " ,
stripPrefix ( handle , " Vk " ) +
( handleIt - > second . deletePool . empty ( ) ? " " : " , " + stripPrefix ( handleIt - > second . deletePool , " Vk " ) ) } ,
{ " i " , indentation } ,
{ " successChecks " , successChecks } ,
{ " successCodes " , successCodes } ,
{ " type " , stripPrefix ( type , " Vk " ) } ,
{ " typeVariable " , typeVariable } ,
{ " uniqueTypeVariable " , uniqueTypeVariable } ,
{ " vectorSize " , isCreateFunction ? " createInfos.size() " : " allocateInfo. " + typeVariable + " Count " } } ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyStandard ( std : : string & str ,
std : : string const & indentation ,
std : : string const & commandName ,
CommandData const & commandData ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : pair < bool , std : : string > returnData = generateFunctionBodyStandardReturn ( commandData . returnType ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( commandName ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( commandName ) - > second ;
assert ( handle . empty ( ) | | ( handle = = commandData . params [ 0 ] . type . type ) ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
str + = indentation + " " + returnData . second + " d. " + commandName + " ( " +
( handle . empty ( ) ? " " : ( " m_ " + startLowerCase ( stripPrefix ( handle , " Vk " ) ) ) ) ;
for ( size_t i = handle . empty ( ) ? 0 : 1 ; i < commandData . params . size ( ) ; i + + )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( 0 < i )
2019-08-27 07:02:49 +00:00
{
str + = " , " ;
}
2020-04-12 19:49:12 +00:00
appendFunctionBodyStandardArgument (
str , commandData . params [ i ] . type , commandData . params [ i ] . name , commandData . params [ i ] . arraySizes ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
str + = std : : string ( " ) " ) + ( returnData . first ? " ) " : " " ) + " ; \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionBodyStandardArgument ( std : : string & str ,
TypeData const & typeData ,
std : : string const & name ,
std : : vector < std : : string > const & arraySizes ) const
2019-03-18 19:48:10 +00:00
{
2020-04-12 19:49:12 +00:00
if ( beginsWith ( typeData . type , " Vk " ) )
2019-03-18 19:48:10 +00:00
{
2019-08-27 07:02:49 +00:00
// the parameter is a vulkan type
2020-04-12 19:49:12 +00:00
if ( ! typeData . postfix . empty ( ) | | ! arraySizes . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( typeData . postfix . empty ( ) | | ( typeData . postfix . back ( ) = = ' * ' ) ) & &
( arraySizes . empty ( ) | | ( arraySizes . size ( ) = = 1 ) ) ) ;
2019-08-27 07:02:49 +00:00
// it's a pointer -> need to reinterpret_cast it
2020-04-12 19:49:12 +00:00
appendReinterpretCast ( str ,
typeData . prefix . find ( " const " ) = = 0 ,
typeData . type ,
typeData . postfix . find ( " * const " ) ! = std : : string : : npos ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-03-10 14:40:05 +00:00
// it's a value -> need to static_cast it
2019-08-27 07:02:49 +00:00
str + = " static_cast< " + typeData . type + " > " ;
}
str + = " ( " + name + " ) " ;
}
else
2019-03-18 19:48:10 +00:00
{
2019-08-27 07:02:49 +00:00
// it's a non-vulkan type -> just use it
str + = name ;
}
}
2019-03-18 19:48:10 +00:00
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : appendFunctionHeaderArgumentEnhanced ( std : : string & str ,
ParamData const & param ,
size_t paramIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool skip ,
bool argEncountered ,
bool isTemplateParam ,
bool isLastArgument ,
bool singular ,
bool withDefaults ,
bool withAllocator ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! skip )
2019-03-18 19:48:10 +00:00
{
2020-04-12 19:49:12 +00:00
if ( argEncountered )
2019-03-18 19:48:10 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " , " ;
2019-03-18 19:48:10 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string strippedParameterName = startLowerCase ( stripPrefix ( param . name , " p " ) ) ;
2019-03-18 19:48:10 +00:00
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator it = vectorParamIndices . find ( paramIndex ) ;
if ( it = = vectorParamIndices . end ( ) )
2019-03-18 19:48:10 +00:00
{
2019-08-27 07:02:49 +00:00
// the argument ist not a vector
2020-04-12 19:49:12 +00:00
if ( param . type . postfix . empty ( ) )
2019-08-27 07:02:49 +00:00
{
// and its not a pointer -> just use its type and name here
2020-04-12 19:49:12 +00:00
appendFunctionHeaderArgumentEnhancedSimple ( str , param , isLastArgument , withDefaults , withAllocator ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// the argument is not a vector, but a pointer
2020-04-12 19:49:12 +00:00
assert ( param . type . postfix . back ( ) = = ' * ' ) ;
appendFunctionHeaderArgumentEnhancedPointer ( str , param , strippedParameterName , withDefaults , withAllocator ) ;
2019-08-27 07:02:49 +00:00
}
2019-03-18 19:48:10 +00:00
}
else
{
2019-08-27 07:02:49 +00:00
// the argument is a vector
2020-04-12 19:49:12 +00:00
appendFunctionHeaderArgumentEnhancedVector ( str ,
param ,
strippedParameterName ,
it - > second ! = INVALID_INDEX ,
isTemplateParam ,
singular ,
withDefaults ,
withAllocator ) ;
2019-03-18 19:48:10 +00:00
}
2019-08-27 07:02:49 +00:00
argEncountered = true ;
2019-03-18 19:48:10 +00:00
}
2019-08-27 07:02:49 +00:00
return argEncountered ;
2019-03-18 19:48:10 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArgumentEnhancedPointer ( std : : string & str ,
ParamData const & param ,
std : : string const & strippedParameterName ,
bool withDefaults ,
bool withAllocator ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( param . type . postfix . back ( ) = = ' * ' ) ;
if ( param . optional )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// for an optional argument, trim the leading 'p' from the name
2020-04-12 19:49:12 +00:00
str + = " Optional< " + param . type . prefix + ( param . type . prefix . empty ( ) ? " " : " " ) +
stripPrefix ( param . type . type , " Vk " ) + " > " + strippedParameterName ;
if ( withDefaults & & ! withAllocator )
2019-08-27 07:02:49 +00:00
{
str + = " = nullptr " ;
}
}
2020-04-12 19:49:12 +00:00
else if ( param . type . type = = " void " )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// for void-pointer, just use type and name
str + = param . type . compose ( ) + " " + param . name ;
}
2020-04-12 19:49:12 +00:00
else if ( param . type . type ! = " char " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// for non-char-pointer, change to reference
2020-04-12 19:49:12 +00:00
assert ( param . type . postfix = = " * " ) ;
str + = param . type . prefix + ( param . type . prefix . empty ( ) ? " " : " " ) + stripPrefix ( param . type . type , " Vk " ) + " & " +
strippedParameterName ;
2018-09-25 09:23:27 +00:00
}
else
{
2019-08-27 07:02:49 +00:00
// for char-pointer, change to const reference to std::string
str + = " const std::string & " + strippedParameterName ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArgumentEnhancedSimple (
std : : string & str , ParamData const & param , bool lastArgument , bool withDefaults , bool withAllocator ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = param . type . compose ( ) + " " + param . name + constructCArraySizes ( param . arraySizes ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
if ( withDefaults & & lastArgument & & ! withAllocator )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// check if the very last argument is a flag without any bits -> provide some empty default for it
2020-04-12 19:49:12 +00:00
std : : map < std : : string , BitmaskData > : : const_iterator bitmasksIt = m_bitmasks . find ( param . type . type ) ;
if ( bitmasksIt ! = m_bitmasks . end ( ) )
2019-08-27 07:02:49 +00:00
{
// get the enum corresponding to this flag, to check if it's empty
2020-04-12 19:49:12 +00:00
std : : string strippedBitmaskName = stripPrefix ( bitmasksIt - > first , " Vk " ) ;
std : : map < std : : string , EnumData > : : const_iterator enumIt = m_enums . find ( bitmasksIt - > second . requirements ) ;
assert ( ( enumIt = = m_enums . end ( ) ) | | ( enumIt - > second . isBitmask ) ) ;
if ( ( enumIt = = m_enums . end ( ) ) | | ( enumIt - > second . values . empty ( ) ) )
2019-08-27 07:02:49 +00:00
{
// there are no bits in this flag -> provide the default
2020-04-12 19:49:12 +00:00
str + = " = " + stripPrefix ( param . type . type , " Vk " ) + " () " ;
2019-08-27 07:02:49 +00:00
}
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArgumentEnhancedVector ( std : : string & str ,
ParamData const & param ,
std : : string const & strippedParameterName ,
bool hasSizeParam ,
bool isTemplateParam ,
bool singular ,
bool withDefaults ,
bool withAllocator ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( param . type . postfix . back ( ) = = ' * ' ) ;
2019-08-27 07:02:49 +00:00
// it's optional, if it's marked as optional and there's no size specified
bool optional = param . optional & & ! hasSizeParam ;
2020-04-12 19:49:12 +00:00
if ( param . type . type . find ( " char " ) ! = std : : string : : npos )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// it's a char-vector -> use a std::string (either optional or a const-reference
2020-04-12 19:49:12 +00:00
if ( optional )
2019-01-14 09:09:19 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " Optional<const std::string> " + strippedParameterName ;
2020-04-12 19:49:12 +00:00
if ( withDefaults & & ! withAllocator )
2019-08-27 07:02:49 +00:00
{
str + = " = nullptr " ;
}
2019-01-14 09:09:19 +00:00
}
2019-08-27 07:02:49 +00:00
else
2019-01-14 09:09:19 +00:00
{
2019-08-27 07:02:49 +00:00
str + = " const std::string & " + strippedParameterName ;
2019-01-14 09:09:19 +00:00
}
2019-08-27 07:02:49 +00:00
}
else
{
// it's a non-char vector (they are never optional)
2020-04-12 19:49:12 +00:00
assert ( ! optional ) ;
if ( singular )
2019-01-14 09:09:19 +00:00
{
2019-08-27 07:02:49 +00:00
// in singular case, change from pointer to reference
2020-04-12 19:49:12 +00:00
str + = param . type . prefix + ( param . type . prefix . empty ( ) ? " " : " " ) + stripPrefix ( param . type . type , " Vk " ) +
" & " + stripPluralS ( strippedParameterName ) ;
2019-08-27 07:02:49 +00:00
}
else
{
// otherwise, use our ArrayProxy
2020-04-12 19:49:12 +00:00
bool isConst = ( param . type . prefix . find ( " const " ) ! = std : : string : : npos ) ;
str + = " ArrayProxy< " +
( isTemplateParam ? ( isConst ? " const T " : " T " ) : stripPostfix ( param . type . compose ( ) , " * " ) ) + " > " +
strippedParameterName ;
2019-01-14 09:09:19 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArguments ( std : : string & str ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool enhanced ,
bool singular ,
bool withDefaults ,
bool withAllocator ) const
2019-08-27 07:02:49 +00:00
{
str + = " ( " ;
2020-04-12 19:49:12 +00:00
if ( enhanced )
{
appendFunctionHeaderArgumentsEnhanced ( str ,
name ,
commandData ,
returnParamIndex ,
templateParamIndex ,
vectorParamIndices ,
singular ,
withDefaults ,
withAllocator ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
appendFunctionHeaderArgumentsStandard ( str , name , commandData , withDefaults ) ;
2019-08-27 07:02:49 +00:00
}
str + = " ) " ;
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
if ( ! m_commandToHandle . find ( name ) - > second . empty ( ) )
2019-08-27 07:02:49 +00:00
{
str + = " const " ;
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArgumentsEnhanced ( std : : string & str ,
std : : string const & name ,
CommandData const & commandData ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool singular ,
bool withDefaults ,
bool withAllocator ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
2019-08-27 07:02:49 +00:00
// check if there's at least one argument left to put in here
2020-04-12 19:49:12 +00:00
std : : set < size_t > skippedParams = determineSkippedParams ( returnParamIndex , vectorParamIndices ) ;
if ( skippedParams . size ( ) + ( handle . empty ( ) ? 0 : 1 ) < commandData . params . size ( ) )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// determine the last argument, where we might provide some default for
size_t lastArgument = INVALID_INDEX ;
2020-04-12 19:49:12 +00:00
for ( size_t i = commandData . params . size ( ) - 1 ; i < commandData . params . size ( ) ; i - - )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( skippedParams . find ( i ) = = skippedParams . end ( ) )
2019-08-27 07:02:49 +00:00
{
lastArgument = i ;
break ;
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " " ;
bool argEncountered = false ;
2020-04-12 19:49:12 +00:00
for ( size_t i = handle . empty ( ) ? 0 : 1 ; i < commandData . params . size ( ) ; i + + )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
argEncountered = appendFunctionHeaderArgumentEnhanced ( str ,
commandData . params [ i ] ,
i ,
vectorParamIndices ,
skippedParams . find ( i ) ! = skippedParams . end ( ) ,
argEncountered ,
( templateParamIndex = = i ) ,
( lastArgument = = i ) ,
singular ,
withDefaults ,
withAllocator ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( argEncountered )
2019-08-27 07:02:49 +00:00
{
str + = " , " ;
2019-01-09 10:55:11 +00:00
}
}
2020-04-12 19:49:12 +00:00
if ( withAllocator )
2019-08-27 07:02:49 +00:00
{
str + = " Allocator const& vectorAllocator, " ;
}
str + = " Dispatch const &d " ;
2020-04-12 19:49:12 +00:00
if ( withDefaults & & ! withAllocator )
2019-08-27 07:02:49 +00:00
{
2019-09-25 09:59:39 +00:00
str + = " = VULKAN_HPP_DEFAULT_DISPATCHER " ;
2019-08-27 07:02:49 +00:00
}
str + = " " ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderArgumentsStandard ( std : : string & str ,
std : : string const & name ,
CommandData const & commandData ,
bool withDefaults ) const
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// for the standard case, just list all the arguments as we've got them
// determine the last argument, where we might provide some default for
2020-03-25 10:00:02 +00:00
size_t lastArgument = commandData . params . size ( ) - 1 ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
assert ( m_commandToHandle . find ( name ) ! = m_commandToHandle . end ( ) ) ;
std : : string const & handle = m_commandToHandle . find ( name ) - > second ;
2019-08-27 07:02:49 +00:00
bool argEncountered = false ;
2020-04-12 19:49:12 +00:00
for ( size_t i = handle . empty ( ) ? 0 : 1 ; i < commandData . params . size ( ) ; i + + )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
argEncountered = appendFunctionHeaderArgumentStandard (
str , commandData . params [ i ] , argEncountered , lastArgument = = i , withDefaults ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( argEncountered )
2019-08-27 07:02:49 +00:00
{
str + = " , " ;
}
str + = " Dispatch const &d " ;
2020-04-12 19:49:12 +00:00
if ( withDefaults )
2019-08-27 07:02:49 +00:00
{
2019-09-25 09:59:39 +00:00
str + = " = VULKAN_HPP_DEFAULT_DISPATCHER " ;
2019-01-09 10:55:11 +00:00
}
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : appendFunctionHeaderArgumentStandard (
std : : string & str , ParamData const & param , bool argEncountered , bool isLastArgument , bool withDefaults ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( argEncountered )
2019-08-27 07:02:49 +00:00
{
str + = " , " ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
str + = " " + param . type . compose ( ) + " " + param . name + constructCArraySizes ( param . arraySizes ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( withDefaults & & isLastArgument )
2019-08-27 07:02:49 +00:00
{
// check if the very last argument is a flag without any bits -> provide some empty default for it
2020-04-12 19:49:12 +00:00
std : : map < std : : string , BitmaskData > : : const_iterator bitmasksIt = m_bitmasks . find ( param . type . type ) ;
if ( bitmasksIt ! = m_bitmasks . end ( ) )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// get the enum corresponding to this flag, to check if it's empty
2020-04-12 19:49:12 +00:00
std : : string strippedBitmaskName = stripPrefix ( bitmasksIt - > first , " Vk " ) ;
std : : map < std : : string , EnumData > : : const_iterator enumIt = m_enums . find ( bitmasksIt - > second . requirements ) ;
assert ( ( enumIt = = m_enums . end ( ) ) | | ( enumIt - > second . isBitmask ) ) ;
if ( ( enumIt = = m_enums . end ( ) ) | | ( enumIt - > second . values . empty ( ) ) )
2019-08-27 07:02:49 +00:00
{
// there are no bits in this flag -> provide the default
2020-04-12 19:49:12 +00:00
str + = " = " + stripPrefix ( param . type . type , " Vk " ) + " () " ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
2019-08-27 07:02:49 +00:00
return true ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderReturnType ( std : : string & str ,
CommandData const & commandData ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
std : : string const & enhancedReturnType ,
bool enhanced ,
bool twoStep ,
bool singular ,
bool unique ,
bool isStructureChain ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( enhanced )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
bool useTypename =
( ( commandData . successCodes . size ( ) = = 1 ) | |
( ( commandData . successCodes . size ( ) = = 2 ) & & ( commandData . successCodes [ 1 ] = = " VK_INCOMPLETE " ) & & twoStep ) ) ;
2019-08-27 07:02:49 +00:00
// the enhanced function might return some pretty complex return stuff
2020-04-12 19:49:12 +00:00
bool isVector = ( enhancedReturnType . find ( " Allocator " ) ! = std : : string : : npos ) ;
if ( unique )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// the unique version returns something prefixed with 'Unique'; potentially a vector of that stuff
// it's a vector, if it's not the singular version and the return parameter is a vector parameter
2020-04-12 19:49:12 +00:00
bool returnsVector = ! singular & & ( vectorParamIndices . find ( returnParamIndex ) ! = vectorParamIndices . end ( ) ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : string returnType = isStructureChain ? " StructureChain<X, Y, Z...> "
: stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) ;
2020-01-15 15:54:55 +00:00
str + = useTypename ? " typename ResultValueType< " : " ResultValue< " ;
2020-04-12 19:49:12 +00:00
str + = returnsVector ? " std::vector<UniqueHandle< " + returnType + " ,Dispatch>,Allocator>> "
: " UniqueHandle< " + returnType + " ,Dispatch>> " ;
2020-01-15 15:54:55 +00:00
str + = useTypename ? " ::type " : " " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( ( enhancedReturnType ! = stripPrefix ( commandData . returnType , " Vk " ) ) & &
( commandData . returnType ! = " void " ) )
{
// if the enhanced return type differs from the original return type, and it's not void, we return a
// ResultValueType<...>::type
assert ( commandData . returnType = = " VkResult " ) ;
// in singular case, we create the ResultValueType from the pure return type, otherwise from the enhanced return
// type
std : : string returnType =
isStructureChain
? " StructureChain<X, Y, Z...> "
: ( singular ? stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) : enhancedReturnType ) ;
2019-08-27 07:02:49 +00:00
// for the non-singular case with allocation, we need to prepend with 'typename' to keep compilers happy
2020-04-12 19:49:12 +00:00
str + = ( useTypename ? " typename ResultValueType< " : " ResultValue< " ) + returnType + " > " +
( useTypename ? " ::type " : " " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( ( returnParamIndex ! = INVALID_INDEX ) & & ( 1 < commandData . successCodes . size ( ) ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
// if there is a return parameter at all, and there are multiple success codes, we return a ResultValue<...> with
// the pure return type
assert ( commandData . returnType = = " VkResult " ) ;
str + = " ResultValue< " +
( isStructureChain ? " StructureChain<X, Y, Z...> "
: stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) ) +
" > " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
else
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// and in every other case, we just return the enhanced return type.
2020-04-12 19:49:12 +00:00
str + = ( isStructureChain & & ! isVector ? " StructureChain<X, Y, Z...> " : enhancedReturnType ) + " " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
}
else
{
// the non-enhanced function just uses the return type
2020-04-12 19:49:12 +00:00
str + = stripPrefix ( commandData . returnType , " Vk " ) + " " ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendFunctionHeaderTemplate ( std : : string & str ,
std : : string const & indentation ,
size_t returnParamIndex ,
size_t templateParamIndex ,
std : : string const & enhancedReturnType ,
bool enhanced ,
bool singular ,
bool unique ,
bool withDefault ,
bool isStructureChain ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
bool withAllocator = ( enhancedReturnType . find ( " Allocator " ) ! = std : : string : : npos ) ;
2019-08-27 07:02:49 +00:00
str + = indentation + " template< " ;
2020-04-12 19:49:12 +00:00
if ( enhanced )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( isStructureChain )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = std : : string ( " typename " ) + ( withAllocator ? " StructureChain " : " X, typename Y, typename ...Z " ) + " , " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( ( templateParamIndex ! = INVALID_INDEX ) & &
( ( templateParamIndex ! = returnParamIndex ) | | ( enhancedReturnType = = " Result " ) ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ! withAllocator ) ;
2019-08-27 07:02:49 +00:00
str + = " typename T, " ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! singular & & withAllocator )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// otherwise, if there's an Allocator used in the enhanced return type, we templatize on that Allocator
2020-04-12 19:49:12 +00:00
assert ( ( enhancedReturnType . substr ( 0 , 12 ) = = " std::vector< " ) & &
( enhancedReturnType . find ( ' , ' ) ! = std : : string : : npos ) & & ( 12 < enhancedReturnType . find ( ' , ' ) ) ) ;
2019-08-27 07:02:49 +00:00
str + = " typename Allocator " ;
2020-04-12 19:49:12 +00:00
if ( withDefault )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
// for the default type get the type from the enhancedReturnType, which is of the form
// 'std::vector<Type,Allocator>'
assert ( ! isStructureChain | | ! unique ) ;
str + = " = std::allocator< " +
( isStructureChain ? " StructureChain "
: ( unique ? " Unique " : " " ) +
enhancedReturnType . substr ( 12 , enhancedReturnType . find ( ' , ' ) - 12 ) ) +
" > " ;
2019-08-27 07:02:49 +00:00
}
str + = " , " ;
2019-03-19 14:34:00 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
str + = std : : string ( " typename Dispatch " ) + ( withDefault ? " = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE " : " " ) + " > \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendHandle ( std : : string & str ,
std : : pair < std : : string , HandleData > const & handleData ,
std : : set < std : : string > & listedHandles ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( listedHandles . find ( handleData . first ) = = listedHandles . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
listedHandles . insert ( handleData . first ) ;
2019-08-27 07:02:49 +00:00
// first check for any handle that needs to be listed before this one
2020-04-12 19:49:12 +00:00
for ( auto const & command : handleData . second . commands )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & parameter : command . second . params )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string typeName = parameter . type . type ;
auto handlesIt = m_handles . find ( typeName ) ;
if ( ( handlesIt ! = m_handles . end ( ) ) & & ( listedHandles . find ( typeName ) = = listedHandles . end ( ) ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendHandle ( str , * handlesIt , listedHandles ) ;
2019-08-27 07:02:49 +00:00
}
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( handleData . first . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & command : handleData . second . commands )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( command . first = = " vkCreateInstance " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
// special handling for createInstance, as we need to explicitly place the forward declarations and the
// deleter classes here
# if !defined( NDEBUG )
auto handleIt = m_handles . find ( " " ) ;
assert ( ( handleIt ! = m_handles . end ( ) ) & & ( handleIt - > second . childrenHandles . size ( ) = = 2 ) ) ;
assert ( handleIt - > second . childrenHandles . find ( " VkInstance " ) ! = handleIt - > second . childrenHandles . end ( ) ) ;
2019-08-27 07:02:49 +00:00
# endif
2020-04-12 19:49:12 +00:00
appendUniqueTypes ( str , " " , { " VkInstance " } ) ;
2019-08-27 07:02:49 +00:00
}
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
appendCommand ( str , " " , command . first , command . second , false ) ;
appendPlatformLeave ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
appendCommand ( str , " " , alias , command . second , false ) ;
2020-03-02 11:32:42 +00:00
}
2019-08-27 07:02:49 +00:00
}
}
2019-01-09 10:55:11 +00:00
else
{
2019-08-27 07:02:49 +00:00
// then append any forward declaration of Deleters used by this handle
2020-04-12 19:49:12 +00:00
if ( ! handleData . second . childrenHandles . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendUniqueTypes ( str , handleData . first , handleData . second . childrenHandles ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( handleData . first = = " VkPhysicalDevice " )
2019-08-27 07:02:49 +00:00
{
// special handling for class Device, as it's created from PhysicalDevice, but destroys itself
2020-04-12 19:49:12 +00:00
appendUniqueTypes ( str , " " , { " VkDevice " } ) ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
std : : string commands ;
// list all the commands that are mapped to members of this class
2020-04-12 19:49:12 +00:00
for ( auto const & command : handleData . second . commands )
2019-08-27 07:02:49 +00:00
{
std : : string enter , leave , commandString ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( enter , ! command . second . aliases . empty ( ) , command . second . platform ) ;
appendPlatformLeave ( leave , ! command . second . aliases . empty ( ) , command . second . platform ) ;
2020-03-02 11:32:42 +00:00
commands + = " \n " + enter ;
2020-04-12 19:49:12 +00:00
std : : string commandName = determineCommandName ( command . first , command . second . params [ 0 ] . type . type ) ;
appendCommand ( commands , " " , command . first , command . second , false ) ;
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( enter . empty ( ) & & leave . empty ( ) ) ;
2020-03-02 11:32:42 +00:00
commands + = " \n " ;
2020-04-12 19:49:12 +00:00
appendCommand ( commands , " " , alias , command . second , false ) ;
2020-03-02 11:32:42 +00:00
}
2019-08-27 07:02:49 +00:00
2020-03-02 11:32:42 +00:00
// special handling for destroy functions
bool platformLeft = false ;
2020-04-12 19:49:12 +00:00
if ( ( ( command . first . substr ( 2 , 7 ) = = " Destroy " ) & & ( commandName ! = " destroy " ) ) | |
( command . first . substr ( 2 , 4 ) = = " Free " ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( 1 < command . second . params . size ( ) ) ;
auto handleIt = m_handles . find ( command . second . params [ 1 ] . type . type ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
if ( ! handleIt - > second . alias . empty ( ) )
2020-03-02 11:32:42 +00:00
{
commands + = leave ;
platformLeft = true ;
}
2019-08-27 07:02:49 +00:00
std : : string destroyCommandString ;
2020-04-12 19:49:12 +00:00
appendCommand ( destroyCommandString , " " , command . first , command . second , false ) ;
std : : string shortenedName = ( command . first . substr ( 2 , 7 ) = = " Destroy " ) ? " destroy " : " free " ;
size_t pos = destroyCommandString . find ( commandName ) ;
while ( pos ! = std : : string : : npos )
2020-03-25 10:00:02 +00:00
{
2020-04-12 19:49:12 +00:00
destroyCommandString . replace ( pos , commandName . length ( ) , shortenedName ) ;
pos = destroyCommandString . find ( commandName , pos ) ;
2020-03-25 10:00:02 +00:00
}
2019-08-27 07:02:49 +00:00
commands + = " \n " + destroyCommandString ;
}
2020-04-12 19:49:12 +00:00
if ( ! platformLeft )
2020-03-02 11:32:42 +00:00
{
commands + = leave ;
}
2019-08-27 07:02:49 +00:00
}
static const std : : string templateString = R " (
2020-03-02 11:32:42 +00:00
$ { enter } class $ { className }
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
public :
using CType = Vk $ { className } ;
static VULKAN_HPP_CONST_OR_CONSTEXPR ObjectType objectType = ObjectType : : e $ { className } ;
public :
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR $ { className } ( ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
: m_ $ { memberName } ( VK_NULL_HANDLE )
{ }
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR $ { className } ( std : : nullptr_t ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
: m_ $ { memberName } ( VK_NULL_HANDLE )
{ }
2019-10-23 08:52:29 +00:00
VULKAN_HPP_TYPESAFE_EXPLICIT $ { className } ( Vk $ { className } $ { memberName } ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
: m_ $ { memberName } ( $ { memberName } )
{ }
# if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
2019-10-23 08:52:29 +00:00
$ { className } & operator = ( Vk $ { className } $ { memberName } ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
m_ $ { memberName } = $ { memberName } ;
2019-10-23 08:52:29 +00:00
return * this ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
# endif
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
$ { className } & operator = ( std : : nullptr_t ) VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
m_ $ { memberName } = VK_NULL_HANDLE ;
return * this ;
}
2018-09-25 09:23:27 +00:00
2020-02-26 13:24:58 +00:00
# if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
auto operator < = > ( $ { className } const & ) const = default ;
# else
2019-10-23 08:52:29 +00:00
bool operator = = ( $ { className } const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
return m_ $ { memberName } = = rhs . m_ $ { memberName } ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
bool operator ! = ( $ { className } const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
return m_ $ { memberName } ! = rhs . m_ $ { memberName } ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
bool operator < ( $ { className } const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
return m_ $ { memberName } < rhs . m_ $ { memberName } ;
}
2020-02-26 13:24:58 +00:00
# endif
2019-08-27 07:02:49 +00:00
$ { commands }
2019-10-23 08:52:29 +00:00
VULKAN_HPP_TYPESAFE_EXPLICIT operator Vk $ { className } ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
return m_ $ { memberName } ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
explicit operator bool ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
return m_ $ { memberName } ! = VK_NULL_HANDLE ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
2019-10-23 08:52:29 +00:00
bool operator ! ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
return m_ $ { memberName } = = VK_NULL_HANDLE ;
}
private :
Vk $ { className } m_ $ { memberName } ;
} ;
static_assert ( sizeof ( $ { className } ) = = sizeof ( Vk $ { className } ) , " handle and wrapper have different size! " ) ;
template < >
2020-04-25 22:10:16 +00:00
struct VULKAN_HPP_DEPRECATED ( " vk::cpp_type is deprecated. Use vk::CppType instead. " ) cpp_type < ObjectType : : e $ { className } >
2019-08-27 07:02:49 +00:00
{
using type = $ { className } ;
} ;
2020-04-21 12:26:32 +00:00
template < >
struct CppType < ObjectType , ObjectType : : e $ { className } >
{
using Type = $ { className } ;
} ;
2019-08-27 07:02:49 +00:00
) " ;
2020-03-02 11:32:42 +00:00
std : : string enter , leave ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( enter , ! handleData . second . alias . empty ( ) , handleData . second . platform ) ;
appendPlatformLeave ( leave , ! handleData . second . alias . empty ( ) , handleData . second . platform ) ;
str + = replaceWithMap ( templateString ,
{ { " className " , stripPrefix ( handleData . first , " Vk " ) } ,
{ " commands " , commands } ,
{ " enter " , enter } ,
{ " memberName " , startLowerCase ( stripPrefix ( handleData . first , " Vk " ) ) } } ) ;
if ( ! handleData . second . alias . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " using " + stripPrefix ( handleData . second . alias , " Vk " ) + " = " +
stripPrefix ( handleData . first , " Vk " ) + " ; \n " ;
2019-01-09 10:55:11 +00:00
}
2020-03-02 11:32:42 +00:00
str + = leave ;
2018-09-25 09:23:27 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendHandles ( std : : string & str ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : set < std : : string > listedHandles ;
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
appendHandle ( str , handle , listedHandles ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendHandlesCommandDefintions ( std : : string & str ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// finally the commands, that are member functions of this handle
2020-04-12 19:49:12 +00:00
for ( auto const & command : handle . second . commands )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string strippedName = startLowerCase ( stripPrefix ( command . first , " vk " ) ) ;
2019-03-21 10:53:30 +00:00
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
appendCommand ( str , " " , command . first , command . second , true ) ;
for ( auto const & alias : command . second . aliases )
2020-03-02 11:32:42 +00:00
{
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendCommand ( str , " " , alias , command . second , true ) ;
2020-03-02 11:32:42 +00:00
}
2019-08-27 07:02:49 +00:00
// special handling for destroy functions
2020-04-12 19:49:12 +00:00
bool platformLeft = false ;
std : : string commandName = determineCommandName ( command . first , command . second . params [ 0 ] . type . type ) ;
if ( ( ( command . first . substr ( 2 , 7 ) = = " Destroy " ) & & ( commandName ! = " destroy " ) ) | |
( command . first . substr ( 2 , 4 ) = = " Free " ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( 1 < command . second . params . size ( ) ) ;
auto handleIt = m_handles . find ( command . second . params [ 1 ] . type . type ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
if ( ! handleIt - > second . alias . empty ( ) )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
2020-03-02 11:32:42 +00:00
platformLeft = true ;
}
2020-03-25 10:00:02 +00:00
std : : string destroyCommandString ;
2020-04-12 19:49:12 +00:00
appendCommand ( destroyCommandString , " " , command . first , command . second , true ) ;
std : : string shortenedName = ( command . first . substr ( 2 , 7 ) = = " Destroy " ) ? " destroy " : " free " ;
size_t pos = destroyCommandString . find ( commandName ) ;
while ( pos ! = std : : string : : npos )
2020-03-25 10:00:02 +00:00
{
2020-04-12 19:49:12 +00:00
destroyCommandString . replace ( pos , commandName . length ( ) , shortenedName ) ;
pos = destroyCommandString . find ( commandName , pos ) ;
2020-03-25 10:00:02 +00:00
}
str + = " \n " + destroyCommandString ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! platformLeft )
2020-03-02 11:32:42 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! command . second . aliases . empty ( ) , command . second . platform ) ;
2020-03-02 11:32:42 +00:00
}
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " \n " ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendHashStructures ( std : : string & str ) const
2020-03-30 10:18:06 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
2020-03-30 10:18:06 +00:00
" namespace std \n "
" { \n " ;
const std : : string hashTemplate = R " ( template <> struct hash<vk::${type}>
{
std : : size_t operator ( ) ( vk : : $ { type } const & $ { name } ) const VULKAN_HPP_NOEXCEPT
{
return std : : hash < Vk $ { type } > { } ( static_cast < Vk $ { type } > ( $ { name } ) ) ;
}
} ;
) " ;
2020-04-12 19:49:12 +00:00
for ( auto handle : m_handles )
2020-03-30 10:18:06 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! handle . first . empty ( ) )
2020-03-30 10:18:06 +00:00
{
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! handle . second . alias . empty ( ) , handle . second . platform ) ;
std : : string type = stripPrefix ( handle . first , " Vk " ) ;
std : : string name = startLowerCase ( type ) ;
str + = replaceWithMap ( hashTemplate , { { " name " , name } , { " type " , type } } ) ;
appendPlatformLeave ( str , ! handle . second . alias . empty ( ) , handle . second . platform ) ;
2020-03-30 10:18:06 +00:00
}
}
str + = " } \n " ;
}
2019-08-27 07:02:49 +00:00
// Intended only for `enum class Result`!
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendResultExceptions ( std : : string & str ) const
2019-07-03 11:53:44 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string templateString = R " (
class $ { className } : public SystemError
{
public :
$ { className } ( std : : string const & message )
: SystemError ( make_error_code ( $ { enumName } : : $ { enumMemberName } ) , message ) { }
$ { className } ( char const * message )
: SystemError ( make_error_code ( $ { enumName } : : $ { enumMemberName } ) , message ) { }
} ;
) " ;
2019-07-03 11:53:44 +00:00
2020-04-12 19:49:12 +00:00
auto enumData = m_enums . find ( " VkResult " ) ;
for ( auto const & value : enumData - > second . values )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
if ( beginsWith ( value . vkValue , " eError " ) )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( templateString ,
{ { " className " , stripPrefix ( value . vkValue , " eError " ) + " Error " } ,
{ " enumName " , stripPrefix ( enumData - > first , " Vk " ) } ,
{ " enumMemberName " , value . vkValue } } ) ;
2019-07-03 11:53:44 +00:00
}
}
2019-08-27 07:02:49 +00:00
str + = " \n " ;
}
2019-07-03 11:53:44 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendPlatformEnter ( std : : string & str , bool isAliased , std : : string const & platform ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! isAliased & & ! platform . empty ( ) )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
auto it = m_platforms . find ( platform ) ;
assert ( ( it ! = m_platforms . end ( ) ) & & ! it - > second . empty ( ) ) ;
2019-08-27 07:02:49 +00:00
str + = " #ifdef " + it - > second + " \n " ;
2019-07-03 11:53:44 +00:00
}
2019-08-27 07:02:49 +00:00
}
2019-07-03 11:53:44 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendPlatformLeave ( std : : string & str , bool isAliased , std : : string const & platform ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! isAliased & & ! platform . empty ( ) )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
auto it = m_platforms . find ( platform ) ;
assert ( ( it ! = m_platforms . end ( ) ) & & ! it - > second . empty ( ) ) ;
2019-08-27 07:02:49 +00:00
str + = " #endif /* " + it - > second + " */ \n " ;
2019-07-03 11:53:44 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStruct ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structure ,
std : : set < std : : string > & listedStructures ) const
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
if ( listedStructures . find ( structure . first ) = = listedStructures . end ( ) )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
listedStructures . insert ( structure . first ) ;
for ( auto const & member : structure . second . members )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
auto structureIt = m_structures . find ( member . type . type ) ;
if ( ( structureIt ! = m_structures . end ( ) ) & &
( listedStructures . find ( member . type . type ) = = listedStructures . end ( ) ) )
2019-07-03 11:53:44 +00:00
{
2020-04-12 19:49:12 +00:00
appendStruct ( str , * structureIt , listedStructures ) ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-12 19:49:12 +00:00
if ( ! structure . second . subStruct . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
auto structureIt = m_structures . find ( structure . second . subStruct ) ;
if ( ( structureIt ! = m_structures . end ( ) ) & &
( listedStructures . find ( structureIt - > first ) = = listedStructures . end ( ) ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendStruct ( str , * structureIt , listedStructures ) ;
2019-07-03 11:53:44 +00:00
}
}
2020-04-12 19:49:12 +00:00
if ( structure . second . isUnion )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendUnion ( str , structure ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
appendStructure ( str , structure ) ;
2019-08-27 07:02:49 +00:00
}
2019-07-03 11:53:44 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructAssignmentOperator ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structData ,
std : : string const & prefix ) const
2020-01-30 09:14:21 +00:00
{
// we need an assignment operator if there is constant sType in this struct
2020-02-11 12:34:33 +00:00
std : : string copyTemplate ;
2020-04-12 19:49:12 +00:00
if ( ( nonConstSTypeStructs . find ( structData . first ) = = nonConstSTypeStructs . end ( ) ) & &
! structData . second . members . empty ( ) & & ( structData . second . members . front ( ) . name = = " sType " ) )
2020-01-30 09:14:21 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( 2 < = structData . second . members . size ( ) ) & & ( structData . second . members [ 1 ] . name = = " pNext " ) ) ;
2020-01-30 09:14:21 +00:00
2020-03-23 13:59:37 +00:00
static const std : : string stringTemplate = R " (
2020-01-30 09:14:21 +00:00
$ { prefix } $ { structName } & operator = ( $ { structName } const & rhs ) VULKAN_HPP_NOEXCEPT
$ { prefix } {
2020-03-23 13:59:37 +00:00
$ { prefix } memcpy ( & pNext , & rhs . pNext , sizeof ( $ { structName } ) - offsetof ( $ { structName } , pNext ) ) ;
2020-01-30 09:14:21 +00:00
$ { prefix } return * this ;
$ { prefix } }
) " ;
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( stringTemplate ,
{ { " prefix " , prefix } , { " structName " , stripPrefix ( structData . first , " Vk " ) } } ) ;
2020-03-23 13:59:37 +00:00
}
2020-01-30 09:14:21 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructCompareOperators ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structData ) const
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
// two structs are compared by comparing each of the elements
std : : string compareMembers ;
std : : string intro = " " ;
2020-04-12 19:49:12 +00:00
for ( size_t i = 0 ; i < structData . second . members . size ( ) ; i + + )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
MemberData const & member = structData . second . members [ i ] ;
2020-03-23 13:59:37 +00:00
compareMembers + = intro + " ( " + member . name + " == rhs. " + member . name + " ) " ;
2019-08-27 07:02:49 +00:00
intro = " \n && " ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
static const std : : string compareTemplate = R " (
2020-02-26 13:24:58 +00:00
# if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
auto operator < = > ( $ { name } const & ) const = default ;
# else
2019-10-23 08:52:29 +00:00
bool operator = = ( $ { name } const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-08-27 07:02:49 +00:00
{
return $ { compareMembers } ;
}
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
bool operator ! = ( $ { name } const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
return ! operator = = ( rhs ) ;
2018-09-25 09:23:27 +00:00
}
2020-02-26 13:24:58 +00:00
# endif
2019-08-27 07:02:49 +00:00
) " ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( compareTemplate ,
{ { " name " , stripPrefix ( structData . first , " Vk " ) } , { " compareMembers " , compareMembers } } ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string
VulkanHppGenerator : : constructConstexprString ( std : : pair < std : : string , StructureData > const & structData ) const
2020-01-30 09:14:21 +00:00
{
// structs with a union (and VkBaseInStructure and VkBaseOutStructure) can't be a constexpr!
2020-04-12 19:49:12 +00:00
bool isConstExpression = ! containsUnion ( structData . first ) & & ( structData . first ! = " VkBaseInStructure " ) & &
( structData . first ! = " VkBaseOutStructure " ) ;
return isConstExpression
? ( std : : string ( " VULKAN_HPP_CONSTEXPR " ) + ( containsArray ( structData . first ) ? " _14 " : " " ) )
: " " ;
2020-01-30 09:14:21 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructConstructor ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structData ,
std : : string const & prefix ) const
2019-08-27 07:02:49 +00:00
{
// the constructor with all the elements as arguments, with defaults
2020-04-12 19:49:12 +00:00
std : : string constexprString = constructConstexprString ( structData ) ;
std : : string ctorOpening = prefix + constexprString + stripPrefix ( structData . first , " Vk " ) ;
std : : string indentation ( ctorOpening . size ( ) + 2 , ' ' ) ;
2019-01-09 10:55:11 +00:00
2020-03-23 13:59:37 +00:00
std : : string arguments , initializers ;
2020-04-12 19:49:12 +00:00
bool listedArgument = false ;
bool firstArgument = true ;
for ( auto const & member : structData . second . members )
2019-01-09 10:55:11 +00:00
{
2019-11-07 07:22:47 +00:00
// gather the arguments
2020-04-12 19:49:12 +00:00
listedArgument = appendStructConstructorArgument ( arguments , listedArgument , indentation , member ) ;
2019-09-18 06:47:17 +00:00
2019-11-07 07:22:47 +00:00
// gather the initializers; skip members 'pNext' and 'sType', they are directly set by initializers
2020-04-12 19:49:12 +00:00
if ( ( member . name ! = " pNext " ) & & ( member . name ! = " sType " ) )
2019-11-07 07:22:47 +00:00
{
2020-04-12 19:49:12 +00:00
initializers + = prefix + " " + ( firstArgument ? " : " : " , " ) + " " + member . name + " ( " + member . name + " _ ) \n " ;
2019-11-07 07:22:47 +00:00
firstArgument = false ;
2018-09-25 09:23:27 +00:00
}
2020-01-30 09:14:21 +00:00
}
2019-11-19 16:44:16 +00:00
2020-04-12 19:49:12 +00:00
str + = ctorOpening + ( arguments . empty ( ) ? " () " : std : : string ( " ( " + arguments + " ) " ) ) +
" VULKAN_HPP_NOEXCEPT \n " + initializers + prefix + " {} \n " ;
2019-08-27 07:02:49 +00:00
}
2019-01-22 08:03:03 +00:00
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : appendStructConstructorArgument ( std : : string & str ,
bool listedArgument ,
std : : string const & indentation ,
MemberData const & memberData ) const
2019-08-27 07:02:49 +00:00
{
// skip members 'pNext' and 'sType', as they are never explicitly set
2020-04-12 19:49:12 +00:00
if ( ( memberData . name ! = " pNext " ) & & ( memberData . name ! = " sType " ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + = ( listedArgument ? ( " , \n " + indentation ) : " " ) ;
if ( memberData . arraySizes . empty ( ) )
2019-03-13 14:33:33 +00:00
{
2019-12-12 10:40:21 +00:00
str + = memberData . type . compose ( ) + " " ;
2019-03-13 14:33:33 +00:00
}
2019-08-27 07:02:49 +00:00
else
2019-03-13 14:33:33 +00:00
{
2020-04-12 19:49:12 +00:00
str + = constructStandardArray ( memberData . type . compose ( ) , memberData . arraySizes ) + " const& " ;
2019-03-13 14:33:33 +00:00
}
2020-01-16 11:12:31 +00:00
str + = memberData . name + " _ = " ;
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( memberData . type . type ) ;
if ( enumIt ! = m_enums . end ( ) & & memberData . type . postfix . empty ( ) )
2020-01-16 11:12:31 +00:00
{
2020-04-29 09:45:10 +00:00
appendEnumInitializer ( str , memberData . type , memberData . arraySizes , enumIt - > second . values ) ;
2020-01-16 11:12:31 +00:00
}
else
{
// all the rest can be initialized with just {}
str + = " {} " ;
}
2019-08-27 07:02:49 +00:00
listedArgument = true ;
}
return listedArgument ;
}
2019-03-13 14:33:33 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructCopyConstructors ( std : : string & str , std : : string const & name ) const
2019-08-27 07:02:49 +00:00
{
static const std : : string templateString = R " (
2019-10-23 08:52:29 +00:00
$ { name } ( Vk $ { name } const & rhs ) VULKAN_HPP_NOEXCEPT
2019-01-22 08:03:03 +00:00
{
2019-11-07 07:22:47 +00:00
* this = rhs ;
2019-01-22 08:03:03 +00:00
}
2019-10-23 08:52:29 +00:00
$ { name } & operator = ( Vk $ { name } const & rhs ) VULKAN_HPP_NOEXCEPT
2019-01-22 08:03:03 +00:00
{
2019-12-02 09:06:44 +00:00
* this = * reinterpret_cast < VULKAN_HPP_NAMESPACE : : $ { name } const * > ( & rhs ) ;
2019-08-27 07:02:49 +00:00
return * this ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
) " ;
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( templateString , { { " name " , name } } ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-21 12:26:32 +00:00
std : : string VulkanHppGenerator : : appendStructMembers ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structData ,
std : : string const & prefix ) const
2018-09-25 09:23:27 +00:00
{
2020-04-21 12:26:32 +00:00
std : : string sTypeValue ;
2020-04-12 19:49:12 +00:00
for ( auto const & member : structData . second . members )
2019-08-27 07:02:49 +00:00
{
2019-11-07 07:22:47 +00:00
str + = prefix ;
2020-04-12 19:49:12 +00:00
if ( ( member . name = = " sType " ) & &
( nonConstSTypeStructs . find ( structData . first ) = =
nonConstSTypeStructs
. end ( ) ) ) // special handling for sType and some nasty little structs that don't get a const sType
2019-11-07 07:22:47 +00:00
{
str + = " const " ;
}
2020-04-12 19:49:12 +00:00
if ( ! member . bitCount . empty ( ) & & beginsWith ( member . type . type , " Vk " ) )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( member . type . prefix . empty ( ) & & member . type . postfix . empty ( ) ) ; // never encounterd a different case
2020-01-13 14:00:59 +00:00
str + = member . type . type ;
}
2020-04-12 19:49:12 +00:00
else if ( member . arraySizes . empty ( ) )
2020-01-13 14:00:59 +00:00
{
str + = member . type . compose ( ) ;
}
2020-03-23 13:59:37 +00:00
else
{
2020-04-12 19:49:12 +00:00
assert ( member . type . prefix . empty ( ) & & member . type . postfix . empty ( ) ) ;
str + = constructStandardArrayWrapper ( member . type . compose ( ) , member . arraySizes ) ;
2020-03-23 13:59:37 +00:00
}
2020-01-13 14:00:59 +00:00
str + = " " + member . name ;
2020-04-12 19:49:12 +00:00
if ( member . name = = " sType " ) // special handling for sType
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( " VkStructureType " ) ;
assert ( enumIt ! = m_enums . end ( ) ) ;
if ( ! member . values . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( beginsWith ( member . values , " VK_STRUCTURE_TYPE " ) ) ;
auto nameIt =
std : : find_if ( enumIt - > second . values . begin ( ) ,
enumIt - > second . values . end ( ) ,
[ & member ] ( EnumValueData const & evd ) { return member . values = = evd . vulkanValue ; } ) ;
assert ( nameIt ! = enumIt - > second . values . end ( ) ) ;
2020-04-21 12:26:32 +00:00
sTypeValue = nameIt - > vkValue ;
str + = " = StructureType:: " + sTypeValue ;
2019-01-09 10:55:11 +00:00
}
2019-12-12 10:40:21 +00:00
else
{
// special handling for those nasty structs with an unspecified value for sType
str + = " = {} " ;
}
2019-01-09 10:55:11 +00:00
}
2019-12-12 10:40:21 +00:00
else
2019-08-27 07:02:49 +00:00
{
2020-01-13 14:00:59 +00:00
// as we don't have any meaningful default initialization values, everything can be initialized by just '{}' !
2020-04-12 19:49:12 +00:00
assert ( member . arraySizes . empty ( ) | | member . bitCount . empty ( ) ) ;
if ( ! member . bitCount . empty ( ) )
2019-12-12 10:40:21 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " : " + member . bitCount ; // except for bitfield members, where no default member initializatin is
// supported (up to C++20)
2020-01-13 14:00:59 +00:00
}
else
{
2020-03-23 13:59:37 +00:00
str + = " = " ;
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( member . type . type ) ;
if ( enumIt ! = m_enums . end ( ) & & member . type . postfix . empty ( ) )
2020-01-16 11:12:31 +00:00
{
2020-04-29 09:45:10 +00:00
appendEnumInitializer ( str , member . type , member . arraySizes , enumIt - > second . values ) ;
2020-01-16 11:12:31 +00:00
}
else
{
2020-03-10 08:47:59 +00:00
str + = " {} " ;
2020-01-16 11:12:31 +00:00
}
2019-12-12 10:40:21 +00:00
}
2019-08-27 07:02:49 +00:00
}
str + = " ; \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-21 12:26:32 +00:00
return sTypeValue ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructs ( std : : string & str ) const
2019-05-21 12:57:52 +00:00
{
2019-08-27 07:02:49 +00:00
std : : set < std : : string > listedStructures ;
2020-04-12 19:49:12 +00:00
for ( auto const & structure : m_structures )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendStruct ( str , structure , listedStructures ) ;
2019-08-27 07:02:49 +00:00
}
2019-05-21 12:57:52 +00:00
}
2020-04-21 12:26:32 +00:00
void VulkanHppGenerator : : appendStructSetter ( std : : string & str ,
std : : string const & structureName ,
bool isUnion ,
MemberData const & memberData ) const
2018-12-03 13:33:37 +00:00
{
2020-04-12 19:49:12 +00:00
if ( memberData . type . type ! = " VkStructureType " ) // filter out StructureType, which is supposed to be immutable !
2018-12-03 13:33:37 +00:00
{
2020-04-20 13:26:40 +00:00
static const std : : string templateString = R " (
$ { structureName } & set $ { MemberName } ( $ { memberType } $ { reference } $ { memberName } _ ) VULKAN_HPP_NOEXCEPT
2020-01-13 14:00:59 +00:00
{
2020-04-20 13:26:40 +00:00
$ { assignment } ;
return * this ;
2020-01-13 14:00:59 +00:00
}
2020-04-20 13:26:40 +00:00
) " ;
2019-08-27 07:02:49 +00:00
2020-04-21 12:26:32 +00:00
std : : string memberType = memberData . arraySizes . empty ( )
? memberData . type . compose ( )
: constructStandardArray ( memberData . type . compose ( ) , memberData . arraySizes ) ;
2020-04-20 13:26:40 +00:00
std : : string assignment ;
2020-04-12 19:49:12 +00:00
if ( ! memberData . bitCount . empty ( ) & & beginsWith ( memberData . type . type , " Vk " ) )
2019-08-27 07:02:49 +00:00
{
2020-04-21 12:26:32 +00:00
assignment =
memberData . name + " = " + " *reinterpret_cast< " + memberData . type . type + " *>(& " + memberData . name + " _) " ;
2020-04-20 13:26:40 +00:00
}
2020-04-21 12:26:32 +00:00
else if ( isUnion & & holdsSType ( memberData . type . type ) )
2020-04-20 13:26:40 +00:00
{
assignment = " memcpy( & " + memberData . name + " , & " + memberData . name + " _, sizeof( " + memberType + " )) " ;
2019-08-27 07:02:49 +00:00
}
else
2018-12-03 13:33:37 +00:00
{
2020-04-20 13:26:40 +00:00
assignment = memberData . name + " = " + memberData . name + " _ " ;
2018-12-03 13:33:37 +00:00
}
2020-04-20 13:26:40 +00:00
2020-04-21 12:26:32 +00:00
str + = replaceWithMap (
templateString ,
{ { " assignment " , assignment } ,
2020-04-20 13:26:40 +00:00
{ " memberName " , memberData . name } ,
2020-04-21 12:26:32 +00:00
{ " MemberName " , startUpperCase ( memberData . name ) } ,
2020-04-20 13:26:40 +00:00
{ " memberType " , memberType } ,
2020-04-21 12:26:32 +00:00
{ " reference " ,
( memberData . type . postfix . empty ( ) & & ( m_structures . find ( memberData . type . type ) ! = m_structures . end ( ) ) )
? " const & "
: " " } ,
{ " structureName " , structureName } } ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructSubConstructor ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structData ,
std : : string const & prefix ) const
2020-01-30 09:14:21 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! structData . second . subStruct . empty ( ) )
2020-01-30 09:14:21 +00:00
{
2020-04-12 19:49:12 +00:00
auto const & subStruct = m_structures . find ( structData . second . subStruct ) ;
assert ( subStruct ! = m_structures . end ( ) ) ;
2020-01-30 09:14:21 +00:00
2020-04-12 19:49:12 +00:00
std : : string subStructArgumentName = startLowerCase ( stripPrefix ( subStruct - > first , " Vk " ) ) ;
std : : string ctorOpening = prefix + " explicit " + stripPrefix ( structData . first , " Vk " ) + " ( " ;
std : : string indentation = std : : string ( ctorOpening . size ( ) , ' ' ) ;
2020-01-30 09:14:21 +00:00
std : : string subCopies ;
2020-04-12 19:49:12 +00:00
bool firstArgument = true ;
for ( size_t i = 0 ; i < subStruct - > second . members . size ( ) ; i + + )
2020-01-30 09:14:21 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( structData . second . members [ i ] . arraySizes . empty ( ) ) ;
subCopies + = prefix + " " + ( firstArgument ? " : " : " , " ) + " " + structData . second . members [ i ] . name + " ( " +
subStructArgumentName + " . " + subStruct - > second . members [ i ] . name + " ) \n " ;
2020-01-30 09:14:21 +00:00
firstArgument = false ;
}
std : : string subArguments ;
2020-04-12 19:49:12 +00:00
bool listedArgument = true ;
for ( size_t i = subStruct - > second . members . size ( ) ; i < structData . second . members . size ( ) ; i + + )
2020-01-30 09:14:21 +00:00
{
2020-04-12 19:49:12 +00:00
listedArgument =
appendStructConstructorArgument ( subArguments , listedArgument , indentation , structData . second . members [ i ] ) ;
2020-01-30 09:14:21 +00:00
2020-04-12 19:49:12 +00:00
assert ( structData . second . members [ i ] . arraySizes . empty ( ) ) ;
subCopies + =
prefix + " , " + structData . second . members [ i ] . name + " ( " + structData . second . members [ i ] . name + " _ ) \n " ;
2020-01-30 09:14:21 +00:00
}
2020-04-12 19:49:12 +00:00
str + =
" \n "
" explicit " +
stripPrefix ( structData . first , " Vk " ) + " ( " + stripPrefix ( subStruct - > first , " Vk " ) + " const& " +
subStructArgumentName + subArguments + " ) \n " + subCopies + " {} \n " ;
2020-01-30 09:14:21 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructure ( std : : string & str ,
std : : pair < std : : string , StructureData > const & structure ) const
2019-08-27 07:02:49 +00:00
{
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2019-08-27 07:02:49 +00:00
2020-01-30 09:14:21 +00:00
std : : string constructorAndSetters ;
2020-04-12 19:49:12 +00:00
appendStructConstructor ( constructorAndSetters , structure , " " ) ;
appendStructSubConstructor ( constructorAndSetters , structure , " " ) ;
appendStructAssignmentOperator ( constructorAndSetters , structure , " " ) ;
appendStructCopyConstructors ( constructorAndSetters , stripPrefix ( structure . first , " Vk " ) ) ;
if ( ! structure . second . returnedOnly )
2019-01-09 10:55:11 +00:00
{
2019-09-18 06:47:17 +00:00
// only structs that are not returnedOnly get setters!
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2019-08-27 07:02:49 +00:00
{
2020-04-21 12:26:32 +00:00
appendStructSetter ( constructorAndSetters , stripPrefix ( structure . first , " Vk " ) , false , member ) ;
2019-08-27 07:02:49 +00:00
}
}
2018-12-03 13:33:37 +00:00
2019-08-27 07:02:49 +00:00
// operator==() and operator!=()
// only structs without a union as a member can have a meaningfull == and != operation; we filter them out
std : : string compareOperators ;
2020-04-12 19:49:12 +00:00
if ( ! containsUnion ( structure . first ) )
2018-12-03 13:33:37 +00:00
{
2020-04-12 19:49:12 +00:00
appendStructCompareOperators ( compareOperators , structure ) ;
2018-12-03 13:33:37 +00:00
}
2019-08-27 07:02:49 +00:00
// the member variables
2020-04-21 12:26:32 +00:00
std : : string members = " \n public: \n " ;
std : : string sTypeValue = appendStructMembers ( members , structure , " " ) ;
2019-08-27 07:02:49 +00:00
2020-04-21 12:26:32 +00:00
static const std : : string structureTemplate = R " ( struct ${structureName}
2019-08-27 07:02:49 +00:00
{
2020-04-21 12:26:32 +00:00
$ { structureType }
2019-08-27 07:02:49 +00:00
$ { constructorAndSetters }
2019-10-23 08:52:29 +00:00
operator $ { vkName } const & ( ) const VULKAN_HPP_NOEXCEPT
2019-03-21 10:53:30 +00:00
{
2019-08-27 07:02:49 +00:00
return * reinterpret_cast < const $ { vkName } * > ( this ) ;
2019-03-21 10:53:30 +00:00
}
2019-10-23 08:52:29 +00:00
operator $ { vkName } & ( ) VULKAN_HPP_NOEXCEPT
2019-03-21 10:53:30 +00:00
{
2019-08-27 07:02:49 +00:00
return * reinterpret_cast < $ { vkName } * > ( this ) ;
}
2019-03-21 10:53:30 +00:00
2019-08-27 07:02:49 +00:00
$ { compareOperators }
$ { members }
} ;
2020-04-21 12:26:32 +00:00
static_assert ( sizeof ( $ { structureName } ) = = sizeof ( $ { vkName } ) , " struct and wrapper have different size! " ) ;
static_assert ( std : : is_standard_layout < $ { structureName } > : : value , " struct wrapper is not a standard layout! " ) ;
2019-03-21 10:53:30 +00:00
) " ;
2019-08-27 07:02:49 +00:00
2020-04-21 12:26:32 +00:00
std : : string structureName = stripPrefix ( structure . first , " Vk " ) ;
std : : string structureType ;
if ( ! sTypeValue . empty ( ) )
{
structureType =
" static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType:: " + sTypeValue + " ; \n " ;
}
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( structureTemplate ,
2020-04-21 12:26:32 +00:00
{ { " structureName " , structureName } ,
{ " structureType " , structureType } ,
2020-04-12 19:49:12 +00:00
{ " constructorAndSetters " , constructorAndSetters } ,
{ " vkName " , structure . first } ,
{ " compareOperators " , compareOperators } ,
{ " members " , members } } ) ;
2020-04-21 12:26:32 +00:00
if ( ! sTypeValue . empty ( ) )
{
std : : string cppTypeTemplate = R " (
template < >
struct CppType < StructureType , StructureType : : $ { sTypeValue } >
{
using Type = $ { structureName } ;
} ;
) " ;
str + = replaceWithMap ( cppTypeTemplate , { { " sTypeValue " , sTypeValue } , { " structureName " , structureName } } ) ;
}
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2019-03-21 10:53:30 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendStructureChainValidation ( std : : string & str )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// append all template functions for the structure pointer chain validation
2020-04-12 19:49:12 +00:00
for ( auto const & structure : m_structures )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! structure . second . structExtends . empty ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// append out allowed structure chains
2020-04-12 19:49:12 +00:00
for ( auto extendName : structure . second . structExtends )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
std : : map < std : : string , StructureData > : : const_iterator itExtend = m_structures . find ( extendName ) ;
if ( itExtend = = m_structures . end ( ) )
2020-03-04 12:33:52 +00:00
{
// look if the extendName acutally is an alias of some other structure
2020-04-12 19:49:12 +00:00
itExtend = std : : find_if ( m_structures . begin ( ) , m_structures . end ( ) , [ extendName ] ( auto const & sd ) {
return sd . second . aliases . find ( extendName ) ! = sd . second . aliases . end ( ) ;
} ) ;
2020-03-04 12:33:52 +00:00
}
2020-04-12 19:49:12 +00:00
if ( itExtend = = m_structures . end ( ) )
2019-08-27 07:02:49 +00:00
{
std : : string errorString ;
2020-02-04 09:35:33 +00:00
errorString = " < " + extendName + " > does not specify a struct in structextends field. " ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// check if symbol name is an alias to a struct
2020-04-12 19:49:12 +00:00
auto itAlias =
std : : find_if ( m_structures . begin ( ) ,
m_structures . end ( ) ,
[ & extendName ] ( std : : pair < std : : string , StructureData > const & it ) - > bool {
return std : : find ( it . second . aliases . begin ( ) , it . second . aliases . end ( ) , extendName ) ! =
it . second . aliases . end ( ) ;
} ) ;
if ( itAlias ! = m_structures . end ( ) )
2019-08-27 07:02:49 +00:00
{
2020-02-04 09:35:33 +00:00
errorString + = " The symbol is an alias and maps to < " + itAlias - > first + " >. " ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
check ( false , structure . second . xmlLine , errorString ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( structure . second . platform ! = itExtend - > second . platform )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! itExtend - > second . aliases . empty ( ) , itExtend - > second . platform ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
str + = " template <> struct isStructureChainValid< " + stripPrefix ( extendName , " Vk " ) + " , " +
stripPrefix ( structure . first , " Vk " ) + " >{ enum { value = true }; }; \n " ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( structure . second . platform ! = itExtend - > second . platform )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! itExtend - > second . aliases . empty ( ) , itExtend - > second . platform ) ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendThrowExceptions ( std : : string & str ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumData = m_enums . find ( " VkResult " ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
str + =
" \n "
2019-11-07 14:42:10 +00:00
" [[noreturn]] static void throwResultException( Result result, char const * message ) \n "
2019-08-27 07:02:49 +00:00
" { \n "
" switch ( result ) \n "
" { \n " ;
2020-04-12 19:49:12 +00:00
for ( auto const & value : enumData - > second . values )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( beginsWith ( value . vkValue , " eError " ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " case Result:: " + value . vkValue + " : throw " + stripPrefix ( value . vkValue , " eError " ) +
" Error( message ); \n " ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
str + =
" default: throw SystemError( make_error_code( result ) ); \n "
2019-08-27 07:02:49 +00:00
" } \n "
" } \n " ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendUnion ( std : : string & str , std : : pair < std : : string , StructureData > const & structure ) const
2018-09-25 09:23:27 +00:00
{
2020-03-02 11:32:42 +00:00
str + = " \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformEnter ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
std : : string unionName = stripPrefix ( structure . first , " Vk " ) ;
str + = " union " + unionName +
" \n "
" { \n "
" " +
unionName + " ( VULKAN_HPP_NAMESPACE:: " + unionName +
" const& rhs ) VULKAN_HPP_NOEXCEPT \n "
" { \n "
" memcpy( static_cast<void*>(this), &rhs, sizeof( VULKAN_HPP_NAMESPACE:: " +
unionName +
" ) ); \n "
" } \n " ;
2019-08-27 07:02:49 +00:00
2020-01-30 09:14:21 +00:00
bool firstMember = true ;
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
// VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t
// constructor.
auto compareBool32Alias = [ ] ( MemberData const & member ) {
return member . type . type = = std : : string ( " uint32_t " ) ;
} ;
if ( member . type . type = = " VkBool32 " )
{
if ( std : : find_if ( structure . second . members . begin ( ) , structure . second . members . end ( ) , compareBool32Alias ) ! =
structure . second . members . end ( ) )
2020-01-30 09:14:21 +00:00
{
continue ;
2019-08-27 07:02:49 +00:00
}
2020-01-30 09:14:21 +00:00
}
2019-01-09 10:55:11 +00:00
2020-01-30 09:14:21 +00:00
static const std : : string constructorTemplate = R " (
2020-01-13 14:00:59 +00:00
$ { unionName } ( $ { memberType } $ { memberName } _ $ { defaultAssignment } )
2020-04-20 13:26:40 +00:00
: $ { memberName } ( $ { memberName } _ )
{ }
2020-01-13 14:00:59 +00:00
) " ;
2020-01-30 09:14:21 +00:00
2020-04-21 12:26:32 +00:00
std : : string memberType =
( member . arraySizes . empty ( ) )
? member . type . compose ( )
: ( " const " + constructStandardArray ( member . type . compose ( ) , member . arraySizes ) + " & " ) ;
str + = replaceWithMap ( constructorTemplate ,
{ { " defaultAssignment " , firstMember ? " = {} " : " " } ,
{ " memberName " , member . name } ,
{ " memberType " , memberType } ,
{ " unionName " , stripPrefix ( structure . first , " Vk " ) } } ) ;
2020-01-30 09:14:21 +00:00
firstMember = false ;
}
// one setter per union element
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2020-01-30 09:14:21 +00:00
{
2020-04-21 12:26:32 +00:00
appendStructSetter ( str , stripPrefix ( structure . first , " Vk " ) , true , member ) ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-01-13 14:00:59 +00:00
// assignment operator
static const std : : string operatorsTemplate = R " (
VULKAN_HPP_NAMESPACE : : $ { unionName } & operator = ( VULKAN_HPP_NAMESPACE : : $ { unionName } const & rhs ) VULKAN_HPP_NOEXCEPT
{
2020-02-11 14:39:46 +00:00
memcpy ( static_cast < void * > ( this ) , & rhs , sizeof ( VULKAN_HPP_NAMESPACE : : $ { unionName } ) ) ;
2020-01-13 14:00:59 +00:00
return * this ;
}
operator Vk $ { unionName } const & ( ) const
{
return * reinterpret_cast < const Vk $ { unionName } * > ( this ) ;
}
operator Vk $ { unionName } & ( )
{
return * reinterpret_cast < Vk $ { unionName } * > ( this ) ;
}
) " ;
2020-04-12 19:49:12 +00:00
str + = replaceWithMap ( operatorsTemplate , { { " unionName " , stripPrefix ( structure . first , " Vk " ) } } ) ;
2019-06-06 11:13:38 +00:00
2019-08-27 07:02:49 +00:00
// the union member variables
// if there's at least one Vk... type in this union, check for unrestricted unions support
2020-04-12 19:49:12 +00:00
bool needsUnrestrictedUnions =
( std : : find_if ( structure . second . members . begin ( ) , structure . second . members . end ( ) , [ ] ( MemberData const & member ) {
return beginsWith ( member . type . type , " Vk " ) ;
} ) ! = structure . second . members . end ( ) ) ;
if ( needsUnrestrictedUnions )
2019-08-27 07:02:49 +00:00
{
str + = " #ifdef VULKAN_HPP_HAS_UNRESTRICTED_UNIONS \n " ;
}
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " " +
( member . arraySizes . empty ( ) ? member . type . compose ( )
: constructStandardArrayWrapper ( member . type . compose ( ) , member . arraySizes ) ) +
" " + member . name + " ; \n " ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( needsUnrestrictedUnions )
2019-08-27 07:02:49 +00:00
{
str + = " #else \n " ;
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " " + member . type . prefix + ( member . type . prefix . empty ( ) ? " " : " " ) + member . type . type +
member . type . postfix + " " + member . name + constructCArraySizes ( member . arraySizes ) + " ; \n " ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " #endif /*VULKAN_HPP_HAS_UNRESTRICTED_UNIONS*/ \n " ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
str + = " }; \n " ;
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! structure . second . aliases . empty ( ) , structure . second . platform ) ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : appendUniqueTypes ( std : : string & str ,
std : : string const & parentType ,
std : : set < std : : string > const & childrenTypes ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
str + =
" \n "
2020-03-02 11:32:42 +00:00
" #ifndef VULKAN_HPP_NO_SMART_HANDLE \n " ;
2020-04-12 19:49:12 +00:00
if ( ! parentType . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " class " + stripPrefix ( parentType , " Vk " ) + " ; \n " ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & childType : childrenTypes )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
auto handleIt = m_handles . find ( childType ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string type = stripPrefix ( childType , " Vk " ) ;
std : : string deleterType = handleIt - > second . deletePool . empty ( ) ? " Object " : " Pool " ;
std : : string deleterAction = ( handleIt - > second . deleteCommand . substr ( 2 , 4 ) = = " Free " ) ? " Free " : " Destroy " ;
std : : string deleterParent = parentType . empty ( ) ? " NoParent " : stripPrefix ( parentType , " Vk " ) ;
std : : string deleterPool =
handleIt - > second . deletePool . empty ( ) ? " " : " , " + stripPrefix ( handleIt - > second . deletePool , " Vk " ) ;
appendPlatformEnter ( str , ! handleIt - > second . alias . empty ( ) , handleIt - > second . platform ) ;
str + = " template <typename Dispatch> class UniqueHandleTraits< " + type +
" , Dispatch> { public: using deleter = " + deleterType + deleterAction + " < " + deleterParent + deleterPool +
" , Dispatch>; }; \n "
" using Unique " +
type + " = UniqueHandle< " + type + " , VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>; \n " ;
2020-01-13 14:00:59 +00:00
2020-04-12 19:49:12 +00:00
if ( ! handleIt - > second . alias . empty ( ) )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
str + = " using Unique " + stripPrefix ( handleIt - > second . alias , " Vk " ) + " = UniqueHandle< " + type +
" , VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>; \n " ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
appendPlatformLeave ( str , ! handleIt - > second . alias . empty ( ) , handleIt - > second . platform ) ;
2019-08-27 07:02:49 +00:00
}
2020-03-02 11:32:42 +00:00
str + = " #endif /*VULKAN_HPP_NO_SMART_HANDLE*/ \n " ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-30 09:30:17 +00:00
void VulkanHppGenerator : : EnumData : : addEnumAlias ( int line ,
std : : string const & name ,
std : : string const & aliasName ,
std : : string const & vkName )
{
// check that the aliasName is either a known enum value or at least a known alias
2020-04-30 12:28:48 +00:00
check ( ( std : : find_if ( values . begin ( ) ,
values . end ( ) ,
[ & aliasName ] ( EnumValueData const & evd ) { return evd . vulkanValue = = aliasName ; } ) ! =
values . end ( ) ) | |
( aliases . find ( aliasName ) ! = aliases . end ( ) ) ,
2020-04-30 09:30:17 +00:00
line ,
" unknown enum alias < " + aliasName + " > " ) ;
auto aliasIt = aliases . find ( name ) ;
check ( ( aliasIt = = aliases . end ( ) ) | | ( aliasIt - > second . first = = aliasName ) ,
line ,
" enum alias < " + name + " > already listed for a different enum value " ) ;
2020-04-30 12:28:48 +00:00
// only list aliases that map to different vkNames
aliasIt = std : : find_if ( aliases . begin ( ) ,
aliases . end ( ) ,
[ & vkName ] ( std : : pair < std : : string , std : : pair < std : : string , std : : string > > const & aliasEntry ) {
return vkName = = aliasEntry . second . second ;
} ) ;
if ( aliasIt = = aliases . end ( ) )
{
aliases . insert ( std : : make_pair ( name , std : : make_pair ( aliasName , vkName ) ) ) ;
}
2020-04-30 09:30:17 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : EnumData : : addEnumValue ( int line ,
std : : string const & valueName ,
bool bitmask ,
bool bitpos ,
std : : string const & prefix ,
std : : string const & postfix ,
std : : string const & tag )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string translatedName = createEnumValueName ( valueName , prefix , postfix , bitmask , tag ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
auto it = std : : find_if ( values . begin ( ) , values . end ( ) , [ & translatedName ] ( EnumValueData const & evd ) {
return evd . vkValue = = translatedName ;
} ) ;
if ( it = = values . end ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
values . push_back ( EnumValueData ( valueName , translatedName , bitpos ) ) ;
2018-09-25 09:23:27 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
check ( it - > vulkanValue = = valueName ,
line ,
" enum value < " + valueName + " > maps to same C++-name as < " + it - > vulkanValue + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
void VulkanHppGenerator : : checkCorrectness ( )
{
2020-04-12 19:49:12 +00:00
check ( ! m_vulkanLicenseHeader . empty ( ) , - 1 , " missing license header " ) ;
for ( auto const & baseType : m_baseTypes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_types . find ( baseType . second . type ) ! = m_types . end ( ) ,
baseType . second . xmlLine ,
" basetype type < " + baseType . second . type + " > not specified " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & bitmask : m_bitmasks )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! bitmask . second . requirements . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_enums . find ( bitmask . second . requirements ) ! = m_enums . end ( ) ,
bitmask . second . xmlLine ,
" bitmask requires unknown < " + bitmask . second . requirements + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
for ( auto const & extension : m_extensions )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! extension . second . deprecatedBy . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ( m_extensions . find ( extension . second . deprecatedBy ) ! = m_extensions . end ( ) ) | |
( m_features . find ( extension . second . deprecatedBy ) ! = m_features . end ( ) ) ,
extension . second . xmlLine ,
" extension deprecated by to unknown extension/version < " + extension . second . promotedTo + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! extension . second . obsoletedBy . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ( m_extensions . find ( extension . second . obsoletedBy ) ! = m_extensions . end ( ) ) | |
( m_features . find ( extension . second . obsoletedBy ) ! = m_features . end ( ) ) ,
extension . second . xmlLine ,
" extension obsoleted by unknown extension/version < " + extension . second . promotedTo + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
if ( ! extension . second . promotedTo . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ( m_extensions . find ( extension . second . promotedTo ) ! = m_extensions . end ( ) ) | |
( m_features . find ( extension . second . promotedTo ) ! = m_features . end ( ) ) ,
extension . second . xmlLine ,
" extension promoted to unknown extension/version < " + extension . second . promotedTo + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & require : extension . second . requirements )
2020-02-11 13:37:22 +00:00
{
2020-05-05 06:57:50 +00:00
warn ( m_extensions . find ( require . first ) ! = m_extensions . end ( ) ,
2020-04-12 19:49:12 +00:00
require . second ,
" unknown extension requires < " + require . first + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
for ( auto const & funcPointer : m_funcPointers )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! funcPointer . second . requirements . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_types . find ( funcPointer . second . requirements ) ! = m_types . end ( ) ,
funcPointer . second . xmlLine ,
" funcpointer requires unknown < " + funcPointer . second . requirements + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-03-10 15:19:37 +00:00
2020-04-12 19:49:12 +00:00
auto structureTypeIt = m_enums . find ( " VkStructureType " ) ;
assert ( structureTypeIt ! = m_enums . end ( ) ) ;
for ( auto const & structure : m_structures )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & extend : structure . second . structExtends )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check (
m_types . find ( extend ) ! = m_types . end ( ) , structure . second . xmlLine , " struct extends unknown < " + extend + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & member : structure . second . members )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! member . values . empty ( ) )
2020-03-10 15:19:37 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( member . name = = " sType " ) ;
check ( std : : find_if ( structureTypeIt - > second . values . begin ( ) ,
structureTypeIt - > second . values . end ( ) ,
[ & member ] ( auto const & evd ) { return member . values = = evd . vulkanValue ; } ) ! =
structureTypeIt - > second . values . end ( ) ,
member . xmlLine ,
" sType value < " + member . values + " > not listed for VkStructureType " ) ;
2020-03-10 15:19:37 +00:00
}
2020-04-12 19:49:12 +00:00
check ( m_types . find ( member . type . type ) ! = m_types . end ( ) ,
member . xmlLine ,
" struct member uses unknown type < " + member . type . type + " > " ) ;
if ( ! member . usedConstant . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_constants . find ( member . usedConstant ) ! = m_constants . end ( ) ,
member . xmlLine ,
" struct member array size uses unknown constant < " + member . usedConstant + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
auto resultIt = m_enums . find ( " VkResult " ) ;
assert ( resultIt ! = m_enums . end ( ) ) ;
2020-02-11 13:37:22 +00:00
std : : set < std : : string > resultCodes ;
2020-04-12 19:49:12 +00:00
for ( auto rc : resultIt - > second . values )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
resultCodes . insert ( rc . vulkanValue ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto rc : resultIt - > second . aliases )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
resultCodes . insert ( rc . first ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & handle : m_handles )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & parent : handle . second . parents )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_handles . find ( parent ) ! = m_handles . end ( ) ,
handle . second . xmlLine ,
" handle with unknown parent < " + parent + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & command : handle . second . commands )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & ec : command . second . errorCodes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( resultCodes . find ( ec ) ! = resultCodes . end ( ) ,
command . second . xmlLine ,
" command uses unknown error code < " + ec + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
for ( auto const & sc : command . second . successCodes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( resultCodes . find ( sc ) ! = resultCodes . end ( ) ,
command . second . xmlLine ,
" command uses unknown success code < " + sc + " > " ) ;
2020-02-11 13:37:22 +00:00
}
// check that functions returning a VkResult specify successcodes
2020-04-12 19:49:12 +00:00
check ( ( command . second . returnType ! = " VkResult " ) | | ! command . second . successCodes . empty ( ) ,
command . second . xmlLine ,
" missing successcodes on command < " + command . first + " > returning VkResult! " ) ;
2020-03-05 10:02:55 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & p : command . second . params )
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_types . find ( p . type . type ) ! = m_types . end ( ) ,
p . xmlLine ,
" comand uses parameter of unknown type < " + p . type . type + " > " ) ;
2020-03-05 10:02:55 +00:00
}
2020-04-12 19:49:12 +00:00
check ( m_types . find ( command . second . returnType ) ! = m_types . end ( ) ,
command . second . xmlLine ,
" command uses unknown return type < " + command . second . returnType + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : checkLenAttribute ( std : : string const & len , std : : vector < ParamData > const & params )
2020-02-11 13:37:22 +00:00
{
// simple: "null-terminated" or previously encountered parameter
2020-04-12 19:49:12 +00:00
if ( ( len = = " null-terminated " ) | | ( std : : find_if ( params . begin ( ) , params . end ( ) , [ & len ] ( ParamData const & pd ) {
return pd . name = = len ;
} ) ! = params . end ( ) ) )
2020-02-11 13:37:22 +00:00
{
return true ;
}
// check if len specifies a member of a struct
2020-04-12 19:49:12 +00:00
std : : vector < std : : string > lenParts = tokenize ( len , " -> " ) ;
if ( lenParts . size ( ) = = 1 )
2020-04-17 18:17:45 +00:00
{
// older versions of vk.xml used the notation parameter::member
2020-04-12 19:49:12 +00:00
lenParts = tokenize ( len , " :: " ) ;
2020-04-17 18:17:45 +00:00
}
2020-04-12 19:49:12 +00:00
if ( lenParts . size ( ) = = 2 )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
auto paramIt =
std : : find_if ( params . begin ( ) , params . end ( ) , [ & l = lenParts [ 0 ] ] ( ParamData const & pd ) { return pd . name = = l ; } ) ;
if ( paramIt ! = params . end ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
auto structureIt = m_structures . find ( paramIt - > type . type ) ;
if ( ( structureIt ! = m_structures . end ( ) ) & & ( std : : find_if ( structureIt - > second . members . begin ( ) ,
structureIt - > second . members . end ( ) ,
[ & n = lenParts [ 1 ] ] ( MemberData const & md ) {
return md . name = = n ;
} ) ! = structureIt - > second . members . end ( ) ) )
2020-02-11 13:37:22 +00:00
{
return true ;
}
}
2018-09-25 09:23:27 +00:00
}
2020-02-11 13:37:22 +00:00
return false ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : containsArray ( std : : string const & type ) const
2019-09-23 13:57:48 +00:00
{
// a simple recursive check if a type is or contains an array
2020-04-12 19:49:12 +00:00
auto structureIt = m_structures . find ( type ) ;
bool found = false ;
if ( structureIt ! = m_structures . end ( ) )
2019-09-23 13:57:48 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto memberIt = structureIt - > second . members . begin ( ) ; memberIt ! = structureIt - > second . members . end ( ) & & ! found ;
+ + memberIt )
2019-09-23 13:57:48 +00:00
{
2020-04-12 19:49:12 +00:00
found = ! memberIt - > arraySizes . empty ( ) | | containsArray ( memberIt - > type . type ) ;
2019-09-23 13:57:48 +00:00
}
}
return found ;
}
2020-04-12 19:49:12 +00:00
bool VulkanHppGenerator : : containsUnion ( std : : string const & type ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// a simple recursive check if a type is or contains a union
2020-04-12 19:49:12 +00:00
auto structureIt = m_structures . find ( type ) ;
bool found = ( structureIt ! = m_structures . end ( ) ) ;
if ( found )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
found = structureIt - > second . isUnion ;
2020-04-12 19:49:12 +00:00
for ( auto memberIt = structureIt - > second . members . begin ( ) ; memberIt ! = structureIt - > second . members . end ( ) & & ! found ;
+ + memberIt )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
found = memberIt - > type . prefix . empty ( ) & & memberIt - > type . postfix . empty ( ) & & containsUnion ( memberIt - > type . type ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
return found ;
}
2020-04-12 19:49:12 +00:00
std : : string VulkanHppGenerator : : determineEnhancedReturnType ( CommandData const & commandData ,
size_t returnParamIndex ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool isStructureChain ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( returnParamIndex = = INVALID_INDEX ) | | ( returnParamIndex < commandData . params . size ( ) ) ) ;
for ( auto vpi : vectorParamIndices )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( vpi . first ! = vpi . second ) & & ( vpi . first < commandData . params . size ( ) ) & &
( ( vpi . second = = INVALID_INDEX ) | | ( vpi . second < commandData . params . size ( ) ) ) ) ;
2019-06-06 11:13:38 +00:00
}
2019-08-27 07:02:49 +00:00
std : : string enhancedReturnType ;
2020-04-12 19:49:12 +00:00
if ( returnParamIndex ! = INVALID_INDEX )
2019-01-09 10:55:11 +00:00
{
2020-03-24 08:43:50 +00:00
// if there is a return parameter, we think returnType is always "void" or "VkResult"
// -> we can return that parameter
2020-04-12 19:49:12 +00:00
assert ( ( commandData . returnType = = " void " ) | | ( commandData . returnType = = " VkResult " ) ) ;
assert ( commandData . successCodes . empty ( ) | | ( commandData . successCodes [ 0 ] = = " VK_SUCCESS " ) ) ;
if ( vectorParamIndices . find ( returnParamIndex ) ! = vectorParamIndices . end ( ) )
{
enhancedReturnType =
( commandData . params [ returnParamIndex ] . type . type = = " void " )
? " std::vector<uint8_t,Allocator> " // the return parameter is a vector-type parameter
: isStructureChain ? " std::vector<StructureChain,Allocator> " // for structureChain returns, it's just
// a vector of StrutureChains
: " std::vector< " + stripPrefix ( commandData . params [ returnParamIndex ] . type . type , " Vk " ) +
" ,Allocator> " ; // for the other parameters, we use a vector of the pure type
2019-08-27 07:02:49 +00:00
}
else
{
// it's a simple parameter -> get the type and just remove the trailing '*' (originally, it's a pointer)
2020-04-12 19:49:12 +00:00
assert ( commandData . params [ returnParamIndex ] . type . postfix . back ( ) = = ' * ' ) ;
assert ( ( commandData . params [ returnParamIndex ] . type . prefix . find ( " const " ) = = std : : string : : npos ) & &
( commandData . params [ returnParamIndex ] . type . postfix . find ( " const " ) = = std : : string : : npos ) ) ;
enhancedReturnType = stripPostfix ( commandData . params [ returnParamIndex ] . type . compose ( ) , " * " ) ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-12 19:49:12 +00:00
else if ( ( commandData . returnType = = " VkResult " ) & & ( commandData . successCodes . size ( ) = = 1 ) )
2019-08-27 07:02:49 +00:00
{
// an original return of type "Result" with just one successCode is changed to void, errors throw an exception
enhancedReturnType = " void " ;
2018-09-25 09:23:27 +00:00
}
else
{
2019-08-27 07:02:49 +00:00
// the return type just stays the original return type
2020-04-12 19:49:12 +00:00
enhancedReturnType = stripPrefix ( commandData . returnType , " Vk " ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
return enhancedReturnType ;
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
size_t VulkanHppGenerator : : determineReturnParamIndex ( CommandData const & commandData ,
std : : map < size_t , size_t > const & vectorParamIndices ,
bool twoStep ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto vpi : vectorParamIndices )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( vpi . first ! = vpi . second ) & & ( vpi . first < commandData . params . size ( ) ) & &
( ( vpi . second = = INVALID_INDEX ) | | ( vpi . second < commandData . params . size ( ) ) ) ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
size_t returnParamIndex = INVALID_INDEX ;
// for return types of type VkResult or void, we can determine a parameter to return
2020-04-12 19:49:12 +00:00
if ( ( commandData . returnType = = " VkResult " ) | | ( commandData . returnType = = " void " ) )
{
for ( size_t i = 0 ; i < commandData . params . size ( ) ; i + + )
{
if ( ( commandData . params [ i ] . type . postfix . find ( ' * ' ) ! = std : : string : : npos ) & &
( ( commandData . params [ i ] . type . type ! = " void " ) | | twoStep | |
( commandData . params [ i ] . type . postfix . find ( " ** " ) ! = std : : string : : npos ) ) & &
( commandData . params [ i ] . type . prefix . find ( " const " ) = = std : : string : : npos ) & &
std : : find_if (
vectorParamIndices . begin ( ) , vectorParamIndices . end ( ) , [ i ] ( std : : pair < size_t , size_t > const & vpi ) {
return vpi . second = = i ;
} ) = = vectorParamIndices . end ( ) )
2019-08-27 07:02:49 +00:00
{
// it's a non-const pointer and not a vector-size parameter
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > : : const_iterator vpit = vectorParamIndices . find ( i ) ;
if ( ( vpit = = vectorParamIndices . end ( ) ) | | twoStep | | ( vectorParamIndices . size ( ) > 1 ) | |
( vpit - > second = = INVALID_INDEX ) | |
( commandData . params [ vpit - > second ] . type . postfix . find ( ' * ' ) ! = std : : string : : npos ) )
2019-08-27 07:02:49 +00:00
{
2020-04-29 09:45:10 +00:00
// it's not a vector parameter, or a two-step process, or there is at least one more vector parameter, or
// the size argument of this vector parameter is not an argument, or the size argument of this vector
// parameter is provided by a pointer
2019-08-27 07:02:49 +00:00
// -> look for another non-cost pointer argument
2020-04-12 19:49:12 +00:00
auto paramIt =
std : : find_if ( commandData . params . begin ( ) + i + 1 , commandData . params . end ( ) , [ ] ( ParamData const & pd ) {
return ( pd . type . postfix . find ( ' * ' ) ! = std : : string : : npos ) & &
( pd . type . postfix . find ( " const " ) = = std : : string : : npos ) ;
} ) ;
2019-08-27 07:02:49 +00:00
// if there is another such argument, we can't decide which one to return -> return INVALID_INDEX
// otherwise return the index of the selcted parameter
returnParamIndex = paramIt ! = commandData . params . end ( ) ? INVALID_INDEX : i ;
}
}
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
return returnParamIndex ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string VulkanHppGenerator : : determineSubStruct ( std : : pair < std : : string , StructureData > const & structure ) const
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
for ( auto const & s : m_structures )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( s . first ! = structure . first ) & & ( s . second . members . size ( ) < structure . second . members . size ( ) ) & &
( s . second . members [ 0 ] . name ! = " sType " ) )
2019-08-27 07:02:49 +00:00
{
bool equal = true ;
2020-04-12 19:49:12 +00:00
for ( size_t i = 0 ; i < s . second . members . size ( ) & & equal ; i + + )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
equal = ( s . second . members [ i ] . type = = structure . second . members [ i ] . type ) & &
( s . second . members [ i ] . name = = structure . second . members [ i ] . name ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
if ( equal )
2019-08-27 07:02:49 +00:00
{
return s . first ;
}
}
}
return " " ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
size_t VulkanHppGenerator : : determineTemplateParamIndex ( std : : vector < ParamData > const & params ,
std : : map < size_t , size_t > const & vectorParamIndices ) const
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
size_t templateParamIndex = INVALID_INDEX ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
for ( size_t i = 0 ; i < params . size ( ) ; i + + )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// any vector parameter on the pure type void is templatized in the enhanced API
2020-04-12 19:49:12 +00:00
if ( ( vectorParamIndices . find ( i ) ! = vectorParamIndices . end ( ) ) & & ( params [ i ] . type . type = = " void " ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
# if !defined( NDEBUG )
for ( size_t j = i + 1 ; j < params . size ( ) ; j + + )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( ( vectorParamIndices . find ( j ) = = vectorParamIndices . end ( ) ) | | ( params [ j ] . type . type ! = " void " ) ) ;
2019-08-27 07:02:49 +00:00
}
# endif
templateParamIndex = i ;
break ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ( templateParamIndex = = INVALID_INDEX ) | |
( vectorParamIndices . find ( templateParamIndex ) ! = vectorParamIndices . end ( ) ) ) ;
2019-08-27 07:02:49 +00:00
return templateParamIndex ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
std : : map < size_t , size_t > VulkanHppGenerator : : determineVectorParamIndices ( std : : vector < ParamData > const & params ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : map < size_t , size_t > vectorParamIndices ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// look for the parameters whose len equals the name of an other parameter
2020-04-12 19:49:12 +00:00
for ( auto it = params . begin ( ) ; it ! = params . end ( ) ; + + it )
{
if ( ! it - > len . empty ( ) )
{
auto findLambda = [ it ] ( ParamData const & pd ) {
return pd . name = = it - > len ;
} ;
auto findIt =
std : : find_if ( params . begin ( ) , it , findLambda ) ; // look for a parameter named as the len of this parameter
assert ( ( std : : count_if ( params . begin ( ) , params . end ( ) , findLambda ) = = 0 ) | |
( findIt < it ) ) ; // make sure, there is no other parameter like that
2020-04-29 09:45:10 +00:00
// add this parameter as a vector parameter, using the len-name parameter as the second value (or INVALID_INDEX
// if there is nothing like that)
2020-04-12 19:49:12 +00:00
vectorParamIndices . insert (
std : : make_pair ( std : : distance ( params . begin ( ) , it ) ,
( findIt < it ) ? std : : distance ( params . begin ( ) , findIt ) : INVALID_INDEX ) ) ;
assert ( ( vectorParamIndices [ std : : distance ( params . begin ( ) , it ) ] ! = INVALID_INDEX ) | |
( it - > len = = " null-terminated " ) | | ( it - > len = = " pAllocateInfo->descriptorSetCount " ) | |
( it - > len = = " pAllocateInfo::descriptorSetCount " ) | |
( it - > len = = " pAllocateInfo->commandBufferCount " ) | |
( it - > len = = " pAllocateInfo::commandBufferCount " ) ) ;
2018-09-25 09:23:27 +00:00
}
}
2019-08-27 07:02:49 +00:00
return vectorParamIndices ;
2018-09-25 09:23:27 +00:00
}
2020-04-21 12:26:32 +00:00
void VulkanHppGenerator : : appendIndexTypeTraits ( std : : string & str ) const
{
auto indexType = m_enums . find ( " VkIndexType " ) ;
assert ( indexType ! = m_enums . end ( ) ) ;
str + = R " (
template < typename T >
struct IndexTypeValue
{ } ;
) " ;
std : : set < std : : string > seenCppTypes ;
for ( auto const & value : indexType - > second . values )
{
std : : string cppType ;
if ( beginsWith ( value . vkValue , " eUint8 " ) )
{
cppType = " uint8_t " ;
}
else if ( beginsWith ( value . vkValue , " eUint16 " ) )
{
cppType = " uint16_t " ;
}
else if ( beginsWith ( value . vkValue , " eUint32 " ) )
{
cppType = " uint32_t " ;
}
else if ( beginsWith ( value . vkValue , " eUint64 " ) )
{
cppType = " uint64_t " ; // No extension for this currently
}
else
{
assert ( value . vkValue = = " eNoneKHR " ) ;
}
if ( ! cppType . empty ( ) )
{
if ( seenCppTypes . insert ( cppType ) . second )
{
// IndexType traits aren't necessarily invertible.
// The Type -> Enum translation will only occur for the first prefixed enum value.
// A hypothetical extension to this enum with a conflicting prefix will use the core spec value.
str + =
" \n "
" template <> \n "
" struct IndexTypeValue< " +
cppType +
" > \n "
" { \n "
" static VULKAN_HPP_CONST_OR_CONSTEXPR IndexType value = IndexType:: " +
value . vkValue +
" ; \n "
" }; \n " ;
}
// Enum -> Type translations are always able to occur.
str + =
" \n "
" template <> \n "
" struct CppType<IndexType, IndexType:: " +
value . vkValue +
" > \n "
" { \n "
" using Type = " +
cppType +
" ; \n "
" }; \n " ;
}
}
}
2020-04-12 19:49:12 +00:00
std : : string const & VulkanHppGenerator : : getTypesafeCheck ( ) const
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
return m_typesafeCheck ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string const & VulkanHppGenerator : : getVersion ( ) const
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
return m_version ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string const & VulkanHppGenerator : : getVulkanLicenseHeader ( ) const
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
return m_vulkanLicenseHeader ;
}
2019-01-09 10:55:11 +00:00
2020-04-21 12:26:32 +00:00
bool VulkanHppGenerator : : holdsSType ( std : : string const & type ) const
2020-04-20 13:26:40 +00:00
{
2020-04-21 12:26:32 +00:00
auto it = m_structures . find ( type ) ;
if ( it ! = m_structures . end ( ) )
2020-04-20 13:26:40 +00:00
{
2020-04-21 12:26:32 +00:00
assert ( ! it - > second . members . empty ( ) ) ;
return ( it - > second . members . front ( ) . name = = " sType " ) ;
2020-04-20 13:26:40 +00:00
}
return false ;
}
2020-04-21 12:26:32 +00:00
bool VulkanHppGenerator : : isTwoStepAlgorithm ( std : : vector < ParamData > const & params ) const
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
// we generate a two-step algorithm for functions returning a vector of stuff, where the length is specified as a
// pointer as well for those functions, the size can be queried first, and then used
2019-08-27 07:02:49 +00:00
bool isTwoStep = false ;
2020-04-12 19:49:12 +00:00
for ( auto paramIt = params . begin ( ) ; paramIt ! = params . end ( ) & & ! isTwoStep ; + + paramIt )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ! paramIt - > len . empty ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto lenIt =
std : : find_if ( params . begin ( ) , paramIt , [ paramIt ] ( ParamData const & pd ) { return paramIt - > len = = pd . name ; } ) ;
if ( lenIt ! = paramIt )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
isTwoStep = ( lenIt - > type . postfix . find ( ' * ' ) ! = std : : string : : npos ) ;
2018-09-25 09:23:27 +00:00
}
}
}
2019-08-27 07:02:49 +00:00
return isTwoStep ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : linkCommandToHandle ( int line , std : : string const & name , CommandData const & commandData )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
// first, find the handle named like the type of the first argument
2020-04-12 19:49:12 +00:00
// if there is no such handle, look for the unnamed "handle", that gathers all the functions not tied to a specific
// handle
check ( ! commandData . params . empty ( ) , line , " command < " + name + " > with no params " ) ;
std : : map < std : : string , HandleData > : : iterator handleIt = m_handles . find ( commandData . params [ 0 ] . type . type ) ;
if ( handleIt = = m_handles . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
handleIt = m_handles . find ( " " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
check ( handleIt ! = m_handles . end ( ) , line , " could not find a handle to hold command < " + name + " > " ) ;
2018-09-25 09:23:27 +00:00
2019-08-27 07:02:49 +00:00
// put the command into the handle's list of commands
2020-04-12 19:49:12 +00:00
check ( handleIt - > second . commands . find ( name ) = = handleIt - > second . commands . end ( ) ,
line ,
" command list of handle < " + handleIt - > first + " > already holds a commnand < " + name + " > " ) ;
handleIt - > second . commands . insert ( std : : make_pair ( name , commandData ) ) ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
// and store the handle in the command-to-handle map
2020-04-12 19:49:12 +00:00
check ( m_commandToHandle . find ( name ) = = m_commandToHandle . end ( ) ,
line ,
" command to handle mapping already holds the command < " + name + " > " ) ;
2019-08-27 07:02:49 +00:00
m_commandToHandle [ name ] = handleIt - > first ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readBaseType ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2018-09-25 09:23:27 +00:00
{
2020-02-04 09:35:33 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " basetype " } } } , { } ) ;
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
NameData nameData ;
TypeData typeData ;
2020-04-12 19:49:12 +00:00
std : : tie ( nameData , typeData ) = readNameAndType ( element ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
check ( nameData . arraySizes . empty ( ) , line , " name < " + nameData . name + " > with unsupported arraySizes " ) ;
check ( nameData . bitCount . empty ( ) ,
line ,
" name < " + nameData . name + " > with unsupported bitCount < " + nameData . bitCount + " > " ) ;
2020-04-27 15:15:53 +00:00
check ( typeData . type . empty ( ) | | ( typeData . prefix = = " typedef " ) ,
line ,
" unexpected type prefix < " + typeData . prefix + " > " ) ;
check ( typeData . prefix . empty ( ) | | ( typeData . prefix = = " typedef " ) ,
line ,
" unexpected type prefix < " + typeData . prefix + " > " ) ;
2020-04-12 19:49:12 +00:00
check ( typeData . postfix . empty ( ) , line , " unexpected type postfix < " + typeData . postfix + " > " ) ;
2020-02-11 13:37:22 +00:00
2020-04-27 15:15:53 +00:00
if ( ! typeData . type . empty ( ) )
{
check ( m_baseTypes . insert ( std : : make_pair ( nameData . name , BaseTypeData ( typeData . type , line ) ) ) . second ,
line ,
" basetype < " + nameData . name + " > already specified " ) ;
}
2020-04-12 19:49:12 +00:00
check ( m_types . insert ( std : : make_pair ( nameData . name , TypeCategory : : BaseType ) ) . second ,
line ,
" basetype < " + nameData . name + " > already specified as a type " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readBitmask ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
auto aliasIt = attributes . find ( " alias " ) ;
if ( aliasIt ! = attributes . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readBitmaskAlias ( element , attributes ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
else
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " bitmask " } } } , { { " requires " , { } } } ) ;
2018-09-25 09:23:27 +00:00
2020-02-26 13:24:58 +00:00
std : : string requirements ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " requires " )
2020-02-11 13:37:22 +00:00
{
2020-02-26 13:24:58 +00:00
requirements = attribute . second ;
2020-02-11 13:37:22 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
NameData nameData ;
TypeData typeData ;
2020-04-12 19:49:12 +00:00
std : : tie ( nameData , typeData ) = readNameAndType ( element ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
check ( beginsWith ( nameData . name , " Vk " ) , line , " name < " + nameData . name + " > does not begin with <Vk> " ) ;
check ( nameData . arraySizes . empty ( ) , line , " name < " + nameData . name + " > with unsupported arraySizes " ) ;
check ( nameData . bitCount . empty ( ) ,
line ,
" name < " + nameData . name + " > with unsupported bitCount < " + nameData . bitCount + " > " ) ;
warn ( ( typeData . type = = " VkFlags " ) | | ( typeData . type = = " VkFlags64 " ) ,
line ,
" unexpected bitmask type < " + typeData . type + " > " ) ;
check ( typeData . prefix = = " typedef " , line , " unexpected type prefix < " + typeData . prefix + " > " ) ;
check ( typeData . postfix . empty ( ) , line , " unexpected type postfix < " + typeData . postfix + " > " ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
check ( m_commandToHandle . find ( nameData . name ) = = m_commandToHandle . end ( ) ,
line ,
" command < " + nameData . name + " > already specified " ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
m_bitmasks . insert ( std : : make_pair ( nameData . name , BitmaskData ( requirements , typeData . type , line ) ) ) ;
check ( m_types . insert ( std : : make_pair ( nameData . name , TypeCategory : : Bitmask ) ) . second ,
line ,
" bitmask < " + nameData . name + " > already specified as a type " ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readBitmaskAlias ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " alias " , { } } , { " category " , { " bitmask " } } , { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
std : : string alias , name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
alias = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
auto bitmasksIt = m_bitmasks . find ( alias ) ;
check ( bitmasksIt ! = m_bitmasks . end ( ) , line , " missing alias < " + alias + " >. " ) ;
check ( bitmasksIt - > second . alias . empty ( ) ,
line ,
" alias for bitmask < " + bitmasksIt - > first + " > already specified as < " + bitmasksIt - > second . alias + " > " ) ;
2020-02-11 13:37:22 +00:00
bitmasksIt - > second . alias = name ;
2020-04-12 19:49:12 +00:00
check ( m_types . insert ( std : : make_pair ( name , TypeCategory : : Bitmask ) ) . second ,
line ,
" aliased bitmask < " + name + " > already specified as a type " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readCommand ( tinyxml2 : : XMLElement const * element )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
auto aliasIt = attributes . find ( " alias " ) ;
if ( aliasIt ! = attributes . end ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readCommandAlias ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
readCommand ( element , attributes ) ;
2020-02-11 13:37:22 +00:00
}
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readCommand ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line ,
attributes ,
{ } ,
{ { " cmdbufferlevel " , { " primary " , " secondary " } } ,
{ " comment " , { } } ,
{ " errorcodes " , { } } ,
{ " pipeline " , { " compute " , " graphics " , " transfer " } } ,
{ " queues " , { " compute " , " graphics " , " sparse_binding " , " transfer " } } ,
{ " renderpass " , { " both " , " inside " , " outside " } } ,
{ " successcodes " , { } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " param " , false } , { " proto " , true } } , { " implicitexternsyncparams " } ) ;
CommandData commandData ( line ) ;
for ( auto const & attribute : attributes )
{
if ( attribute . first = = " errorcodes " )
{
commandData . errorCodes = tokenize ( attribute . second , " , " ) ;
2020-02-11 13:37:22 +00:00
// errorCodes are checked in checkCorrectness after complete reading
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " successcodes " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
commandData . successCodes = tokenize ( attribute . second , " , " ) ;
2020-02-11 13:37:22 +00:00
// successCodes are checked in checkCorrectness after complete reading
2019-08-27 07:02:49 +00:00
}
2020-02-11 13:37:22 +00:00
}
2019-01-09 10:55:11 +00:00
2020-02-11 13:37:22 +00:00
std : : string name ;
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2020-02-11 13:37:22 +00:00
{
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " param " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
commandData . params . push_back ( readCommandParam ( child , commandData . params ) ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " proto " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
std : : tie ( name , commandData . returnType ) = readCommandProto ( child ) ;
2020-02-11 13:37:22 +00:00
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
registerDeleter ( name , std : : make_pair ( name , commandData ) ) ;
linkCommandToHandle ( line , name , commandData ) ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readCommandAlias ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2019-08-27 07:02:49 +00:00
{
// for command aliases, create a copy of the aliased command
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line ,
attributes ,
{ } ,
{
{ " alias " , { } } ,
{ " name " , { } } ,
} ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-01-09 10:55:11 +00:00
2020-02-11 13:37:22 +00:00
std : : string alias , name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
alias = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( beginsWith ( name , " vk " ) , line , " name < " + name + " > should begin with <vk> " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
auto commandToHandleIt = m_commandToHandle . find ( alias ) ;
check ( commandToHandleIt ! = m_commandToHandle . end ( ) , line , " missing command < " + alias + " > " ) ;
auto handleIt = m_handles . find ( commandToHandleIt - > second ) ;
check ( handleIt ! = m_handles . end ( ) , line , " missing handle < " + commandToHandleIt - > second + " > " ) ;
auto commandsIt = handleIt - > second . commands . find ( alias ) ;
if ( commandsIt = = handleIt - > second . commands . end ( ) )
2020-03-04 12:33:52 +00:00
{
// look, if this command is aliases and already aliased command
2020-04-12 19:49:12 +00:00
commandsIt =
std : : find_if ( handleIt - > second . commands . begin ( ) , handleIt - > second . commands . end ( ) , [ & alias ] ( auto const & cd ) {
return cd . second . aliases . find ( alias ) ! = cd . second . aliases . end ( ) ;
} ) ;
}
check ( commandsIt ! = handleIt - > second . commands . end ( ) ,
line ,
" missing command < " + alias + " > in handle < " + handleIt - > first + " > " ) ;
check ( commandsIt - > second . aliases . insert ( name ) . second ,
line ,
" alias < " + name + " > for command < " + alias + " > already specified " ) ;
2020-03-04 12:33:52 +00:00
// and store the alias in the command-to-handle map
2020-04-12 19:49:12 +00:00
check ( m_commandToHandle . find ( name ) = = m_commandToHandle . end ( ) ,
line ,
" command to handle mapping already holds the command < " + name + " > " ) ;
2020-03-04 12:33:52 +00:00
m_commandToHandle [ name ] = handleIt - > first ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
VulkanHppGenerator : : ParamData VulkanHppGenerator : : readCommandParam ( tinyxml2 : : XMLElement const * element ,
std : : vector < ParamData > const & params )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes (
line ,
attributes ,
{ } ,
{ { " externsync " , { } } , { " len " , { } } , { " noautovalidity " , { " true " } } , { " optional " , { " false " , " true " } } } ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
ParamData paramData ( line ) ;
for ( auto attribute : attributes )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " len " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
paramData . len = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( checkLenAttribute ( paramData . len , params ) ,
line ,
" command param len < " + paramData . len + " > is not recognized as a valid len value " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " optional " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
paramData . optional = ( attribute . second = = " true " ) ;
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-02-11 13:37:22 +00:00
NameData nameData ;
2020-04-12 19:49:12 +00:00
std : : tie ( nameData , paramData . type ) = readNameAndType ( element ) ;
check ( nameData . bitCount . empty ( ) ,
line ,
" name < " + nameData . name + " > with unsupported bitCount < " + nameData . bitCount + " > " ) ;
check ( m_types . find ( paramData . type . type ) ! = m_types . end ( ) , line , " unknown type < " + paramData . type . type + " > " ) ;
check ( paramData . type . prefix . empty ( ) | | ( paramData . type . prefix = = " const " ) | |
( paramData . type . prefix = = " const struct " ) | | ( paramData . type . prefix = = " struct " ) ,
line ,
" unexpected type prefix < " + paramData . type . prefix + " > " ) ;
check ( paramData . type . postfix . empty ( ) | | ( paramData . type . postfix = = " * " ) | | ( paramData . type . postfix = = " ** " ) | |
( paramData . type . postfix = = " * const* " ) ,
line ,
" unexpected type postfix < " + paramData . type . postfix + " > " ) ;
check ( std : : find_if ( params . begin ( ) ,
params . end ( ) ,
[ & name = nameData . name ] ( ParamData const & pd ) { return pd . name = = name ; } ) = = params . end ( ) ,
line ,
" command param < " + nameData . name + " > already used " ) ;
paramData . name = nameData . name ;
2020-02-11 13:37:22 +00:00
paramData . arraySizes = nameData . arraySizes ;
2019-01-09 10:55:11 +00:00
2019-08-27 07:02:49 +00:00
return paramData ;
}
2019-07-09 07:24:14 +00:00
2020-04-12 19:49:12 +00:00
std : : pair < std : : string , std : : string > VulkanHppGenerator : : readCommandProto ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
2020-02-11 13:37:22 +00:00
NameData nameData ;
TypeData typeData ;
2020-04-12 19:49:12 +00:00
std : : tie ( nameData , typeData ) = readNameAndType ( element ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
check ( beginsWith ( nameData . name , " vk " ) , line , " name < " + nameData . name + " > does not begin with <vk> " ) ;
check ( nameData . arraySizes . empty ( ) , line , " name < " + nameData . name + " > with unsupported arraySizes " ) ;
check ( nameData . bitCount . empty ( ) ,
line ,
" name < " + nameData . name + " > with unsupported bitCount < " + nameData . bitCount + " > " ) ;
check ( m_types . find ( typeData . type ) ! = m_types . end ( ) , line , " unknown type < " + typeData . type + " > " ) ;
check ( typeData . prefix . empty ( ) , line , " unexpected type prefix < " + typeData . prefix + " > " ) ;
check ( typeData . postfix . empty ( ) , line , " unexpected type postfix < " + typeData . postfix + " > " ) ;
check ( m_commandToHandle . find ( nameData . name ) = = m_commandToHandle . end ( ) ,
line ,
" command < " + nameData . name + " > already specified " ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
return std : : make_pair ( nameData . name , typeData . type ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readCommands ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { { " comment " , { } } } ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " command " , false } } ) ;
for ( auto child : children )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readCommand ( child ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
std : : string VulkanHppGenerator : : readComment ( tinyxml2 : : XMLElement const * element )
2019-01-09 10:55:11 +00:00
{
2020-02-04 09:35:33 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
return element - > GetText ( ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readDefine ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2019-08-27 07:02:49 +00:00
{
2020-02-04 09:35:33 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " define " } } } , { { " name " , { } } , { " requires " , { } } } ) ;
2019-08-27 07:02:49 +00:00
2020-03-09 10:23:46 +00:00
std : : string name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2020-03-09 10:23:46 +00:00
{
name = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " requires " )
2020-03-09 10:23:46 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_defines . find ( attribute . second ) ! = m_defines . end ( ) ,
line ,
" using undefined requires < " + attribute . second + " > " ) ;
2020-03-09 10:23:46 +00:00
}
}
2020-04-12 19:49:12 +00:00
if ( ! name . empty ( ) )
2020-03-09 10:23:46 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ! element - > FirstChildElement ( ) , line , " unknown formatting of type category=define name < " + name + " > " ) ;
check ( name = = " VK_DEFINE_NON_DISPATCHABLE_HANDLE " , line , " unknown type category=define name < " + name + " > " ) ;
check ( element - > LastChild ( ) & & element - > LastChild ( ) - > ToText ( ) & & element - > LastChild ( ) - > ToText ( ) - > Value ( ) ,
line ,
" unknown formatting of type category=define named < " + name + " > " ) ;
2019-08-27 07:02:49 +00:00
// filter out the check for the different types of VK_DEFINE_NON_DISPATCHABLE_HANDLE
2020-04-12 19:49:12 +00:00
std : : string text = element - > LastChild ( ) - > ToText ( ) - > Value ( ) ;
size_t start = text . find ( " #if defined(__LP64__) " ) ;
check ( start ! = std : : string : : npos , line , " unexpected text in type category=define named < " + name + " > " ) ;
size_t end = text . find_first_of ( " \r \n " , start + 1 ) ;
check ( end ! = std : : string : : npos , line , " unexpected text in type category=define named < " + name + " > " ) ;
m_typesafeCheck = text . substr ( start , end - start ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( element - > GetText ( ) )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
std : : string text = element - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
if ( ( text . find ( " class " ) ! = std : : string : : npos ) | | ( text . find ( " struct " ) ! = std : : string : : npos ) )
2020-02-11 13:37:22 +00:00
{
// here are a couple of structs as defines, which really are types!
2020-04-12 19:49:12 +00:00
tinyxml2 : : XMLElement const * child = element - > FirstChildElement ( ) ;
check ( child & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) & & child - > GetText ( ) ,
line ,
" unexpected formatting of type category=define " ) ;
2020-03-09 10:23:46 +00:00
name = child - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
check ( m_types . insert ( std : : make_pair ( name , TypeCategory : : Define ) ) . second ,
line ,
" type < " + name + " > has already been speficied " ) ;
2020-02-11 13:37:22 +00:00
}
else
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
tinyxml2 : : XMLElement const * child = element - > FirstChildElement ( ) ;
check ( child & & ! child - > FirstAttribute ( ) & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) & & child - > GetText ( ) ,
line ,
" unknown formatting of type category define " ) ;
name = trim ( child - > GetText ( ) ) ;
if ( name = = " VK_HEADER_VERSION " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
m_version = trimEnd ( element - > LastChild ( ) - > ToText ( ) - > Value ( ) ) ;
2020-02-11 13:37:22 +00:00
}
// ignore all the other defines
2020-04-12 19:49:12 +00:00
warn ( ! child - > NextSiblingElement ( ) | |
( child - > NextSiblingElement ( ) & & ! child - > NextSiblingElement ( ) - > FirstAttribute ( ) & &
( strcmp ( child - > NextSiblingElement ( ) - > Value ( ) , " type " ) = = 0 ) & &
! child - > NextSiblingElement ( ) - > NextSiblingElement ( ) ) ,
line ,
" unknown formatting of type category define " ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-03-09 10:23:46 +00:00
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
check ( m_defines . insert ( name ) . second , line , " define < " + name + " > has already been specified " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readEnum ( tinyxml2 : : XMLElement const * element ,
EnumData & enumData ,
bool bitmask ,
std : : string const & prefix ,
std : : string const & postfix )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
auto aliasIt = attributes . find ( " alias " ) ;
if ( aliasIt ! = attributes . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readEnumAlias ( element , attributes , enumData , bitmask , prefix , postfix ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
readEnum ( element , attributes , enumData , bitmask , prefix , postfix ) ;
2019-08-27 07:02:49 +00:00
}
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readEnum ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes ,
EnumData & enumData ,
bool bitmask ,
std : : string const & prefix ,
std : : string const & postfix )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " name " , { } } } , { { " bitpos " , { } } , { " comment " , { } } , { " value " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
std : : string alias , bitpos , name , value ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " bitpos " )
2020-02-11 13:37:22 +00:00
{
bitpos = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! bitpos . empty ( ) , line , " enum with empty bitpos " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , line , " enum with empty name " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " value " )
2020-02-11 13:37:22 +00:00
{
value = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! value . empty ( ) , line , " enum with empty value " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
std : : string tag = findTag ( m_tags , name , postfix ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
check ( bitpos . empty ( ) ^ value . empty ( ) , line , " invalid set of attributes for enum < " + name + " > " ) ;
enumData . addEnumValue ( line , name , bitmask , ! bitpos . empty ( ) , prefix , postfix , tag ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readEnumAlias ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes ,
EnumData & enumData ,
bool bitmask ,
std : : string const & prefix ,
std : : string const & postfix )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " alias " , { } } , { " name " , { } } } , { { " comment " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
std : : string alias , bitpos , name , value ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
alias = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! alias . empty ( ) , line , " enum with empty alias " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , line , " enum with empty name " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
std : : string tag = findTag ( m_tags , name , postfix ) ;
2020-04-30 09:30:17 +00:00
enumData . addEnumAlias ( line , name , alias , createEnumValueName ( name , prefix , postfix , bitmask , tag ) ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readEnumConstant ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { { " alias " , { } } , { " comment " , { } } , { " value " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_constants . find ( attribute . second ) ! = m_constants . end ( ) ,
line ,
" unknown enum constant alias < " + attribute . second + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_constants . insert ( attribute . second ) . second ,
line ,
" already specified enum constant < " + attribute . second + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readEnums ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { { " comment " , { } } , { " type " , { " bitmask " , " enum " } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
2020-02-11 13:37:22 +00:00
std : : string name , type ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , line , " enum with empty name " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " type " )
2020-02-11 13:37:22 +00:00
{
type = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! type . empty ( ) , line , " enum with empty type " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
if ( name = = " API Constants " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
checkElements ( line , children , { { " enum " , false } } , { } ) ;
for ( auto const & child : children )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readEnumConstant ( child ) ;
2020-02-11 13:37:22 +00:00
}
}
else
{
2020-04-12 19:49:12 +00:00
checkElements ( line , children , { } , { " comment " , " enum " , " unused " } ) ;
check ( ! type . empty ( ) , line , " enum without type " ) ;
2020-02-11 13:37:22 +00:00
2020-01-13 14:00:59 +00:00
// get the EnumData entry in enum map
2020-04-12 19:49:12 +00:00
std : : map < std : : string , EnumData > : : iterator it = m_enums . find ( name ) ;
if ( it = = m_enums . end ( ) )
2020-01-13 14:00:59 +00:00
{
// well, some enums are not listed in the <types> section
2020-04-12 19:49:12 +00:00
warn ( false , line , " enum < " + name + " > is not listed as enum in the types section " ) ;
it = m_enums . insert ( std : : make_pair ( name , EnumData ( ) ) ) . first ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
check ( it - > second . values . empty ( ) , line , " enum < " + name + " > already holds values " ) ;
2020-01-13 14:00:59 +00:00
2020-02-11 13:37:22 +00:00
// mark it as a bitmask, if it is one
2020-04-12 19:49:12 +00:00
bool bitmask = ( type = = " bitmask " ) ;
2020-01-13 14:00:59 +00:00
it - > second . isBitmask = bitmask ;
2020-04-12 19:49:12 +00:00
if ( bitmask )
2020-02-20 11:04:27 +00:00
{
// look for the corresponding bitmask and set the requirements if needed!
2020-04-12 19:49:12 +00:00
auto bitmaskIt = std : : find_if ( m_bitmasks . begin ( ) , m_bitmasks . end ( ) , [ & name ] ( auto const & bitmask ) {
return bitmask . second . requirements = = name ;
} ) ;
if ( bitmaskIt = = m_bitmasks . end ( ) )
2020-02-20 11:04:27 +00:00
{
2020-04-12 19:49:12 +00:00
warn ( false , line , " enum < " + name + " > is not listed as an requires for any bitmask in the types section " ) ;
2020-02-20 11:04:27 +00:00
std : : string bitmaskName = name ;
2020-04-12 19:49:12 +00:00
size_t pos = bitmaskName . rfind ( " FlagBits " ) ;
check ( pos ! = std : : string : : npos , line , " enum < " + name + " > does not contain <FlagBits> as substring " ) ;
bitmaskName . replace ( pos , 8 , " Flags " ) ;
bitmaskIt = m_bitmasks . find ( bitmaskName ) ;
check ( bitmaskIt ! = m_bitmasks . end ( ) ,
line ,
" enum < " + name + " > has not corresponding bitmask < " + bitmaskName + " > listed in the types section " ) ;
assert ( bitmaskIt - > second . requirements . empty ( ) ) ;
2020-02-26 13:24:58 +00:00
bitmaskIt - > second . requirements = name ;
2020-02-20 11:04:27 +00:00
}
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : string prefix = getEnumPrefix ( line , name , bitmask ) ;
std : : string postfix = getEnumPostfix ( name , m_tags , prefix ) ;
2019-08-27 07:02:49 +00:00
// read the names of the enum values
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " comment " )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " enum " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readEnum ( child , it - > second , bitmask , prefix , postfix ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtension ( tinyxml2 : : XMLElement const * element )
{
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line ,
attributes ,
{ { " name " , { } } , { " number " , { } } , { " supported " , { " disabled " , " enabled " , " vulkan " } } } ,
{ { " author " , { } } ,
{ " comment " , { } } ,
{ " contact " , { } } ,
{ " deprecatedby " , { } } ,
{ " obsoletedby " , { } } ,
{ " platform " , { } } ,
{ " promotedto " , { } } ,
{ " provisional " , { " true " } } ,
{ " requires " , { } } ,
{ " requiresCore " , { } } ,
{ " sortorder " , { " 1 " } } ,
{ " specialuse " , { " cadsupport " , " d3demulation " , " debugging " , " devtools " , " glemulation " } } ,
{ " type " , { " device " , " instance " } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { } , { " require " } ) ;
std : : string deprecatedBy , name , obsoletedBy , platform , promotedTo , supported ;
2020-02-26 13:24:58 +00:00
std : : vector < std : : string > requirements ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " deprecatedby " )
2020-02-11 13:37:22 +00:00
{
deprecatedBy = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " obsoletedby " )
2020-02-11 13:37:22 +00:00
{
obsoletedBy = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " platform " )
2020-02-11 13:37:22 +00:00
{
platform = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( m_platforms . find ( platform ) ! = m_platforms . end ( ) , line , " unknown platform < " + platform + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " promotedto " )
2020-02-11 13:37:22 +00:00
{
promotedTo = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " requires " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
requirements = tokenize ( attribute . second , " , " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " requiresCore " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string const & requiresCore = attribute . second ;
check ( std : : find_if ( m_features . begin ( ) ,
m_features . end ( ) ,
[ & requiresCore ] ( std : : pair < std : : string , std : : string > const & nameNumber ) {
return nameNumber . second = = requiresCore ;
} ) ! = m_features . end ( ) ,
line ,
" unknown feature number < " + attribute . second + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " supported " )
2020-02-11 13:37:22 +00:00
{
supported = attribute . second ;
}
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
if ( supported = = " disabled " )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
// kick out all the disabled stuff we've read before !!
2020-04-12 19:49:12 +00:00
for ( auto const & child : children )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionDisabledRequire ( name , child ) ;
2020-02-11 13:37:22 +00:00
}
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
auto pitb = m_extensions . insert ( std : : make_pair ( name , ExtensionData ( line ) ) ) ;
check ( pitb . second , line , " already encountered extension < " + name + " > " ) ;
2020-02-11 13:37:22 +00:00
pitb . first - > second . deprecatedBy = deprecatedBy ;
2020-04-12 19:49:12 +00:00
pitb . first - > second . obsoletedBy = obsoletedBy ;
pitb . first - > second . promotedTo = promotedTo ;
for ( auto const & r : requirements )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( pitb . first - > second . requirements . insert ( std : : make_pair ( r , line ) ) . second ,
line ,
" required extension < " + r + " > already listed " ) ;
2020-02-11 13:37:22 +00:00
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : string tag = extractTag ( line , name , m_tags ) ;
for ( auto child : children )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionRequire ( child , platform , tag , pitb . first - > second . requirements ) ;
2019-08-27 07:02:49 +00:00
}
2019-03-21 10:53:30 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionDisabledCommand ( tinyxml2 : : XMLElement const * element )
2019-03-21 10:53:30 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
std : : string name = attributes . find ( " name " ) - > second ;
2020-02-11 13:37:22 +00:00
// first unlink the command from its class
2020-04-12 19:49:12 +00:00
auto commandToHandleIt = m_commandToHandle . find ( name ) ;
check ( commandToHandleIt ! = m_commandToHandle . end ( ) , line , " try to remove unknown command < " + name + " > " ) ;
auto handlesIt = m_handles . find ( m_commandToHandle . find ( name ) - > second ) ;
check ( handlesIt ! = m_handles . end ( ) , line , " cannot find handle corresponding to command < " + name + " > " ) ;
auto commandIt = handlesIt - > second . commands . find ( name ) ;
check ( commandIt ! = handlesIt - > second . commands . end ( ) ,
line ,
" cannot find command < " + name + " > in commands associated with handle < " + handlesIt - > first + " > " ) ;
if ( ! commandIt - > second . aliases . empty ( ) )
{
// if there's an alias of the to-be-removed command, insert that as a new command with the very same CommandData
// (minus its alias)
check ( commandIt - > second . aliases . size ( ) = = 1 ,
line ,
" try to disable command < " + name + " > with more than one alias -> don't know what to do " ) ;
2020-03-05 10:02:55 +00:00
std : : string aliasName = * commandIt - > second . aliases . begin ( ) ;
commandIt - > second . aliases . clear ( ) ;
2020-04-12 19:49:12 +00:00
handlesIt - > second . commands . insert ( std : : make_pair ( aliasName , commandIt - > second ) ) ;
2020-03-05 10:02:55 +00:00
}
2020-04-12 19:49:12 +00:00
handlesIt - > second . commands . erase ( commandIt ) ;
2020-02-11 13:37:22 +00:00
// then remove the command from the command-to-handle map
2020-04-12 19:49:12 +00:00
m_commandToHandle . erase ( commandToHandleIt ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionDisabledEnum ( std : : string const & extensionName ,
tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line ,
attributes ,
{ { " name " , { } } } ,
{ { " alias " , { } } , { " bitpos " , { } } , { " extends " , { } } , { " offset " , { } } , { " value " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
std : : string extends , name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2019-03-21 10:53:30 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " extends " )
2020-02-11 13:37:22 +00:00
{
extends = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
}
2020-04-12 19:49:12 +00:00
if ( ! extends . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( extends ) ;
check ( enumIt ! = m_enums . end ( ) ,
line ,
" disabled extension < " + extensionName + " > references unknown enum < " + extends + " > " ) ;
check ( std : : find_if ( enumIt - > second . values . begin ( ) ,
enumIt - > second . values . end ( ) ,
[ & name ] ( EnumValueData const & evd ) { return evd . vulkanValue = = name ; } ) = =
enumIt - > second . values . end ( ) ,
line ,
" disabled extension < " + extensionName + " > references known enum value < " + name + " > " ) ;
2019-03-21 10:53:30 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionDisabledRequire ( std : : string const & extensionName ,
tinyxml2 : : XMLElement const * element )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " enum " , false } } , { " command " , " comment " , " type " } ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " command " )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionDisabledCommand ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " comment " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " enum " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionDisabledEnum ( extensionName , child ) ;
2018-09-25 09:23:27 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
assert ( value = = " type " ) ;
readExtensionDisabledType ( child ) ;
2018-09-25 09:23:27 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionDisabledType ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
std : : string name = attributes . find ( " name " ) - > second ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
auto typeIt = m_types . find ( name ) ;
check ( typeIt ! = m_types . end ( ) , line , " trying to remove unknown type < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
2020-04-12 19:49:12 +00:00
switch ( typeIt - > second )
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
case TypeCategory : : Bitmask :
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
auto bitmasksIt = m_bitmasks . find ( name ) ;
check ( bitmasksIt ! = m_bitmasks . end ( ) , line , " trying to remove unknown bitmask < " + name + " > " ) ;
check ( bitmasksIt - > second . alias . empty ( ) ,
line ,
" trying to remove disabled bitmask < " + name + " > which has alias < " + bitmasksIt - > second . alias + " > " ) ;
m_bitmasks . erase ( bitmasksIt ) ;
2020-03-05 10:02:55 +00:00
}
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Enum :
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( name ) ;
check ( enumIt ! = m_enums . end ( ) , line , " trying to remove unknown enum < " + name + " > " ) ;
check ( enumIt - > second . alias . empty ( ) ,
line ,
" trying to remove disabled enum < " + name + " > which has alias < " + enumIt - > second . alias + " > " ) ;
m_enums . erase ( enumIt ) ;
2020-03-05 10:02:55 +00:00
}
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Struct :
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
auto structIt = m_structures . find ( name ) ;
check ( structIt ! = m_structures . end ( ) , line , " trying to remove unknown struct < " + name + " > " ) ;
check ( structIt - > second . aliases . empty ( ) ,
line ,
" trying to remove disabled structure < " + name + " > which has " +
std : : to_string ( structIt - > second . aliases . size ( ) ) + " aliases " ) ;
m_structures . erase ( structIt ) ;
2020-03-05 10:02:55 +00:00
}
break ;
2020-04-12 19:49:12 +00:00
default :
check ( false , line , " trying to remove < " + name + " > of unhandled type < " + toString ( typeIt - > second ) + " > " ) ;
break ;
2020-03-05 10:02:55 +00:00
}
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionRequire ( tinyxml2 : : XMLElement const * element ,
std : : string const & platform ,
std : : string const & tag ,
std : : map < std : : string , int > & requirements )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { } , { { " extension " , { } } , { " feature " , { } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { } , { " command " , " comment " , " enum " , " type " } ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " extension " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( requirements . insert ( std : : make_pair ( attribute . second , line ) ) . second ,
line ,
" required extension < " + attribute . second + " > already listed " ) ;
2020-02-11 13:37:22 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
assert ( attribute . first = = " feature " ) ;
check (
m_features . find ( attribute . second ) ! = m_features . end ( ) , line , " unknown feature < " + attribute . second + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " command " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionRequireCommand ( child , platform ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " comment " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " enum " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readRequireEnum ( child , tag ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " type " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensionRequireType ( child , platform ) ;
2019-08-27 07:02:49 +00:00
}
}
2019-01-09 10:55:11 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionRequireCommand ( tinyxml2 : : XMLElement const * element ,
std : : string const & platform )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-07-23 07:28:14 +00:00
2019-08-27 07:02:49 +00:00
// just add the protect string to the CommandData
2020-04-12 19:49:12 +00:00
if ( ! platform . empty ( ) )
{
std : : string name = attributes . find ( " name " ) - > second ;
check ( m_platforms . find ( platform ) ! = m_platforms . end ( ) , line , " unknown platform < " + platform + " > " ) ;
auto commandToHandleIt = m_commandToHandle . find ( name ) ;
check ( commandToHandleIt ! = m_commandToHandle . end ( ) , line , " unknown command < " + name + " > " ) ;
auto const & handlesIt = m_handles . find ( commandToHandleIt - > second ) ;
check ( handlesIt ! = m_handles . end ( ) , line , " unknown handle for command < " + name + " > " ) ;
auto const & commandsIt = handlesIt - > second . commands . find ( name ) ;
check ( commandsIt ! = handlesIt - > second . commands . end ( ) ,
line ,
" unknown command < " + name + " > for handle < " + handlesIt - > first + " > " ) ;
2019-08-27 07:02:49 +00:00
commandsIt - > second . platform = platform ;
}
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensionRequireType ( tinyxml2 : : XMLElement const * element , std : : string const & platform )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-08-27 07:02:49 +00:00
// add the protect-string to the appropriate type: enum, flag, handle, scalar, or struct
2020-04-12 19:49:12 +00:00
std : : string name = attributes . find ( " name " ) - > second ;
2020-01-10 09:18:55 +00:00
2020-04-12 19:49:12 +00:00
auto typeIt = m_types . find ( name ) ;
check ( typeIt ! = m_types . end ( ) , line , " failed to find required type < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
2020-04-12 19:49:12 +00:00
if ( typeIt - > second = = TypeCategory : : Handle )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
assert ( beginsWith ( name , " Vk " ) ) ;
auto objectTypeIt = m_enums . find ( " VkObjectType " ) ;
assert ( objectTypeIt ! = m_enums . end ( ) ) ;
std : : string objectTypeName = " e " + stripPrefix ( name , " Vk " ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
auto handleIt = m_handles . find ( name ) ;
if ( handleIt ! = m_handles . end ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
auto valueIt =
std : : find_if ( objectTypeIt - > second . values . begin ( ) ,
objectTypeIt - > second . values . end ( ) ,
[ objectTypeName ] ( EnumValueData const & evd ) { return evd . vkValue = = objectTypeName ; } ) ;
check ( valueIt ! = objectTypeIt - > second . values . end ( ) ,
line ,
" missing entry in VkObjectType enum for handle < " + name + " >. " ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-30 09:30:17 +00:00
check ( std : : find_if ( objectTypeIt - > second . aliases . begin ( ) ,
objectTypeIt - > second . aliases . end ( ) ,
[ objectTypeName ] ( auto const & alias ) { return alias . second . second = = objectTypeName ; } ) ! =
objectTypeIt - > second . aliases . end ( ) ,
2020-04-12 19:49:12 +00:00
line ,
" missing alias entry in VkObjectType enum for alias handle < " + name + " >. " ) ;
2020-03-05 10:02:55 +00:00
}
}
2020-04-12 19:49:12 +00:00
if ( ! platform . empty ( ) )
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
switch ( typeIt - > second )
2020-03-05 10:02:55 +00:00
{
2020-04-27 15:15:53 +00:00
case TypeCategory : : BaseType :
// no need to protect a base type
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Bitmask :
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto bitmaskIt = m_bitmasks . find ( name ) ;
check ( bitmaskIt ! = m_bitmasks . end ( ) , line , " failed to find required bitmask < " + name + " > " ) ;
check ( bitmaskIt - > second . platform . empty ( ) , line , " platform already specified for bitmask < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
bitmaskIt - > second . platform = platform ;
2020-04-12 19:49:12 +00:00
assert ( ( m_enums . find ( bitmaskIt - > second . requirements ) = = m_enums . end ( ) ) | |
( m_enums . find ( bitmaskIt - > second . requirements ) - > second . isBitmask ) ) ;
2018-09-25 09:23:27 +00:00
}
2020-03-05 10:02:55 +00:00
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Define :
// no need to protect a "defined" type
break ;
case TypeCategory : : Enum :
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( name ) ;
check ( enumIt ! = m_enums . end ( ) , line , " failed to find required enum < " + name + " > " ) ;
check ( enumIt - > second . platform . empty ( ) , line , " platform already specified for enum < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
enumIt - > second . platform = platform ;
2018-09-25 09:23:27 +00:00
}
2020-03-05 10:02:55 +00:00
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Handle :
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
auto handleIt = m_handles . find ( name ) ;
check ( handleIt ! = m_handles . end ( ) , line , " failed to find required handle < " + name + " > " ) ;
check ( handleIt - > second . platform . empty ( ) , line , " platform already specified for handle < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
handleIt - > second . platform = platform ;
}
break ;
2020-04-12 19:49:12 +00:00
case TypeCategory : : Struct :
case TypeCategory : : Union : // unions are listed together with the structures!
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
auto structIt = m_structures . find ( name ) ;
check ( structIt ! = m_structures . end ( ) , line , " failed to find required struct < " + name + " > " ) ;
check ( structIt - > second . platform . empty ( ) , line , " platform already specified for structure < " + name + " > " ) ;
2020-03-05 10:02:55 +00:00
structIt - > second . platform = platform ;
}
break ;
2020-04-12 19:49:12 +00:00
default :
check ( false , line , " trying to protect < " + name + " > of unhandled type < " + toString ( typeIt - > second ) + " > " ) ;
break ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readExtensions ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { { " comment " , { } } } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " extension " , false } } ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
readExtension ( child ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readFeature ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes (
line , attributes , { { " api " , { " vulkan " } } , { " comment " , { } } , { " name " , { } } , { " number " , { } } } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " require " , false } } ) ;
2020-02-11 13:37:22 +00:00
std : : string name , number , modifiedNumber ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " number " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
number = attribute . second ;
2020-02-11 13:37:22 +00:00
modifiedNumber = number ;
2020-04-12 19:49:12 +00:00
std : : replace ( modifiedNumber . begin ( ) , modifiedNumber . end ( ) , ' . ' , ' _ ' ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) & & ! number . empty ( ) ) ;
check ( name = = " VK_VERSION_ " + modifiedNumber , line , " unexpected formatting of name < " + name + " > " ) ;
check ( m_features . insert ( std : : make_pair ( name , number ) ) . second , line , " already specified feature < " + name + " > " ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readFeatureRequire ( child ) ;
2019-08-27 07:02:49 +00:00
}
}
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readFeatureRequire ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { { " comment " , { } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { } , { " command " , " comment " , " enum " , " type " } ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2019-08-27 07:02:49 +00:00
{
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " command " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readRequireCommand ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " comment " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " enum " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readRequireEnum ( child , " " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " type " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readRequireType ( child ) ;
2020-02-11 13:37:22 +00:00
}
2018-09-25 09:23:27 +00:00
}
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readFuncpointer ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " funcpointer " } } } , { { " requires " , { } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " name " , true } } , { " type " } ) ;
2019-08-27 07:02:49 +00:00
2020-02-26 13:24:58 +00:00
std : : string requirements ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " requires " )
2020-02-11 13:37:22 +00:00
{
2020-02-26 13:24:58 +00:00
requirements = attribute . second ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
for ( auto const & child : children )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string value = child - > Value ( ) ;
int childLine = child - > GetLineNum ( ) ;
if ( value = = " name " )
2020-02-11 13:37:22 +00:00
{
std : : string name = child - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , childLine , " funcpointer with empty name " ) ;
check ( m_funcPointers . insert ( std : : make_pair ( name , FuncPointerData ( requirements , line ) ) ) . second ,
childLine ,
" funcpointer < " + name + " > already specified " ) ;
check ( m_types . insert ( std : : make_pair ( name , TypeCategory : : FuncPointer ) ) . second ,
childLine ,
" funcpointer < " + name + " > already specified as a type " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " type " )
2020-02-11 13:37:22 +00:00
{
std : : string type = child - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
check ( ! type . empty ( ) , childLine , " funcpointer argument with empty type " ) ;
check ( ( m_types . find ( type ) ! = m_types . end ( ) ) | | ( type = = requirements ) ,
childLine ,
" funcpointer argument of unknown type < " + type + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2019-07-23 07:28:14 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readHandle ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
auto aliasIt = attributes . find ( " alias " ) ;
if ( aliasIt ! = attributes . end ( ) )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " alias " , { } } , { " category " , { " handle " } } , { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
auto handlesIt = m_handles . find ( aliasIt - > second ) ;
check ( handlesIt ! = m_handles . end ( ) , line , " using unspecified alias < " + aliasIt - > second + " >. " ) ;
check ( handlesIt - > second . alias . empty ( ) ,
line ,
" handle < " + handlesIt - > first + " > already has an alias < " + handlesIt - > second . alias + " > " ) ;
handlesIt - > second . alias = attributes . find ( " name " ) - > second ;
check ( m_types . insert ( std : : make_pair ( handlesIt - > second . alias , TypeCategory : : Handle ) ) . second ,
line ,
" handle alias < " + handlesIt - > second . alias + " > already specified as a type " ) ;
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
else
{
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " handle " } } } , { { " parent " , { } } } ) ;
2019-07-23 07:28:14 +00:00
2020-02-11 13:37:22 +00:00
std : : string parent ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " parent " )
2020-02-11 13:37:22 +00:00
{
parent = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! parent . empty ( ) , line , " handle with empty parent " ) ;
2020-02-11 13:37:22 +00:00
}
}
NameData nameData ;
TypeData typeData ;
2020-04-12 19:49:12 +00:00
std : : tie ( nameData , typeData ) = readNameAndType ( element ) ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
check ( beginsWith ( nameData . name , " Vk " ) , line , " name < " + nameData . name + " > does not begin with <Vk> " ) ;
check ( nameData . arraySizes . empty ( ) , line , " name < " + nameData . name + " > with unsupported arraySizes " ) ;
check ( nameData . bitCount . empty ( ) ,
line ,
" name < " + nameData . name + " > with unsupported bitCount < " + nameData . bitCount + " > " ) ;
check ( ( typeData . type = = " VK_DEFINE_HANDLE " ) | | ( typeData . type = = " VK_DEFINE_NON_DISPATCHABLE_HANDLE " ) ,
line ,
" handle with invalid type < " + typeData . type + " > " ) ;
check ( typeData . prefix . empty ( ) , line , " unexpected type prefix < " + typeData . prefix + " > " ) ;
check ( typeData . postfix = = " ( " , line , " unexpected type postfix < " + typeData . postfix + " > " ) ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
check ( m_handles . insert ( std : : make_pair ( nameData . name , HandleData ( tokenize ( parent , " , " ) , line ) ) ) . second ,
line ,
" handle < " + nameData . name + " > already specified " ) ;
check ( m_types . insert ( std : : make_pair ( nameData . name , TypeCategory : : Handle ) ) . second ,
line ,
" handle < " + nameData . name + " > already specified as a type " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
std : : pair < VulkanHppGenerator : : NameData , VulkanHppGenerator : : TypeData >
VulkanHppGenerator : : readNameAndType ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
2020-04-27 15:15:53 +00:00
checkElements ( line , children , { { " name " , true } } , { { " type " } } ) ;
2020-02-11 13:37:22 +00:00
NameData nameData ;
TypeData typeData ;
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2020-02-11 13:37:22 +00:00
{
line = child - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( child ) , { } , { } ) ;
checkElements ( line , getChildElements ( child ) , { } ) ;
2020-02-11 13:37:22 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " name " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
nameData . name = child - > GetText ( ) ;
std : : tie ( nameData . arraySizes , nameData . bitCount ) = readModifiers ( child - > NextSibling ( ) ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " type " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
typeData . prefix = readTypePrefix ( child - > PreviousSibling ( ) ) ;
typeData . type = child - > GetText ( ) ;
typeData . postfix = readTypePostfix ( child - > NextSibling ( ) ) ;
2020-02-11 13:37:22 +00:00
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
return std : : make_pair ( nameData , typeData ) ;
2019-07-23 07:28:14 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readPlatform ( tinyxml2 : : XMLElement const * element )
2019-07-23 07:28:14 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " comment " , { } } , { " name " , { } } , { " protect " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-07-23 07:28:14 +00:00
2019-08-27 07:02:49 +00:00
std : : string name , protect ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , line , " attribute <name> is empty " ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " protect " )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
protect = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! protect . empty ( ) , line , " attribute <protect> is empty " ) ;
2019-07-23 07:28:14 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) & & ! protect . empty ( ) ) ;
check ( m_platforms . find ( name ) = = m_platforms . end ( ) , line , " platform name < " + name + " > already specified " ) ;
check ( std : : find_if ( m_platforms . begin ( ) ,
m_platforms . end ( ) ,
[ & protect ] ( std : : pair < std : : string , std : : string > const & p ) { return p . second = = protect ; } ) = =
m_platforms . end ( ) ,
line ,
" platform protect < " + protect + " > already specified " ) ;
2019-08-27 07:02:49 +00:00
m_platforms [ name ] = protect ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readPlatforms ( tinyxml2 : : XMLElement const * element )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { { " comment " , { } } } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " platform " , false } } ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readPlatform ( child ) ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRegistry ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line ,
children ,
{ { " commands " , true } ,
{ " comment " , false } ,
{ " enums " , false } ,
{ " extensions " , true } ,
{ " feature " , false } ,
{ " platforms " , true } ,
{ " tags " , true } ,
{ " types " , true } } ) ;
for ( auto child : children )
2020-02-11 13:37:22 +00:00
{
const std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " commands " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readCommands ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " comment " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
std : : string comment = readComment ( child ) ;
if ( comment . find ( " \n Copyright " ) = = 0 )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
setVulkanLicenseHeader ( child - > GetLineNum ( ) , comment ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
else if ( value = = " enums " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readEnums ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " extensions " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readExtensions ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " feature " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readFeature ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " platforms " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readPlatforms ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " tags " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readTags ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " types " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readTypes ( child ) ;
2020-02-11 13:37:22 +00:00
}
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequireCommand ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { } , { { " name " , { } } } ) ;
std : : string command = attributes . find ( " name " ) - > second ;
check ( m_commandToHandle . find ( command ) ! = m_commandToHandle . end ( ) ,
line ,
" feature requires unknown command < " + command + " > " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequireEnum ( tinyxml2 : : XMLElement const * element , std : : string const & tag )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
if ( attributes . find ( " alias " ) ! = attributes . end ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readRequireEnumAlias ( element , attributes , tag ) ;
2020-02-11 13:37:22 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
readRequireEnum ( element , attributes , tag ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequireEnum ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes ,
std : : string const & tag )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line ,
attributes ,
{ { " name " , { } } } ,
{ { " bitpos " , { } } ,
{ " comment " , { } } ,
{ " extends " , { } } ,
{ " dir " , { " - " } } ,
{ " extnumber " , { } } ,
{ " offset " , { } } ,
{ " value " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2018-09-25 09:23:27 +00:00
2020-02-11 13:37:22 +00:00
std : : string bitpos , name , extends , extnumber , offset , value ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " bitpos " )
2020-02-11 13:37:22 +00:00
{
bitpos = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " extends " )
2020-02-11 13:37:22 +00:00
{
extends = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " offset " )
2020-02-11 13:37:22 +00:00
{
offset = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " value " )
2020-02-11 13:37:22 +00:00
{
value = attribute . second ;
}
}
2020-04-12 19:49:12 +00:00
if ( ! extends . empty ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( extends ) ;
check ( enumIt ! = m_enums . end ( ) , line , " feature extends unknown enum < " + extends + " > " ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string prefix = getEnumPrefix ( element - > GetLineNum ( ) , enumIt - > first , enumIt - > second . isBitmask ) ;
std : : string postfix = getEnumPostfix ( enumIt - > first , m_tags , prefix ) ;
2019-08-27 07:02:49 +00:00
2020-02-11 13:37:22 +00:00
// add this enum name to the list of values
2020-04-12 19:49:12 +00:00
check ( bitpos . empty ( ) + offset . empty ( ) + value . empty ( ) = = 2 ,
line ,
" exactly one out of bitpos = < " + bitpos + " >, offset = < " + offset + " >, and value = < " + value +
" > are supposed to be empty " ) ;
enumIt - > second . addEnumValue (
element - > GetLineNum ( ) , name , enumIt - > second . isBitmask , ! bitpos . empty ( ) , prefix , postfix , tag ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_constants . find ( name ) ! = m_constants . end ( ) , line , " unknown required enum < " + name + " > " ) ;
2020-02-11 13:37:22 +00:00
}
}
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequireEnumAlias ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes ,
std : : string const & tag )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " alias " , { } } , { " extends " , { } } , { " name " , { } } } , { { " comment " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
std : : string alias , bitpos , name , extends , extnumber , offset , value ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2019-01-09 10:55:11 +00:00
{
2020-02-11 13:37:22 +00:00
alias = attribute . second ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " extends " )
2020-02-11 13:37:22 +00:00
{
extends = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
}
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( extends ) ;
check ( enumIt ! = m_enums . end ( ) , line , " feature extends unknown enum < " + extends + " > " ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
std : : string prefix = getEnumPrefix ( element - > GetLineNum ( ) , enumIt - > first , enumIt - > second . isBitmask ) ;
std : : string postfix = getEnumPostfix ( enumIt - > first , m_tags , prefix ) ;
2020-02-11 13:37:22 +00:00
// add this enum name to the list of aliases
2020-04-12 19:49:12 +00:00
std : : string valueName = createEnumValueName ( name , prefix , postfix , enumIt - > second . isBitmask , tag ) ;
if ( ! enumIt - > second . alias . empty ( ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
prefix = getEnumPrefix ( element - > GetLineNum ( ) , enumIt - > second . alias , enumIt - > second . isBitmask ) ;
postfix = getEnumPostfix ( enumIt - > second . alias , m_tags , prefix ) ;
if ( endsWith ( name , postfix ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
valueName = createEnumValueName ( name , prefix , postfix , enumIt - > second . isBitmask , tag ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
2020-04-30 09:30:17 +00:00
enumIt - > second . addEnumAlias ( line , name , alias , valueName ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequires ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2018-09-25 09:23:27 +00:00
{
2020-02-04 09:35:33 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " name " , { } } , { " requires " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
for ( auto attribute : attributes )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_types . insert ( std : : make_pair ( attribute . second , TypeCategory : : Requires ) ) . second ,
line ,
" type named < " + attribute . second + " > already specified " ) ;
2020-02-04 09:35:33 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
assert ( attribute . first = = " requires " ) ;
check ( m_includes . find ( attribute . second ) ! = m_includes . end ( ) ,
line ,
" type requires unknown include < " + attribute . second + " > " ) ;
2020-02-04 09:35:33 +00:00
}
}
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readRequireType ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-11 13:37:22 +00:00
}
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readStruct ( tinyxml2 : : XMLElement const * element ,
bool isUnion ,
std : : map < std : : string , std : : string > const & attributes )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
if ( attributes . find ( " alias " ) ! = attributes . end ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readStructAlias ( element , attributes ) ;
2019-07-23 07:28:14 +00:00
}
2019-08-27 07:02:49 +00:00
else
{
2020-04-12 19:49:12 +00:00
checkAttributes ( line ,
attributes ,
{ { " category " , { isUnion ? " union " : " struct " } } , { " name " , { } } } ,
2020-05-04 14:46:47 +00:00
{ { " allowduplicate " , { " true " } } ,
{ " comment " , { } } ,
{ " returnedonly " , { " true " } } ,
{ " structextends " , { } } } ) ;
2020-04-12 19:49:12 +00:00
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { } , { " member " , " comment " } ) ;
std : : string category , name ;
std : : vector < std : : string > structExtends ;
bool returnedOnly = false ;
for ( auto const & attribute : attributes )
{
if ( attribute . first = = " category " )
2020-03-05 10:02:55 +00:00
{
category = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " returnedonly " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
check (
attribute . second = = " true " , line , " unknown value for attribute returnedonly: < " + attribute . second + " > " ) ;
2020-02-11 13:37:22 +00:00
returnedOnly = true ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " structextends " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
structExtends = tokenize ( attribute . second , " , " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
check ( m_structures . find ( name ) = = m_structures . end ( ) , line , " struct < " + name + " > already specfied " ) ;
std : : map < std : : string , StructureData > : : iterator it =
m_structures . insert ( std : : make_pair ( name , StructureData ( structExtends , line ) ) ) . first ;
2020-02-11 13:37:22 +00:00
it - > second . returnedOnly = returnedOnly ;
2020-04-12 19:49:12 +00:00
it - > second . isUnion = isUnion ;
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2020-02-11 13:37:22 +00:00
{
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " comment " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " member " )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readStructMember ( child , it - > second . members ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
it - > second . subStruct = determineSubStruct ( * it ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
m_extendedStructs . insert ( structExtends . begin ( ) , structExtends . end ( ) ) ;
check (
m_types . insert ( std : : make_pair ( name , ( category = = " struct " ) ? TypeCategory : : Struct : TypeCategory : : Union ) )
. second ,
line ,
" struct < " + name + " > already specified as a type " ) ; // log type and alias in m_types
2019-07-23 07:28:14 +00:00
}
2019-08-27 07:02:49 +00:00
}
2019-07-23 07:28:14 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readStructAlias ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2019-08-27 07:02:49 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " alias " , { } } , { " category " , { " struct " } } , { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } , { } ) ;
2018-09-25 09:23:27 +00:00
2020-02-11 13:37:22 +00:00
std : : string alias , name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
alias = attribute . second ;
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
}
}
2020-04-12 19:49:12 +00:00
auto structIt = m_structures . find ( alias ) ;
check ( structIt ! = m_structures . end ( ) , line , " missing alias < " + alias + " >. " ) ;
check (
structIt - > second . aliases . insert ( name ) . second , line , " struct < " + alias + " > already uses alias < " + name + " > " ) ;
check ( m_structureAliases . insert ( std : : make_pair ( name , alias ) ) . second ,
line ,
" structure alias < " + name + " > already used " ) ;
check ( m_types . insert ( std : : make_pair ( name , TypeCategory : : Struct ) ) . second ,
line ,
" struct < " + name + " > already specified as a type " ) ;
}
void VulkanHppGenerator : : readStructMember ( tinyxml2 : : XMLElement const * element , std : : vector < MemberData > & members )
{
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line ,
attributes ,
{ } ,
{ { " altlen " , { } } ,
{ " externsync " , { " true " } } ,
{ " len " , { } } ,
{ " noautovalidity " , { " true " } } ,
{ " optional " , { " false " , " true " } } ,
{ " values " , { } } } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " name " , true } , { " type " , true } } , { " comment " , " enum " } ) ;
members . push_back ( MemberData ( line ) ) ;
2020-02-11 13:37:22 +00:00
MemberData & memberData = members . back ( ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2019-07-23 07:28:14 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " enum " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readStructMemberEnum ( child , memberData ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " name " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readStructMemberName ( child , memberData , members ) ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( value = = " type " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readStructMemberType ( child , memberData ) ;
2019-08-27 07:02:49 +00:00
}
}
2020-04-29 07:04:21 +00:00
auto valuesIt = attributes . find ( " values " ) ;
if ( valuesIt ! = attributes . end ( ) )
{
check ( memberData . name = = " sType " ,
line ,
" Structure member named differently than <sType> with attribute <values> encountered: " ) ;
check ( m_sTypeValues . insert ( valuesIt - > second ) . second ,
line ,
" < " + valuesIt - > second + " > already encountered as values for the sType member of a struct " ) ;
memberData . values = valuesIt - > second ;
}
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readStructMemberEnum ( tinyxml2 : : XMLElement const * element , MemberData & memberData )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } , { } ) ;
2019-07-23 07:28:14 +00:00
2020-02-11 13:37:22 +00:00
std : : string enumString = element - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
check ( element - > PreviousSibling ( ) & & ( strcmp ( element - > PreviousSibling ( ) - > Value ( ) , " [ " ) = = 0 ) & &
element - > NextSibling ( ) & & ( strcmp ( element - > NextSibling ( ) - > Value ( ) , " ] " ) = = 0 ) ,
line ,
std : : string ( " structure member array specifiation is ill-formatted: < " ) + enumString + " > " ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
memberData . arraySizes . push_back ( enumString ) ;
check ( memberData . usedConstant . empty ( ) , line , " struct already holds a constant < " + memberData . usedConstant + " > " ) ;
2020-02-11 13:37:22 +00:00
memberData . usedConstant = enumString ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readStructMemberName ( tinyxml2 : : XMLElement const * element ,
MemberData & memberData ,
std : : vector < MemberData > const & members )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } , { } ) ;
2020-02-11 13:37:22 +00:00
std : : string name = element - > GetText ( ) ;
2020-04-12 19:49:12 +00:00
check ( std : : find_if ( members . begin ( ) , members . end ( ) , [ & name ] ( MemberData const & md ) { return md . name = = name ; } ) = =
members . end ( ) ,
line ,
" structure member name < " + name + " > already used " ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
memberData . name = name ;
std : : tie ( memberData . arraySizes , memberData . bitCount ) = readModifiers ( element - > NextSibling ( ) ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readStructMemberType ( tinyxml2 : : XMLElement const * element , MemberData & memberData )
2019-01-09 10:55:11 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } , { } ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
memberData . type . prefix = readTypePrefix ( element - > PreviousSibling ( ) ) ;
memberData . type . type = element - > GetText ( ) ;
memberData . type . postfix = readTypePostfix ( element - > NextSibling ( ) ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readTag ( tinyxml2 : : XMLElement const * element )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
checkAttributes ( line , attributes , { { " author " , { } } , { " contact " , { } } , { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2019-01-09 10:55:11 +00:00
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " name " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_tags . find ( attribute . second ) = = m_tags . end ( ) ,
line ,
" tag named < " + attribute . second + " > has already been specified " ) ;
m_tags . insert ( attribute . second ) ;
2019-08-27 07:02:49 +00:00
}
else
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ( attribute . first = = " author " ) | | ( attribute . first = = " contact " ) ,
line ,
" unknown attribute < " + attribute . first + " > " ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readTags ( tinyxml2 : : XMLElement const * element )
2020-02-11 13:37:22 +00:00
{
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { { " comment " , { } } } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " tag " , false } } ) ;
2020-02-11 13:37:22 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
readTag ( child ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readType ( tinyxml2 : : XMLElement const * element )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
int line = element - > GetLineNum ( ) ;
std : : map < std : : string , std : : string > attributes = getAttributes ( element ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
auto categoryIt = attributes . find ( " category " ) ;
if ( categoryIt ! = attributes . end ( ) )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
if ( categoryIt - > second = = " basetype " )
2019-08-14 09:57:10 +00:00
{
2020-04-12 19:49:12 +00:00
readBaseType ( element , attributes ) ;
2019-05-30 07:18:32 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " bitmask " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readBitmask ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " define " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readDefine ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " enum " )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
readTypeEnum ( element , attributes ) ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " funcpointer " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readFuncpointer ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " handle " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readHandle ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " include " )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
readTypeInclude ( element , attributes ) ;
2020-02-04 09:35:33 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( categoryIt - > second = = " struct " )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readStruct ( element , false , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2020-02-04 09:35:33 +00:00
else
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
check (
categoryIt - > second = = " union " , element - > GetLineNum ( ) , " unknown type category < " + categoryIt - > second + " > " ) ;
readStruct ( element , true , attributes ) ;
2019-08-27 07:02:49 +00:00
}
2019-01-09 10:55:11 +00:00
}
2019-08-27 07:02:49 +00:00
else
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
auto requiresIt = attributes . find ( " requires " ) ;
if ( requiresIt ! = attributes . end ( ) )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
readRequires ( element , attributes ) ;
2019-08-27 07:02:49 +00:00
}
else
2019-08-15 07:50:26 +00:00
{
2020-04-12 19:49:12 +00:00
check ( ( attributes . size ( ) = = 1 ) & & ( attributes . begin ( ) - > first = = " name " ) & &
( attributes . begin ( ) - > second = = " int " ) ,
line ,
" unknown type " ) ;
check ( m_types . insert ( std : : make_pair ( attributes . begin ( ) - > second , TypeCategory : : Unknown ) ) . second ,
line ,
" type < " + attributes . begin ( ) - > second + " > already specified " ) ;
2019-08-15 07:50:26 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readTypeEnum ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2020-01-13 14:00:59 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " enum " } } , { " name " , { } } } , { { " alias " , { } } } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-01-13 14:00:59 +00:00
2020-02-11 13:37:22 +00:00
std : : string alias , name ;
2020-04-12 19:49:12 +00:00
for ( auto const & attribute : attributes )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
if ( attribute . first = = " alias " )
2020-02-11 13:37:22 +00:00
{
alias = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! alias . empty ( ) , line , " enum with empty alias " ) ;
2020-02-11 13:37:22 +00:00
}
2020-04-12 19:49:12 +00:00
else if ( attribute . first = = " name " )
2020-02-11 13:37:22 +00:00
{
name = attribute . second ;
2020-04-12 19:49:12 +00:00
check ( ! name . empty ( ) , line , " enum with empty name " ) ;
check ( m_enums . find ( name ) = = m_enums . end ( ) , line , " enum < " + name + " > already specified " ) ;
2020-02-11 13:37:22 +00:00
}
}
2020-04-12 19:49:12 +00:00
assert ( ! name . empty ( ) ) ;
2020-01-13 14:00:59 +00:00
2020-04-12 19:49:12 +00:00
if ( alias . empty ( ) )
2020-01-13 14:00:59 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_enums . insert ( std : : make_pair ( name , EnumData ( ) ) ) . second , line , " enum < " + name + " > already specified " ) ;
2020-01-13 14:00:59 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
auto enumIt = m_enums . find ( alias ) ;
check ( enumIt ! = m_enums . end ( ) , line , " enum with unknown alias < " + alias + " > " ) ;
check ( enumIt - > second . alias . empty ( ) ,
line ,
" enum < " + enumIt - > first + " > already has an alias < " + enumIt - > second . alias + " > " ) ;
2020-02-11 13:37:22 +00:00
enumIt - > second . alias = name ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
check ( m_types . insert ( std : : make_pair ( name , TypeCategory : : Enum ) ) . second ,
line ,
" enum < " + name + " > already specified as a type " ) ;
2020-01-13 14:00:59 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readTypeInclude ( tinyxml2 : : XMLElement const * element ,
std : : map < std : : string , std : : string > const & attributes )
2020-02-04 09:35:33 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , attributes , { { " category " , { " include " } } , { " name " , { } } } , { } ) ;
checkElements ( line , getChildElements ( element ) , { } ) ;
2020-02-04 09:35:33 +00:00
2020-04-12 19:49:12 +00:00
std : : string name = attributes . find ( " name " ) - > second ;
check ( m_includes . insert ( name ) . second , element - > GetLineNum ( ) , " include named < " + name + " > already specified " ) ;
2020-02-04 09:35:33 +00:00
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : readTypes ( tinyxml2 : : XMLElement const * element )
2018-09-25 09:23:27 +00:00
{
2020-02-11 13:37:22 +00:00
int line = element - > GetLineNum ( ) ;
2020-04-12 19:49:12 +00:00
checkAttributes ( line , getAttributes ( element ) , { { " comment " , { } } } , { } ) ;
std : : vector < tinyxml2 : : XMLElement const * > children = getChildElements ( element ) ;
checkElements ( line , children , { { " comment " , false } , { " type " , false } } ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
for ( auto child : children )
2019-01-09 10:55:11 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string value = child - > Value ( ) ;
2020-04-12 19:49:12 +00:00
if ( value = = " comment " )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
readComment ( child ) ;
2019-08-27 07:02:49 +00:00
}
else
{
2020-04-12 19:49:12 +00:00
assert ( value = = " type " ) ;
readType ( child ) ;
2019-08-27 07:02:49 +00:00
}
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : registerDeleter ( std : : string const & name ,
std : : pair < std : : string , CommandData > const & commandData )
2019-01-09 10:55:11 +00:00
{
2020-04-12 19:49:12 +00:00
if ( ( commandData . first . substr ( 2 , 7 ) = = " Destroy " ) | | ( commandData . first . substr ( 2 , 4 ) = = " Free " ) )
2018-09-25 09:23:27 +00:00
{
2019-08-27 07:02:49 +00:00
std : : string key ;
2020-04-12 19:49:12 +00:00
size_t valueIndex ;
switch ( commandData . second . params . size ( ) )
{
case 2 :
case 3 :
assert ( commandData . second . params . back ( ) . type . type = = " VkAllocationCallbacks " ) ;
key = ( commandData . second . params . size ( ) = = 2 ) ? " " : commandData . second . params [ 0 ] . type . type ;
valueIndex = commandData . second . params . size ( ) - 2 ;
break ;
case 4 :
key = commandData . second . params [ 0 ] . type . type ;
valueIndex = 3 ;
assert ( m_handles . find ( commandData . second . params [ valueIndex ] . type . type ) ! = m_handles . end ( ) ) ;
m_handles . find ( commandData . second . params [ valueIndex ] . type . type ) - > second . deletePool =
commandData . second . params [ 1 ] . type . type ;
break ;
default : assert ( false ) ; valueIndex = 0 ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
auto keyHandleIt = m_handles . find ( key ) ;
assert ( ( keyHandleIt ! = m_handles . end ( ) ) & &
( keyHandleIt - > second . childrenHandles . find ( commandData . second . params [ valueIndex ] . type . type ) = =
keyHandleIt - > second . childrenHandles . end ( ) ) ) ;
keyHandleIt - > second . childrenHandles . insert ( commandData . second . params [ valueIndex ] . type . type ) ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
auto handleIt = m_handles . find ( commandData . second . params [ valueIndex ] . type . type ) ;
assert ( handleIt ! = m_handles . end ( ) ) ;
2019-08-27 07:02:49 +00:00
handleIt - > second . deleteCommand = name ;
2018-09-25 09:23:27 +00:00
}
}
2020-04-12 19:49:12 +00:00
void VulkanHppGenerator : : setVulkanLicenseHeader ( int line , std : : string const & comment )
2019-08-27 07:02:49 +00:00
{
2020-04-12 19:49:12 +00:00
check ( m_vulkanLicenseHeader . empty ( ) , line , " second encounter of a Copyright comment " ) ;
2020-02-11 13:37:22 +00:00
m_vulkanLicenseHeader = comment ;
// replace any '\n' with "\n// "
2020-04-12 19:49:12 +00:00
for ( size_t pos = m_vulkanLicenseHeader . find ( ' \n ' ) ; pos ! = std : : string : : npos ;
pos = m_vulkanLicenseHeader . find ( ' \n ' , pos + 1 ) )
2020-02-11 13:37:22 +00:00
{
2020-04-12 19:49:12 +00:00
m_vulkanLicenseHeader . replace ( pos , 1 , " \n // " ) ;
2020-02-11 13:37:22 +00:00
}
// and add a little message on our own
m_vulkanLicenseHeader + = " \n \n // This header is generated from the Khronos Vulkan XML API Registry. " ;
2020-04-12 19:49:12 +00:00
m_vulkanLicenseHeader = trim ( m_vulkanLicenseHeader ) + " \n " ;
2019-08-27 07:02:49 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string VulkanHppGenerator : : toString ( TypeCategory category )
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
switch ( category )
2020-03-05 10:02:55 +00:00
{
2020-04-12 19:49:12 +00:00
case TypeCategory : : Bitmask : return " bitmask " ;
case TypeCategory : : BaseType : return " basetype " ;
case TypeCategory : : Define : return " define " ;
case TypeCategory : : Enum : return " enum " ;
case TypeCategory : : FuncPointer : return " funcpointer " ;
case TypeCategory : : Handle : return " handle " ;
case TypeCategory : : Requires : return " requires " ;
case TypeCategory : : Struct : return " struct " ;
case TypeCategory : : Union : return " union " ;
case TypeCategory : : Unknown : return " unkown " ;
default : assert ( false ) ; return " " ;
2020-03-05 10:02:55 +00:00
}
}
2019-01-09 10:55:11 +00:00
std : : string VulkanHppGenerator : : TypeData : : compose ( ) const
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
return prefix + ( prefix . empty ( ) ? " " : " " ) + ( ( type . substr ( 0 , 2 ) = = " Vk " ) ? " VULKAN_HPP_NAMESPACE:: " : " " ) +
stripPrefix ( type , " Vk " ) + postfix ;
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
std : : string to_string ( tinyxml2 : : XMLError error )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
switch ( error )
2020-02-04 09:35:33 +00:00
{
2020-04-12 19:49:12 +00:00
case tinyxml2 : : XML_SUCCESS : return " XML_SUCCESS " ;
case tinyxml2 : : XML_NO_ATTRIBUTE : return " XML_NO_ATTRIBUTE " ;
case tinyxml2 : : XML_WRONG_ATTRIBUTE_TYPE : return " XML_WRONG_ATTRIBUTE_TYPE " ;
case tinyxml2 : : XML_ERROR_FILE_NOT_FOUND : return " XML_ERROR_FILE_NOT_FOUND " ;
case tinyxml2 : : XML_ERROR_FILE_COULD_NOT_BE_OPENED : return " XML_ERROR_FILE_COULD_NOT_BE_OPENED " ;
case tinyxml2 : : XML_ERROR_FILE_READ_ERROR : return " XML_ERROR_FILE_READ_ERROR " ;
case tinyxml2 : : XML_ERROR_PARSING_ELEMENT : return " XML_ERROR_PARSING_ELEMENT " ;
case tinyxml2 : : XML_ERROR_PARSING_ATTRIBUTE : return " XML_ERROR_PARSING_ATTRIBUTE " ;
case tinyxml2 : : XML_ERROR_PARSING_TEXT : return " XML_ERROR_PARSING_TEXT " ;
case tinyxml2 : : XML_ERROR_PARSING_CDATA : return " XML_ERROR_PARSING_CDATA " ;
case tinyxml2 : : XML_ERROR_PARSING_COMMENT : return " XML_ERROR_PARSING_COMMENT " ;
case tinyxml2 : : XML_ERROR_PARSING_DECLARATION : return " XML_ERROR_PARSING_DECLARATION " ;
case tinyxml2 : : XML_ERROR_PARSING_UNKNOWN : return " XML_ERROR_PARSING_UNKNOWN " ;
case tinyxml2 : : XML_ERROR_EMPTY_DOCUMENT : return " XML_ERROR_EMPTY_DOCUMENT " ;
case tinyxml2 : : XML_ERROR_MISMATCHED_ELEMENT : return " XML_ERROR_MISMATCHED_ELEMENT " ;
case tinyxml2 : : XML_ERROR_PARSING : return " XML_ERROR_PARSING " ;
case tinyxml2 : : XML_CAN_NOT_CONVERT_TEXT : return " XML_CAN_NOT_CONVERT_TEXT " ;
case tinyxml2 : : XML_NO_TEXT_NODE : return " XML_NO_TEXT_NODE " ;
default : return " unknown error code < " + std : : to_string ( error ) + " > " ;
2020-02-04 09:35:33 +00:00
}
}
2020-04-12 19:49:12 +00:00
int main ( int argc , char * * argv )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static const std : : string classArrayProxy = R " (
# if !defined(VULKAN_HPP_DISABLE_ENHANCED_MODE)
template < typename T >
class ArrayProxy
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2020-04-09 15:01:24 +00:00
VULKAN_HPP_CONSTEXPR ArrayProxy ( ) VULKAN_HPP_NOEXCEPT
: m_count ( 0 )
, m_ptr ( nullptr )
{ }
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR ArrayProxy ( std : : nullptr_t ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_count ( 0 )
, m_ptr ( nullptr )
{ }
2018-09-25 09:23:27 +00:00
2020-04-09 15:01:24 +00:00
ArrayProxy ( T & value ) VULKAN_HPP_NOEXCEPT
: m_count ( 1 )
, m_ptr ( & value )
{ }
template < typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( typename std : : remove_const < T > : : type & value ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_count ( 1 )
2020-04-09 15:01:24 +00:00
, m_ptr ( & value )
2019-01-09 10:55:11 +00:00
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
ArrayProxy ( uint32_t count , T * ptr ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_count ( count )
, m_ptr ( ptr )
{ }
2018-09-25 09:23:27 +00:00
2020-04-09 15:01:24 +00:00
template < typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( uint32_t count , typename std : : remove_const < T > : : type * ptr ) VULKAN_HPP_NOEXCEPT
: m_count ( count )
, m_ptr ( ptr )
{ }
ArrayProxy ( std : : initializer_list < T > const & list ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( list . size ( ) ) )
, m_ptr ( list . begin ( ) )
{ }
template < typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : initializer_list < typename std : : remove_const < T > : : type > const & list ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( list . size ( ) ) )
, m_ptr ( list . begin ( ) )
2019-01-09 10:55:11 +00:00
{ }
2018-09-25 09:23:27 +00:00
2020-04-09 15:01:24 +00:00
ArrayProxy ( std : : initializer_list < T > & list ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( list . size ( ) ) )
, m_ptr ( list . begin ( ) )
2019-01-09 10:55:11 +00:00
{ }
2020-04-09 15:01:24 +00:00
template < typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : initializer_list < typename std : : remove_const < T > : : type > & list ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( list . size ( ) ) )
, m_ptr ( list . begin ( ) )
2019-01-09 10:55:11 +00:00
{ }
2020-05-05 09:34:02 +00:00
template < size_t N >
ArrayProxy ( std : : array < T , N > const & data ) VULKAN_HPP_NOEXCEPT
: m_count ( N )
, m_ptr ( data . data ( ) )
2019-01-09 10:55:11 +00:00
{ }
2020-05-05 09:34:02 +00:00
template < size_t N , typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : array < typename std : : remove_const < T > : : type , N > const & data ) VULKAN_HPP_NOEXCEPT
: m_count ( N )
, m_ptr ( data . data ( ) )
{ }
template < size_t N >
ArrayProxy ( std : : array < T , N > & data ) VULKAN_HPP_NOEXCEPT
: m_count ( N )
, m_ptr ( data . data ( ) )
{ }
template < size_t N , typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : array < typename std : : remove_const < T > : : type , N > & data ) VULKAN_HPP_NOEXCEPT
: m_count ( N )
, m_ptr ( data . data ( ) )
{ }
template < class Allocator = std : : allocator < typename std : : remove_const < T > : : type > >
ArrayProxy ( std : : vector < T , Allocator > const & data ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( data . size ( ) ) )
, m_ptr ( data . data ( ) )
{ }
template < class Allocator = std : : allocator < typename std : : remove_const < T > : : type > , typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : vector < typename std : : remove_const < T > : : type , Allocator > const & data ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( data . size ( ) ) )
, m_ptr ( data . data ( ) )
{ }
template < class Allocator = std : : allocator < typename std : : remove_const < T > : : type > >
ArrayProxy ( std : : vector < T , Allocator > & data ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( data . size ( ) ) )
, m_ptr ( data . data ( ) )
{ }
template < class Allocator = std : : allocator < typename std : : remove_const < T > : : type > , typename B = T , typename std : : enable_if < std : : is_const < B > : : value , int > : : type = 0 >
ArrayProxy ( std : : vector < typename std : : remove_const < T > : : type , Allocator > & data ) VULKAN_HPP_NOEXCEPT
: m_count ( static_cast < uint32_t > ( data . size ( ) ) )
, m_ptr ( data . data ( ) )
2019-01-09 10:55:11 +00:00
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
const T * begin ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_ptr ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
const T * end ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_ptr + m_count ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
const T & front ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
VULKAN_HPP_ASSERT ( m_count & & m_ptr ) ;
return * m_ptr ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
const T & back ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
VULKAN_HPP_ASSERT ( m_count & & m_ptr ) ;
return * ( m_ptr + m_count - 1 ) ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
bool empty ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return ( m_count = = 0 ) ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
uint32_t size ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return m_count ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
T * data ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return m_ptr ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
private :
uint32_t m_count ;
T * m_ptr ;
} ;
# endif
) " ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
static const std : : string classArrayWrapper = R " (
2020-03-23 13:59:37 +00:00
template < typename T , size_t N >
class ArrayWrapper1D : public std : : array < T , N >
{
public :
VULKAN_HPP_CONSTEXPR ArrayWrapper1D ( ) VULKAN_HPP_NOEXCEPT
: std : : array < T , N > ( )
{ }
VULKAN_HPP_CONSTEXPR ArrayWrapper1D ( std : : array < T , N > const & data ) VULKAN_HPP_NOEXCEPT
: std : : array < T , N > ( data )
{ }
# if defined(_WIN32) && !defined(_WIN64)
VULKAN_HPP_CONSTEXPR T const & operator [ ] ( int index ) const VULKAN_HPP_NOEXCEPT
{
return std : : array < T , N > : : operator [ ] ( index ) ;
}
VULKAN_HPP_CONSTEXPR T & operator [ ] ( int index ) VULKAN_HPP_NOEXCEPT
{
return std : : array < T , N > : : operator [ ] ( index ) ;
}
# endif
operator T const * ( ) const VULKAN_HPP_NOEXCEPT
{
return this - > data ( ) ;
}
operator T * ( ) VULKAN_HPP_NOEXCEPT
{
return this - > data ( ) ;
}
} ;
// specialization of relational operators between std::string and arrays of chars
template < size_t N >
bool operator < ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs < rhs . data ( ) ;
}
template < size_t N >
bool operator < = ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs < = rhs . data ( ) ;
}
template < size_t N >
bool operator > ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs > rhs . data ( ) ;
}
template < size_t N >
bool operator > = ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs > = rhs . data ( ) ;
}
template < size_t N >
bool operator = = ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs = = rhs . data ( ) ;
}
template < size_t N >
bool operator ! = ( std : : string const & lhs , ArrayWrapper1D < char , N > const & rhs ) VULKAN_HPP_NOEXCEPT
{
return lhs ! = rhs . data ( ) ;
}
template < typename T , size_t N , size_t M >
class ArrayWrapper2D : public std : : array < ArrayWrapper1D < T , M > , N >
{
public :
VULKAN_HPP_CONSTEXPR ArrayWrapper2D ( ) VULKAN_HPP_NOEXCEPT
: std : : array < ArrayWrapper1D < T , M > , N > ( )
{ }
VULKAN_HPP_CONSTEXPR ArrayWrapper2D ( std : : array < std : : array < T , M > , N > const & data ) VULKAN_HPP_NOEXCEPT
: std : : array < ArrayWrapper1D < T , M > , N > ( * reinterpret_cast < std : : array < ArrayWrapper1D < T , M > , N > const * > ( & data ) )
{ }
} ;
) " ;
2019-01-09 10:55:11 +00:00
static const std : : string classFlags = R " (
template < typename FlagBitsType > struct FlagTraits
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
enum { allFlags = 0 } ;
} ;
2018-09-25 09:23:27 +00:00
2020-02-20 11:04:27 +00:00
template < typename BitType >
2019-01-09 10:55:11 +00:00
class Flags
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2020-02-20 11:04:27 +00:00
using MaskType = typename std : : underlying_type < BitType > : : type ;
2020-01-09 08:44:41 +00:00
// constructors
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR Flags ( ) VULKAN_HPP_NOEXCEPT
2020-01-21 11:01:35 +00:00
: m_mask ( 0 )
2019-09-23 13:57:48 +00:00
{ }
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR Flags ( BitType bit ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_mask ( static_cast < MaskType > ( bit ) )
2019-09-23 13:57:48 +00:00
{ }
2018-09-25 09:23:27 +00:00
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR Flags ( Flags < BitType > const & rhs ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_mask ( rhs . m_mask )
2019-09-23 13:57:48 +00:00
{ }
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
VULKAN_HPP_CONSTEXPR explicit Flags ( MaskType flags ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_mask ( flags )
2019-09-23 13:57:48 +00:00
{ }
2019-01-09 10:55:11 +00:00
2020-01-09 08:44:41 +00:00
// relational operators
2020-02-26 13:24:58 +00:00
# if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
auto operator < = > ( Flags < BitType > const & ) const = default ;
# else
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator < ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return m_mask < rhs . m_mask ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator < = ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return m_mask < = rhs . m_mask ;
2018-09-25 09:23:27 +00:00
}
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator > ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return m_mask > rhs . m_mask ;
2018-09-25 09:23:27 +00:00
}
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator > = ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return m_mask > = rhs . m_mask ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator = = ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-01-09 08:44:41 +00:00
return m_mask = = rhs . m_mask ;
}
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR bool operator ! = ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
return m_mask ! = rhs . m_mask ;
2019-01-09 10:55:11 +00:00
}
2020-02-26 13:24:58 +00:00
# endif
2018-09-25 09:23:27 +00:00
2020-01-09 08:44:41 +00:00
// logical operator
VULKAN_HPP_CONSTEXPR bool operator ! ( ) const VULKAN_HPP_NOEXCEPT
{
return ! m_mask ;
}
// bitwise operators
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR Flags < BitType > operator & ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-02-20 11:04:27 +00:00
return Flags < BitType > ( m_mask & rhs . m_mask ) ;
2018-09-25 09:23:27 +00:00
}
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR Flags < BitType > operator | ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-02-20 11:04:27 +00:00
return Flags < BitType > ( m_mask | rhs . m_mask ) ;
2019-01-09 10:55:11 +00:00
}
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR Flags < BitType > operator ^ ( Flags < BitType > const & rhs ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-02-20 11:04:27 +00:00
return Flags < BitType > ( m_mask ^ rhs . m_mask ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2020-02-20 11:04:27 +00:00
VULKAN_HPP_CONSTEXPR Flags < BitType > operator ~ ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-02-20 11:04:27 +00:00
return Flags < BitType > ( m_mask ^ FlagTraits < BitType > : : allFlags ) ;
2018-09-25 09:23:27 +00:00
}
2020-01-09 08:44:41 +00:00
// assignment operators
2020-04-20 08:27:26 +00:00
VULKAN_HPP_CONSTEXPR_14 Flags < BitType > & operator = ( Flags < BitType > const & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
m_mask = rhs . m_mask ;
return * this ;
2018-09-25 09:23:27 +00:00
}
2020-04-20 08:27:26 +00:00
VULKAN_HPP_CONSTEXPR_14 Flags < BitType > & operator | = ( Flags < BitType > const & rhs ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-01-09 08:44:41 +00:00
m_mask | = rhs . m_mask ;
return * this ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2020-04-20 08:27:26 +00:00
VULKAN_HPP_CONSTEXPR_14 Flags < BitType > & operator & = ( Flags < BitType > const & rhs ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
m_mask & = rhs . m_mask ;
return * this ;
}
2020-04-20 08:27:26 +00:00
VULKAN_HPP_CONSTEXPR_14 Flags < BitType > & operator ^ = ( Flags < BitType > const & rhs ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
m_mask ^ = rhs . m_mask ;
return * this ;
}
// cast operators
2019-10-23 08:52:29 +00:00
explicit VULKAN_HPP_CONSTEXPR operator bool ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return ! ! m_mask ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
explicit VULKAN_HPP_CONSTEXPR operator MaskType ( ) const VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return m_mask ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
private :
MaskType m_mask ;
} ;
2020-02-26 13:24:58 +00:00
# if !defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
// relational operators only needed for pre C++20
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator < ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return flags > bit ;
2018-09-25 09:23:27 +00:00
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator < = ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return flags > = bit ;
2018-09-25 09:23:27 +00:00
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator > ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2020-01-09 08:44:41 +00:00
return flags < bit ;
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator > = ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
return flags < = bit ;
2018-09-25 09:23:27 +00:00
}
2019-10-10 11:29:59 +00:00
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator = = ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2019-10-10 11:29:59 +00:00
{
return flags = = bit ;
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR bool operator ! = ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2019-10-10 11:29:59 +00:00
{
return flags ! = bit ;
}
2020-02-26 13:24:58 +00:00
# endif
2020-01-09 08:44:41 +00:00
// bitwise operators
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR Flags < BitType > operator & ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
return flags & bit ;
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR Flags < BitType > operator | ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
return flags | bit ;
}
2020-02-20 11:04:27 +00:00
template < typename BitType >
VULKAN_HPP_CONSTEXPR Flags < BitType > operator ^ ( BitType bit , Flags < BitType > const & flags ) VULKAN_HPP_NOEXCEPT
2020-01-09 08:44:41 +00:00
{
return flags ^ bit ;
}
2019-01-09 10:55:11 +00:00
) " ;
static const std : : string classObjectDestroy = R " (
struct AllocationCallbacks ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename OwnerType , typename Dispatch >
class ObjectDestroy
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2019-11-28 15:01:22 +00:00
ObjectDestroy ( )
: m_owner ( )
, m_allocationCallbacks ( nullptr )
, m_dispatch ( nullptr )
{ }
2020-01-16 07:50:50 +00:00
ObjectDestroy ( OwnerType owner , Optional < const AllocationCallbacks > allocationCallbacks = nullptr , Dispatch const & dispatch = VULKAN_HPP_DEFAULT_DISPATCHER ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_owner ( owner )
, m_allocationCallbacks ( allocationCallbacks )
, m_dispatch ( & dispatch )
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
OwnerType getOwner ( ) const VULKAN_HPP_NOEXCEPT { return m_owner ; }
Optional < const AllocationCallbacks > getAllocator ( ) const VULKAN_HPP_NOEXCEPT { return m_allocationCallbacks ; }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
protected :
template < typename T >
2019-10-23 08:52:29 +00:00
void destroy ( T t ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( m_owner & & m_dispatch ) ;
2019-01-09 10:55:11 +00:00
m_owner . destroy ( t , m_allocationCallbacks , * m_dispatch ) ;
}
private :
OwnerType m_owner ;
Optional < const AllocationCallbacks > m_allocationCallbacks ;
Dispatch const * m_dispatch ;
} ;
class NoParent ;
template < typename Dispatch >
class ObjectDestroy < NoParent , Dispatch >
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2019-11-28 15:01:22 +00:00
ObjectDestroy ( )
: m_allocationCallbacks ( nullptr )
, m_dispatch ( nullptr )
{ }
2019-12-04 07:34:58 +00:00
ObjectDestroy ( Optional < const AllocationCallbacks > allocationCallbacks , Dispatch const & dispatch = VULKAN_HPP_DEFAULT_DISPATCHER ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_allocationCallbacks ( allocationCallbacks )
, m_dispatch ( & dispatch )
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
Optional < const AllocationCallbacks > getAllocator ( ) const VULKAN_HPP_NOEXCEPT { return m_allocationCallbacks ; }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
protected :
template < typename T >
2019-10-23 08:52:29 +00:00
void destroy ( T t ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( m_dispatch ) ;
2019-01-09 10:55:11 +00:00
t . destroy ( m_allocationCallbacks , * m_dispatch ) ;
}
private :
Optional < const AllocationCallbacks > m_allocationCallbacks ;
Dispatch const * m_dispatch ;
} ;
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string classObjectFree = R " (
template < typename OwnerType , typename Dispatch >
class ObjectFree
{
public :
2019-11-28 15:01:22 +00:00
ObjectFree ( )
: m_owner ( )
, m_allocationCallbacks ( nullptr )
, m_dispatch ( nullptr )
{ }
ObjectFree ( OwnerType owner , Optional < const AllocationCallbacks > allocationCallbacks , Dispatch const & dispatch ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_owner ( owner )
, m_allocationCallbacks ( allocationCallbacks )
, m_dispatch ( & dispatch )
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
OwnerType getOwner ( ) const VULKAN_HPP_NOEXCEPT { return m_owner ; }
Optional < const AllocationCallbacks > getAllocator ( ) const VULKAN_HPP_NOEXCEPT { return m_allocationCallbacks ; }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
protected :
template < typename T >
2019-10-23 08:52:29 +00:00
void destroy ( T t ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( m_owner & & m_dispatch ) ;
2019-01-09 10:55:11 +00:00
m_owner . free ( t , m_allocationCallbacks , * m_dispatch ) ;
}
2018-10-26 07:07:25 +00:00
2019-01-09 10:55:11 +00:00
private :
OwnerType m_owner ;
Optional < const AllocationCallbacks > m_allocationCallbacks ;
Dispatch const * m_dispatch ;
} ;
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string classOptional = R " (
template < typename RefType >
class Optional
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2019-10-23 08:52:29 +00:00
Optional ( RefType & reference ) VULKAN_HPP_NOEXCEPT { m_ptr = & reference ; }
Optional ( RefType * ptr ) VULKAN_HPP_NOEXCEPT { m_ptr = ptr ; }
Optional ( std : : nullptr_t ) VULKAN_HPP_NOEXCEPT { m_ptr = nullptr ; }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
operator RefType * ( ) const VULKAN_HPP_NOEXCEPT { return m_ptr ; }
RefType const * operator - > ( ) const VULKAN_HPP_NOEXCEPT { return m_ptr ; }
explicit operator bool ( ) const VULKAN_HPP_NOEXCEPT { return ! ! m_ptr ; }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
private :
RefType * m_ptr ;
} ;
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string classPoolFree = R " (
template < typename OwnerType , typename PoolType , typename Dispatch >
class PoolFree
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2019-10-23 08:52:29 +00:00
PoolFree ( OwnerType owner = OwnerType ( ) , PoolType pool = PoolType ( ) , Dispatch const & dispatch = VULKAN_HPP_DEFAULT_DISPATCHER ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: m_owner ( owner )
, m_pool ( pool )
, m_dispatch ( & dispatch )
{ }
2018-10-26 07:07:25 +00:00
2019-10-23 08:52:29 +00:00
OwnerType getOwner ( ) const VULKAN_HPP_NOEXCEPT { return m_owner ; }
PoolType getPool ( ) const VULKAN_HPP_NOEXCEPT { return m_pool ; }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
protected :
template < typename T >
2019-10-23 08:52:29 +00:00
void destroy ( T t ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
m_owner . free ( m_pool , t , * m_dispatch ) ;
}
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
private :
OwnerType m_owner ;
PoolType m_pool ;
Dispatch const * m_dispatch ;
} ;
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string classStructureChain = R " (
template < typename X , typename Y > struct isStructureChainValid { enum { value = false } ; } ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename P , typename T >
struct TypeList
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
using list = P ;
using last = T ;
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename List , typename X >
struct extendCheck
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static const bool valid = isStructureChainValid < typename List : : last , X > : : value | | extendCheck < typename List : : list , X > : : valid ;
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename T , typename X >
struct extendCheck < TypeList < void , T > , X >
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static const bool valid = isStructureChainValid < T , X > : : value ;
} ;
template < typename X >
struct extendCheck < void , X >
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static const bool valid = true ;
} ;
2018-09-25 09:23:27 +00:00
2019-11-28 14:58:15 +00:00
template < typename Type , class . . . >
struct isPartOfStructureChain
{
static const bool valid = false ;
} ;
template < typename Type , typename Head , typename . . . Tail >
struct isPartOfStructureChain < Type , Head , Tail . . . >
{
static const bool valid = std : : is_same < Type , Head > : : value | | isPartOfStructureChain < Type , Tail . . . > : : valid ;
} ;
2019-01-09 10:55:11 +00:00
template < class Element >
class StructureChainElement
2018-09-25 09:23:27 +00:00
{
public :
2019-10-23 08:52:29 +00:00
explicit operator Element & ( ) VULKAN_HPP_NOEXCEPT { return value ; }
explicit operator const Element & ( ) const VULKAN_HPP_NOEXCEPT { return value ; }
2019-01-09 10:55:11 +00:00
private :
Element value ;
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename . . . StructureElements >
class StructureChain : private StructureChainElement < StructureElements > . . .
{
public :
2019-10-23 08:52:29 +00:00
StructureChain ( ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
2019-10-23 08:52:29 +00:00
link < void , StructureElements . . . > ( ) ;
2019-01-09 10:55:11 +00:00
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
StructureChain ( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
linkAndCopy < void , StructureElements . . . > ( rhs ) ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
StructureChain ( StructureElements const & . . . elems ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
linkAndCopyElements < void , StructureElements . . . > ( elems . . . ) ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
StructureChain & operator = ( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
linkAndCopy < void , StructureElements . . . > ( rhs ) ;
2018-09-25 09:23:27 +00:00
return * this ;
}
2019-10-23 08:52:29 +00:00
template < typename ClassType > ClassType & get ( ) VULKAN_HPP_NOEXCEPT { return static_cast < ClassType & > ( * this ) ; }
2019-01-09 10:55:11 +00:00
2020-03-02 21:32:06 +00:00
template < typename ClassType > const ClassType & get ( ) const VULKAN_HPP_NOEXCEPT { return static_cast < const ClassType & > ( * this ) ; }
2019-03-11 14:25:31 +00:00
template < typename ClassTypeA , typename ClassTypeB , typename . . . ClassTypes >
2020-01-29 09:00:41 +00:00
std : : tuple < ClassTypeA & , ClassTypeB & , ClassTypes & . . . > get ( )
2019-03-11 14:25:31 +00:00
{
2020-02-03 14:55:06 +00:00
return std : : tie ( get < ClassTypeA > ( ) , get < ClassTypeB > ( ) , get < ClassTypes > ( ) . . . ) ;
2020-03-02 21:32:06 +00:00
}
template < typename ClassTypeA , typename ClassTypeB , typename . . . ClassTypes >
2020-03-04 12:33:52 +00:00
std : : tuple < const ClassTypeA & , const ClassTypeB & , const ClassTypes & . . . > get ( ) const
2020-03-02 21:32:06 +00:00
{
return std : : tie ( get < ClassTypeA > ( ) , get < ClassTypeB > ( ) , get < ClassTypes > ( ) . . . ) ;
2019-03-11 14:25:31 +00:00
}
2019-11-28 14:58:15 +00:00
template < typename ClassType >
void unlink ( ) VULKAN_HPP_NOEXCEPT
{
static_assert ( isPartOfStructureChain < ClassType , StructureElements . . . > : : valid , " Can't unlink Structure that's not part of this StructureChain! " ) ;
static_assert ( ! std : : is_same < ClassType , typename std : : tuple_element < 0 , std : : tuple < StructureElements . . . > > : : type > : : value , " It's not allowed to unlink the first element! " ) ;
VkBaseOutStructure * ptr = reinterpret_cast < VkBaseOutStructure * > ( & get < ClassType > ( ) ) ;
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( ptr ! = nullptr ) ;
2019-11-28 14:58:15 +00:00
VkBaseOutStructure * * ppNext = & ( reinterpret_cast < VkBaseOutStructure * > ( this ) - > pNext ) ;
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( * ppNext ! = nullptr ) ;
2019-11-28 14:58:15 +00:00
while ( * ppNext ! = ptr )
{
ppNext = & ( * ppNext ) - > pNext ;
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( * ppNext ! = nullptr ) ; // fires, if the ClassType member has already been unlinked !
2019-11-28 14:58:15 +00:00
}
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( * ppNext = = ptr ) ;
2019-11-28 14:58:15 +00:00
* ppNext = ( * ppNext ) - > pNext ;
}
template < typename ClassType >
void relink ( ) VULKAN_HPP_NOEXCEPT
{
static_assert ( isPartOfStructureChain < ClassType , StructureElements . . . > : : valid , " Can't relink Structure that's not part of this StructureChain! " ) ;
static_assert ( ! std : : is_same < ClassType , typename std : : tuple_element < 0 , std : : tuple < StructureElements . . . > > : : type > : : value , " It's not allowed to have the first element unlinked! " ) ;
VkBaseOutStructure * ptr = reinterpret_cast < VkBaseOutStructure * > ( & get < ClassType > ( ) ) ;
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( ptr ! = nullptr ) ;
2019-11-28 14:58:15 +00:00
VkBaseOutStructure * * ppNext = & ( reinterpret_cast < VkBaseOutStructure * > ( this ) - > pNext ) ;
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( * ppNext ! = nullptr ) ;
2019-11-28 14:58:15 +00:00
# if !defined(NDEBUG)
while ( * ppNext )
{
2020-01-30 08:57:51 +00:00
VULKAN_HPP_ASSERT ( * ppNext ! = ptr ) ; // fires, if the ClassType member has not been unlinked before
2019-11-28 14:58:15 +00:00
ppNext = & ( * ppNext ) - > pNext ;
}
ppNext = & ( reinterpret_cast < VkBaseOutStructure * > ( this ) - > pNext ) ;
# endif
ptr - > pNext = * ppNext ;
* ppNext = ptr ;
}
2019-01-09 10:55:11 +00:00
private :
template < typename List , typename X >
2019-10-23 08:52:29 +00:00
void link ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename List , typename X , typename Y , typename . . . Z >
2019-10-23 08:52:29 +00:00
void link ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
X & x = static_cast < X & > ( * this ) ;
Y & y = static_cast < Y & > ( * this ) ;
x . pNext = & y ;
link < TypeList < List , X > , Y , Z . . . > ( ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename List , typename X >
2019-10-23 08:52:29 +00:00
void linkAndCopy ( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
static_cast < X & > ( * this ) = static_cast < X const & > ( rhs ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename List , typename X , typename Y , typename . . . Z >
2019-10-23 08:52:29 +00:00
void linkAndCopy ( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
X & x = static_cast < X & > ( * this ) ;
Y & y = static_cast < Y & > ( * this ) ;
x = static_cast < X const & > ( rhs ) ;
x . pNext = & y ;
linkAndCopy < TypeList < List , X > , Y , Z . . . > ( rhs ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename List , typename X >
2019-10-23 08:52:29 +00:00
void linkAndCopyElements ( X const & xelem ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
static_cast < X & > ( * this ) = xelem ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename List , typename X , typename Y , typename . . . Z >
2019-10-23 08:52:29 +00:00
void linkAndCopyElements ( X const & xelem , Y const & yelem , Z const & . . . zelem ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static_assert ( extendCheck < List , X > : : valid , " The structure chain is not valid! " ) ;
X & x = static_cast < X & > ( * this ) ;
Y & y = static_cast < Y & > ( * this ) ;
x = xelem ;
x . pNext = & y ;
linkAndCopyElements < TypeList < List , X > , Y , Z . . . > ( yelem , zelem . . . ) ;
2018-09-25 09:23:27 +00:00
}
} ;
) " ;
2019-01-09 10:55:11 +00:00
static const std : : string classUniqueHandle = R " (
# if !defined(VULKAN_HPP_NO_SMART_HANDLE)
template < typename Type , typename Dispatch > class UniqueHandleTraits ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename Type , typename Dispatch >
class UniqueHandle : public UniqueHandleTraits < Type , Dispatch > : : deleter
{
private :
using Deleter = typename UniqueHandleTraits < Type , Dispatch > : : deleter ;
2019-05-09 07:22:10 +00:00
2019-05-16 06:07:36 +00:00
public :
2019-05-09 07:22:10 +00:00
using element_type = Type ;
2019-11-28 15:01:22 +00:00
UniqueHandle ( )
: Deleter ( )
, m_value ( )
{ }
explicit UniqueHandle ( Type const & value , Deleter const & deleter = Deleter ( ) ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: Deleter ( deleter )
, m_value ( value )
{ }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
UniqueHandle ( UniqueHandle const & ) = delete ;
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
UniqueHandle ( UniqueHandle & & other ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
: Deleter ( std : : move ( static_cast < Deleter & > ( other ) ) )
, m_value ( other . release ( ) )
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
~ UniqueHandle ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
if ( m_value ) this - > destroy ( m_value ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
UniqueHandle & operator = ( UniqueHandle const & ) = delete ;
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
UniqueHandle & operator = ( UniqueHandle & & other ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
reset ( other . release ( ) ) ;
* static_cast < Deleter * > ( this ) = std : : move ( static_cast < Deleter & > ( other ) ) ;
return * this ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
explicit operator bool ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_value . operator bool ( ) ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
Type const * operator - > ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return & m_value ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
Type * operator - > ( ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return & m_value ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
Type const & operator * ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_value ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
Type & operator * ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return m_value ;
2018-09-25 09:23:27 +00:00
}
2019-10-23 08:52:29 +00:00
const Type & get ( ) const VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_value ;
}
2019-10-23 08:52:29 +00:00
Type & get ( ) VULKAN_HPP_NOEXCEPT
2019-01-09 10:55:11 +00:00
{
return m_value ;
}
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
void reset ( Type const & value = Type ( ) ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
if ( m_value ! = value )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
if ( m_value ) this - > destroy ( m_value ) ;
m_value = value ;
2018-09-25 09:23:27 +00:00
}
}
2019-10-23 08:52:29 +00:00
Type release ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
Type value = m_value ;
m_value = nullptr ;
return value ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
void swap ( UniqueHandle < Type , Dispatch > & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
std : : swap ( m_value , rhs . m_value ) ;
std : : swap ( static_cast < Deleter & > ( * this ) , static_cast < Deleter & > ( rhs ) ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
private :
Type m_value ;
} ;
2019-05-16 06:07:36 +00:00
template < typename UniqueType >
VULKAN_HPP_INLINE std : : vector < typename UniqueType : : element_type > uniqueToRaw ( std : : vector < UniqueType > const & handles )
{
std : : vector < typename UniqueType : : element_type > newBuffer ( handles . size ( ) ) ;
std : : transform ( handles . begin ( ) , handles . end ( ) , newBuffer . begin ( ) , [ ] ( UniqueType const & handle ) { return handle . get ( ) ; } ) ;
return newBuffer ;
}
2019-01-09 10:55:11 +00:00
template < typename Type , typename Dispatch >
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE void swap ( UniqueHandle < Type , Dispatch > & lhs , UniqueHandle < Type , Dispatch > & rhs ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
lhs . swap ( rhs ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
# endif
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string defines = R " (
// <tuple> includes <sys/sysmacros.h> through some other header
// this results in major(x) being resolved to gnu_dev_major(x)
// which is an expression in a constructor initializer list.
# if defined(major)
# undef major
# endif
# if defined(minor)
# undef minor
# endif
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
// Windows defines MemoryBarrier which is deprecated and collides
2019-12-02 09:06:44 +00:00
// with the VULKAN_HPP_NAMESPACE::MemoryBarrier struct.
2019-01-09 10:55:11 +00:00
# if defined(MemoryBarrier)
# undef MemoryBarrier
# endif
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
# if !defined(VULKAN_HPP_HAS_UNRESTRICTED_UNIONS)
# if defined(__clang__)
# if __has_feature(cxx_unrestricted_unions)
# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
# endif
# elif defined(__GNUC__)
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# if 40600 <= GCC_VERSION
# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
# endif
# elif defined(_MSC_VER)
# if 1900 <= _MSC_VER
# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
# endif
# endif
# endif
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
# if !defined(VULKAN_HPP_INLINE)
2019-07-25 12:26:03 +00:00
# if defined(__clang__)
2019-01-09 10:55:11 +00:00
# if __has_attribute(always_inline)
# define VULKAN_HPP_INLINE __attribute__((always_inline)) __inline__
# else
2019-10-23 08:52:29 +00:00
# define VULKAN_HPP_INLINE inline
2019-01-09 10:55:11 +00:00
# endif
# elif defined(__GNUC__)
# define VULKAN_HPP_INLINE __attribute__((always_inline)) __inline__
# elif defined(_MSC_VER)
# define VULKAN_HPP_INLINE inline
# else
# define VULKAN_HPP_INLINE inline
# endif
# endif
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
# if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
# define VULKAN_HPP_TYPESAFE_EXPLICIT
# else
# define VULKAN_HPP_TYPESAFE_EXPLICIT explicit
# endif
2018-09-25 09:23:27 +00:00
2019-09-23 13:57:48 +00:00
# if defined(__cpp_constexpr)
2019-01-09 10:55:11 +00:00
# define VULKAN_HPP_CONSTEXPR constexpr
2019-09-23 13:57:48 +00:00
# if __cpp_constexpr >= 201304
# define VULKAN_HPP_CONSTEXPR_14 constexpr
# else
# define VULKAN_HPP_CONSTEXPR_14
# endif
2019-07-09 07:24:14 +00:00
# define VULKAN_HPP_CONST_OR_CONSTEXPR constexpr
2019-09-23 13:57:48 +00:00
# else
# define VULKAN_HPP_CONSTEXPR
# define VULKAN_HPP_CONSTEXPR_14
# define VULKAN_HPP_CONST_OR_CONSTEXPR const
2019-01-09 10:55:11 +00:00
# endif
2019-10-23 08:52:29 +00:00
# if !defined(VULKAN_HPP_NOEXCEPT)
# if defined(_MSC_VER) && (_MSC_VER <= 1800)
# define VULKAN_HPP_NOEXCEPT
# else
# define VULKAN_HPP_NOEXCEPT noexcept
# define VULKAN_HPP_HAS_NOEXCEPT 1
# endif
# endif
2020-04-27 11:39:14 +00:00
# if __cplusplus >= 201402L
# define VULKAN_HPP_DEPRECATED( msg ) [[deprecated( msg )]]
# else
2020-04-25 22:10:16 +00:00
# define VULKAN_HPP_DEPRECATED( msg )
# endif
2019-01-09 10:55:11 +00:00
# if !defined(VULKAN_HPP_NAMESPACE)
# define VULKAN_HPP_NAMESPACE vk
# endif
# define VULKAN_HPP_STRINGIFY2(text) #text
# define VULKAN_HPP_STRINGIFY(text) VULKAN_HPP_STRINGIFY2(text)
# define VULKAN_HPP_NAMESPACE_STRING VULKAN_HPP_STRINGIFY(VULKAN_HPP_NAMESPACE)
) " ;
static const std : : string exceptions = R " (
class ErrorCategoryImpl : public std : : error_category
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
2019-10-23 08:52:29 +00:00
virtual const char * name ( ) const VULKAN_HPP_NOEXCEPT override { return VULKAN_HPP_NAMESPACE_STRING " ::Result " ; }
2019-01-09 10:55:11 +00:00
virtual std : : string message ( int ev ) const override { return to_string ( static_cast < Result > ( ev ) ) ; }
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
class Error
{
public :
2019-10-23 08:52:29 +00:00
Error ( ) VULKAN_HPP_NOEXCEPT = default ;
Error ( const Error & ) VULKAN_HPP_NOEXCEPT = default ;
virtual ~ Error ( ) VULKAN_HPP_NOEXCEPT = default ;
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
virtual const char * what ( ) const VULKAN_HPP_NOEXCEPT = 0 ;
2019-01-09 10:55:11 +00:00
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
class LogicError : public Error , public std : : logic_error
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
public :
explicit LogicError ( const std : : string & what )
: Error ( ) , std : : logic_error ( what ) { }
explicit LogicError ( char const * what )
: Error ( ) , std : : logic_error ( what ) { }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
virtual const char * what ( ) const VULKAN_HPP_NOEXCEPT { return std : : logic_error : : what ( ) ; }
2019-01-09 10:55:11 +00:00
} ;
class SystemError : public Error , public std : : system_error
{
public :
SystemError ( std : : error_code ec )
: Error ( ) , std : : system_error ( ec ) { }
SystemError ( std : : error_code ec , std : : string const & what )
: Error ( ) , std : : system_error ( ec , what ) { }
SystemError ( std : : error_code ec , char const * what )
: Error ( ) , std : : system_error ( ec , what ) { }
SystemError ( int ev , std : : error_category const & ecat )
: Error ( ) , std : : system_error ( ev , ecat ) { }
SystemError ( int ev , std : : error_category const & ecat , std : : string const & what )
: Error ( ) , std : : system_error ( ev , ecat , what ) { }
SystemError ( int ev , std : : error_category const & ecat , char const * what )
: Error ( ) , std : : system_error ( ev , ecat , what ) { }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
virtual const char * what ( ) const VULKAN_HPP_NOEXCEPT { return std : : system_error : : what ( ) ; }
2019-01-09 10:55:11 +00:00
} ;
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE const std : : error_category & errorCategory ( ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
static ErrorCategoryImpl instance ;
return instance ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE std : : error_code make_error_code ( Result e ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return std : : error_code ( static_cast < int > ( e ) , errorCategory ( ) ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
2019-10-23 08:52:29 +00:00
VULKAN_HPP_INLINE std : : error_condition make_error_condition ( Result e ) VULKAN_HPP_NOEXCEPT
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
return std : : error_condition ( static_cast < int > ( e ) , errorCategory ( ) ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string includes = R " (
# ifndef VULKAN_HPP
# define VULKAN_HPP
# include <algorithm>
# include <array>
# include <cstddef>
# include <cstdint>
# include <cstring>
2020-03-30 10:18:06 +00:00
# include <functional>
2019-01-09 10:55:11 +00:00
# include <initializer_list>
# include <string>
# include <system_error>
# include <tuple>
# include <type_traits>
# include <vulkan/vulkan.h>
2020-02-17 13:20:40 +00:00
# if defined(VULKAN_HPP_DISABLE_ENHANCED_MODE)
# if !defined(VULKAN_HPP_NO_SMART_HANDLE)
# define VULKAN_HPP_NO_SMART_HANDLE
# endif
# else
2019-01-09 10:55:11 +00:00
# include <memory>
# include <vector>
# endif
# if !defined(VULKAN_HPP_ASSERT)
# include <cassert>
# define VULKAN_HPP_ASSERT assert
# endif
2019-09-24 10:12:49 +00:00
2019-11-11 16:23:35 +00:00
# if !defined(VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL)
# define VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL 1
2019-09-24 10:12:49 +00:00
# endif
2019-11-11 16:23:35 +00:00
# if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL == 1
# if defined(__linux__) || defined(__APPLE__)
# include <dlfcn.h>
# endif
# if defined(_WIN32)
# include <windows.h>
# endif
# endif
2020-02-26 13:24:58 +00:00
# if 201711 <= __cpp_impl_three_way_comparison
# define VULKAN_HPP_HAS_SPACESHIP_OPERATOR
# endif
# if defined(VULKAN_HPP_HAS_SPACESHIP_OPERATOR)
# include <compare>
# endif
2019-01-09 10:55:11 +00:00
) " ;
static const std : : string is_error_code_enum = R " (
2020-01-06 14:55:31 +00:00
# ifndef VULKAN_HPP_NO_EXCEPTIONS
2019-01-09 10:55:11 +00:00
namespace std
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
template < >
struct is_error_code_enum < VULKAN_HPP_NAMESPACE : : Result > : public true_type
{ } ;
2018-09-25 09:23:27 +00:00
}
2020-01-06 14:55:31 +00:00
# endif
2019-01-09 10:55:11 +00:00
) " ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
static const std : : string structResultValue = R " (
2019-10-23 08:52:29 +00:00
template < typename T > void ignore ( T const & ) VULKAN_HPP_NOEXCEPT { }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < typename T >
struct ResultValue
2018-09-25 09:23:27 +00:00
{
2019-10-23 08:52:29 +00:00
# ifdef VULKAN_HPP_HAS_NOEXCEPT
2019-10-25 11:21:49 +00:00
ResultValue ( Result r , T & v ) VULKAN_HPP_NOEXCEPT ( VULKAN_HPP_NOEXCEPT ( T ( v ) ) )
2019-10-23 08:52:29 +00:00
# else
2019-01-09 10:55:11 +00:00
ResultValue ( Result r , T & v )
2019-10-23 08:52:29 +00:00
# endif
2019-01-09 10:55:11 +00:00
: result ( r )
, value ( v )
{ }
2018-09-25 09:23:27 +00:00
2019-10-23 08:52:29 +00:00
# ifdef VULKAN_HPP_HAS_NOEXCEPT
2019-10-25 11:21:49 +00:00
ResultValue ( Result r , T & & v ) VULKAN_HPP_NOEXCEPT ( VULKAN_HPP_NOEXCEPT ( T ( std : : move ( v ) ) ) )
2019-10-23 08:52:29 +00:00
# else
2019-01-09 10:55:11 +00:00
ResultValue ( Result r , T & & v )
2019-10-23 08:52:29 +00:00
# endif
2019-01-09 10:55:11 +00:00
: result ( r )
, value ( std : : move ( v ) )
{ }
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
Result result ;
T value ;
2019-10-23 08:52:29 +00:00
operator std : : tuple < Result & , T & > ( ) VULKAN_HPP_NOEXCEPT { return std : : tuple < Result & , T & > ( result , value ) ; }
2020-03-25 10:44:45 +00:00
# if !defined(VULKAN_HPP_DISABLE_IMPLICIT_RESULT_VALUE_CAST)
operator T const & ( ) const VULKAN_HPP_NOEXCEPT
{
return value ;
}
operator T & ( ) VULKAN_HPP_NOEXCEPT
{
return value ;
}
# endif
2019-01-09 10:55:11 +00:00
} ;
2020-03-25 10:44:45 +00:00
# if !defined(VULKAN_HPP_DISABLE_IMPLICIT_RESULT_VALUE_CAST)
template < typename Type , typename Dispatch >
struct ResultValue < UniqueHandle < Type , Dispatch > >
{
# ifdef VULKAN_HPP_HAS_NOEXCEPT
ResultValue ( Result r , UniqueHandle < Type , Dispatch > & v ) VULKAN_HPP_NOEXCEPT
# else
ResultValue ( Result r , UniqueHandle < Type , Dispatch > & v )
# endif
: result ( r )
, value ( v )
{ }
# ifdef VULKAN_HPP_HAS_NOEXCEPT
ResultValue ( Result r , UniqueHandle < Type , Dispatch > & & v ) VULKAN_HPP_NOEXCEPT
# else
ResultValue ( Result r , UniqueHandle < Type , Dispatch > & & v )
# endif
: result ( r )
, value ( std : : move ( v ) )
{ }
Result result ;
UniqueHandle < Type , Dispatch > value ;
operator std : : tuple < Result & , UniqueHandle < Type , Dispatch > & > ( ) VULKAN_HPP_NOEXCEPT { return std : : tuple < Result & , UniqueHandle < Type , Dispatch > & > ( result , value ) ; }
operator UniqueHandle < Type , Dispatch > ( ) VULKAN_HPP_NOEXCEPT
{
return std : : move ( value ) ;
}
} ;
# endif
2019-01-09 10:55:11 +00:00
template < typename T >
struct ResultValueType
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
typedef ResultValue < T > type ;
# else
typedef T type ;
2018-09-25 09:23:27 +00:00
# endif
2019-01-09 10:55:11 +00:00
} ;
2018-09-25 09:23:27 +00:00
2019-01-09 10:55:11 +00:00
template < >
struct ResultValueType < void >
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
typedef Result type ;
# else
typedef void type ;
# endif
} ;
VULKAN_HPP_INLINE ResultValueType < void > : : type createResultValue ( Result result , char const * message )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( result = = Result : : eSuccess ) ;
return result ;
# else
if ( result ! = Result : : eSuccess )
{
throwResultException ( result , message ) ;
}
# endif
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename T >
VULKAN_HPP_INLINE typename ResultValueType < T > : : type createResultValue ( Result result , T & data , char const * message )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( result = = Result : : eSuccess ) ;
return ResultValue < T > ( result , std : : move ( data ) ) ;
# else
if ( result ! = Result : : eSuccess )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
throwResultException ( result , message ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
return std : : move ( data ) ;
# endif
}
VULKAN_HPP_INLINE Result createResultValue ( Result result , char const * message , std : : initializer_list < Result > successCodes )
{
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) ! = successCodes . end ( ) ) ;
# else
if ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) = = successCodes . end ( ) )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
throwResultException ( result , message ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
# endif
return result ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
template < typename T >
VULKAN_HPP_INLINE ResultValue < T > createResultValue ( Result result , T & data , char const * message , std : : initializer_list < Result > successCodes )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) ! = successCodes . end ( ) ) ;
# else
if ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) = = successCodes . end ( ) )
{
throwResultException ( result , message ) ;
}
# endif
return ResultValue < T > ( result , data ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
# ifndef VULKAN_HPP_NO_SMART_HANDLE
template < typename T , typename D >
VULKAN_HPP_INLINE typename ResultValueType < UniqueHandle < T , D > > : : type createResultValue ( Result result , T & data , char const * message , typename UniqueHandleTraits < T , D > : : deleter const & deleter )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( result = = Result : : eSuccess ) ;
return ResultValue < UniqueHandle < T , D > > ( result , UniqueHandle < T , D > ( data , deleter ) ) ;
# else
if ( result ! = Result : : eSuccess )
2018-09-25 09:23:27 +00:00
{
2019-01-09 10:55:11 +00:00
throwResultException ( result , message ) ;
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
return UniqueHandle < T , D > ( data , deleter ) ;
2020-03-25 10:44:45 +00:00
# endif
}
template < typename T , typename D >
VULKAN_HPP_INLINE ResultValue < UniqueHandle < T , D > > createResultValue ( Result result , T & data , char const * message , std : : initializer_list < Result > successCodes , typename UniqueHandleTraits < T , D > : : deleter const & deleter )
{
# ifdef VULKAN_HPP_NO_EXCEPTIONS
ignore ( message ) ;
VULKAN_HPP_ASSERT ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) ! = successCodes . end ( ) ) ;
return ResultValue < UniqueHandle < T , D > > ( result , UniqueHandle < T , D > ( data , deleter ) ) ;
# else
if ( std : : find ( successCodes . begin ( ) , successCodes . end ( ) , result ) = = successCodes . end ( ) )
{
throwResultException ( result , message ) ;
}
return ResultValue < UniqueHandle < T , D > > ( result , UniqueHandle < T , D > ( data , deleter ) ) ;
2019-01-09 10:55:11 +00:00
# endif
2018-09-25 09:23:27 +00:00
}
2019-01-09 10:55:11 +00:00
# endif
) " ;
2018-09-25 09:23:27 +00:00
2019-07-09 07:24:14 +00:00
static const std : : string typeTraits = R " (
2020-04-21 12:26:32 +00:00
template < typename EnumType , EnumType value >
struct CppType
{ } ;
2019-07-09 07:24:14 +00:00
) " ;
2020-04-12 19:49:12 +00:00
try
{
2018-09-25 09:23:27 +00:00
tinyxml2 : : XMLDocument doc ;
2020-04-12 19:49:12 +00:00
std : : string filename = ( argc = = 1 ) ? VK_SPEC : argv [ 1 ] ;
2018-09-25 09:23:27 +00:00
std : : cout < < " Loading vk.xml from " < < filename < < std : : endl ;
std : : cout < < " Writing vulkan.hpp to " < < VULKAN_HPP_FILE < < std : : endl ;
2020-04-12 19:49:12 +00:00
tinyxml2 : : XMLError error = doc . LoadFile ( filename . c_str ( ) ) ;
if ( error ! = tinyxml2 : : XML_SUCCESS )
2018-09-25 09:23:27 +00:00
{
2020-04-12 19:49:12 +00:00
std : : cout < < " VulkanHppGenerator: failed to load file " < < filename < < " with error < " < < to_string ( error )
< < " > " < < std : : endl ;
2018-09-25 09:23:27 +00:00
return - 1 ;
}
2020-04-12 19:49:12 +00:00
VulkanHppGenerator generator ( doc ) ;
2018-09-25 09:23:27 +00:00
2020-04-12 19:49:12 +00:00
std : : string str ;
2019-08-27 07:02:49 +00:00
static const size_t estimatedLength = 4 * 1024 * 1024 ;
2020-04-12 19:49:12 +00:00
str . reserve ( estimatedLength ) ;
str + = generator . getVulkanLicenseHeader ( ) + includes + " \n " ;
appendVersionCheck ( str , generator . getVersion ( ) ) ;
appendTypesafeStuff ( str , generator . getTypesafeCheck ( ) ) ;
str + = defines + " \n " + " namespace VULKAN_HPP_NAMESPACE \n " + " { \n " + classArrayProxy + classArrayWrapper +
classFlags + classOptional + classStructureChain + classUniqueHandle ;
generator . appendDispatchLoaderStatic ( str ) ;
generator . appendDispatchLoaderDefault ( str ) ;
str + = classObjectDestroy + classObjectFree + classPoolFree + " \n " ;
generator . appendBaseTypes ( str ) ;
2019-08-27 07:02:49 +00:00
str + = typeTraits ;
2020-04-21 12:26:32 +00:00
generator . appendEnums ( str ) ;
generator . appendIndexTypeTraits ( str ) ;
2020-04-12 19:49:12 +00:00
generator . appendBitmasks ( str ) ;
str + = " } // namespace VULKAN_HPP_NAMESPACE \n " + is_error_code_enum + " \n " + " namespace VULKAN_HPP_NAMESPACE \n " +
" { \n " + " #ifndef VULKAN_HPP_NO_EXCEPTIONS " + exceptions ;
generator . appendResultExceptions ( str ) ;
generator . appendThrowExceptions ( str ) ;
str + = " #endif \n " + structResultValue ;
generator . appendForwardDeclarations ( str ) ;
generator . appendHandles ( str ) ;
generator . appendStructs ( str ) ;
generator . appendHandlesCommandDefintions ( str ) ;
generator . appendStructureChainValidation ( str ) ;
generator . appendDispatchLoaderDynamic ( str ) ;
2020-03-30 10:18:06 +00:00
str + = " } // namespace VULKAN_HPP_NAMESPACE \n " ;
2020-04-12 19:49:12 +00:00
generator . appendHashStructures ( str ) ;
2020-03-30 10:18:06 +00:00
str + = " #endif \n " ;
2019-08-27 07:02:49 +00:00
2020-04-12 19:49:12 +00:00
std : : ofstream ofs ( VULKAN_HPP_FILE ) ;
assert ( ! ofs . fail ( ) ) ;
2019-08-27 07:02:49 +00:00
ofs < < str ;
2019-07-23 07:28:14 +00:00
ofs . close ( ) ;
2020-04-12 19:49:12 +00:00
# if defined( CLANG_FORMAT_EXECUTABLE )
std : : cout < < " VulkanHppGenerator: formatting vulkan.hpp using clang-format... " ;
int ret = std : : system ( " \" " CLANG_FORMAT_EXECUTABLE " \" -i --style=file " VULKAN_HPP_FILE ) ;
if ( ret ! = 0 )
{
std : : cout < < " VulkanHppGenerator: failed to format file " < < filename < < " with error < " < < ret < < " > \n " ;
return - 1 ;
}
# else
std : : cout
< < " VulkanHppGenerator: could not find clang-format. The generated vulkan.hpp will not be formatted accordingly. \n " ;
# endif
2018-09-25 09:23:27 +00:00
}
2020-04-12 19:49:12 +00:00
catch ( std : : exception const & e )
2018-09-25 09:23:27 +00:00
{
std : : cout < < " caught exception: " < < e . what ( ) < < std : : endl ;
return - 1 ;
}
2020-04-12 19:49:12 +00:00
catch ( . . . )
2018-09-25 09:23:27 +00:00
{
std : : cout < < " caught unknown exception " < < std : : endl ;
return - 1 ;
}
}