diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 6f33a46..527638c 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -31,7 +31,6 @@ void checkElements( int std::set const & optional = {} ); std::set determineSingularParams( size_t returnParamIndex, std::map const & vectorParamIndices ); -std::set determineSkippedParams( size_t returnParamIndex, std::map const & vectorParamIndices ); std::string findTag( std::set const & tags, std::string const & name, std::string const & postfix = "" ); std::string generateCArraySizes( std::vector const & sizes ); std::pair @@ -1021,11 +1020,8 @@ void VulkanHppGenerator::appendRAIIDispatcherCommands( std::vector instanceMembers += addTitleAndProtection( title, im, imp ); } -void VulkanHppGenerator::checkCorrectness() const +void VulkanHppGenerator::checkBitmaskCorrectness() const { - check( !m_vulkanLicenseHeader.empty(), -1, "missing license header" ); - - // bitmask checks for ( auto const & bitmask : m_bitmasks ) { // check that a bitmask is referenced somewhere @@ -1044,7 +1040,10 @@ void VulkanHppGenerator::checkCorrectness() const "bitmask requires unknown <" + bitmask.second.requirements + ">" ); } } +} +void VulkanHppGenerator::checkCommandCorrectness() const +{ // prepare command checks by gathering all result codes and aliases into one set of resultCodes auto resultIt = m_enums.find( "VkResult" ); assert( resultIt != m_enums.end() ); @@ -1097,8 +1096,22 @@ void VulkanHppGenerator::checkCorrectness() const command.second.xmlLine, "command uses unknown return type <" + command.second.returnType + ">" ); } +} - // enum checks +void VulkanHppGenerator::checkCorrectness() const +{ + check( !m_vulkanLicenseHeader.empty(), -1, "missing license header" ); + checkBitmaskCorrectness(); + checkCommandCorrectness(); + checkEnumCorrectness(); + checkExtensionCorrectness(); + checkFuncPointerCorrectness(); + checkHandleCorrectness(); + checkStructCorrectness(); +} + +void VulkanHppGenerator::checkEnumCorrectness() const +{ for ( auto const & e : m_enums ) { // check that a bitmask is referenced somewhere @@ -1148,230 +1161,6 @@ void VulkanHppGenerator::checkCorrectness() const { checkEnumCorrectness( ext.second.requireData ); } - - // extension checks - for ( auto const & extension : m_extensions ) - { - // check for existence of any deprecation, obsoletion, or promotion - if ( !extension.second.deprecatedBy.empty() ) - { - 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 + ">" ); - } - if ( !extension.second.obsoletedBy.empty() ) - { - 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 + ">" ); - } - if ( !extension.second.promotedTo.empty() ) - { - 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 + ">" ); - } - - // check for existence of any requirement - for ( auto const & require : extension.second.requireData ) - { - check( require.title.empty() || ( m_features.find( require.title ) != m_features.end() ) || - ( m_extensions.find( require.title ) != m_extensions.end() ), - require.xmlLine, - "extension <" + extension.first + "> lists an unknown require <" + require.title + ">" ); - } - } - - // funcPointer checks - for ( auto const & funcPointer : m_funcPointers ) - { - if ( !funcPointer.second.requirements.empty() ) - { - check( m_types.find( funcPointer.second.requirements ) != m_types.end(), - funcPointer.second.xmlLine, - "funcpointer requires unknown <" + funcPointer.second.requirements + ">" ); - } - } - - // prepare handle checks by getting the VkObjectType enum - auto objectTypeIt = m_enums.find( "VkObjectType" ); - assert( objectTypeIt != m_enums.end() ); - - // handle checks - for ( auto const & handle : m_handles ) - { - // check the existence of the parent - check( m_handles.find( handle.second.parent ) != m_handles.end(), - handle.second.xmlLine, - "handle <" + handle.first + "> with unknown parent <" + handle.second.parent + ">" ); - - // check existence of objTypeEnum used with this handle type - if ( !handle.first.empty() ) - { - assert( !handle.second.objTypeEnum.empty() ); - check( std::find_if( objectTypeIt->second.values.begin(), - objectTypeIt->second.values.end(), - [&handle]( EnumValueData const & evd ) - { return evd.name == handle.second.objTypeEnum; } ) != objectTypeIt->second.values.end(), - handle.second.xmlLine, - "handle <" + handle.first + "> specifies unknown \"objtypeenum\" <" + handle.second.objTypeEnum + ">" ); - } - } - - // check that all specified objectType values are used with a handle type - for ( auto const & objectTypeValue : objectTypeIt->second.values ) - { - if ( objectTypeValue.name != "VK_OBJECT_TYPE_UNKNOWN" ) - { - check( std::find_if( m_handles.begin(), - m_handles.end(), - [&objectTypeValue]( std::pair const & hd ) - { return hd.second.objTypeEnum == objectTypeValue.name; } ) != m_handles.end(), - objectTypeValue.xmlLine, - "VkObjectType value <" + objectTypeValue.name + "> not specified as \"objtypeenum\" for any handle" ); - } - } - - // structure checks - std::set sTypeValues; - for ( auto const & structure : m_structures ) - { - // check that a struct is referenced somewhere - // I think, it's not forbidden to not reference a struct, but it would probably be not intended? - auto typeIt = m_types.find( structure.first ); - assert( typeIt != m_types.end() ); - check( !typeIt->second.referencedIn.empty(), - structure.second.xmlLine, - "structure <" + structure.first + "> not listed in any feature or extension" ); - - // check for existence of all structs that are extended by this struct - for ( auto const & extend : structure.second.structExtends ) - { - check( m_structures.find( extend ) != m_structures.end(), - structure.second.xmlLine, - "struct <" + structure.first + "> extends unknown <" + extend + ">" ); - } - - // checks on the members of a struct - for ( auto const & member : structure.second.members ) - { - // if a member specifies a selector, that member is a union and the selector is an enum - // check that there's a 1-1 connection between the specified selections and the values of that enum - if ( !member.selector.empty() ) - { - std::string const & selector = member.selector; - auto selectorIt = std::find_if( structure.second.members.begin(), - structure.second.members.end(), - [&selector]( MemberData const & md ) { return md.name == selector; } ); - assert( selectorIt != structure.second.members.end() ); - auto selectorEnumIt = m_enums.find( selectorIt->type.type ); - assert( selectorEnumIt != m_enums.end() ); - auto unionIt = m_structures.find( member.type.type ); - assert( ( unionIt != m_structures.end() ) && unionIt->second.isUnion ); - for ( auto const & unionMember : unionIt->second.members ) - { - // check that each union member has a selection, that is a value of the seleting enum - assert( !unionMember.selection.empty() ); - std::string const & selection = unionMember.selection; - check( std::find_if( selectorEnumIt->second.values.begin(), - selectorEnumIt->second.values.end(), - [&selection]( EnumValueData const & evd ) - { return evd.name == selection; } ) != selectorEnumIt->second.values.end(), - unionMember.xmlLine, - "union member <" + unionMember.name + "> uses selection <" + selection + - "> that is not part of the selector type <" + selectorIt->type.type + ">" ); - } - for ( auto const & selectorValue : selectorEnumIt->second.values ) - { - // check that each enum value is used as a selection in the corresponding union - check( std::find_if( unionIt->second.members.begin(), - unionIt->second.members.end(), - [selectorValue]( MemberData const & md ) - { return md.selection == selectorValue.name; } ) != unionIt->second.members.end(), - selectorEnumIt->second.xmlLine, - "enum <" + selectorEnumIt->first + "> has value <" + selectorValue.name + - "> that is not used by corresponding union <" + unionIt->first + ">" ); - } - } - - // check that each member type is known - check( m_types.find( member.type.type ) != m_types.end(), - member.xmlLine, - "struct member uses unknown type <" + member.type.type + ">" ); - - // check that any used constant is a known constant - if ( !member.usedConstant.empty() ) - { - check( m_constants.find( member.usedConstant ) != m_constants.end(), - member.xmlLine, - "struct member array size uses unknown constant <" + member.usedConstant + ">" ); - } - - // checks if a value is specified - if ( !member.value.empty() ) - { - auto enumIt = m_enums.find( member.type.type ); - if ( enumIt != m_enums.end() ) - { - // check that the value exists in the specified enum - check( std::find_if( enumIt->second.values.begin(), - enumIt->second.values.end(), - [&member]( auto const & evd ) - { return member.value == evd.name; } ) != enumIt->second.values.end(), - member.xmlLine, - "value <" + member.value + "> for member <" + member.name + "> in structure <" + structure.first + - "> of enum type <" + member.type.type + "> not listed" ); - // special handling for sType: no value should appear more than once - if ( member.name == "sType" ) - { - check( sTypeValues.insert( member.value ).second, - member.xmlLine, - "sType value <" + member.value + "> has been used before" ); - } - } - else if ( member.type.type == "uint32_t" ) - { - // check that a value for a uint32_t is all digits - check( member.value.find_first_not_of( "0123456789" ) == std::string::npos, - member.xmlLine, - "value <" + member.value + "> for member <" + member.name + "> in structure <" + structure.first + - "> of type <" + member.type.type + "> is not a number" ); - } - else - { - // don't know the type of the value -> error out - check( false, - member.xmlLine, - "member <" + member.name + "> in structure <" + structure.first + "> holds value <" + member.value + - "> for an unhandled type <" + member.type.type + ">" ); - } - } - } - } - - // enum VkStructureType checks (need to be after structure checks because of sTypeValues gathered there) - auto structureTypeIt = m_enums.find( "VkStructureType" ); - assert( structureTypeIt != m_enums.end() ); - for ( auto const & enumValue : structureTypeIt->second.values ) - { - if ( ( enumValue.name == "VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO" ) || - ( enumValue.name == "VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO" ) ) - { - check( sTypeValues.find( enumValue.name ) == sTypeValues.end(), - enumValue.xmlLine, - "Reserved VkStructureType enum value <" + enumValue.name + "> is used" ); - } - else - { - check( sTypeValues.erase( enumValue.name ) == 1, - enumValue.xmlLine, - "VkStructureType enum value <" + enumValue.name + "> never used" ); - } - } - assert( sTypeValues.empty() ); } void VulkanHppGenerator::checkEnumCorrectness( std::vector const & requireData ) const @@ -1458,33 +1247,271 @@ bool VulkanHppGenerator::checkEquivalentSingularConstructor( { // check, if there is no singular constructor with the very same arguments as this array constructor // (besides the size, of course) + auto isEquivalentSingularConstructor = [constructorIt, lenIt]( std::map::const_iterator it ) + { + if ( it->second.params.size() + 1 != constructorIt->second.params.size() ) + { + return false; + } + size_t lenIdx = std::distance( constructorIt->second.params.begin(), lenIt ); + for ( size_t i = 0, j = 0; i < it->second.params.size(); ++i, ++j ) + { + assert( j < constructorIt->second.params.size() ); + if ( j == lenIdx ) + { + ++j; + } + if ( it->second.params[i].type.type != constructorIt->second.params[j].type.type ) + { + return false; + } + } + return true; + }; auto singularCommandIt = - std::find_if( constructorIts.begin(), - constructorIts.end(), - [constructorIt, lenIt]( std::map::const_iterator it ) - { - if ( it->second.params.size() + 1 != constructorIt->second.params.size() ) - { - return false; - } - size_t lenIdx = std::distance( constructorIt->second.params.begin(), lenIt ); - for ( size_t i = 0, j = 0; i < it->second.params.size(); ++i, ++j ) - { - assert( j < constructorIt->second.params.size() ); - if ( j == lenIdx ) - { - ++j; - } - if ( it->second.params[i].type.type != constructorIt->second.params[j].type.type ) - { - return false; - } - } - return true; - } ); + std::find_if( constructorIts.begin(), constructorIts.end(), isEquivalentSingularConstructor ); return ( singularCommandIt != constructorIts.end() ); } +void VulkanHppGenerator::checkExtensionCorrectness() const +{ + for ( auto const & extension : m_extensions ) + { + // check for existence of any deprecation, obsoletion, or promotion + if ( !extension.second.deprecatedBy.empty() ) + { + 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 + ">" ); + } + if ( !extension.second.obsoletedBy.empty() ) + { + 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 + ">" ); + } + if ( !extension.second.promotedTo.empty() ) + { + 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 + ">" ); + } + + // check for existence of any requirement + for ( auto const & require : extension.second.requireData ) + { + check( require.title.empty() || ( m_features.find( require.title ) != m_features.end() ) || + ( m_extensions.find( require.title ) != m_extensions.end() ), + require.xmlLine, + "extension <" + extension.first + "> lists an unknown require <" + require.title + ">" ); + } + } +} + +void VulkanHppGenerator::checkFuncPointerCorrectness() const +{ + for ( auto const & funcPointer : m_funcPointers ) + { + if ( !funcPointer.second.requirements.empty() ) + { + check( m_types.find( funcPointer.second.requirements ) != m_types.end(), + funcPointer.second.xmlLine, + "funcpointer requires unknown <" + funcPointer.second.requirements + ">" ); + } + } +} + +void VulkanHppGenerator::checkHandleCorrectness() const +{ + // prepare handle checks by getting the VkObjectType enum + auto objectTypeIt = m_enums.find( "VkObjectType" ); + assert( objectTypeIt != m_enums.end() ); + + // handle checks + for ( auto const & handle : m_handles ) + { + // check the existence of the parent + check( m_handles.find( handle.second.parent ) != m_handles.end(), + handle.second.xmlLine, + "handle <" + handle.first + "> with unknown parent <" + handle.second.parent + ">" ); + + // check existence of objTypeEnum used with this handle type + if ( !handle.first.empty() ) + { + assert( !handle.second.objTypeEnum.empty() ); + check( std::find_if( objectTypeIt->second.values.begin(), + objectTypeIt->second.values.end(), + [&handle]( EnumValueData const & evd ) + { return evd.name == handle.second.objTypeEnum; } ) != objectTypeIt->second.values.end(), + handle.second.xmlLine, + "handle <" + handle.first + "> specifies unknown \"objtypeenum\" <" + handle.second.objTypeEnum + ">" ); + } + } + + // check that all specified objectType values are used with a handle type + for ( auto const & objectTypeValue : objectTypeIt->second.values ) + { + if ( objectTypeValue.name != "VK_OBJECT_TYPE_UNKNOWN" ) + { + check( std::find_if( m_handles.begin(), + m_handles.end(), + [&objectTypeValue]( std::pair const & hd ) + { return hd.second.objTypeEnum == objectTypeValue.name; } ) != m_handles.end(), + objectTypeValue.xmlLine, + "VkObjectType value <" + objectTypeValue.name + "> not specified as \"objtypeenum\" for any handle" ); + } + } +} + +void VulkanHppGenerator::checkStructCorrectness() const +{ + std::set sTypeValues; + for ( auto const & structure : m_structures ) + { + // check that a struct is referenced somewhere + // I think, it's not forbidden to not reference a struct, but it would probably be not intended? + auto typeIt = m_types.find( structure.first ); + assert( typeIt != m_types.end() ); + check( !typeIt->second.referencedIn.empty(), + structure.second.xmlLine, + "structure <" + structure.first + "> not listed in any feature or extension" ); + + // check for existence of all structs that are extended by this struct + for ( auto const & extend : structure.second.structExtends ) + { + check( m_structures.find( extend ) != m_structures.end(), + structure.second.xmlLine, + "struct <" + structure.first + "> extends unknown <" + extend + ">" ); + } + + // checks on the members of a struct + checkStructMemberCorrectness( structure.first, structure.second.members, sTypeValues ); + } + + // enum VkStructureType checks (need to be after structure checks because of sTypeValues gathered there) + auto structureTypeIt = m_enums.find( "VkStructureType" ); + assert( structureTypeIt != m_enums.end() ); + for ( auto const & enumValue : structureTypeIt->second.values ) + { + if ( ( enumValue.name == "VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO" ) || + ( enumValue.name == "VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO" ) ) + { + check( sTypeValues.find( enumValue.name ) == sTypeValues.end(), + enumValue.xmlLine, + "Reserved VkStructureType enum value <" + enumValue.name + "> is used" ); + } + else + { + check( sTypeValues.erase( enumValue.name ) == 1, + enumValue.xmlLine, + "VkStructureType enum value <" + enumValue.name + "> never used" ); + } + } + assert( sTypeValues.empty() ); +} + +void VulkanHppGenerator::checkStructMemberCorrectness( std::string const & structureName, + std::vector const & members, + std::set & sTypeValues ) const +{ + for ( auto const & member : members ) + { + // if a member specifies a selector, that member is a union and the selector is an enum + // check that there's a 1-1 connection between the specified selections and the values of that enum + if ( !member.selector.empty() ) + { + std::string const & selector = member.selector; + auto selectorIt = std::find_if( + members.begin(), members.end(), [&selector]( MemberData const & md ) { return md.name == selector; } ); + assert( selectorIt != members.end() ); + auto selectorEnumIt = m_enums.find( selectorIt->type.type ); + assert( selectorEnumIt != m_enums.end() ); + auto unionIt = m_structures.find( member.type.type ); + assert( ( unionIt != m_structures.end() ) && unionIt->second.isUnion ); + for ( auto const & unionMember : unionIt->second.members ) + { + // check that each union member has a selection, that is a value of the seleting enum + assert( !unionMember.selection.empty() ); + std::string const & selection = unionMember.selection; + check( std::find_if( selectorEnumIt->second.values.begin(), + selectorEnumIt->second.values.end(), + [&selection]( EnumValueData const & evd ) + { return evd.name == selection; } ) != selectorEnumIt->second.values.end(), + unionMember.xmlLine, + "union member <" + unionMember.name + "> uses selection <" + selection + + "> that is not part of the selector type <" + selectorIt->type.type + ">" ); + } + for ( auto const & selectorValue : selectorEnumIt->second.values ) + { + // check that each enum value is used as a selection in the corresponding union + check( std::find_if( unionIt->second.members.begin(), + unionIt->second.members.end(), + [selectorValue]( MemberData const & md ) + { return md.selection == selectorValue.name; } ) != unionIt->second.members.end(), + selectorEnumIt->second.xmlLine, + "enum <" + selectorEnumIt->first + "> has value <" + selectorValue.name + + "> that is not used by corresponding union <" + unionIt->first + ">" ); + } + } + + // check that each member type is known + check( m_types.find( member.type.type ) != m_types.end(), + member.xmlLine, + "struct member uses unknown type <" + member.type.type + ">" ); + + // check that any used constant is a known constant + if ( !member.usedConstant.empty() ) + { + check( m_constants.find( member.usedConstant ) != m_constants.end(), + member.xmlLine, + "struct member array size uses unknown constant <" + member.usedConstant + ">" ); + } + + // checks if a value is specified + if ( !member.value.empty() ) + { + auto enumIt = m_enums.find( member.type.type ); + if ( enumIt != m_enums.end() ) + { + // check that the value exists in the specified enum + check( std::find_if( enumIt->second.values.begin(), + enumIt->second.values.end(), + [&member]( auto const & evd ) + { return member.value == evd.name; } ) != enumIt->second.values.end(), + member.xmlLine, + "value <" + member.value + "> for member <" + member.name + "> in structure <" + structureName + + "> of enum type <" + member.type.type + "> not listed" ); + // special handling for sType: no value should appear more than once + if ( member.name == "sType" ) + { + check( sTypeValues.insert( member.value ).second, + member.xmlLine, + "sType value <" + member.value + "> has been used before" ); + } + } + else if ( member.type.type == "uint32_t" ) + { + // check that a value for a uint32_t is all digits + check( member.value.find_first_not_of( "0123456789" ) == std::string::npos, + member.xmlLine, + "value <" + member.value + "> for member <" + member.name + "> in structure <" + structureName + + "> of type <" + member.type.type + "> is not a number" ); + } + else + { + // don't know the type of the value -> error out + check( false, + member.xmlLine, + "member <" + member.name + "> in structure <" + structureName + "> holds value <" + member.value + + "> for an unhandled type <" + member.type.type + ">" ); + } + } + } +} + bool VulkanHppGenerator::containsArray( std::string const & type ) const { // a simple recursive check if a type is or contains an array @@ -1518,6 +1545,23 @@ bool VulkanHppGenerator::containsUnion( std::string const & type ) const return found; } +std::vector VulkanHppGenerator::determineConstPointerParamIndices( std::vector const & params ) const +{ + std::vector constPointerParamIndices; + + for ( size_t i = 0; i < params.size(); i++ ) + { + // very special handling for some types, which come in as non-const pointers, but are meant as const-pointers + if ( params[i].type.isConstPointer() || + ( params[i].type.isNonConstPointer() && + ( specialPointerTypes.find( params[i].type.type ) != specialPointerTypes.end() ) ) ) + { + constPointerParamIndices.push_back( i ); + } + } + return constPointerParamIndices; +} + size_t VulkanHppGenerator::determineDefaultStartIndex( std::vector const & params, std::set const & skippedParams ) const { @@ -1555,26 +1599,42 @@ size_t VulkanHppGenerator::determineInitialSkipCount( std::string const & comman } } +std::vector + VulkanHppGenerator::determineNonConstPointerParamIndices( std::vector const & params ) const +{ + std::vector nonConstPointerParamIndices; + + for ( size_t i = 0; i < params.size(); i++ ) + { + // very special handling of parameters of some types, which always come as a non-const pointer but are not meant + // to be a potential return value! + if ( params[i].type.isNonConstPointer() && + ( specialPointerTypes.find( params[i].type.type ) == specialPointerTypes.end() ) ) + { + nonConstPointerParamIndices.push_back( i ); + } + } + return nonConstPointerParamIndices; +} + std::vector::const_iterator> VulkanHppGenerator::determineRAIIHandleConstructors( std::string const & handleType, std::map::const_iterator destructorIt, std::set & specialFunctions ) const { std::vector::const_iterator> constructorIts; + auto isConstructorCandidate = [&handleType]( std::pair const & cd ) + { + return std::find_if( cd.second.params.begin(), + cd.second.params.end(), + [&handleType]( ParamData const & pd ) { + return ( pd.type.type == handleType ) && pd.type.isNonConstPointer(); + } ) != cd.second.params.end(); + }; for ( auto commandIt = m_commands.begin(); commandIt != m_commands.end(); ) { // find the commands that get a non-const pointer to the handleType, that is, return a handle type - commandIt = - std::find_if( commandIt, - m_commands.end(), - [&handleType]( std::pair const & cd ) - { - return std::find_if( cd.second.params.begin(), - cd.second.params.end(), - [&handleType]( ParamData const & pd ) { - return ( pd.type.type == handleType ) && pd.type.isNonConstPointer(); - } ) != cd.second.params.end(); - } ); + commandIt = std::find_if( commandIt, m_commands.end(), isConstructorCandidate ); if ( commandIt != m_commands.end() ) { // only commands that provide all information needed for the destructor can be considered a constructor! @@ -1587,36 +1647,44 @@ std::vector::const_iterat destructorIt->second.params.end(), [&handleType]( ParamData const & pd ) { return pd.type.type == handleType; } ); assert( desctructorHandleParamIt != destructorIt->second.params.end() ); - // check that all destructor parameters are part of the constructor command candidate - // this commandIt is a valid candidate, if the outer find_if runs to the end of the destructor params - valid = - ( std::find_if( destructorIt->second.params.begin(), - destructorIt->second.params.end(), - [&desctructorHandleParamIt, &commandIt, this]( ParamData const & destructorParam ) - { - // return true if the destructorParam could _not_ be identified in the constructor candidate - // params, that is, if the destructorParam is not the len in the destructor, and the type - // can not be found in the constructor candidate argument list (the find_if runs to the end - // of the constructor candidate params) - return ( destructorParam.name != desctructorHandleParamIt->len ) && - ( std::find_if( commandIt->second.params.begin(), - commandIt->second.params.end(), - [&destructorParam, this]( ParamData const & pd ) - { - if ( pd.type.type != destructorParam.type.type ) - { - auto structureIt = m_structures.find( pd.type.type ); - return ( structureIt != m_structures.end() ) && - ( std::find_if( - structureIt->second.members.begin(), - structureIt->second.members.end(), - [&destructorParam]( MemberData const & md ) { - return md.type.type == destructorParam.type.type; - } ) != structureIt->second.members.end() ); - } - return true; - } ) == commandIt->second.params.end() ); - } ) == destructorIt->second.params.end() ); + + // lambda to check if a destructor parameter is a parameter of the constructor candidate + // (or it's just the len parameter, which is not needed for the constructor) + auto isConstructorCandidateParam = + [&desctructorHandleParamIt, &commandIt, this]( ParamData const & destructorParam ) + { + // check if the destructor param type equals this param type, or, if this param type is a struct, is part of + // that struct + auto isDestructorParamType = [&destructorParam, this]( ParamData const & pd ) + { + if ( pd.type.type != destructorParam.type.type ) + { + // check if the destructor param type equals a structure member type + auto isStructureMemberType = [&destructorParam]( MemberData const & md ) + { + return md.type.type == destructorParam.type.type; + }; + + auto structureIt = m_structures.find( pd.type.type ); + return ( structureIt != m_structures.end() ) && + ( std::find_if( structureIt->second.members.begin(), + structureIt->second.members.end(), + isStructureMemberType ) != structureIt->second.members.end() ); + } + return true; + }; + + return ( destructorParam.name == desctructorHandleParamIt->len ) || + ( std::find_if( commandIt->second.params.begin(), + commandIt->second.params.end(), + isDestructorParamType ) != commandIt->second.params.end() ); + }; + + // the constructor candidate is valid, if none of the (relevant) destructor parameters is missing in the + // constructor candidate params + valid = ( std::find_if_not( destructorIt->second.params.begin(), + destructorIt->second.params.end(), + isConstructorCandidateParam ) == destructorIt->second.params.end() ); } if ( valid ) { @@ -1634,6 +1702,493 @@ std::vector::const_iterat return constructorIts; } +std::map::const_iterator + VulkanHppGenerator::determineRAIIHandleDestructor( std::string const & handleType ) const +{ + std::string type = stripPrefix( handleType, "Vk" ); + auto destructorIt = m_commands.find( "vkDestroy" + type ); + if ( destructorIt == m_commands.end() ) + { + destructorIt = m_commands.find( "vkFree" + type + "s" ); + if ( destructorIt == m_commands.end() ) + { + destructorIt = m_commands.find( "vkRelease" + type ); + if ( destructorIt == m_commands.end() ) + { + if ( handleType == "VkDeviceMemory" ) + { + // special handling for vkDeviceMemory + destructorIt = m_commands.find( "vkFreeMemory" ); + assert( destructorIt != m_commands.end() ); + } + else if ( handleType == "VkDisplayKHR" ) + { + // special handling for VkDisplayKHR + destructorIt = m_commands.find( "vkReleaseDisplayEXT" ); + assert( destructorIt != m_commands.end() ); + } + else + { + assert( ( handleType == "VkDisplayModeKHR" ) || ( handleType == "VkPhysicalDevice" ) || + ( handleType == "VkQueue" ) ); + } + } + } + } + return destructorIt; +} + +std::set VulkanHppGenerator::determineSkippedParams( std::vector const & params, + size_t initialSkipCount, + std::map const & vectorParamIndices, + std::vector const & returnParamIndices, + bool singular ) const +{ + // skip the initial skips (get fed by the object) + assert( initialSkipCount <= params.size() ); + std::set skippedParams; + for ( size_t i = 0; i < initialSkipCount; ++i ) + { + skippedParams.insert( i ); + } + + // skip the size parameters (get derived from an array) + for ( auto const & vpi : vectorParamIndices ) + { + assert( !params[vpi.first].len.empty() ); + if ( ( ( std::find_if( returnParamIndices.begin(), + returnParamIndices.end(), + [&vpi]( size_t rpi ) { return vpi.first == rpi; } ) == returnParamIndices.end() ) && + isParam( params[vpi.first].len, params ) ) || + ( singular && params[vpi.second].type.isValue() ) ) + { + skippedParams.insert( vpi.second ); + } + } + + // skip the return parameters (get resolved by local variables to be returned) + skippedParams.insert( returnParamIndices.begin(), returnParamIndices.end() ); + + return skippedParams; +} + +std::string VulkanHppGenerator::determineSubStruct( std::pair const & structure ) const +{ + if ( structure.second.members.front().name != "sType" ) + { + // check if sd is a substruct of structure + auto isSubStruct = [&structure]( std::pair const & sd ) + { + // member-by-member comparison of type and name + auto memberIt = structure.second.members.begin(); + auto isMember = [&memberIt]( MemberData const & md ) + { + if ( ( md.type == memberIt->type ) && ( md.name == memberIt->name ) ) + { + ++memberIt; + return true; + } + return false; + }; + + return ( sd.second.members.size() < structure.second.members.size() ) && + ( std::find_if_not( sd.second.members.begin(), sd.second.members.end(), isMember ) == + sd.second.members.end() ); + }; + + // look for a struct in m_structures that starts identically to structure + auto structIt = std::find_if( m_structures.begin(), m_structures.end(), isSubStruct ); + return ( structIt == m_structures.end() ) ? "" : structIt->first; + } + return ""; +} + +std::map VulkanHppGenerator::determineVectorParamIndices( std::vector const & params ) const +{ + std::map vectorParamIndices; + + // look for the parameters whose len equals the name of an other parameter + for ( size_t i = 0; i < params.size(); i++ ) + { + if ( !params[i].len.empty() ) + { + for ( size_t j = 0; j < i; j++ ) + { + if ( ( params[j].name == params[i].len ) || isLenByStructMember( params[i].len, params[j] ) ) + { + // add this parameter as a vector parameter, using the len-name parameter as the second value + vectorParamIndices.insert( std::make_pair( i, j ) ); + } + } + } + } + return vectorParamIndices; +} + +void VulkanHppGenerator::distributeSecondLevelCommands( std::set const & specialFunctions ) +{ + // distribute commands from instance/device to second-level handles, like Queue, Event,... for RAII handles + for ( auto & handle : m_handles ) + { + if ( !handle.first.empty() ) + { + for ( auto command = handle.second.commands.begin(); command != handle.second.commands.end(); ) + { + bool foundCommand = false; + if ( specialFunctions.find( *command ) == specialFunctions.end() ) + { + auto commandIt = m_commands.find( *command ); + assert( commandIt != m_commands.end() ); + assert( commandIt->second.params.front().type.type == handle.first ); + if ( ( 1 < commandIt->second.params.size() ) && ( isHandleType( commandIt->second.params[1].type.type ) ) && + !commandIt->second.params[1].optional ) + { + auto handleIt = m_handles.find( commandIt->second.params[1].type.type ); + assert( handleIt != m_handles.end() ); + assert( !handleIt->second.constructorIts.empty() ); + if ( ( *handleIt->second.constructorIts.begin() )->second.handle == handle.first ) + { + assert( std::find_if( handleIt->second.constructorIts.begin(), + handleIt->second.constructorIts.end(), + [&handle]( auto const & constructorIt ) { + return constructorIt->second.handle != handle.first; + } ) == handleIt->second.constructorIts.end() ); + handleIt->second.secondLevelCommands.insert( *command ); + command = handle.second.commands.erase( command ); + foundCommand = true; + } + } + } + if ( !foundCommand ) + { + ++command; + } + } + } + } +} + +std::string VulkanHppGenerator::findBaseName( std::string aliasName, + std::map const & aliases ) const +{ + std::string baseName = aliasName; + auto aliasIt = aliases.find( baseName ); + while ( aliasIt != aliases.end() ) + { + baseName = aliasIt->second.name; + aliasIt = aliases.find( baseName ); + } + return baseName; +} + +std::string VulkanHppGenerator::generateArgumentEnhancedConstPointer( ParamData const & param, + bool definition, + bool withAllocators, +#if !defined( NDEBUG ) + bool withDispatcher, +#endif + bool & hasDefaultAssignment ) const +{ + std::string argument; + std::string name = startLowerCase( stripPrefix( param.name, "p" ) ); + if ( param.len.empty() ) + { + assert( withDispatcher || !isHandleType( param.type.type ) ); + assert( !param.type.prefix.empty() && ( param.type.postfix == "*" ) ); + assert( param.arraySizes.empty() ); + if ( param.type.type == "void" ) + { + assert( !param.optional ); + argument = param.type.compose() + " " + param.name; + } + else if ( param.optional ) + { + argument = "Optional " + name + + ( ( definition || withAllocators ) ? "" : " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT" ); + hasDefaultAssignment = true; + } + else + { + argument = param.type.prefix + " " + stripPrefix( param.type.type, "Vk" ) + " & " + name; + } + } + else + { + // a const-pointer with a non-empty len is either null-terminated (aka a string) or represented by an + // ArrayProxy + assert( param.arraySizes.empty() ); + if ( param.len == "null-terminated" ) + { + assert( param.type.type == "char" ); + if ( param.optional ) + { + argument = "Optional " + name + + ( ( definition || withAllocators ) ? "" : " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT" ); + hasDefaultAssignment = true; + } + else + { + argument = "const std::string & " + name; + } + } + else + { + // an ArrayProxy also covers no data, so any optiona flag can be ignored here + assert( endsWith( param.type.postfix, "*" ) ); + std::string type = stripPostfix( param.type.compose(), "*" ); + size_t pos = type.find( "void" ); + if ( pos != std::string::npos ) + { + type.replace( pos, 4, "T" ); + } + argument = "ArrayProxy<" + type + "> const & " + name; + if ( param.optional && !definition ) + { + argument += " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT"; + hasDefaultAssignment = true; + } + } + } + return argument; +} + +std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector const & params, + std::set const & skippedParams, + std::set const & singularParams, + bool definition, + bool withAllocators, + bool structureChain, + bool withDispatcher ) const +{ + size_t defaultStartIndex = withAllocators ? ~0 : determineDefaultStartIndex( params, skippedParams ); + + std::string argumentList; + bool encounteredArgument = false; + for ( size_t i = 0; i < params.size(); ++i ) + { + if ( skippedParams.find( i ) == skippedParams.end() ) + { + if ( encounteredArgument ) + { + argumentList += ", "; + } + bool hasDefaultAssignment = false; + if ( singularParams.find( i ) != singularParams.end() ) + { + assert( !params[i].optional ); + assert( params[i].type.isConstPointer() && !params[i].len.empty() && + !isLenByStructMember( params[i].len, params ) && beginsWith( params[i].type.type, "Vk" ) ); + assert( !isHandleType( params[i].type.type ) ); + argumentList += "const VULKAN_HPP_NAMESPACE::" + stripPrefix( params[i].type.type, "Vk" ) + " & " + + stripPluralS( startLowerCase( stripPrefix( params[i].name, "p" ) ) ); + } + else if ( params[i].type.isConstPointer() ) + { + argumentList += generateArgumentEnhancedConstPointer( params[i], + definition, + withAllocators, +#if !defined( NDEBUG ) + withDispatcher, +#endif + hasDefaultAssignment ); + } + else if ( params[i].type.isNonConstPointer() ) + { + assert( withDispatcher || !isHandleType( params[i].type.type ) ); + assert( params[i].len.empty() && !params[i].optional ); + argumentList += params[i].type.prefix + ( params[i].type.prefix.empty() ? "" : " " ) + params[i].type.type + + " & " + params[i].name; + } + else + { + assert( params[i].type.isValue() ); + argumentList += params[i].type.compose() + " " + params[i].name + generateCArraySizes( params[i].arraySizes ); + } + argumentList += std::string( !definition && ( defaultStartIndex <= i ) && !hasDefaultAssignment + ? " VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT" + : "" ); + encounteredArgument = true; + } + } + if ( withAllocators ) + { + if ( structureChain ) + { + if ( encounteredArgument ) + { + argumentList += ", "; + } + argumentList += "StructureChainAllocator & structureChainAllocator"; + encounteredArgument = true; + } + else + { + for ( auto sp : skippedParams ) + { + if ( !params[sp].len.empty() ) + { + if ( encounteredArgument ) + { + argumentList += ", "; + } + std::string type = ( params[sp].type.type == "void" ) + ? "Uint8_t" + : startUpperCase( stripPrefix( params[sp].type.type, "Vk" ) ); + argumentList += type + "Allocator & " + startLowerCase( type ) + "Allocator"; + encounteredArgument = true; + } + } + } + } + if ( withDispatcher ) + { + if ( encounteredArgument ) + { + argumentList += ", "; + } + argumentList += + std::string( "Dispatch const & d" ) + ( definition ? "" : " VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT" ); + } + return argumentList; +} + +std::string VulkanHppGenerator::generateArgumentListStandard( std::vector const & params, + std::set const & skippedParams ) const +{ + std::string argumentList; + for ( size_t i = 0; i < params.size(); ++i ) + { + if ( skippedParams.find( i ) == skippedParams.end() ) + { + argumentList += + params[i].type.compose() + " " + params[i].name + generateCArraySizes( params[i].arraySizes ) + ", "; + } + } + argumentList += "Dispatch const & d "; + return argumentList; +} + +std::string VulkanHppGenerator::generateBitmask( std::map::const_iterator bitmaskIt ) const +{ + auto bitmaskBitsIt = m_enums.find( bitmaskIt->second.requirements ); + assert( bitmaskBitsIt != m_enums.end() ); + + std::string strippedBitmaskName = stripPrefix( bitmaskIt->first, "Vk" ); + std::string strippedEnumName = stripPrefix( bitmaskBitsIt->first, "Vk" ); + + // each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter + std::string str = "\n using " + strippedBitmaskName + " = Flags<" + strippedEnumName + ">;\n"; + + std::string alias = + bitmaskIt->second.alias.empty() + ? "" + : ( "\n using " + stripPrefix( bitmaskIt->second.alias, "Vk" ) + " = " + strippedBitmaskName + ";\n" ); + + if ( bitmaskBitsIt->second.values.empty() ) + { + static std::string bitmaskValuesTemplate = R"(${alias} + VULKAN_HPP_INLINE std::string to_string( ${bitmaskName} ) + { + return "{}"; + } +)"; + str += replaceWithMap( bitmaskValuesTemplate, { { "alias", alias }, { "bitmaskName", strippedBitmaskName } } ); + } + else + { + static const std::string bitmaskValuesTemplate = R"( + template <> struct FlagTraits<${enumName}> + { + enum : ${bitmaskType} + { + allFlags = ${allFlags} + }; + }; + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator|( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT + { + return ${bitmaskName}( bit0 ) | bit1; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator&( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT + { + return ${bitmaskName}( bit0 ) & bit1; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator^( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT + { + return ${bitmaskName}( bit0 ) ^ bit1; + } + + VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator~( ${enumName} bits ) VULKAN_HPP_NOEXCEPT + { + return ~( ${bitmaskName}( bits ) ); + } +${alias} + VULKAN_HPP_INLINE std::string to_string( ${bitmaskName} value ) + { + if ( !value ) + return "{}"; + + std::string result; +${toStringChecks} + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; + } +)"; + + std::string allFlags, toStringChecks; + std::tie( allFlags, toStringChecks ) = generateBitmaskValues( bitmaskIt, bitmaskBitsIt ); + + str += replaceWithMap( bitmaskValuesTemplate, + { { "alias", alias }, + { "allFlags", allFlags }, + { "bitmaskName", strippedBitmaskName }, + { "bitmaskType", bitmaskIt->second.type }, + { "enumName", strippedEnumName }, + { "toStringChecks", toStringChecks } } ); + } + + return str; +} + +std::pair + VulkanHppGenerator::generateBitmaskValues( std::map::const_iterator bitmaskIt, + std::map::const_iterator bitmaskBitsIt ) const +{ + assert( !bitmaskBitsIt->second.values.empty() ); + + std::string allFlags, toStringChecks; + std::string strippedEnumName = stripPrefix( bitmaskBitsIt->first, "Vk" ); + bool encounteredFlag = false; + std::string previousEnter, previousLeave; + for ( auto const & value : bitmaskBitsIt->second.values ) + { + std::string enter, leave; + std::tie( enter, leave ) = generateProtection( value.extension, value.protect ); + std::string valueName = generateEnumValueName( bitmaskBitsIt->first, value.name, true, m_tags ); + allFlags += ( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " + + ( encounteredFlag ? "| " : " " ) + bitmaskIt->second.type + "( " + strippedEnumName + + "::" + valueName + " )"; + if ( value.singleBit ) + { + toStringChecks += ( ( previousEnter != enter ) ? ( previousLeave + enter ) : "" ) + " if ( value & " + + strippedEnumName + "::" + valueName + " ) result += \"" + valueName.substr( 1 ) + " | \";\n"; + } + encounteredFlag = true; + previousEnter = enter; + previousLeave = leave; + } + if ( !previousLeave.empty() ) + { + assert( endsWith( previousLeave, "\n" ) ); + toStringChecks += previousLeave; + previousLeave.resize( previousLeave.size() - strlen( "\n" ) ); + allFlags += "\n" + previousLeave; + } + + return std::make_pair( allFlags, toStringChecks ); +} + // // VulkanHppGenerator local functions // @@ -1745,29 +2300,6 @@ std::set determineSingularParams( size_t returnParamIndex, std::map determineSkippedParams( size_t returnParamIndex, std::map const & vectorParamIndices ) -{ - std::set skippedParams; - - // the size-parameters of vector parameters are not explicitly used in the enhanced API - std::for_each( vectorParamIndices.begin(), - vectorParamIndices.end(), - [&skippedParams]( std::pair const & vp ) - { - if ( vp.second != INVALID_INDEX ) - { - skippedParams.insert( vp.second ); - } - } ); - - // and the return parameter is also skipped - if ( returnParamIndex != INVALID_INDEX ) - { - skippedParams.insert( returnParamIndex ); - } - return skippedParams; -} - std::string findTag( std::set const & tags, std::string const & name, std::string const & postfix ) { auto tagIt = std::find_if( @@ -2236,7 +2768,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionValue0Return( std::map::const_iterator commandIt, size_t initialSkipCount, bool definition ) const { std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); if ( beginsWith( commandIt->second.returnType, "Vk" ) ) { function = generateRAIIHandleMemberFunctionVkType( commandIt, initialSkipCount, vectorParamIndices, definition ); @@ -2283,562 +2815,6 @@ void VulkanHppGenerator::EnumData::addEnumValue( } } -std::map::const_iterator - VulkanHppGenerator::determineRAIIHandleDestructor( std::string const & handleType ) const -{ - std::string type = stripPrefix( handleType, "Vk" ); - auto destructorIt = m_commands.find( "vkDestroy" + type ); - if ( destructorIt == m_commands.end() ) - { - destructorIt = m_commands.find( "vkFree" + type + "s" ); - if ( destructorIt == m_commands.end() ) - { - destructorIt = m_commands.find( "vkRelease" + type ); - if ( destructorIt == m_commands.end() ) - { - if ( handleType == "VkDeviceMemory" ) - { - // special handling for vkDeviceMemory - destructorIt = m_commands.find( "vkFreeMemory" ); - assert( destructorIt != m_commands.end() ); - } - else if ( handleType == "VkDisplayKHR" ) - { - // special handling for VkDisplayKHR - destructorIt = m_commands.find( "vkReleaseDisplayEXT" ); - assert( destructorIt != m_commands.end() ); - } - else - { - assert( ( handleType == "VkDisplayModeKHR" ) || ( handleType == "VkPhysicalDevice" ) || - ( handleType == "VkQueue" ) ); - } - } - } - } - return destructorIt; -} - -size_t VulkanHppGenerator::determineReturnParamIndex( CommandData const & commandData, - std::map const & vectorParamIndices, - bool twoStep ) const -{ -#if !defined( NDEBUG ) - for ( auto vpi : vectorParamIndices ) - { - assert( ( vpi.first != vpi.second ) && ( vpi.first < commandData.params.size() ) && - ( ( vpi.second == INVALID_INDEX ) || ( vpi.second < commandData.params.size() ) ) ); - } -#endif - - size_t returnParamIndex = INVALID_INDEX; - // for return types of type VkResult or void, we can determine a parameter to return - if ( ( commandData.returnType == "VkResult" ) || ( commandData.returnType == "void" ) ) - { - size_t index = commandData.params.size() - 1; - if ( ( commandData.params[index].type.postfix.find( '*' ) != std::string::npos ) && - ( ( commandData.params[index].type.type != "void" ) || twoStep || - ( commandData.params[index].type.postfix.find( "**" ) != std::string::npos ) ) && - ( commandData.params[index].type.prefix.find( "const" ) == std::string::npos ) ) - { - // it's a non-const pointer - // assert that it's not a vector-size parameter - assert( std::find_if( vectorParamIndices.begin(), - vectorParamIndices.end(), - [index]( std::pair const & vpi ) - { return vpi.second == index; } ) == vectorParamIndices.end() ); - - std::map::const_iterator vpit = vectorParamIndices.find( index ); - if ( ( vpit == vectorParamIndices.end() ) || twoStep || ( vectorParamIndices.size() > 1 ) || - ( vpit->second == INVALID_INDEX ) ) - { - // 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 - // -> return the index of the selcted parameter - returnParamIndex = index; - } - } - } - - return returnParamIndex; -} - -std::set VulkanHppGenerator::determineSkippedParams( std::vector const & params, - size_t initialSkipCount, - std::map const & vectorParamIndices, - std::vector const & returnParamIndices, - bool singular ) const -{ - assert( initialSkipCount <= params.size() ); - std::set skippedParams; - for ( size_t i = 0; i < initialSkipCount; ++i ) - { - skippedParams.insert( i ); - } - - for ( auto const & vpi : vectorParamIndices ) - { - assert( !params[vpi.first].len.empty() ); - if ( ( ( std::find_if( returnParamIndices.begin(), - returnParamIndices.end(), - [&vpi]( size_t rpi ) { return vpi.first == rpi; } ) == returnParamIndices.end() ) && - isParam( params[vpi.first].len, params ) ) || - ( singular && params[vpi.second].type.isValue() ) ) - { - skippedParams.insert( vpi.second ); - } - } - - skippedParams.insert( returnParamIndices.begin(), returnParamIndices.end() ); - - return skippedParams; -} - -std::string VulkanHppGenerator::determineSubStruct( std::pair const & structure ) const -{ - for ( auto const & s : m_structures ) - { - if ( ( s.first != structure.first ) && ( s.second.members.size() < structure.second.members.size() ) && - ( s.second.members[0].name != "sType" ) ) - { - bool equal = true; - for ( size_t i = 0; i < s.second.members.size() && equal; i++ ) - { - equal = ( s.second.members[i].type == structure.second.members[i].type ) && - ( s.second.members[i].name == structure.second.members[i].name ); - } - if ( equal ) - { - return s.first; - } - } - } - return ""; -} - -std::vector VulkanHppGenerator::determineConstPointerParamIndices( std::vector const & params ) const -{ - std::vector constPointerParamIndices; - - for ( size_t i = 0; i < params.size(); i++ ) - { - // very special handling for some types, which come in as non-const pointers, but are meant as const-pointers - if ( params[i].type.isConstPointer() || - ( params[i].type.isNonConstPointer() && - ( specialPointerTypes.find( params[i].type.type ) != specialPointerTypes.end() ) ) ) - { - constPointerParamIndices.push_back( i ); - } - } - return constPointerParamIndices; -} - -std::vector - VulkanHppGenerator::determineNonConstPointerParamIndices( std::vector const & params ) const -{ - std::vector nonConstPointerParamIndices; - - for ( size_t i = 0; i < params.size(); i++ ) - { - // very special handling of parameters of some types, which always come as a non-const pointer but are not meant - // to be a potential return value! - if ( params[i].type.isNonConstPointer() && - ( specialPointerTypes.find( params[i].type.type ) == specialPointerTypes.end() ) ) - { - nonConstPointerParamIndices.push_back( i ); - } - } - return nonConstPointerParamIndices; -} - -std::map - VulkanHppGenerator::determineVectorParamIndicesNew( std::vector const & params ) const -{ - std::map vectorParamIndices; - - // look for the parameters whose len equals the name of an other parameter - for ( auto it = params.begin(); it != params.end(); ++it ) - { - if ( !it->len.empty() ) - { - auto findIt = std::find_if( params.begin(), - it, - [this, &it]( ParamData const & pd ) - { return ( pd.name == it->len ) || isLenByStructMember( it->len, pd ); } ); - - if ( findIt < it ) - { - // add this parameter as a vector parameter, using the len-name parameter as the second value - vectorParamIndices.insert( - std::make_pair( std::distance( params.begin(), it ), std::distance( params.begin(), findIt ) ) ); - } - } - } - return vectorParamIndices; -} - -void VulkanHppGenerator::distributeSecondLevelCommands( std::set const & specialFunctions ) -{ - for ( auto & handle : m_handles ) - { - if ( !handle.first.empty() ) - { - for ( auto command = handle.second.commands.begin(); command != handle.second.commands.end(); ) - { - bool foundCommand = false; - if ( specialFunctions.find( *command ) == specialFunctions.end() ) - { - auto commandIt = m_commands.find( *command ); - assert( commandIt != m_commands.end() ); - assert( commandIt->second.params.front().type.type == handle.first ); - if ( ( 1 < commandIt->second.params.size() ) && ( isHandleType( commandIt->second.params[1].type.type ) ) && - !commandIt->second.params[1].optional ) - { - auto handleIt = m_handles.find( commandIt->second.params[1].type.type ); - assert( handleIt != m_handles.end() ); - assert( !handleIt->second.constructorIts.empty() ); - if ( ( *handleIt->second.constructorIts.begin() )->second.handle == handle.first ) - { - assert( std::find_if( handleIt->second.constructorIts.begin(), - handleIt->second.constructorIts.end(), - [&handle]( auto const & constructorIt ) { - return constructorIt->second.handle != handle.first; - } ) == handleIt->second.constructorIts.end() ); - handleIt->second.secondLevelCommands.insert( *command ); - command = handle.second.commands.erase( command ); - foundCommand = true; - } - } - } - if ( !foundCommand ) - { - ++command; - } - } - } - } -} - -std::string VulkanHppGenerator::findBaseName( std::string aliasName, - std::map const & aliases ) const -{ - std::string baseName = aliasName; - auto aliasIt = aliases.find( baseName ); - while ( aliasIt != aliases.end() ) - { - baseName = aliasIt->second.name; - aliasIt = aliases.find( baseName ); - } - return baseName; -} - -std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector const & params, - std::set const & skippedParams, - std::set const & singularParams, - bool definition, - bool withAllocators, - bool structureChain, - bool withDispatcher ) const -{ - size_t defaultStartIndex = withAllocators ? ~0 : determineDefaultStartIndex( params, skippedParams ); - - std::string argumentList; - bool encounteredArgument = false; - for ( size_t i = 0; i < params.size(); ++i ) - { - if ( skippedParams.find( i ) == skippedParams.end() ) - { - if ( encounteredArgument ) - { - argumentList += ", "; - } - bool hasDefaultAssignment = false; - if ( singularParams.find( i ) != singularParams.end() ) - { - assert( !params[i].optional ); - assert( params[i].type.isConstPointer() && !params[i].len.empty() && - !isLenByStructMember( params[i].len, params ) && beginsWith( params[i].type.type, "Vk" ) ); - assert( !isHandleType( params[i].type.type ) ); - argumentList += "const VULKAN_HPP_NAMESPACE::" + stripPrefix( params[i].type.type, "Vk" ) + " & " + - stripPluralS( startLowerCase( stripPrefix( params[i].name, "p" ) ) ); - } - else if ( params[i].type.isConstPointer() ) - { - std::string name = startLowerCase( stripPrefix( params[i].name, "p" ) ); - if ( params[i].len.empty() ) - { - assert( withDispatcher || !isHandleType( params[i].type.type ) ); - assert( !params[i].type.prefix.empty() && ( params[i].type.postfix == "*" ) ); - assert( params[i].arraySizes.empty() ); - if ( params[i].type.type == "void" ) - { - assert( !params[i].optional ); - argumentList += params[i].type.compose() + " " + params[i].name; - } - else if ( params[i].optional ) - { - argumentList += - "Optional " + name + - ( ( definition || withAllocators ) ? "" : " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT" ); - hasDefaultAssignment = true; - } - else - { - argumentList += params[i].type.prefix + " " + stripPrefix( params[i].type.type, "Vk" ) + " & " + name; - } - } - else - { - // a const-pointer with a non-empty len is either null-terminated (aka a string) or represented by an - // ArrayProxy - assert( params[i].arraySizes.empty() ); - if ( params[i].len == "null-terminated" ) - { - assert( params[i].type.type == "char" ); - if ( params[i].optional ) - { - argumentList += - "Optional " + name + - ( ( definition || withAllocators ) ? "" : " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT" ); - hasDefaultAssignment = true; - } - else - { - argumentList += "const std::string & " + name; - } - } - else - { - // an ArrayProxy also covers no data, so any optiona flag can be ignored here - assert( endsWith( params[i].type.postfix, "*" ) ); - std::string type = stripPostfix( params[i].type.compose(), "*" ); - size_t pos = type.find( "void" ); - if ( pos != std::string::npos ) - { - type.replace( pos, 4, "T" ); - } - argumentList += "ArrayProxy<" + type + "> const & " + name; - if ( params[i].optional && !definition ) - { - argumentList += " VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT"; - hasDefaultAssignment = true; - } - } - } - } - else if ( params[i].type.isNonConstPointer() ) - { - assert( withDispatcher || !isHandleType( params[i].type.type ) ); - assert( params[i].len.empty() && !params[i].optional ); - if ( !params[i].type.prefix.empty() ) - { - argumentList += params[i].type.prefix + " "; - } - argumentList += params[i].type.type + " & " + params[i].name; - } - else - { - assert( params[i].type.isValue() ); - argumentList += params[i].type.compose() + " " + params[i].name + generateCArraySizes( params[i].arraySizes ); - } - argumentList += std::string( !definition && ( defaultStartIndex <= i ) && !hasDefaultAssignment - ? " VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT" - : "" ); - encounteredArgument = true; - } - } - if ( withAllocators ) - { - if ( structureChain ) - { - if ( encounteredArgument ) - { - argumentList += ", "; - } - argumentList += "StructureChainAllocator & structureChainAllocator"; - encounteredArgument = true; - } - else - { - for ( auto sp : skippedParams ) - { - if ( !params[sp].len.empty() ) - { - if ( encounteredArgument ) - { - argumentList += ", "; - } - std::string type = ( params[sp].type.type == "void" ) - ? "Uint8_t" - : startUpperCase( stripPrefix( params[sp].type.type, "Vk" ) ); - argumentList += type + "Allocator & " + startLowerCase( type ) + "Allocator"; - encounteredArgument = true; - } - } - } - } - if ( withDispatcher ) - { - if ( encounteredArgument ) - { - argumentList += ", "; - } - argumentList += - std::string( "Dispatch const & d" ) + ( definition ? "" : " VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT" ); - } - return argumentList; -} - -std::string VulkanHppGenerator::generateArgumentListStandard( std::vector const & params, - std::set const & skippedParams ) const -{ - std::string argumentList; - for ( size_t i = 0; i < params.size(); ++i ) - { - if ( skippedParams.find( i ) == skippedParams.end() ) - { - argumentList += - params[i].type.compose() + " " + params[i].name + generateCArraySizes( params[i].arraySizes ) + ", "; - } - } - argumentList += "Dispatch const & d "; - return argumentList; -} - -std::string VulkanHppGenerator::generateBitmask( std::map::const_iterator bitmaskIt ) const -{ - auto bitmaskBits = m_enums.find( bitmaskIt->second.requirements ); - bool hasBits = ( bitmaskBits != m_enums.end() ); - check( bitmaskIt->second.requirements.empty() || hasBits, - bitmaskIt->second.xmlLine, - "bitmask <" + bitmaskIt->first + "> references the undefined requires <" + bitmaskIt->second.requirements + - ">" ); - - std::string strippedBitmaskName = stripPrefix( bitmaskIt->first, "Vk" ); - std::string strippedEnumName = hasBits ? stripPrefix( bitmaskBits->first, "Vk" ) : ""; - - // each Flags class is using the class 'Flags' with the corresponding FlagBits enum as the template parameter - std::string str = "\n using " + strippedBitmaskName + " = Flags<" + strippedEnumName + ">;\n"; - - if ( !bitmaskBits->second.values.empty() ) - { - std::string allFlags; - bool encounteredFlag = false; - std::string previousEnter, previousLeave; - for ( auto const & value : bitmaskBits->second.values ) - { - std::string enter, leave; - std::tie( enter, leave ) = generateProtection( value.extension, value.protect ); - std::string valueName = generateEnumValueName( bitmaskBits->first, value.name, true, m_tags ); - allFlags += ( ( previousEnter != enter ) ? ( "\n" + previousLeave + enter ) : "\n" ) + " " + - ( encounteredFlag ? "| " : " " ) + bitmaskIt->second.type + "( " + strippedEnumName + - "::" + valueName + " )"; - encounteredFlag = true; - previousEnter = enter; - previousLeave = leave; - } - if ( !previousLeave.empty() ) - { - assert( endsWith( previousLeave, "\n" ) ); - previousLeave.resize( previousLeave.size() - strlen( "\n" ) ); - allFlags += "\n" + previousLeave; - } - - static const std::string bitmaskOperatorsTemplate = R"( - template <> struct FlagTraits<${enumName}> - { - enum : ${bitmaskType} - { - allFlags = ${allFlags} - }; - }; - - VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator|( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT - { - return ${bitmaskName}( bit0 ) | bit1; - } - - VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator&( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT - { - return ${bitmaskName}( bit0 ) & bit1; - } - - VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator^( ${enumName} bit0, ${enumName} bit1 ) VULKAN_HPP_NOEXCEPT - { - return ${bitmaskName}( bit0 ) ^ bit1; - } - - VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR ${bitmaskName} operator~( ${enumName} bits ) VULKAN_HPP_NOEXCEPT - { - return ~( ${bitmaskName}( bits ) ); - } -)"; - - str += replaceWithMap( bitmaskOperatorsTemplate, - { { "bitmaskName", strippedBitmaskName }, - { "bitmaskType", bitmaskIt->second.type }, - { "enumName", strippedEnumName }, - { "allFlags", allFlags } } ); - } - - if ( !bitmaskIt->second.alias.empty() ) - { - str += - "\n" - " using " + - stripPrefix( bitmaskIt->second.alias, "Vk" ) + " = " + strippedBitmaskName + ";\n"; - } - - // generate the to_string functions for bitmasks - str += - "\n" - " VULKAN_HPP_INLINE std::string to_string( " + - strippedBitmaskName + ( bitmaskBits->second.values.empty() ? " " : " value " ) + - " )\n" - " {\n"; - - if ( bitmaskBits->second.values.empty() ) - { - str += " return \"{}\";\n"; - } - else - { - // 'or' together all the bits in the value - str += - " if ( !value ) return \"{}\";\n\n" - " std::string result;\n"; - std::string previousEnter, previousLeave; - for ( auto const & evd : bitmaskBits->second.values ) - { - if ( evd.singleBit ) - { - std::string enter, leave; - std::tie( enter, leave ) = generateProtection( evd.extension, evd.protect ); - std::string valueName = generateEnumValueName( bitmaskBits->first, evd.name, true, m_tags ); - if ( previousEnter != enter ) - { - str += previousLeave + enter; - } - str += " if ( value & " + strippedEnumName + "::" + valueName + " ) result += \"" + valueName.substr( 1 ) + - " | \";\n"; - previousEnter = enter; - previousLeave = leave; - } - } - if ( !previousLeave.empty() ) - { - assert( endsWith( previousLeave, "\n" ) ); - previousLeave.resize( previousLeave.size() - strlen( "\n" ) ); - str += previousLeave + "\n"; - } - str += " return \"{ \" + result.substr(0, result.size() - 3) + \" }\";\n"; - } - - str += " }\n"; - - return str; -} - std::string VulkanHppGenerator::generateBitmasks( std::vector const & requireData, std::set & listedBitmasks, std::string const & title ) const @@ -3442,7 +3418,7 @@ std::string VulkanHppGenerator::generateCommandResult0Return( std::string const size_t initialSkipCount, bool definition ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); std::vector constPointerParamIndices = determineConstPointerParamIndices( commandData.params ); if ( vectorParamIndices.empty() && std::find_if( constPointerParamIndices.begin(), @@ -3469,7 +3445,7 @@ std::string VulkanHppGenerator::generateCommandResult1Return( std::string const bool definition, size_t returnParamIndex ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); if ( isHandleType( commandData.params[returnParamIndex].type.type ) ) { // get handle(s) @@ -3548,7 +3524,7 @@ std::string VulkanHppGenerator::generateCommandResult2Return( std::string const { assert( returnParamIndices.size() == 2 ); - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); if ( !isHandleType( commandData.params[returnParamIndices[0]].type.type ) && !isStructureChainAnchor( commandData.params[returnParamIndices[0]].type.type ) ) { @@ -3603,7 +3579,7 @@ std::string VulkanHppGenerator::generateCommandResult3Return( std::string const { assert( returnParamIndices.size() == 3 ); - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); if ( ( vectorParamIndices.size() == 2 ) && ( vectorParamIndices.begin()->second == returnParamIndices[0] ) && ( vectorParamIndices.begin()->first == returnParamIndices[1] ) && ( std::next( vectorParamIndices.begin() )->first == returnParamIndices[2] ) ) @@ -3969,13 +3945,20 @@ std::string VulkanHppGenerator::generateCommandResultEnumerateTwoVectorsDeprecat std::map const & vectorParamIndices, bool withAllocators ) const { - size_t returnParamIndex = determineReturnParamIndex( commandData, vectorParamIndices, true ); + std::vector rpis = determineNonConstPointerParamIndices( commandData.params ); + assert( !rpis.empty() && ( rpis.back() + 1 == commandData.params.size() ) ); + size_t returnParamIndex = rpis.back(); - std::string argumentList = generateFunctionHeaderArgumentsEnhanced( - commandData, returnParamIndex, returnParamIndex, vectorParamIndices, !definition, withAllocators ); - std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, m_tags ); - std::string nodiscard = generateNoDiscard( 1 < commandData.successCodes.size(), 1 < commandData.errorCodes.size() ); - std::string returnType = generateEnhancedReturnType( commandData, returnParamIndex, false ); + std::string argumentList = generateFunctionHeaderArgumentsEnhanced( commandData, + returnParamIndex, + returnParamIndex, + initialSkipCount, + vectorParamIndices, + !definition, + withAllocators ); + std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, m_tags ); + std::string nodiscard = generateNoDiscard( 1 < commandData.successCodes.size(), 1 < commandData.errorCodes.size() ); + std::string returnType = generateEnhancedReturnType( commandData, returnParamIndex, false ); std::string templateType = stripPrefix( commandData.params[returnParamIndex].type.type, "Vk" ); if ( definition ) @@ -4417,7 +4400,7 @@ std::string assert( ( vectorParamIndices.find( returnParamIndex ) == vectorParamIndices.end() ) ); std::string argumentList = generateFunctionHeaderArgumentsEnhanced( - commandData, returnParamIndex, INVALID_INDEX, vectorParamIndices, !definition, false ); + commandData, returnParamIndex, INVALID_INDEX, initialSkipCount, vectorParamIndices, !definition, false ); std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, m_tags ); std::string nodiscard = generateNoDiscard( 1 < commandData.successCodes.size(), 1 < commandData.errorCodes.size() ); @@ -4724,7 +4707,7 @@ std::string assert( commandData.returnType == "VkResult" ); std::string argumentList = generateFunctionHeaderArgumentsEnhanced( - commandData, INVALID_INDEX, returnParamIndex, vectorParamIndices, !definition, false ); + commandData, INVALID_INDEX, returnParamIndex, initialSkipCount, vectorParamIndices, !definition, false ); std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, m_tags ); std::string nodiscard = generateNoDiscard( 1 < commandData.successCodes.size(), 1 < commandData.errorCodes.size() ); std::string returnType = generateReturnType( commandData, "void" ); @@ -5909,7 +5892,7 @@ std::string VulkanHppGenerator::generateCommandValue0Return( std::string const & size_t initialSkipCount, bool definition ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); std::vector constPointerParamIndices = determineConstPointerParamIndices( commandData.params ); if ( vectorParamIndices.empty() && std::find_if( constPointerParamIndices.begin(), constPointerParamIndices.end(), @@ -6012,7 +5995,7 @@ std::string VulkanHppGenerator::generateCommandVoid0Return( std::string const & size_t initialSkipCount, bool definition ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); std::vector constPointerParamIndices = determineConstPointerParamIndices( commandData.params ); if ( vectorParamIndices.empty() && std::find_if( constPointerParamIndices.begin(), constPointerParamIndices.end(), @@ -6038,7 +6021,7 @@ std::string VulkanHppGenerator::generateCommandVoid1Return( std::string const & bool definition, size_t returnParamIndex ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); if ( isHandleType( commandData.params[returnParamIndex].type.type ) ) { // get handle(s) @@ -6084,7 +6067,7 @@ std::string VulkanHppGenerator::generateCommandVoid2Return( std::string const & { assert( returnParamIndices.size() == 2 ); - std::map vectorParamIndices = determineVectorParamIndicesNew( commandData.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandData.params ); if ( !isHandleType( commandData.params[returnParamIndices[0]].type.type ) && !isStructureChainAnchor( commandData.params[returnParamIndices[0]].type.type ) ) { @@ -7070,6 +7053,7 @@ std::string VulkanHppGenerator::generateFunctionHeaderArgumentsEnhanced( CommandData const & commandData, size_t returnParamIndex, size_t templateParamIndex, + size_t initialSkipCount, std::map const & vectorParamIndices, bool withDefaults, bool withAllocator ) const @@ -7077,12 +7061,18 @@ std::string std::string str; // check if there's at least one argument left to put in here - std::set skippedParams = ::determineSkippedParams( returnParamIndex, vectorParamIndices ); - if ( skippedParams.size() + ( commandData.handle.empty() ? 0 : 1 ) < commandData.params.size() ) + std::vector returnParamIndices; + if ( returnParamIndex != INVALID_INDEX ) + { + returnParamIndices.push_back( returnParamIndex ); + } + std::set skippedParams = + determineSkippedParams( commandData.params, initialSkipCount, vectorParamIndices, returnParamIndices, false ); + if ( skippedParams.size() < commandData.params.size() ) { str += " "; bool argEncountered = false; - for ( size_t i = commandData.handle.empty() ? 0 : 1; i < commandData.params.size(); i++ ) + for ( size_t i = 0; i < commandData.params.size(); i++ ) { std::string arg = generateFunctionHeaderArgumentEnhanced( commandData.params[i], i, @@ -8538,7 +8528,7 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorVectorSingular( std::string const & leave ) const { size_t returnParamIndex = static_cast( std::distance( constructorIt->second.params.begin(), handleParamIt ) ); - std::map vectorParamIndices = determineVectorParamIndicesNew( constructorIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( constructorIt->second.params ); std::set singularParams = determineSingularParams( returnParamIndex, vectorParamIndices ); std::string callArguments = generateRAIIHandleConstructorCallArguments( @@ -9000,7 +8990,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionResult0Return( std::map::const_iterator commandIt, size_t initialSkipCount, bool definition ) const { std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); if ( commandIt->second.errorCodes.empty() ) { if ( commandIt->second.successCodes.size() == 1 ) @@ -9040,7 +9030,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionResult1Return( assert( !isHandleType( commandIt->second.params[returnParamIndex].type.type ) ); std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); auto returnVectorParamIt = vectorParamIndices.find( returnParamIndex ); if ( returnVectorParamIt == vectorParamIndices.end() ) { @@ -9139,7 +9129,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionResult2Return( assert( !commandIt->second.successCodes.empty() ); std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); switch ( vectorParamIndices.size() ) { case 0: @@ -9210,7 +9200,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionResult3Return( assert( returnParamIndices.size() == 3 ); std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); if ( vectorParamIndices.size() == 2 ) { // two vector parameters @@ -10629,7 +10619,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionVoid( std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionVoid0Return( std::map::const_iterator commandIt, size_t initialSkipCount, bool definition ) const { - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); std::set skippedParameters = determineSkippedParams( commandIt->second.params, initialSkipCount, vectorParamIndices, {}, false ); std::string argumentList = @@ -10697,7 +10687,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionVoid1Return( assert( !isHandleType( commandIt->second.params[returnParamIndex].type.type ) ); std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); auto returnVectorParamIt = vectorParamIndices.find( returnParamIndex ); if ( returnVectorParamIt == vectorParamIndices.end() ) { @@ -10737,7 +10727,7 @@ std::string VulkanHppGenerator::generateRAIIHandleMemberFunctionVoid2Return( assert( !isHandleType( commandIt->second.params[returnParamIndices[0]].type.type ) ); std::string function; - std::map vectorParamIndices = determineVectorParamIndicesNew( commandIt->second.params ); + std::map vectorParamIndices = determineVectorParamIndices( commandIt->second.params ); switch ( vectorParamIndices.size() ) { case 1: diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 36d1480..0a9a7c6 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -56,6 +56,11 @@ private: return ( prefix == rhs.prefix ) && ( type == rhs.type ) && ( postfix == rhs.postfix ); } + bool operator!=( TypeInfo const & rhs ) const + { + return !operator==( rhs ); + } + bool operator<( TypeInfo const & rhs ) const { return ( prefix < rhs.prefix ) || @@ -343,38 +348,51 @@ private: std::string & deviceMembers, std::string & instanceAssignments, std::string & instanceMembers ) const; + void checkBitmaskCorrectness() const; + void checkCommandCorrectness() const; void checkCorrectness() const; + void checkEnumCorrectness() const; void checkEnumCorrectness( std::vector const & requireData ) const; bool checkEquivalentSingularConstructor( std::vector::const_iterator> const & constructorIts, std::map::const_iterator constructorIt, std::vector::const_iterator lenIt ) const; - bool containsArray( std::string const & type ) const; - bool containsUnion( std::string const & type ) const; - size_t determineDefaultStartIndex( std::vector const & params, - std::set const & skippedParams ) const; - size_t determineInitialSkipCount( std::string const & command ) const; + void checkExtensionCorrectness() const; + void checkFuncPointerCorrectness() const; + void checkHandleCorrectness() const; + void checkStructCorrectness() const; + void checkStructMemberCorrectness( std::string const & structureName, + std::vector const & members, + std::set & sTypeValues ) const; + bool containsArray( std::string const & type ) const; + bool containsUnion( std::string const & type ) const; + std::vector determineConstPointerParamIndices( std::vector const & params ) const; + size_t determineDefaultStartIndex( std::vector const & params, + std::set const & skippedParams ) const; + size_t determineInitialSkipCount( std::string const & command ) const; + std::vector determineNonConstPointerParamIndices( std::vector const & params ) const; std::vector::const_iterator> determineRAIIHandleConstructors( std::string const & handleType, std::map::const_iterator destructorIt, std::set & specialFunctions ) const; - std::map::const_iterator determineRAIIHandleDestructor( std::string const & handleType ) const; - size_t determineReturnParamIndex( CommandData const & commandData, - std::map const & vectorParamIndices, - bool twoStep ) const; std::set determineSkippedParams( std::vector const & params, size_t initialSkipCount, std::map const & vectorParamIndices, std::vector const & returnParamIndex, bool singular ) const; std::string determineSubStruct( std::pair const & structure ) const; - std::vector determineConstPointerParamIndices( std::vector const & params ) const; - std::vector determineNonConstPointerParamIndices( std::vector const & params ) const; - std::map determineVectorParamIndicesNew( std::vector const & params ) const; + std::map determineVectorParamIndices( std::vector const & params ) const; void distributeSecondLevelCommands( std::set const & specialFunctions ); std::string findBaseName( std::string aliasName, std::map const & aliases ) const; + std::string generateArgumentEnhancedConstPointer( ParamData const & param, + bool definition, + bool withAllocators, +#if !defined( NDEBUG ) + bool withDispatcher, +#endif + bool & hasDefaultAssignment ) const; std::string generateArgumentListEnhanced( std::vector const & params, std::set const & skippedParams, std::set const & singularParams, @@ -385,6 +403,9 @@ private: std::string generateArgumentListStandard( std::vector const & params, std::set const & skippedParams ) const; std::string generateBitmask( std::map::const_iterator bitmaskIt ) const; + std::pair generateBitmaskValues( std::map::const_iterator bitmaskIt, + std::map::const_iterator bitmaskBitsIt ) const; + std::string generateBitmasks( std::vector const & requireData, std::set & listedBitmasks, std::string const & title ) const; @@ -772,6 +793,7 @@ private: std::string generateFunctionHeaderArgumentsEnhanced( CommandData const & commandData, size_t returnParamIndex, size_t templateParamIndex, + size_t initialSkipCount, std::map const & vectorParamIndices, bool withDefaults, bool withAllocator ) const; diff --git a/vulkan/vulkan_enums.hpp b/vulkan/vulkan_enums.hpp index 96005e0..fbd45cb 100644 --- a/vulkan/vulkan_enums.hpp +++ b/vulkan/vulkan_enums.hpp @@ -8038,6 +8038,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & FormatFeatureFlagBits::eVideoEncodeDpbKHR ) result += "VideoEncodeDpbKHR | "; #endif /*VK_ENABLE_BETA_EXTENSIONS*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8120,6 +8121,7 @@ namespace VULKAN_HPP_NAMESPACE result += "SampleLocationsCompatibleDepthEXT | "; if ( value & ImageCreateFlagBits::eSubsampledEXT ) result += "SubsampledEXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8216,6 +8218,7 @@ namespace VULKAN_HPP_NAMESPACE #endif /*VK_ENABLE_BETA_EXTENSIONS*/ if ( value & ImageUsageFlagBits::eInvocationMaskHUAWEI ) result += "InvocationMaskHUAWEI | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8270,6 +8273,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DeviceLocal | "; if ( value & MemoryHeapFlagBits::eMultiInstance ) result += "MultiInstance | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8337,6 +8341,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DeviceUncachedAMD | "; if ( value & MemoryPropertyFlagBits::eRdmaCapableNV ) result += "RdmaCapableNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8401,6 +8406,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & QueueFlagBits::eVideoEncodeKHR ) result += "VideoEncodeKHR | "; #endif /*VK_ENABLE_BETA_EXTENSIONS*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8461,6 +8467,7 @@ namespace VULKAN_HPP_NAMESPACE result += "32 | "; if ( value & SampleCountFlagBits::e64 ) result += "64 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8514,6 +8521,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & DeviceQueueCreateFlagBits::eProtected ) result += "Protected | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8625,6 +8633,7 @@ namespace VULKAN_HPP_NAMESPACE result += "FragmentShadingRateAttachmentKHR | "; if ( value & PipelineStageFlagBits::eCommandPreprocessNV ) result += "CommandPreprocessNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8702,6 +8711,7 @@ namespace VULKAN_HPP_NAMESPACE result += "MemoryPlane2EXT | "; if ( value & ImageAspectFlagBits::eMemoryPlane3EXT ) result += "MemoryPlane3EXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8754,6 +8764,7 @@ namespace VULKAN_HPP_NAMESPACE result += "AlignedMipSize | "; if ( value & SparseImageFormatFlagBits::eNonstandardBlockSize ) result += "NonstandardBlockSize | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8800,6 +8811,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & SparseMemoryBindFlagBits::eMetadata ) result += "Metadata | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8845,6 +8857,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & FenceCreateFlagBits::eSignaled ) result += "Signaled | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8897,6 +8910,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & EventCreateFlagBits::eDeviceOnlyKHR ) result += "DeviceOnlyKHR | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -8973,6 +8987,7 @@ namespace VULKAN_HPP_NAMESPACE result += "TessellationEvaluationShaderInvocations | "; if ( value & QueryPipelineStatisticFlagBits::eComputeShaderInvocations ) result += "ComputeShaderInvocations | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9039,6 +9054,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & QueryResultFlagBits::eWithStatusKHR ) result += "WithStatusKHR | "; #endif /*VK_ENABLE_BETA_EXTENSIONS*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9094,6 +9110,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Protected | "; if ( value & BufferCreateFlagBits::eDeviceAddressCaptureReplay ) result += "DeviceAddressCaptureReplay | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9198,6 +9215,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & BufferUsageFlagBits::eVideoEncodeSrcKHR ) result += "VideoEncodeSrcKHR | "; #endif /*VK_ENABLE_BETA_EXTENSIONS*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9254,6 +9272,7 @@ namespace VULKAN_HPP_NAMESPACE result += "FragmentDensityMapDynamicEXT | "; if ( value & ImageViewCreateFlagBits::eFragmentDensityMapDeferredEXT ) result += "FragmentDensityMapDeferredEXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9307,6 +9326,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & PipelineCacheCreateFlagBits::eExternallySynchronizedEXT ) result += "ExternallySynchronizedEXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9360,6 +9380,7 @@ namespace VULKAN_HPP_NAMESPACE result += "B | "; if ( value & ColorComponentFlagBits::eA ) result += "A | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9408,6 +9429,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Front | "; if ( value & CullModeFlagBits::eBack ) result += "Back | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9515,6 +9537,7 @@ namespace VULKAN_HPP_NAMESPACE result += "EarlyReturnOnFailureEXT | "; if ( value & PipelineCreateFlagBits::eRayTracingAllowMotionNV ) result += "RayTracingAllowMotionNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9606,6 +9629,7 @@ namespace VULKAN_HPP_NAMESPACE result += "AllowVaryingSubgroupSizeEXT | "; if ( value & PipelineShaderStageCreateFlagBits::eRequireFullSubgroupsEXT ) result += "RequireFullSubgroupsEXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9708,6 +9732,7 @@ namespace VULKAN_HPP_NAMESPACE result += "MeshNV | "; if ( value & ShaderStageFlagBits::eSubpassShadingHUAWEI ) result += "SubpassShadingHUAWEI | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9756,6 +9781,7 @@ namespace VULKAN_HPP_NAMESPACE result += "SubsampledEXT | "; if ( value & SamplerCreateFlagBits::eSubsampledCoarseReconstructionEXT ) result += "SubsampledCoarseReconstructionEXT | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9808,6 +9834,7 @@ namespace VULKAN_HPP_NAMESPACE result += "UpdateAfterBind | "; if ( value & DescriptorPoolCreateFlagBits::eHostOnlyVALVE ) result += "HostOnlyVALVE | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9867,6 +9894,7 @@ namespace VULKAN_HPP_NAMESPACE result += "PushDescriptorKHR | "; if ( value & DescriptorSetLayoutCreateFlagBits::eHostOnlyPoolVALVE ) result += "HostOnlyPoolVALVE | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -9985,6 +10013,7 @@ namespace VULKAN_HPP_NAMESPACE result += "CommandPreprocessReadNV | "; if ( value & AccessFlagBits::eCommandPreprocessWriteNV ) result += "CommandPreprocessWriteNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10031,6 +10060,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & AttachmentDescriptionFlagBits::eMayAlias ) result += "MayAlias | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10081,6 +10111,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DeviceGroup | "; if ( value & DependencyFlagBits::eViewLocal ) result += "ViewLocal | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10127,6 +10158,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & FramebufferCreateFlagBits::eImageless ) result += "Imageless | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10173,6 +10205,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & RenderPassCreateFlagBits::eTransformQCOM ) result += "TransformQCOM | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10228,6 +10261,7 @@ namespace VULKAN_HPP_NAMESPACE result += "FragmentRegionQCOM | "; if ( value & SubpassDescriptionFlagBits::eShaderResolveQCOM ) result += "ShaderResolveQCOM | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10280,6 +10314,7 @@ namespace VULKAN_HPP_NAMESPACE result += "ResetCommandBuffer | "; if ( value & CommandPoolCreateFlagBits::eProtected ) result += "Protected | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10326,6 +10361,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & CommandPoolResetFlagBits::eReleaseResources ) result += "ReleaseResources | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10372,6 +10408,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & CommandBufferResetFlagBits::eReleaseResources ) result += "ReleaseResources | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10424,6 +10461,7 @@ namespace VULKAN_HPP_NAMESPACE result += "RenderPassContinue | "; if ( value & CommandBufferUsageFlagBits::eSimultaneousUse ) result += "SimultaneousUse | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10469,6 +10507,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & QueryControlFlagBits::ePrecise ) result += "Precise | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10517,6 +10556,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Front | "; if ( value & StencilFaceFlagBits::eBack ) result += "Back | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10585,6 +10625,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Quad | "; if ( value & SubgroupFeatureFlagBits::ePartitionedNV ) result += "PartitionedNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10640,6 +10681,7 @@ namespace VULKAN_HPP_NAMESPACE result += "GenericSrc | "; if ( value & PeerMemoryFeatureFlagBits::eGenericDst ) result += "GenericDst | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10693,6 +10735,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DeviceAddress | "; if ( value & MemoryAllocateFlagBits::eDeviceAddressCaptureReplay ) result += "DeviceAddressCaptureReplay | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10803,6 +10846,7 @@ namespace VULKAN_HPP_NAMESPACE #endif /*VK_USE_PLATFORM_FUCHSIA*/ if ( value & ExternalMemoryHandleTypeFlagBits::eRdmaAddressNV ) result += "RdmaAddressNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10857,6 +10901,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Exportable | "; if ( value & ExternalMemoryFeatureFlagBits::eImportable ) result += "Importable | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10914,6 +10959,7 @@ namespace VULKAN_HPP_NAMESPACE result += "OpaqueWin32Kmt | "; if ( value & ExternalFenceHandleTypeFlagBits::eSyncFd ) result += "SyncFd | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -10965,6 +11011,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Exportable | "; if ( value & ExternalFenceFeatureFlagBits::eImportable ) result += "Importable | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11012,6 +11059,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & FenceImportFlagBits::eTemporary ) result += "Temporary | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11060,6 +11108,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & SemaphoreImportFlagBits::eTemporary ) result += "Temporary | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11127,6 +11176,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & ExternalSemaphoreHandleTypeFlagBits::eZirconEventFUCHSIA ) result += "ZirconEventFUCHSIA | "; #endif /*VK_USE_PLATFORM_FUCHSIA*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11178,6 +11228,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Exportable | "; if ( value & ExternalSemaphoreFeatureFlagBits::eImportable ) result += "Importable | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11237,6 +11288,7 @@ namespace VULKAN_HPP_NAMESPACE result += "PartiallyBound | "; if ( value & DescriptorBindingFlagBits::eVariableDescriptorCount ) result += "VariableDescriptorCount | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11292,6 +11344,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Min | "; if ( value & ResolveModeFlagBits::eMax ) result += "Max | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11339,6 +11392,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & SemaphoreWaitFlagBits::eAny ) result += "Any | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11394,6 +11448,7 @@ namespace VULKAN_HPP_NAMESPACE result += "PostMultiplied | "; if ( value & CompositeAlphaFlagBitsKHR::eInherit ) result += "Inherit | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11448,6 +11503,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Protected | "; if ( value & SwapchainCreateFlagBitsKHR::eMutableFormat ) result += "MutableFormat | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11503,6 +11559,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Sum | "; if ( value & DeviceGroupPresentModeFlagBitsKHR::eLocalMultiDevice ) result += "LocalMultiDevice | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11566,6 +11623,7 @@ namespace VULKAN_HPP_NAMESPACE result += "PerPixel | "; if ( value & DisplayPlaneAlphaFlagBitsKHR::ePerPixelPremultiplied ) result += "PerPixelPremultiplied | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11642,6 +11700,7 @@ namespace VULKAN_HPP_NAMESPACE result += "HorizontalMirrorRotate270 | "; if ( value & SurfaceTransformFlagBitsKHR::eInherit ) result += "Inherit | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11755,6 +11814,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Error | "; if ( value & DebugReportFlagBitsEXT::eDebug ) result += "Debug | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11815,6 +11875,7 @@ namespace VULKAN_HPP_NAMESPACE if ( value & VideoCodecOperationFlagBitsKHR::eDecodeH265EXT ) result += "DecodeH265EXT | "; # endif /*VK_ENABLE_BETA_EXTENSIONS*/ + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11870,6 +11931,7 @@ namespace VULKAN_HPP_NAMESPACE result += "422 | "; if ( value & VideoChromaSubsamplingFlagBitsKHR::e444 ) result += "444 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11922,6 +11984,7 @@ namespace VULKAN_HPP_NAMESPACE result += "10 | "; if ( value & VideoComponentBitDepthFlagBitsKHR::e12 ) result += "12 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -11971,6 +12034,7 @@ namespace VULKAN_HPP_NAMESPACE result += "ProtectedContent | "; if ( value & VideoCapabilityFlagBitsKHR::eSeparateReferenceImages ) result += "SeparateReferenceImages | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12018,6 +12082,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoSessionCreateFlagBitsKHR::eProtectedContent ) result += "ProtectedContent | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12078,6 +12143,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoCodingControlFlagBitsKHR::eReset ) result += "Reset | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12131,6 +12197,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Power | "; if ( value & VideoCodingQualityPresetFlagBitsKHR::eQuality ) result += "Quality | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } #endif /*VK_ENABLE_BETA_EXTENSIONS*/ @@ -12181,6 +12248,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoDecodeFlagBitsKHR::eReserved0 ) result += "Reserved0 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } #endif /*VK_ENABLE_BETA_EXTENSIONS*/ @@ -12270,6 +12338,7 @@ namespace VULKAN_HPP_NAMESPACE result += "MultipleSlicePerFrame | "; if ( value & VideoEncodeH264CapabilityFlagBitsEXT::eEvenlyDistributedSliceSize ) result += "EvenlyDistributedSliceSize | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12322,6 +12391,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Slice | "; if ( value & VideoEncodeH264InputModeFlagBitsEXT::eNonVcl ) result += "NonVcl | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12374,6 +12444,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Slice | "; if ( value & VideoEncodeH264OutputModeFlagBitsEXT::eNonVcl ) result += "NonVcl | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12421,6 +12492,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoEncodeH264CreateFlagBitsEXT::eReserved0 ) result += "Reserved0 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } #endif /*VK_ENABLE_BETA_EXTENSIONS*/ @@ -12475,6 +12547,7 @@ namespace VULKAN_HPP_NAMESPACE result += "InterlacedInterleavedLines | "; if ( value & VideoDecodeH264PictureLayoutFlagBitsEXT::eInterlacedSeparatePlanes ) result += "InterlacedSeparatePlanes | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12551,6 +12624,7 @@ namespace VULKAN_HPP_NAMESPACE result += "D3D11Image | "; if ( value & ExternalMemoryHandleTypeFlagBitsNV::eD3D11ImageKmt ) result += "D3D11ImageKmt | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12603,6 +12677,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Exportable | "; if ( value & ExternalMemoryFeatureFlagBitsNV::eImportable ) result += "Importable | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12662,6 +12737,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & ConditionalRenderingFlagBitsEXT::eInverted ) result += "Inverted | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12710,6 +12786,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & SurfaceCounterFlagBitsEXT::eVblank ) result += "Vblank | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12798,6 +12875,7 @@ namespace VULKAN_HPP_NAMESPACE result += "PerformanceImpacting | "; if ( value & PerformanceCounterDescriptionFlagBitsKHR::eConcurrentlyImpacted ) result += "ConcurrentlyImpacted | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12884,6 +12962,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Warning | "; if ( value & DebugUtilsMessageSeverityFlagBitsEXT::eError ) result += "Error | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -12936,6 +13015,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Validation | "; if ( value & DebugUtilsMessageTypeFlagBitsEXT::ePerformance ) result += "Performance | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13010,6 +13090,7 @@ namespace VULKAN_HPP_NAMESPACE result += "Opaque | "; if ( value & GeometryFlagBitsKHR::eNoDuplicateAnyHitInvocation ) result += "NoDuplicateAnyHitInvocation | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13067,6 +13148,7 @@ namespace VULKAN_HPP_NAMESPACE result += "ForceOpaque | "; if ( value & GeometryInstanceFlagBitsKHR::eForceNoOpaque ) result += "ForceNoOpaque | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13130,6 +13212,7 @@ namespace VULKAN_HPP_NAMESPACE result += "LowMemory | "; if ( value & BuildAccelerationStructureFlagBitsKHR::eMotionNV ) result += "MotionNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13179,6 +13262,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DeviceAddressCaptureReplay | "; if ( value & AccelerationStructureCreateFlagBitsKHR::eMotionNV ) result += "MotionNV | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13271,6 +13355,7 @@ namespace VULKAN_HPP_NAMESPACE result += "ApplicationPipelineCacheHit | "; if ( value & PipelineCreationFeedbackFlagBitsEXT::eBasePipelineAcceleration ) result += "BasePipelineAcceleration | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13365,6 +13450,7 @@ namespace VULKAN_HPP_NAMESPACE result += "DebugReporting | "; if ( value & ToolPurposeFlagBitsEXT::eDebugMarkers ) result += "DebugMarkers | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13431,6 +13517,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & IndirectStateFlagBitsNV::eFlagFrontface ) result += "FlagFrontface | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13483,6 +13570,7 @@ namespace VULKAN_HPP_NAMESPACE result += "IndexedSequences | "; if ( value & IndirectCommandsLayoutUsageFlagBitsNV::eUnorderedSequences ) result += "UnorderedSequences | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13550,6 +13638,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoEncodeFlagBitsKHR::eReserved0 ) result += "Reserved0 | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13597,6 +13686,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & VideoEncodeRateControlFlagBitsKHR::eReset ) result += "Reset | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13643,6 +13733,7 @@ namespace VULKAN_HPP_NAMESPACE return "{}"; std::string result; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } #endif /*VK_ENABLE_BETA_EXTENSIONS*/ @@ -13698,6 +13789,7 @@ namespace VULKAN_HPP_NAMESPACE result += "EnableResourceTracking | "; if ( value & DeviceDiagnosticsConfigFlagBitsNV::eEnableAutomaticCheckpoints ) result += "EnableAutomaticCheckpoints | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13851,6 +13943,7 @@ namespace VULKAN_HPP_NAMESPACE result += "SubpassShadingHUAWEI | "; if ( value & PipelineStageFlagBits2KHR::eInvocationMaskHUAWEI ) result += "InvocationMaskHUAWEI | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -13995,6 +14088,7 @@ namespace VULKAN_HPP_NAMESPACE result += "ColorAttachmentReadNoncoherentEXT | "; if ( value & AccessFlagBits2KHR::eInvocationMaskReadHUAWEI ) result += "InvocationMaskReadHUAWEI | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } @@ -14040,6 +14134,7 @@ namespace VULKAN_HPP_NAMESPACE std::string result; if ( value & SubmitFlagBitsKHR::eProtected ) result += "Protected | "; + return "{ " + result.substr( 0, result.size() - 3 ) + " }"; }