Reorder commands in DispatchLoaderStatic.

This commit is contained in:
asuessenbach 2021-04-27 17:19:32 +02:00
parent ac6a0945ec
commit e47c3c8b84
3 changed files with 3658 additions and 3366 deletions

View File

@ -2247,51 +2247,99 @@ void VulkanHppGenerator::appendDispatchLoaderStatic( std::string & str )
{ {
public:)"; public:)";
for ( auto const & command : m_commands ) std::set<std::string> listedCommands;
for ( auto const & feature : m_features )
{ {
std::string parameterList, parameters; str += "\n //=== " + feature.first + " ===\n";
bool firstParam = true; for ( auto const & command : feature.second.commands )
for ( auto param : command.second.params )
{ {
if ( !firstParam ) assert( listedCommands.find( command ) == listedCommands.end() );
{ listedCommands.insert( command );
parameterList += ", ";
parameters += ", ";
}
parameterList += param.type.prefix + ( param.type.prefix.empty() ? "" : " " ) + param.type.type +
param.type.postfix + " " + param.name + constructCArraySizes( param.arraySizes );
parameters += param.name;
firstParam = false;
}
std::string commandName = stripPrefix( command.first, "vk" );
auto commandIt = m_commands.find( command );
assert( commandIt != m_commands.end() );
str += "\n"; str += "\n";
appendStaticCommand( str, *commandIt );
}
}
std::map<std::string, std::map<std::string, ExtensionData>::const_iterator> numberToExtensionMap;
for ( auto extensionIt = m_extensions.begin(); extensionIt != m_extensions.end(); ++extensionIt )
{
assert( numberToExtensionMap.find( extensionIt->second.number ) == numberToExtensionMap.end() );
numberToExtensionMap[extensionIt->second.number] = extensionIt;
}
for ( auto const & extIt : numberToExtensionMap )
{
if ( !extIt.second->second.commands.empty() )
{
std::string referencedIn;
std::string firstCommandName = *extIt.second->second.commands.begin();
auto commandIt = m_commands.find( firstCommandName );
if ( commandIt == m_commands.end() )
{
commandIt =
std::find_if( m_commands.begin(),
m_commands.end(),
[&firstCommandName]( auto const & command ) {
return command.second.aliasData.find( firstCommandName ) != command.second.aliasData.end();
} );
assert( commandIt != m_commands.end() );
auto aliasDataIt = commandIt->second.aliasData.find( firstCommandName );
assert( aliasDataIt != commandIt->second.aliasData.end() );
referencedIn = aliasDataIt->second.referencedIn;
}
else
{
referencedIn = commandIt->second.referencedIn;
}
std::string enter, leave; std::string enter, leave;
std::tie( enter, leave ) = generateProtection( command.second.referencedIn ); std::tie( enter, leave ) = generateProtection( referencedIn );
str += enter + " " + command.second.returnType + " vk" + commandName + "( " + parameterList + if ( !enter.empty() )
" ) const VULKAN_HPP_NOEXCEPT\n"
" {\n"
" return ::vk" +
commandName + "( " + parameters +
" );\n"
" }\n" +
leave;
for ( auto const & aliasData : command.second.aliasData )
{ {
commandName = stripPrefix( aliasData.first, "vk" ); enter = "\n" + enter;
}
str += enter + "\n //=== " + extIt.second->first + " ===\n";
for ( auto const & commandName : extIt.second->second.commands )
{
// some commands are listed for multiple extensions !
if ( listedCommands.find( commandName ) == listedCommands.end() )
{
listedCommands.insert( commandName );
commandIt = m_commands.find( commandName );
if ( commandIt == m_commands.end() )
{
commandIt =
std::find_if( m_commands.begin(),
m_commands.end(),
[&commandName]( auto const & command ) {
return command.second.aliasData.find( commandName ) != command.second.aliasData.end();
} );
assert( commandIt != m_commands.end() );
auto aliasDataIt = commandIt->second.aliasData.find( commandName );
assert( aliasDataIt != commandIt->second.aliasData.end() );
assert( aliasDataIt->second.referencedIn == referencedIn );
std::pair<std::string, CommandData> aliasCommand = std::make_pair( aliasDataIt->first, commandIt->second );
aliasCommand.second.aliasData.clear();
aliasCommand.second.xmlLine = aliasDataIt->second.xmlLine;
str += "\n"; str += "\n";
std::tie( enter, leave ) = generateProtection( aliasData.second.referencedIn ); appendStaticCommand( str, aliasCommand );
str += enter + " " + command.second.returnType + " vk" + commandName + "( " + parameterList + }
" ) const VULKAN_HPP_NOEXCEPT\n" else
" {\n" {
" return ::vk" + assert( commandIt->second.referencedIn == referencedIn );
commandName + "( " + parameters +
" );\n" str += "\n";
" }\n" + appendStaticCommand( str, *commandIt );
leave;
} }
} }
}
str += leave;
}
}
str += " };\n#endif\n"; str += " };\n#endif\n";
} }
@ -3801,6 +3849,35 @@ ${memberFunctionDeclarations}
str += replaceWithMap( contextTemplate, { { "memberFunctionDeclarations", declarations } } ); str += replaceWithMap( contextTemplate, { { "memberFunctionDeclarations", declarations } } );
} }
std::pair<std::string, std::string>
VulkanHppGenerator::appendStaticCommand( std::string & str, std::pair<std::string, CommandData> const & command )
{
std::string parameterList, parameters;
bool firstParam = true;
for ( auto param : command.second.params )
{
if ( !firstParam )
{
parameterList += ", ";
parameters += ", ";
}
parameterList += param.type.prefix + ( param.type.prefix.empty() ? "" : " " ) + param.type.type +
param.type.postfix + " " + param.name + constructCArraySizes( param.arraySizes );
parameters += param.name;
firstParam = false;
}
std::string commandName = stripPrefix( command.first, "vk" );
str += " " + command.second.returnType + " vk" + commandName + "( " + parameterList +
" ) const VULKAN_HPP_NOEXCEPT\n"
" {\n"
" return ::vk" +
commandName + "( " + parameters +
" );\n"
" }\n";
return std::make_pair( parameterList, parameters );
}
void VulkanHppGenerator::appendStruct( std::string & str, std::pair<std::string, StructureData> const & structure ) void VulkanHppGenerator::appendStruct( std::string & str, std::pair<std::string, StructureData> const & structure )
{ {
assert( m_listingTypes.find( structure.first ) == m_listingTypes.end() ); assert( m_listingTypes.find( structure.first ) == m_listingTypes.end() );
@ -11321,7 +11398,7 @@ void VulkanHppGenerator::checkCorrectness()
{ return enumValue == evd.vulkanValue; } ) != enumIt->second.values.end(), { return enumValue == evd.vulkanValue; } ) != enumIt->second.values.end(),
member.xmlLine, member.xmlLine,
"value <" + enumValue + "> for member <" + member.name + "> in structure <" + structure.first + "value <" + enumValue + "> for member <" + member.name + "> in structure <" + structure.first +
" of enum type <" + member.type.type + "> not listed" ); "> of enum type <" + member.type.type + "> not listed" );
} }
// special handling for sType: no value should appear more than once // special handling for sType: no value should appear more than once
if ( member.name == "sType" ) if ( member.name == "sType" )
@ -12850,7 +12927,7 @@ void VulkanHppGenerator::readExtension( tinyxml2::XMLElement const * element )
std::vector<tinyxml2::XMLElement const *> children = getChildElements( element ); std::vector<tinyxml2::XMLElement const *> children = getChildElements( element );
checkElements( line, children, {}, { "require" } ); checkElements( line, children, {}, { "require" } );
std::string deprecatedBy, name, obsoletedBy, platform, promotedTo, supported; std::string deprecatedBy, name, number, obsoletedBy, platform, promotedTo, supported;
std::vector<std::string> requirements; std::vector<std::string> requirements;
for ( auto const & attribute : attributes ) for ( auto const & attribute : attributes )
{ {
@ -12862,6 +12939,10 @@ void VulkanHppGenerator::readExtension( tinyxml2::XMLElement const * element )
{ {
name = attribute.second; name = attribute.second;
} }
else if ( attribute.first == "number" )
{
number = attribute.second;
}
else if ( attribute.first == "obsoletedby" ) else if ( attribute.first == "obsoletedby" )
{ {
obsoletedBy = attribute.second; obsoletedBy = attribute.second;
@ -12898,8 +12979,8 @@ void VulkanHppGenerator::readExtension( tinyxml2::XMLElement const * element )
std::string const & requiresCore = attribute.second; std::string const & requiresCore = attribute.second;
check( std::find_if( m_features.begin(), check( std::find_if( m_features.begin(),
m_features.end(), m_features.end(),
[&requiresCore]( std::pair<std::string, std::string> const & nameNumber ) [&requiresCore]( std::pair<std::string, FeatureData> const & feature )
{ return nameNumber.second == requiresCore; } ) != m_features.end(), { return feature.second.number == requiresCore; } ) != m_features.end(),
line, line,
"unknown feature number <" + attribute.second + ">" ); "unknown feature number <" + attribute.second + ">" );
} }
@ -12920,7 +13001,7 @@ void VulkanHppGenerator::readExtension( tinyxml2::XMLElement const * element )
else else
{ {
auto pitb = m_extensions.insert( auto pitb = m_extensions.insert(
std::make_pair( name, ExtensionData( line, deprecatedBy, obsoletedBy, platform, promotedTo ) ) ); std::make_pair( name, ExtensionData( line, deprecatedBy, number, obsoletedBy, platform, promotedTo ) ) );
check( pitb.second, line, "already encountered extension <" + name + ">" ); check( pitb.second, line, "already encountered extension <" + name + ">" );
for ( auto const & r : requirements ) for ( auto const & r : requirements )
{ {
@ -12932,7 +13013,7 @@ void VulkanHppGenerator::readExtension( tinyxml2::XMLElement const * element )
std::string tag = extractTag( line, name, m_tags ); std::string tag = extractTag( line, name, m_tags );
for ( auto child : children ) for ( auto child : children )
{ {
readExtensionRequire( child, name, tag, pitb.first->second.requirements ); readExtensionRequire( child, pitb.first, tag );
} }
} }
} }
@ -13045,9 +13126,8 @@ void VulkanHppGenerator::readExtensionDisabledType( tinyxml2::XMLElement const *
} }
void VulkanHppGenerator::readExtensionRequire( tinyxml2::XMLElement const * element, void VulkanHppGenerator::readExtensionRequire( tinyxml2::XMLElement const * element,
std::string const & extension, std::map<std::string, ExtensionData>::iterator extensionIt,
std::string const & tag, std::string const & tag )
std::map<std::string, int> & requirements )
{ {
int line = element->GetLineNum(); int line = element->GetLineNum();
std::map<std::string, std::string> attributes = getAttributes( element ); std::map<std::string, std::string> attributes = getAttributes( element );
@ -13059,7 +13139,7 @@ void VulkanHppGenerator::readExtensionRequire( tinyxml2::XMLElement const * elem
{ {
if ( attribute.first == "extension" ) if ( attribute.first == "extension" )
{ {
check( requirements.insert( std::make_pair( attribute.second, line ) ).second, check( extensionIt->second.requirements.insert( std::make_pair( attribute.second, line ) ).second,
line, line,
"required extension <" + attribute.second + "> already listed" ); "required extension <" + attribute.second + "> already listed" );
} }
@ -13076,7 +13156,7 @@ void VulkanHppGenerator::readExtensionRequire( tinyxml2::XMLElement const * elem
std::string value = child->Value(); std::string value = child->Value();
if ( value == "command" ) if ( value == "command" )
{ {
readExtensionRequireCommand( child, extension ); readExtensionRequireCommand( child, extensionIt );
} }
else if ( value == "comment" ) else if ( value == "comment" )
{ {
@ -13084,17 +13164,17 @@ void VulkanHppGenerator::readExtensionRequire( tinyxml2::XMLElement const * elem
} }
else if ( value == "enum" ) else if ( value == "enum" )
{ {
readRequireEnum( child, extension, tag ); readRequireEnum( child, extensionIt->first, tag );
} }
else if ( value == "type" ) else if ( value == "type" )
{ {
readExtensionRequireType( child, extension ); readExtensionRequireType( child, extensionIt->first );
} }
} }
} }
void VulkanHppGenerator::readExtensionRequireCommand( tinyxml2::XMLElement const * element, void VulkanHppGenerator::readExtensionRequireCommand( tinyxml2::XMLElement const * element,
std::string const & extension ) std::map<std::string, ExtensionData>::iterator extensionIt )
{ {
int line = element->GetLineNum(); int line = element->GetLineNum();
std::map<std::string, std::string> attributes = getAttributes( element ); std::map<std::string, std::string> attributes = getAttributes( element );
@ -13122,23 +13202,29 @@ void VulkanHppGenerator::readExtensionRequireCommand( tinyxml2::XMLElement const
if ( aliasDataIt != commandIt->second.aliasData.end() ) if ( aliasDataIt != commandIt->second.aliasData.end() )
{ {
assert( aliasDataIt->second.referencedIn.empty() ); assert( aliasDataIt->second.referencedIn.empty() );
aliasDataIt->second.referencedIn = extension; aliasDataIt->second.referencedIn = extensionIt->first;
foundAlias = true; foundAlias = true;
} }
} }
check( foundAlias, line, "extension <" + extension + "> requires unknown command <" + name + ">" ); check( foundAlias, line, "extension <" + extensionIt->first + "> requires unknown command <" + name + ">" );
} }
else if ( commandIt->second.referencedIn.empty() ) else if ( commandIt->second.referencedIn.empty() )
{ {
commandIt->second.referencedIn = extension; commandIt->second.referencedIn = extensionIt->first;
} }
else else
{ {
check( getPlatform( commandIt->second.referencedIn ) == getPlatform( extension ), check( getPlatform( commandIt->second.referencedIn ) == getPlatform( extensionIt->first ),
line, line,
"command <" + name + "> is referenced in extensions <" + commandIt->second.referencedIn + "> and <" + "command <" + name + "> is referenced in extensions <" + commandIt->second.referencedIn + "> and <" +
extension + "> and thus protected by different platforms <" + extensionIt->first + "> and thus protected by different platforms <" +
getPlatform( commandIt->second.referencedIn ) + "> and <" + getPlatform( extension ) + ">!" ); getPlatform( commandIt->second.referencedIn ) + "> and <" + getPlatform( extensionIt->first ) + ">!" );
}
if ( std::find( extensionIt->second.commands.begin(), extensionIt->second.commands.end(), name ) ==
extensionIt->second.commands.end() )
{
// some commands are listed more than once under different additional requirements
extensionIt->second.commands.push_back( name );
} }
} }
@ -13213,15 +13299,17 @@ void VulkanHppGenerator::readFeature( tinyxml2::XMLElement const * element )
} }
assert( !name.empty() && !number.empty() ); assert( !name.empty() && !number.empty() );
check( name == "VK_VERSION_" + modifiedNumber, line, "unexpected formatting of name <" + name + ">" ); check( name == "VK_VERSION_" + modifiedNumber, line, "unexpected formatting of name <" + name + ">" );
check( m_features.insert( std::make_pair( name, number ) ).second, line, "already specified feature <" + name + ">" ); check( m_features.find( name ) == m_features.end(), line, "already specified feature <" + name + ">" );
auto featureIt = m_features.insert( std::make_pair( name, number ) ).first;
for ( auto child : children ) for ( auto child : children )
{ {
readFeatureRequire( child, name ); readFeatureRequire( child, featureIt );
} }
} }
void VulkanHppGenerator::readFeatureRequire( tinyxml2::XMLElement const * element, std::string const & feature ) void VulkanHppGenerator::readFeatureRequire( tinyxml2::XMLElement const * element,
std::map<std::string, FeatureData>::iterator featureIt )
{ {
int line = element->GetLineNum(); int line = element->GetLineNum();
checkAttributes( line, getAttributes( element ), {}, { { "comment", {} } } ); checkAttributes( line, getAttributes( element ), {}, { { "comment", {} } } );
@ -13233,7 +13321,7 @@ void VulkanHppGenerator::readFeatureRequire( tinyxml2::XMLElement const * elemen
std::string value = child->Value(); std::string value = child->Value();
if ( value == "command" ) if ( value == "command" )
{ {
readFeatureRequireCommand( child, feature ); readFeatureRequireCommand( child, featureIt );
} }
else if ( value == "comment" ) else if ( value == "comment" )
{ {
@ -13245,23 +13333,27 @@ void VulkanHppGenerator::readFeatureRequire( tinyxml2::XMLElement const * elemen
} }
else if ( value == "type" ) else if ( value == "type" )
{ {
readFeatureRequireType( child, feature ); readFeatureRequireType( child, featureIt->first );
} }
} }
} }
void VulkanHppGenerator::readFeatureRequireCommand( tinyxml2::XMLElement const * element, std::string const & feature ) void VulkanHppGenerator::readFeatureRequireCommand( tinyxml2::XMLElement const * element,
std::map<std::string, FeatureData>::iterator featureIt )
{ {
int line = element->GetLineNum(); int line = element->GetLineNum();
std::map<std::string, std::string> attributes = getAttributes( element ); std::map<std::string, std::string> attributes = getAttributes( element );
checkAttributes( line, attributes, {}, { { "name", {} } } ); checkAttributes( line, attributes, {}, { { "name", {} } } );
std::string command = attributes.find( "name" )->second; std::string name = attributes.find( "name" )->second;
auto commandIt = m_commands.find( command ); auto commandIt = m_commands.find( name );
check( commandIt != m_commands.end(), line, "feature requires unknown command <" + command + ">" ); check( commandIt != m_commands.end(), line, "feature requires unknown command <" + name + ">" );
check( commandIt->second.referencedIn.empty(), check( commandIt->second.referencedIn.empty(),
line, line,
"command <" + commandIt->first + "> already listed with feature <" + commandIt->second.referencedIn + ">" ); "command <" + name + "> already listed with feature <" + commandIt->second.referencedIn + ">" );
commandIt->second.referencedIn = feature; commandIt->second.referencedIn = featureIt->first;
assert( std::find( featureIt->second.commands.begin(), featureIt->second.commands.end(), name ) ==
featureIt->second.commands.end() );
featureIt->second.commands.push_back( name );
} }
void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * element, std::string const & feature ) void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * element, std::string const & feature )

