Fix issue #13, support extending enums by extensions

This commit is contained in:
Markus Tavenrath 2016-02-18 09:45:18 +01:00
parent 759aca579f
commit 4aa2b3f4dc
2 changed files with 82 additions and 31 deletions

View File

@ -214,7 +214,11 @@ struct NameValue
struct EnumData
{
bool bitmask;
std::string prefix;
std::string postfix;
std::vector<NameValue> members;
void addEnum(std::string const & name);
};
struct CommandData
@ -259,6 +263,7 @@ struct DependencyData
void createDefaults( std::vector<DependencyData> const& dependencies, std::map<std::string,EnumData> const& enums, std::map<std::string,std::string> & defaultValues );
size_t findComplexIndex(CommandData const& commandData, std::vector<std::pair<size_t, size_t>> const& lenParameters);
size_t findReturnIndex(CommandData const& commandData, std::vector<std::pair<size_t, size_t>> const& lenParameters);
std::string getEnumName(std::string const& name); // get vkcpp enum name from vk enum name
std::vector<std::pair<size_t, size_t>> getLenParameters(CommandData const& commandData);
bool noDependencies(std::set<std::string> const& dependencies, std::map<std::string, std::string> & listedTypes);
void readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector<MemberData> & arguments );
@ -266,10 +271,10 @@ CommandData & readCommandProto( tinyxml2::XMLElement * element, std::list<Depend
void readCommands( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies, std::map<std::string,CommandData> & commands );
void readCommandsCommand( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies, std::map<std::string,CommandData> & commands );
void readEnums( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies, std::map<std::string,EnumData> & enums, std::set<std::string> & vkTypes );
void readEnumsEnum( tinyxml2::XMLElement * element, std::string const& prefix, std::string const& postfix, EnumData & enumData );
void readExtensionRequire( tinyxml2::XMLElement * element, std::vector<std::string> & elements );
void readExtensions( tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions );
void readExtensionsExtension( tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions );
void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData );
void readExtensionRequire( tinyxml2::XMLElement * element, std::vector<std::string> & elements, std::map<std::string, EnumData> & enums );
void readExtensions( tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions, std::map<std::string, EnumData> & enums );
void readExtensionsExtension(tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions, std::map<std::string, EnumData> & enums);
void readTypeBasetype( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies );
void readTypeBitmask( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies, std::set<std::string> & flags, std::set<std::string> & vkTypes );
void readTypeDefine( tinyxml2::XMLElement * element, std::string & version );
@ -303,6 +308,21 @@ void writeTypeUnion( std::ofstream & ofs, DependencyData const& dependencyData,
void writeTypes( std::ofstream & ofs, std::vector<DependencyData> const& dependencies, std::map<std::string,CommandData> const& commands, std::map<std::string,EnumData> const& enums, std::map<std::string,StructData> const& structs, std::map<std::string,std::string> const& defaultValues, std::set<std::string> const& vkTypes );
void writeVersionCheck( std::ofstream & ofs, std::string const& version );
void EnumData::addEnum(std::string const & name)
{
members.push_back(NameValue());
members.back().name = "e" + toCamelCase(strip(name, prefix));
members.back().value = name;
if (!postfix.empty())
{
size_t pos = members.back().name.find(postfix);
if (pos != std::string::npos)
{
members.back().name.erase(pos);
}
}
}
void createDefaults( std::vector<DependencyData> const& dependencies, std::map<std::string,EnumData> const& enums, std::map<std::string,std::string> & defaultValues )
{
for ( std::vector<DependencyData>::const_iterator it = dependencies.begin() ; it != dependencies.end() ; ++it )
@ -374,6 +394,11 @@ size_t findReturnIndex(CommandData const& commandData, std::vector<std::pair<siz
return ~0;
}
std::string getEnumName(std::string const& name) // get vkcpp enum name from vk enum name
{
return strip(name, "Vk");
}
std::vector<std::pair<size_t, size_t>> getLenParameters(CommandData const& commandData)
{
std::vector<std::pair<size_t,size_t>> lenParameters;
@ -545,7 +570,7 @@ void readCommandsCommand( tinyxml2::XMLElement * element, std::list<DependencyDa
void readEnums( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies, std::map<std::string,EnumData> & enums, std::set<std::string> & vkTypes )
{
assert( element->Attribute( "name" ) );
std::string name = strip( element->Attribute( "name" ), "Vk" );
std::string name = getEnumName(element->Attribute("name"));
if ( name != "API Constants" )
{
dependencies.push_back( DependencyData( DependencyData::Category::ENUM, name ) );
@ -560,50 +585,41 @@ void readEnums( tinyxml2::XMLElement * element, std::list<DependencyData> & depe
{
size_t pos = name.find( "FlagBits" );
assert( pos != std::string::npos );
prefix = "VK" + toUpperCase( name.substr( 0, pos ) ) + "_";
postfix = "Bit";
it->second.prefix = "VK" + toUpperCase( name.substr( 0, pos ) ) + "_";
it->second.postfix = "Bit";
}
else
{
prefix = "VK" + toUpperCase( name ) + "_";
it->second.prefix = "VK" + toUpperCase( name ) + "_";
}
readEnumsEnum( element, prefix, postfix, it->second );
readEnumsEnum( element, it->second );
assert( vkTypes.find( name ) == vkTypes.end() );
vkTypes.insert( name );
}
}
void readEnumsEnum( tinyxml2::XMLElement * element, std::string const& prefix, std::string const& postfix, EnumData & enumData )
void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData )
{
tinyxml2::XMLElement * child = element->FirstChildElement();
do
{
if ( child->Attribute( "name" ) )
{
enumData.members.push_back( NameValue() );
enumData.members.back().name = "e" + toCamelCase( strip( child->Attribute( "name" ), prefix ) );
enumData.members.back().value = child->Attribute( "name" );
if ( !postfix.empty() )
{
size_t pos = enumData.members.back().name.find( postfix );
if ( pos != std::string::npos )
{
enumData.members.back().name.erase( pos );
}
}
enumData.addEnum(child->Attribute("name"));
}
} while ( child = child->NextSiblingElement() );
}
void readExtensionRequire( tinyxml2::XMLElement * element, std::vector<std::string> & elements )
void readExtensionRequire(tinyxml2::XMLElement * element, std::vector<std::string> & elements, std::map<std::string, EnumData> & enums)
{
tinyxml2::XMLElement * child = element->FirstChildElement();
do
{
std::string value = child->Value();
assert( child->Attribute( "name" ) );
if ( value == "command" )
{
elements.push_back( strip( child->Attribute( "name" ), "vk" ) );
@ -614,31 +630,47 @@ void readExtensionRequire( tinyxml2::XMLElement * element, std::vector<std::stri
{
elements.push_back( strip( child->Attribute( "name" ), "Vk" ) );
}
else if ( value == "enum")
{
// TODO process enums which don't extend existing enums
if (child->Attribute("extends"))
{
assert(enums.find(getEnumName(child->Attribute("extends"))) != enums.end());
enums[getEnumName(child->Attribute("extends"))].addEnum(child->Attribute("name"));
}
}
else
{
assert( value == "enum" );
assert("unknown attribute, check me");
}
} while ( child = child->NextSiblingElement() );
}
void readExtensions( tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions )
void readExtensions(tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions, std::map<std::string, EnumData> & enums)
{
tinyxml2::XMLElement * child = element->FirstChildElement();
assert( child );
do
{
assert( strcmp( child->Value(), "extension" ) == 0 );
readExtensionsExtension( child, extensions );
readExtensionsExtension( child, extensions, enums );
} while ( child = child->NextSiblingElement() );
}
void readExtensionsExtension( tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions )
void readExtensionsExtension(tinyxml2::XMLElement * element, std::vector<ExtensionData> & extensions, std::map<std::string, EnumData> & enums )
{
extensions.push_back( ExtensionData() );
ExtensionData & ext = extensions.back();
assert( element->Attribute( "name" ) );
ext.name = element->Attribute( "name" );
// don't parse disabled extensions
if (strcmp(element->Attribute("supported"), "disabled") == 0)
{
return;
}
if ( element->Attribute( "protect" ) )
{
ext.protect = element->Attribute( "protect" );
@ -646,7 +678,7 @@ void readExtensionsExtension( tinyxml2::XMLElement * element, std::vector<Extens
tinyxml2::XMLElement * child = element->FirstChildElement();
assert( child && ( strcmp( child->Value(), "require" ) == 0 ) && !child->NextSiblingElement() );
readExtensionRequire( child, ext.elements );
readExtensionRequire( child, ext.elements, enums);
}
void readTypeBasetype( tinyxml2::XMLElement * element, std::list<DependencyData> & dependencies )
@ -1848,7 +1880,7 @@ int main( int argc, char **argv )
}
else if ( value == "extensions" )
{
readExtensions( child, extensions );
readExtensions( child, extensions, enums );
}
else if ( value == "types" )
{

View File

@ -2170,7 +2170,8 @@ namespace vk
eShaderReadOnlyOptimal = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
eTransferSrcOptimal = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
eTransferDstOptimal = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
ePreinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED
ePreinitialized = VK_IMAGE_LAYOUT_PREINITIALIZED,
ePresentSrcKhr = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
};
class DescriptorImageInfo
@ -3270,7 +3271,19 @@ namespace vk
eImageMemoryBarrier = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
eMemoryBarrier = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
eLoaderInstanceCreateInfo = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO,
eLoaderDeviceCreateInfo = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
eLoaderDeviceCreateInfo = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
eSwapchainCreateInfoKhr = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
ePresentInfoKhr = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
eDisplayModeCreateInfoKhr = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR,
eDisplaySurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR,
eDisplayPresentInfoKhr = VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR,
eXlibSurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
eXcbSurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
eWaylandSurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
eMirSurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR,
eAndroidSurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
eWin32SurfaceCreateInfoKhr = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
eDebugReportCreateInfoExt = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT
};
class ApplicationInfo
@ -5865,7 +5878,13 @@ namespace vk
eVkErrorFeatureNotPresent = VK_ERROR_FEATURE_NOT_PRESENT,
eVkErrorIncompatibleDriver = VK_ERROR_INCOMPATIBLE_DRIVER,
eVkErrorTooManyObjects = VK_ERROR_TOO_MANY_OBJECTS,
eVkErrorFormatNotSupported = VK_ERROR_FORMAT_NOT_SUPPORTED
eVkErrorFormatNotSupported = VK_ERROR_FORMAT_NOT_SUPPORTED,
eVkErrorSurfaceLostKhr = VK_ERROR_SURFACE_LOST_KHR,
eVkErrorNativeWindowInUseKhr = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR,
eVkSuboptimalKhr = VK_SUBOPTIMAL_KHR,
eVkErrorOutOfDateKhr = VK_ERROR_OUT_OF_DATE_KHR,
eVkErrorIncompatibleDisplayKhr = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR,
eVkErrorValidationFailedExt = VK_ERROR_VALIDATION_FAILED_EXT
};
class PresentInfoKHR