From 4aa2b3f4dc93c815adc511dfec926c77795ceabb Mon Sep 17 00:00:00 2001 From: Markus Tavenrath Date: Thu, 18 Feb 2016 09:45:18 +0100 Subject: [PATCH] Fix issue #13, support extending enums by extensions --- VkCppGenerator.cpp | 88 +++++++++++++++++++++++++++++++--------------- vulkan/vk_cpp.h | 25 +++++++++++-- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/VkCppGenerator.cpp b/VkCppGenerator.cpp index d9cae97..3fdd47a 100644 --- a/VkCppGenerator.cpp +++ b/VkCppGenerator.cpp @@ -214,7 +214,11 @@ struct NameValue struct EnumData { bool bitmask; + std::string prefix; + std::string postfix; std::vector members; + + void addEnum(std::string const & name); }; struct CommandData @@ -259,6 +263,7 @@ struct DependencyData void createDefaults( std::vector const& dependencies, std::map const& enums, std::map & defaultValues ); size_t findComplexIndex(CommandData const& commandData, std::vector> const& lenParameters); size_t findReturnIndex(CommandData const& commandData, std::vector> const& lenParameters); +std::string getEnumName(std::string const& name); // get vkcpp enum name from vk enum name std::vector> getLenParameters(CommandData const& commandData); bool noDependencies(std::set const& dependencies, std::map & listedTypes); void readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ); @@ -266,10 +271,10 @@ CommandData & readCommandProto( tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands ); void readCommandsCommand( tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands ); void readEnums( tinyxml2::XMLElement * element, std::list & dependencies, std::map & enums, std::set & vkTypes ); -void readEnumsEnum( tinyxml2::XMLElement * element, std::string const& prefix, std::string const& postfix, EnumData & enumData ); -void readExtensionRequire( tinyxml2::XMLElement * element, std::vector & elements ); -void readExtensions( tinyxml2::XMLElement * element, std::vector & extensions ); -void readExtensionsExtension( tinyxml2::XMLElement * element, std::vector & extensions ); +void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData ); +void readExtensionRequire( tinyxml2::XMLElement * element, std::vector & elements, std::map & enums ); +void readExtensions( tinyxml2::XMLElement * element, std::vector & extensions, std::map & enums ); +void readExtensionsExtension(tinyxml2::XMLElement * element, std::vector & extensions, std::map & enums); void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ); void readTypeBitmask( tinyxml2::XMLElement * element, std::list & dependencies, std::set & flags, std::set & 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 const& dependencies, std::map const& commands, std::map const& enums, std::map const& structs, std::map const& defaultValues, std::set 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 const& dependencies, std::map const& enums, std::map & defaultValues ) { for ( std::vector::const_iterator it = dependencies.begin() ; it != dependencies.end() ; ++it ) @@ -374,6 +394,11 @@ size_t findReturnIndex(CommandData const& commandData, std::vector> getLenParameters(CommandData const& commandData) { std::vector> lenParameters; @@ -545,7 +570,7 @@ void readCommandsCommand( tinyxml2::XMLElement * element, std::list & dependencies, std::map & enums, std::set & 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 & 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 & elements ) +void readExtensionRequire(tinyxml2::XMLElement * element, std::vector & elements, std::map & 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::vectorAttribute( "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 & extensions ) +void readExtensions(tinyxml2::XMLElement * element, std::vector & extensions, std::map & 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 & extensions ) +void readExtensionsExtension(tinyxml2::XMLElement * element, std::vector & extensions, std::map & 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::vectorFirstChildElement(); 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 & 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" ) { diff --git a/vulkan/vk_cpp.h b/vulkan/vk_cpp.h index f5453dc..83ff760 100644 --- a/vulkan/vk_cpp.h +++ b/vulkan/vk_cpp.h @@ -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