Simplify alias handling for Bitmasks and Commands. (#1843)

This commit is contained in:
Andreas Süßenbach 2024-04-11 08:43:15 +02:00 committed by GitHub
parent ed5b48b517
commit 3134b1b42a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 145 additions and 125 deletions

View File

@ -29,6 +29,10 @@ namespace
template <typename T> template <typename T>
typename std::vector<T>::iterator findByName( std::vector<T> & values, std::string const & name ); typename std::vector<T>::iterator findByName( std::vector<T> & values, std::string const & name );
template <typename T> template <typename T>
typename std::map<std::string, T>::const_iterator findByNameOrAlias( std::map<std::string, T> const & values, std::string const & name );
template <typename T>
typename std::map<std::string, T>::iterator findByNameOrAlias( std::map<std::string, T> & values, std::string const & name );
template <typename T>
typename std::vector<T>::const_iterator findByNameOrAlias( std::vector<T> const & values, std::string const & name ); typename std::vector<T>::const_iterator findByNameOrAlias( std::vector<T> const & values, std::string const & name );
template <typename T> template <typename T>
typename std::vector<T>::iterator findByNameOrAlias( std::vector<T> & values, std::string const & name ); typename std::vector<T>::iterator findByNameOrAlias( std::vector<T> & values, std::string const & name );
@ -880,13 +884,14 @@ void VulkanHppGenerator::addCommandsToHandle( std::vector<RequireData> const & r
{ {
for ( auto const & command : require.commands ) for ( auto const & command : require.commands )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
auto handleIt = m_handles.find( commandData.handle ); assert( commandIt != m_commands.end() );
auto handleIt = m_handles.find( commandIt->second.handle );
assert( handleIt != m_handles.end() ); assert( handleIt != m_handles.end() );
if ( !handleIt->second.commands.contains( command ) ) if ( !handleIt->second.commands.contains( command ) )
{ {
handleIt->second.commands.insert( command ); handleIt->second.commands.insert( command );
registerDeleter( command, commandData ); registerDeleter( command, commandIt->second );
} }
} }
} }
@ -983,20 +988,21 @@ void VulkanHppGenerator::appendDispatchLoaderDynamicCommands( std::vector<Requir
{ {
if ( listedCommands.insert( command ).second ) if ( listedCommands.insert( command ).second )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
members += " PFN_" + command + " " + command + " = 0;\n"; members += " PFN_" + command + " " + command + " = 0;\n";
placeholders += " PFN_dummy " + command + "_placeholder = 0;\n"; placeholders += " PFN_dummy " + command + "_placeholder = 0;\n";
if ( commandData.handle.empty() ) if ( commandIt->second.handle.empty() )
{ {
initial += generateDispatchLoaderDynamicCommandAssignment( command, "NULL" ); initial += generateDispatchLoaderDynamicCommandAssignment( command, commandIt->first, "NULL" );
} }
else else
{ {
instance += generateDispatchLoaderDynamicCommandAssignment( command, "instance" ); instance += generateDispatchLoaderDynamicCommandAssignment( command, commandIt->first, "instance" );
if ( isDeviceCommand( commandData ) ) if ( isDeviceCommand( commandIt->second ) )
{ {
device += generateDispatchLoaderDynamicCommandAssignment( command, "device" ); device += generateDispatchLoaderDynamicCommandAssignment( command, commandIt->first, "device" );
} }
} }
} }
@ -1044,23 +1050,20 @@ void VulkanHppGenerator::appendRAIIDispatcherCommands( std::vector<RequireData>
{ {
if ( listedCommands.insert( command ).second ) if ( listedCommands.insert( command ).second )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
if ( commandData.handle.empty() ) if ( commandIt->second.handle.empty() )
{ {
assert( findAlias( command, m_commandAliases ) == m_commandAliases.end() );
ci += ", " + command + "( PFN_" + command + "( getProcAddr( NULL, \"" + command + "\" ) ) )"; ci += ", " + command + "( PFN_" + command + "( getProcAddr( NULL, \"" + command + "\" ) ) )";
cm += " PFN_" + command + " " + command + " = 0;\n"; cm += " PFN_" + command + " " + command + " = 0;\n";
} }
else if ( ( commandData.handle == "VkDevice" ) || hasParentHandle( commandData.handle, "VkDevice" ) ) else if ( ( commandIt->second.handle == "VkDevice" ) || hasParentHandle( commandIt->second.handle, "VkDevice" ) )
{ {
da += " " + command + " = PFN_" + command + "( vkGetDeviceProcAddr( device, \"" + command + "\" ) );\n"; da += " " + command + " = PFN_" + command + "( vkGetDeviceProcAddr( device, \"" + command + "\" ) );\n";
// if this is an alias'ed function, use it as a fallback for the original one // if this is an alias'ed function, use it as a fallback for the original one
auto aliasIt = m_commandAliases.find( command ); if ( command != commandIt->first )
if ( aliasIt != m_commandAliases.end() )
{ {
da += " if ( !" + aliasIt->second.name + " ) " + aliasIt->second.name + " = " + command + ";\n"; da += " if ( !" + commandIt->first + " ) " + commandIt->first + " = " + command + ";\n";
} }
dm += " PFN_" + command + " " + command + " = 0;\n"; dm += " PFN_" + command + " " + command + " = 0;\n";
@ -1068,7 +1071,7 @@ void VulkanHppGenerator::appendRAIIDispatcherCommands( std::vector<RequireData>
} }
else else
{ {
assert( ( commandData.handle == "VkInstance" ) || hasParentHandle( commandData.handle, "VkInstance" ) ); assert( ( commandIt->second.handle == "VkInstance" ) || hasParentHandle( commandIt->second.handle, "VkInstance" ) );
// filter out vkGetInstanceProcAddr, as starting with Vulkan 1.2 it can resolve itself only (!) with an // filter out vkGetInstanceProcAddr, as starting with Vulkan 1.2 it can resolve itself only (!) with an
// instance nullptr ! // instance nullptr !
@ -1076,10 +1079,9 @@ void VulkanHppGenerator::appendRAIIDispatcherCommands( std::vector<RequireData>
{ {
ia += " " + command + " = PFN_" + command + "( vkGetInstanceProcAddr( instance, \"" + command + "\" ) );\n"; ia += " " + command + " = PFN_" + command + "( vkGetInstanceProcAddr( instance, \"" + command + "\" ) );\n";
// if this is an alias'ed function, use it as a fallback for the original one // if this is an alias'ed function, use it as a fallback for the original one
auto aliasIt = m_commandAliases.find( command ); if ( command != commandIt->first )
if ( aliasIt != m_commandAliases.end() )
{ {
ia += " if ( !" + aliasIt->second.name + " ) " + aliasIt->second.name + " = " + command + ";\n"; ia += " if ( !" + commandIt->first + " ) " + commandIt->first + " = " + command + ";\n";
} }
} }
@ -1277,11 +1279,6 @@ void VulkanHppGenerator::checkEnumCorrectness( std::vector<RequireData> const &
"> which is not required by any feature or extension!" ); "> which is not required by any feature or extension!" );
} }
} }
else
{
// every bitmask not listed in the m_bitmasks, should be an alias of such a thing
checkForError( m_bitmaskAliases.contains( type ), typeIt->second.xmlLine, "bitmask type <" + type + "> is not listed as a bitmask" );
}
} }
break; break;
case TypeCategory::Enum: case TypeCategory::Enum:
@ -1820,14 +1817,8 @@ size_t VulkanHppGenerator::determineInitialSkipCount( std::string const & comman
// -> 0: the command is not bound to an instance or a device (the corresponding handle has no name) // -> 0: the command is not bound to an instance or a device (the corresponding handle has no name)
// -> 1: the command bound to an instance or a device (the corresponding handle has a name) // -> 1: the command bound to an instance or a device (the corresponding handle has a name)
// -> 2: the command has been moved to a second handle // -> 2: the command has been moved to a second handle
auto commandIt = m_commands.find( command ); auto commandIt = findByNameOrAlias( m_commands, command );
if ( commandIt == m_commands.end() ) assert( commandIt != m_commands.end() );
{
auto aliasIt = m_commandAliases.find( command );
assert( aliasIt != m_commandAliases.end() );
commandIt = m_commands.find( aliasIt->second.name );
assert( commandIt != m_commands.end() );
}
auto handleIt = m_handles.find( commandIt->second.handle ); auto handleIt = m_handles.find( commandIt->second.handle );
assert( handleIt != m_handles.end() ); assert( handleIt != m_handles.end() );
if ( !handleIt->second.commands.contains( command ) ) if ( !handleIt->second.commands.contains( command ) )
@ -2125,11 +2116,12 @@ void VulkanHppGenerator::distributeSecondLevelCommands( std::set<std::string> co
bool foundCommand = false; bool foundCommand = false;
if ( !specialFunctions.contains( *command ) ) if ( !specialFunctions.contains( *command ) )
{ {
auto const & commandData = getCommandData( *command ); auto commandIt = findByNameOrAlias( m_commands, *command );
assert( commandData.params.front().type.type == handle.first ); assert( commandIt != m_commands.end() );
if ( ( 1 < commandData.params.size() ) && ( isHandleType( commandData.params[1].type.type ) ) && !commandData.params[1].optional ) 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( commandData.params[1].type.type ); auto handleIt = m_handles.find( commandIt->second.params[1].type.type );
assert( handleIt != m_handles.end() ); assert( handleIt != m_handles.end() );
// filter out functions seem to fit due to taking handles as first and second argument, but the first argument is not the // filter out functions seem to fit due to taking handles as first and second argument, but the first argument is not the
// type to create the second one, and so it's unknown to the raii handle! // type to create the second one, and so it's unknown to the raii handle!
@ -2525,11 +2517,8 @@ std::string VulkanHppGenerator::generateBitmask( std::map<std::string, BitmaskDa
auto bitmaskBitsIt = m_enums.find( bitmaskIt->second.require ); auto bitmaskBitsIt = m_enums.find( bitmaskIt->second.require );
assert( bitmaskBitsIt != m_enums.end() ); assert( bitmaskBitsIt != m_enums.end() );
std::string bitmaskName = stripPrefix( bitmaskIt->first, "Vk" ); std::string bitmaskName = stripPrefix( bitmaskIt->first, "Vk" );
std::string enumName = stripPrefix( bitmaskBitsIt->first, "Vk" ); std::string enumName = stripPrefix( bitmaskBitsIt->first, "Vk" );
auto aliasBitmaskIt = findAlias( bitmaskIt->first, m_bitmaskAliases );
std::string alias =
( aliasBitmaskIt == m_bitmaskAliases.end() ) ? "" : ( " using " + stripPrefix( aliasBitmaskIt->first, "Vk" ) + " = " + bitmaskName + ";\n" );
std::string allFlags; std::string allFlags;
if ( bitmaskBitsIt->second.values.empty() || if ( bitmaskBitsIt->second.values.empty() ||
@ -2565,9 +2554,16 @@ std::string VulkanHppGenerator::generateBitmask( std::map<std::string, BitmaskDa
} }
allFlags += ";"; allFlags += ";";
} }
std::string aliases;
for ( auto const & a : bitmaskIt->second.aliases )
{
aliases += " using " + stripPrefix( a.first, "Vk" ) + " = " + bitmaskName + ";\n";
}
static const std::string bitmaskTemplate = R"( static const std::string bitmaskTemplate = R"(
using ${bitmaskName} = Flags<${enumName}>; using ${bitmaskName} = Flags<${enumName}>;
${alias} ${aliases}
template <> struct FlagTraits<${enumName}> template <> struct FlagTraits<${enumName}>
{ {
@ -2576,7 +2572,7 @@ ${alias}
}; };
)"; )";
return replaceWithMap( bitmaskTemplate, { { "alias", alias }, { "allFlags", allFlags }, { "bitmaskName", bitmaskName }, { "enumName", enumName } } ); return replaceWithMap( bitmaskTemplate, { { "aliases", aliases }, { "allFlags", allFlags }, { "bitmaskName", bitmaskName }, { "enumName", enumName } } );
} }
std::string VulkanHppGenerator::generateBitmasksToString() const std::string VulkanHppGenerator::generateBitmasksToString() const
@ -3307,7 +3303,9 @@ std::string VulkanHppGenerator::generateCommandDefinitions( std::vector<RequireD
{ {
if ( listedCommands.insert( command ).second ) if ( listedCommands.insert( command ).second )
{ {
str += generateCommandDefinitions( command, getCommandData( command ).handle ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
str += generateCommandDefinitions( command, commandIt->second.handle );
} }
} }
} }
@ -3316,16 +3314,17 @@ std::string VulkanHppGenerator::generateCommandDefinitions( std::vector<RequireD
std::string VulkanHppGenerator::generateCommandDefinitions( std::string const & command, std::string const & handle ) const std::string VulkanHppGenerator::generateCommandDefinitions( std::string const & command, std::string const & handle ) const
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
std::string str = "\n" + generateCommand( command, commandData, handle.empty() ? 0 : 1, true, false ); std::string str = "\n" + generateCommand( command, commandIt->second, handle.empty() ? 0 : 1, true, false );
// special handling for destroy functions, filter out alias functions // special handling for destroy functions, filter out alias functions
std::string commandName = generateCommandName( command, commandData.params, 1 ); std::string commandName = generateCommandName( command, commandIt->second.params, 1 );
if ( !m_commandAliases.contains( command ) && ( ( ( command.substr( 2, 7 ) == "Destroy" ) && ( commandName != "destroy" ) ) || if ( ( command == commandIt->first ) && ( ( ( command.substr( 2, 7 ) == "Destroy" ) && ( commandName != "destroy" ) ) ||
( command.substr( 2, 4 ) == "Free" ) || ( command == "vkReleasePerformanceConfigurationINTEL" ) ) ) ( command.substr( 2, 4 ) == "Free" ) || ( command == "vkReleasePerformanceConfigurationINTEL" ) ) )
{ {
CommandData specialCommandData = commandData; CommandData specialCommandData = commandIt->second;
assert( ( 1 < specialCommandData.params.size() ) && ( specialCommandData.params[0].type.type == handle ) ); assert( ( 1 < specialCommandData.params.size() ) && ( specialCommandData.params[0].type.type == handle ) );
specialCommandData.params[1].optional = false; // make sure, the object to destroy/free/release is not optional in the shortened version! specialCommandData.params[1].optional = false; // make sure, the object to destroy/free/release is not optional in the shortened version!
@ -3365,10 +3364,10 @@ std::string VulkanHppGenerator::generateCommandDefinitions( std::string const &
} }
// we need to remove the default argument for the first argument, to prevent ambiguities! // we need to remove the default argument for the first argument, to prevent ambiguities!
assert( 1 < commandData.params.size() ); assert( 1 < commandIt->second.params.size() );
pos = destroyCommandString.find( commandData.params[1].name ); // skip the standard version of the function pos = destroyCommandString.find( commandIt->second.params[1].name ); // skip the standard version of the function
assert( pos != std::string::npos ); assert( pos != std::string::npos );
pos = destroyCommandString.find( commandData.params[1].name, pos = destroyCommandString.find( commandIt->second.params[1].name,
pos + 1 ); // get the argument to destroy in the advanced version pos + 1 ); // get the argument to destroy in the advanced version
assert( pos != std::string::npos ); assert( pos != std::string::npos );
pos = destroyCommandString.find( " VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT", pos ); pos = destroyCommandString.find( " VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT", pos );
@ -6455,8 +6454,8 @@ std::string VulkanHppGenerator::generateDestroyCommand( std::string const & name
{ {
// special handling for destroy functions, filter out alias functions // special handling for destroy functions, filter out alias functions
std::string commandName = generateCommandName( name, commandData.params, 1 ); std::string commandName = generateCommandName( name, commandData.params, 1 );
if ( !m_commandAliases.contains( name ) && ( ( ( name.substr( 2, 7 ) == "Destroy" ) && ( commandName != "destroy" ) ) || ( name.substr( 2, 4 ) == "Free" ) || if ( m_commands.contains( name ) && ( ( ( name.substr( 2, 7 ) == "Destroy" ) && ( commandName != "destroy" ) ) || ( name.substr( 2, 4 ) == "Free" ) ||
( name == "vkReleasePerformanceConfigurationINTEL" ) ) ) ( name == "vkReleasePerformanceConfigurationINTEL" ) ) )
{ {
assert( 1 < commandData.params.size() ); assert( 1 < commandData.params.size() );
// make sure, the object to destroy/free/release is not optional in the shortened version! // make sure, the object to destroy/free/release is not optional in the shortened version!
@ -6502,7 +6501,9 @@ std::string VulkanHppGenerator::generateDestroyCommand( std::string const & name
return ""; return "";
} }
std::string VulkanHppGenerator::generateDispatchLoaderDynamicCommandAssignment( std::string const & commandName, std::string const & firstArg ) const std::string VulkanHppGenerator::generateDispatchLoaderDynamicCommandAssignment( std::string const & commandName,
std::string const & aliasName,
std::string const & firstArg ) const
{ {
if ( commandName == "vkGetInstanceProcAddr" ) if ( commandName == "vkGetInstanceProcAddr" )
{ {
@ -6512,10 +6513,9 @@ std::string VulkanHppGenerator::generateDispatchLoaderDynamicCommandAssignment(
std::string str = " " + commandName + " = PFN_" + commandName + "( vkGet" + ( ( firstArg == "device" ) ? "Device" : "Instance" ) + "ProcAddr( " + std::string str = " " + commandName + " = PFN_" + commandName + "( vkGet" + ( ( firstArg == "device" ) ? "Device" : "Instance" ) + "ProcAddr( " +
firstArg + ", \"" + commandName + "\" ) );\n"; firstArg + ", \"" + commandName + "\" ) );\n";
// if this is an alias'ed function, use it as a fallback for the original one // if this is an alias'ed function, use it as a fallback for the original one
auto aliasIt = m_commandAliases.find( commandName ); if ( commandName != aliasName )
if ( aliasIt != m_commandAliases.end() )
{ {
str += " if ( !" + aliasIt->second.name + " ) " + aliasIt->second.name + " = " + commandName + ";\n"; str += " if ( !" + aliasName + " ) " + aliasName + " = " + commandName + ";\n";
} }
return str; return str;
} }
@ -6532,12 +6532,13 @@ std::string VulkanHppGenerator::generateDispatchLoaderStaticCommands( std::vecto
// some commands are listed for multiple extensions ! // some commands are listed for multiple extensions !
if ( listedCommands.insert( command ).second ) if ( listedCommands.insert( command ).second )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
str += "\n"; str += "\n";
std::string parameterList, parameters; std::string parameterList, parameters;
assert( !commandData.params.empty() ); assert( !commandIt->second.params.empty() );
for ( auto param : commandData.params ) for ( auto param : commandIt->second.params )
{ {
parameterList += param.type.compose( "" ) + " " + param.name + generateCArraySizes( param.arraySizes ) + ", "; parameterList += param.type.compose( "" ) + " " + param.name + generateCArraySizes( param.arraySizes ) + ", ";
parameters += param.name + ", "; parameters += param.name + ", ";
@ -6555,7 +6556,7 @@ std::string VulkanHppGenerator::generateDispatchLoaderStaticCommands( std::vecto
str += replaceWithMap( str += replaceWithMap(
commandTemplate, commandTemplate,
{ { "commandName", command }, { "parameterList", parameterList }, { "parameters", parameters }, { "returnType", commandData.returnType } } ); { { "commandName", command }, { "parameterList", parameterList }, { "parameters", parameters }, { "returnType", commandIt->second.returnType } } );
} }
} }
} }
@ -7707,13 +7708,14 @@ std::string VulkanHppGenerator::generateHandleCommandDeclarations( std::set<std:
str += "\n" + enter + " //=== " + extension.name + " ===\n"; str += "\n" + enter + " //=== " + extension.name + " ===\n";
for ( auto const & command : commandNames ) for ( auto const & command : commandNames )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
std::string commandString; std::string commandString;
std::string commandName = generateCommandName( command, commandData.params, 1 ); std::string commandName = generateCommandName( command, commandIt->second.params, 1 );
str += "\n"; str += "\n";
str += generateCommand( command, commandData, 1, false, false ); str += generateCommand( command, commandIt->second, 1, false, false );
str += generateDestroyCommand( command, commandData ); str += generateDestroyCommand( command, commandIt->second );
} }
str += leave; str += leave;
} }
@ -7726,8 +7728,9 @@ std::string VulkanHppGenerator::generateHandleDependencies( std::pair<std::strin
std::string str; std::string str;
for ( auto const & command : handleData.second.commands ) for ( auto const & command : handleData.second.commands )
{ {
auto const & commandData = getCommandData( command ); auto commandIt = findByNameOrAlias( m_commands, command );
for ( auto const & parameter : commandData.params ) assert( commandIt != m_commands.end() );
for ( auto const & parameter : commandIt->second.params )
{ {
auto handleIt = m_handles.find( parameter.type.type ); auto handleIt = m_handles.find( parameter.type.type );
if ( ( handleIt != m_handles.end() ) && ( parameter.type.type != handleData.first ) && !listedHandles.contains( parameter.type.type ) ) if ( ( handleIt != m_handles.end() ) && ( parameter.type.type != handleData.first ) && !listedHandles.contains( parameter.type.type ) )
@ -8492,7 +8495,9 @@ std::string VulkanHppGenerator::generateRAIIHandleCommand( std::string const & c
std::string str; std::string str;
if ( !m_RAIISpecialFunctions.contains( command ) ) if ( !m_RAIISpecialFunctions.contains( command ) )
{ {
str = generateCommand( command, getCommandData( command ), initialSkipCount, definition, true ); auto commandIt = findByNameOrAlias( m_commands, command );
assert( commandIt != m_commands.end() );
str = generateCommand( command, commandIt->second, initialSkipCount, definition, true );
} }
return str; return str;
} }
@ -12155,19 +12160,6 @@ ${throws}
return onlyThrows ? throws : replaceWithMap( sizeCheckTemplate, { { "assertions", assertions }, { "throws", throws } } ); return onlyThrows ? throws : replaceWithMap( sizeCheckTemplate, { { "assertions", assertions }, { "throws", throws } } );
} }
VulkanHppGenerator::CommandData const & VulkanHppGenerator::getCommandData( std::string const & command ) const
{
auto commandIt = m_commands.find( command );
if ( commandIt == m_commands.end() )
{
auto aliasIt = m_commandAliases.find( command );
assert( aliasIt != m_commandAliases.end() );
commandIt = m_commands.find( aliasIt->second.name );
assert( commandIt != m_commands.end() );
}
return commandIt->second;
}
std::pair<std::string, std::string> VulkanHppGenerator::getParentTypeAndName( std::pair<std::string, HandleData> const & handle ) const std::pair<std::string, std::string> VulkanHppGenerator::getParentTypeAndName( std::pair<std::string, HandleData> const & handle ) const
{ {
std::string parentType, parentName; std::string parentType, parentName;
@ -12305,14 +12297,8 @@ void VulkanHppGenerator::handleRemoval( RemoveData const & removeData )
for ( auto const & command : removeData.commands ) for ( auto const & command : removeData.commands )
{ {
bool removed = false; bool removed = false;
auto commandIt = m_commands.find( command ); auto commandIt = findByNameOrAlias( m_commands, command );
if ( commandIt == m_commands.end() ) assert( commandIt != m_commands.end() );
{
auto aliasIt = m_commandAliases.find( command );
assert( aliasIt != m_commandAliases.end() );
commandIt = m_commands.find( aliasIt->second.name );
assert( commandIt != m_commands.end() );
}
for ( auto const & requiredBy : commandIt->second.requiredBy ) for ( auto const & requiredBy : commandIt->second.requiredBy )
{ {
auto featureIt = std::find_if( m_features.begin(), m_features.end(), [&requiredBy]( FeatureData const & fd ) { return fd.name == requiredBy; } ); auto featureIt = std::find_if( m_features.begin(), m_features.end(), [&requiredBy]( FeatureData const & fd ) { return fd.name == requiredBy; } );
@ -12730,8 +12716,10 @@ void VulkanHppGenerator::readCommand( tinyxml2::XMLElement const * element )
std::string name = attributes.find( "name" )->second; std::string name = attributes.find( "name" )->second;
checkForError( name.starts_with( "vk" ), line, "name <" + name + "> should begin with \"vk\"" ); checkForError( name.starts_with( "vk" ), line, "name <" + name + "> should begin with \"vk\"" );
checkForError( m_commands.contains( alias ), line, "command <" + name + "> is aliased to unknown command <" + alias + ">" ); auto commandIt = m_commands.find( alias );
checkForError( m_commandAliases.insert( { name, { alias, line } } ).second, line, "command <" + name + "> already specified as alias" ); checkForError( commandIt != m_commands.end(), line, "command <" + name + "> is aliased to unknown command <" + alias + ">" );
checkForError(
commandIt->second.aliases.insert( { name, line } ).second, line, "command <" + name + "> is already listed as alias for command <" + alias + ">" );
} }
else else
{ {
@ -13850,14 +13838,8 @@ std::string VulkanHppGenerator::readRequireCommand( tinyxml2::XMLElement const *
checkElements( line, getChildElements( element ), {} ); checkElements( line, getChildElements( element ), {} );
std::string name = attributes.find( "name" )->second; std::string name = attributes.find( "name" )->second;
auto commandIt = m_commands.find( name ); auto commandIt = findByNameOrAlias( m_commands, name );
if ( commandIt == m_commands.end() ) assert( commandIt != m_commands.end() );
{
auto aliasIt = m_commandAliases.find( name );
checkForError( aliasIt != m_commandAliases.end(), line, "unknown required command <" + name + ">" );
commandIt = m_commands.find( aliasIt->second.name );
assert( commandIt != m_commands.end() );
}
commandIt->second.requiredBy.insert( requiredBy ); commandIt->second.requiredBy.insert( requiredBy );
return name; return name;
@ -14634,19 +14616,31 @@ void VulkanHppGenerator::readTypeBitmask( tinyxml2::XMLElement const * element,
{ {
const int line = element->GetLineNum(); const int line = element->GetLineNum();
auto aliasIt = attributes.find( "alias" ); if ( attributes.contains( "alias" ) )
if ( aliasIt != attributes.end() )
{ {
checkAttributes( line, attributes, { { "alias", {} }, { "category", { "bitmask" } }, { "name", {} } }, {} ); checkAttributes( line, attributes, { { "alias", {} }, { "category", { "bitmask" } }, { "name", {} } }, {} );
checkElements( line, getChildElements( element ), {} ); checkElements( line, getChildElements( element ), {} );
std::string alias = aliasIt->second; std::string alias, name;
std::string name = attributes.find( "name" )->second; for ( auto const & attribute : attributes )
{
if ( attribute.first == "alias" )
{
alias = attribute.second;
}
else if ( attribute.first == "name" )
{
name = attribute.second;
}
}
checkForError( m_bitmasks.contains( alias ), line, "bitmask <" + name + "> is an alias of an unknown bitmask <" + alias + ">." );
checkForError( m_types.insert( { name, TypeData{ TypeCategory::Bitmask, {}, line } } ).second, line, "bitmask <" + name + "> already specified" ); checkForError( m_types.insert( { name, TypeData{ TypeCategory::Bitmask, {}, line } } ).second, line, "bitmask <" + name + "> already specified" );
assert( !m_bitmaskAliases.contains( name ) );
m_bitmaskAliases[name] = { alias, line }; auto bitmaskIt = m_bitmasks.find( alias );
checkForError( bitmaskIt != m_bitmasks.end(), line, "bitmask <" + name + "> is an alias of an unknown bitmask <" + alias + ">." );
checkForError( bitmaskIt->second.aliases.insert( { name, line } ).second,
line,
"bitmask alias <" + name + "> is already listed as an alias for bitmask <" + alias + ">" );
} }
else else
{ {
@ -14691,7 +14685,7 @@ void VulkanHppGenerator::readTypeBitmask( tinyxml2::XMLElement const * element,
checkForError( checkForError(
m_types.insert( { nameData.name, TypeData{ TypeCategory::Bitmask, {}, line } } ).second, line, "bitmask <" + nameData.name + "> already specified" ); m_types.insert( { nameData.name, TypeData{ TypeCategory::Bitmask, {}, line } } ).second, line, "bitmask <" + nameData.name + "> already specified" );
assert( !m_bitmasks.contains( nameData.name ) ); assert( !m_bitmasks.contains( nameData.name ) );
m_bitmasks[nameData.name] = { require, typeInfo.type, line }; m_bitmasks[nameData.name] = { {}, require, typeInfo.type, line };
} }
} }
} }
@ -15444,6 +15438,32 @@ namespace
return std::find_if( values.begin(), values.end(), [&name]( T const & value ) { return value.name == name; } ); return std::find_if( values.begin(), values.end(), [&name]( T const & value ) { return value.name == name; } );
} }
template <typename T>
typename std::map<std::string, T>::const_iterator findByNameOrAlias( std::map<std::string, T> const & values, std::string const & name )
{
auto it = values.find( name );
if ( it == values.end() )
{
it = std::find_if(
values.begin(), values.end(), [&name]( auto const & value ) { return ( value.first == name ) || value.second.aliases.contains( name ); } );
}
assert( it != values.end() );
return it;
}
template <typename T>
typename std::map<std::string, T>::iterator findByNameOrAlias( std::map<std::string, T> & values, std::string const & name )
{
auto it = values.find( name );
if ( it == values.end() )
{
it = std::find_if(
values.begin(), values.end(), [&name]( auto const & value ) { return ( value.first == name ) || value.second.aliases.contains( name ); } );
}
assert( it != values.end() );
return it;
}
template <typename T> template <typename T>
typename std::vector<T>::const_iterator findByNameOrAlias( std::vector<T> const & values, std::string const & name ) typename std::vector<T>::const_iterator findByNameOrAlias( std::vector<T> const & values, std::string const & name )
{ {

View File

@ -128,9 +128,10 @@ private:
struct BitmaskData struct BitmaskData
{ {
std::string require = {}; std::map<std::string, int> aliases = {};
std::string type = {}; std::string require = {};
int xmlLine = {}; std::string type = {};
int xmlLine = {};
}; };
struct EnumValueAlias struct EnumValueAlias
@ -186,13 +187,14 @@ private:
struct CommandData struct CommandData
{ {
std::vector<std::string> errorCodes = {}; std::map<std::string, int> aliases = {};
std::string handle = {}; std::vector<std::string> errorCodes = {};
std::vector<ParamData> params = {}; std::string handle = {};
std::set<std::string> requiredBy = {}; std::vector<ParamData> params = {};
std::string returnType = {}; std::set<std::string> requiredBy = {};
std::vector<std::string> successCodes = {}; std::string returnType = {};
int xmlLine = {}; std::vector<std::string> successCodes = {};
int xmlLine = {};
}; };
struct ConstantData struct ConstantData
@ -705,7 +707,8 @@ private:
std::string generateDispatchLoaderDynamic() const; // uses vkGet*ProcAddress to get function pointers std::string generateDispatchLoaderDynamic() const; // uses vkGet*ProcAddress to get function pointers
std::string generateDispatchLoaderStatic() const; // uses exported symbols from loader std::string generateDispatchLoaderStatic() const; // uses exported symbols from loader
std::string generateDestroyCommand( std::string const & name, CommandData const & commandData ) const; std::string generateDestroyCommand( std::string const & name, CommandData const & commandData ) const;
std::string generateDispatchLoaderDynamicCommandAssignment( std::string const & commandName, std::string const & firstArg ) const; std::string
generateDispatchLoaderDynamicCommandAssignment( std::string const & commandName, std::string const & aliasName, std::string const & firstArg ) const;
std::string generateDispatchLoaderStaticCommands( std::vector<RequireData> const & requireData, std::string generateDispatchLoaderStaticCommands( std::vector<RequireData> const & requireData,
std::set<std::string> & listedCommands, std::set<std::string> & listedCommands,
std::string const & title ) const; std::string const & title ) const;
@ -912,7 +915,6 @@ private:
std::map<size_t, std::vector<size_t>> const & countToVectorMap, std::map<size_t, std::vector<size_t>> const & countToVectorMap,
std::set<size_t> const & skippedParams, std::set<size_t> const & skippedParams,
bool onlyThrows ) const; bool onlyThrows ) const;
CommandData const & getCommandData( std::string const & command ) const;
std::pair<std::string, std::string> getParentTypeAndName( std::pair<std::string, HandleData> const & handle ) const; std::pair<std::string, std::string> getParentTypeAndName( std::pair<std::string, HandleData> const & handle ) const;
std::string getPlatform( std::string const & title ) const; std::string getPlatform( std::string const & title ) const;
std::pair<std::string, std::string> getPoolTypeAndName( std::string const & type ) const; std::pair<std::string, std::string> getPoolTypeAndName( std::string const & type ) const;
@ -1029,9 +1031,7 @@ private:
private: private:
std::string m_api; std::string m_api;
std::map<std::string, BaseTypeData> m_baseTypes; std::map<std::string, BaseTypeData> m_baseTypes;
std::map<std::string, AliasData> m_bitmaskAliases;
std::map<std::string, BitmaskData> m_bitmasks; std::map<std::string, BitmaskData> m_bitmasks;
std::map<std::string, AliasData> m_commandAliases;
std::map<std::string, CommandData> m_commands; std::map<std::string, CommandData> m_commands;
std::map<std::string, AliasData> m_constantAliases; std::map<std::string, AliasData> m_constantAliases;
std::map<std::string, ConstantData> m_constants; std::map<std::string, ConstantData> m_constants;