View File

@ -170,21 +170,33 @@ private:
int xmlLine; int xmlLine;
}; };
struct FeatureData
{
FeatureData( std::string const & number_ ) : number( number_ ) {}
std::vector<std::string> commands;
std::string number;
};
struct ExtensionData struct ExtensionData
{ {
ExtensionData( int line, ExtensionData( int line,
std::string const & deprecatedBy_, std::string const & deprecatedBy_,
std::string const & number_,
std::string const & obsoletedBy_, std::string const & obsoletedBy_,
std::string const & platform_, std::string const & platform_,
std::string const & promotedTo_ ) std::string const & promotedTo_ )
: deprecatedBy( deprecatedBy_ ) : deprecatedBy( deprecatedBy_ )
, number( number_ )
, obsoletedBy( obsoletedBy_ ) , obsoletedBy( obsoletedBy_ )
, platform( platform_ ) , platform( platform_ )
, promotedTo( promotedTo_ ) , promotedTo( promotedTo_ )
, xmlLine( line ) , xmlLine( line )
{} {}
std::vector<std::string> commands;
std::string deprecatedBy; std::string deprecatedBy;
std::string number;
std::string obsoletedBy; std::string obsoletedBy;
std::string platform; std::string platform;
std::string promotedTo; std::string promotedTo;
@ -535,6 +547,8 @@ private:
std::string & commandDefinitions, std::string & commandDefinitions,
std::pair<std::string, HandleData> const & handle, std::pair<std::string, HandleData> const & handle,
std::set<std::string> const & specialFunctions ) const; std::set<std::string> const & specialFunctions ) const;
std::pair<std::string, std::string> appendStaticCommand( std::string & str,
std::pair<std::string, CommandData> const & command );
void appendStruct( std::string & str, std::pair<std::string, StructureData> const & structure ); void appendStruct( std::string & str, std::pair<std::string, StructureData> const & structure );
void appendStructAssignmentOperators( std::string & str, void appendStructAssignmentOperators( std::string & str,
std::pair<std::string, StructureData> const & structure, std::pair<std::string, StructureData> const & structure,
@ -1119,15 +1133,17 @@ private:
void readExtensionDisabledRequire( tinyxml2::XMLElement const * element ); void readExtensionDisabledRequire( tinyxml2::XMLElement const * element );
void readExtensionDisabledType( tinyxml2::XMLElement const * element ); void readExtensionDisabledType( tinyxml2::XMLElement const * element );
void readExtensionRequire( tinyxml2::XMLElement const * element, void readExtensionRequire( tinyxml2::XMLElement const * element,
std::string const & extension, std::map<std::string, ExtensionData>::iterator extensionIt,
std::string const & tag, std::string const & tag );
std::map<std::string, int> & requirements ); void readExtensionRequireCommand( tinyxml2::XMLElement const * element,
void readExtensionRequireCommand( tinyxml2::XMLElement const * element, std::string const & extension ); std::map<std::string, ExtensionData>::iterator extensionIt );
void readExtensionRequireType( tinyxml2::XMLElement const * element, std::string const & extension ); void readExtensionRequireType( tinyxml2::XMLElement const * element, std::string const & extension );
void readExtensions( tinyxml2::XMLElement const * element ); void readExtensions( tinyxml2::XMLElement const * element );
void readFeature( tinyxml2::XMLElement const * element ); void readFeature( tinyxml2::XMLElement const * element );
void readFeatureRequire( tinyxml2::XMLElement const * element, std::string const & feature ); void readFeatureRequire( tinyxml2::XMLElement const * element,
void readFeatureRequireCommand( tinyxml2::XMLElement const * element, std::string const & feature ); std::map<std::string, FeatureData>::iterator featureIt );
void readFeatureRequireCommand( tinyxml2::XMLElement const * element,
std::map<std::string, FeatureData>::iterator featureIt );
void readFeatureRequireType( tinyxml2::XMLElement const * element, std::string const & feature ); void readFeatureRequireType( tinyxml2::XMLElement const * element, std::string const & feature );
void readFuncpointer( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes ); void readFuncpointer( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
void readHandle( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes ); void readHandle( tinyxml2::XMLElement const * element, std::map<std::string, std::string> const & attributes );
@ -1189,7 +1205,7 @@ private:
std::map<std::string, EnumData> m_enums; std::map<std::string, EnumData> m_enums;
std::set<std::string> m_extendedStructs; // structs which are referenced by the structextends tag std::set<std::string> m_extendedStructs; // structs which are referenced by the structextends tag
std::map<std::string, ExtensionData> m_extensions; std::map<std::string, ExtensionData> m_extensions;
std::map<std::string, std::string> m_features; std::map<std::string, FeatureData> m_features;
std::map<std::string, FuncPointerData> m_funcPointers; std::map<std::string, FuncPointerData> m_funcPointers;
std::map<std::string, HandleData> m_handles; std::map<std::string, HandleData> m_handles;
std::set<std::string> m_includes; std::set<std::string> m_includes;

File diff suppressed because it is too large Load Diff