From 976debbd80641325c77ff2da29decd2553098342 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Mon, 22 Nov 2021 14:27:34 +0100 Subject: [PATCH] Add support for new elements in vk.xml. --- VulkanHppGenerator.cpp | 209 +++++++++++++++++++++++++++++++++++++++++ VulkanHppGenerator.hpp | 44 +++++++++ 2 files changed, 253 insertions(+) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index e867d20..eb21d95 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -13435,6 +13435,210 @@ void VulkanHppGenerator::readFeatureRequireType( tinyxml2::XMLElement const * } } +void VulkanHppGenerator::readFormats( tinyxml2::XMLElement const * element ) +{ + int line = element->GetLineNum(); + checkAttributes( line, getAttributes( element ), {}, {} ); + std::vector children = getChildElements( element ); + checkElements( line, children, { { "format", false } } ); + + for ( auto child : children ) + { + readFormatsFormat( child ); + } +} + +void VulkanHppGenerator::readFormatsFormat( tinyxml2::XMLElement const * element ) +{ + int line = element->GetLineNum(); + std::map attributes = getAttributes( element ); + checkAttributes( + line, + attributes, + { { "blockSize", { "1", "2", "3", "4", "5", "6", "8", "12", "16", "24", "32" } }, + { "class", {} }, + { "name", {} }, + { "texelsPerBlock", + { "1", "16", "20", "25", "30", "36", "40", "48", "50", "60", "64", "80", "100", "120", "144" } } }, + { { "blockExtent", { "1", "2", "4", "5", "6", "8", "10", "12" } }, + { "chroma", { "420", "422", "444" } }, + { "compressed", { "ASTC HDR", "ASTC LDR", "BC", "EAC", "ETC", "ETC2", "PVRTC" } }, + { "packed", { "8", "16", "32" } } } ); + std::vector children = getChildElements( element ); + checkElements( line, children, { { "component", false } }, { "plane", "spirvimageformat" } ); + + FormatData format( line ); + std::string name; + for ( auto const & attribute : attributes ) + { + if ( attribute.first == "blockExtent" ) + { + check( tokenize( attribute.second, "," ).size() == 3, + line, + "unexpected number of elements in attribute " ); + format.blockExtent = attribute.second; + } + if ( attribute.first == "blockSize" ) + { + format.blockSize = attribute.second; + } + else if ( attribute.first == "chroma" ) + { + format.chroma = attribute.second; + } + else if ( attribute.first == "class" ) + { + format.classAttribute = attribute.second; + } + else if ( attribute.first == "compressed" ) + { + format.compressed = attribute.second; + } + else if ( attribute.first == "name" ) + { + name = attribute.second; + } + else if ( attribute.first == "packed" ) + { + format.packed = attribute.second; + } + else if ( attribute.first == "texelsPerBlock" ) + { + format.texelsPerBlock = attribute.second; + } + } + + auto formatIt = m_enums.find( "VkFormat" ); + assert( formatIt != m_enums.end() ); + + check( std::find_if( formatIt->second.values.begin(), + formatIt->second.values.end(), + [&name]( EnumValueData const & evd ) + { return evd.name == name; } ) != formatIt->second.values.end(), + line, + "format <" + name + "> not found in the list of formats specified on line " + + std::to_string( formatIt->second.xmlLine ) ); + auto [it, inserted] = m_formats.insert( std::make_pair( name, format ) ); + check( inserted, line, "format <" + name + "> already specified on line " + std::to_string( it->second.xmlLine ) ); + + for ( auto child : children ) + { + std::string value = child->Value(); + if ( value == "component" ) + { + readFormatsFormatComponent( child, it->second ); + } + else if ( value == "plane" ) + { + readFormatsFormatPlane( child, it->second ); + } + else if ( value == "spirvimageformat" ) + { + readFormatsFormatSPIRVImageFormat( child, it->second ); + } + } +} + +void VulkanHppGenerator::readFormatsFormatComponent( tinyxml2::XMLElement const * element, FormatData & formatData ) +{ + int line = element->GetLineNum(); + std::map attributes = getAttributes( element ); + checkAttributes( + line, + attributes, + { { "bits", { "1", "2", "4", "5", "6", "8", "9", "10", "11", "12", "16", "24", "32", "64", "compressed" } }, + { "name", {} }, + { "numericFormat", { "SFLOAT", "SINT", "SNORM", "SRGB", "SSCALED", "UFLOAT", "UINT", "UNORM", "USCALED" } } }, + { { "planeIndex", { "0", "1", "2" } } } ); + checkElements( line, getChildElements( element ), {} ); + + formatData.components.emplace_back( line ); + ComponentData & component = formatData.components.back(); + for ( auto const & attribute : attributes ) + { + if ( attribute.first == "bits" ) + { + check( ( attribute.second != "compressed" ) || !formatData.compressed.empty(), + line, + "component of a not compressed format is marked as compressed" ); + component.bits = attribute.second; + } + else if ( attribute.first == "name" ) + { + component.name = attribute.second; + } + else if ( attribute.first == "numericFormat" ) + { + component.numericFormat = attribute.second; + } + else if ( attribute.first == "planeIndex" ) + { + component.planeIndex = attribute.second; + } + } +} + +void VulkanHppGenerator::readFormatsFormatPlane( tinyxml2::XMLElement const * element, FormatData & formatData ) +{ + int line = element->GetLineNum(); + std::map attributes = getAttributes( element ); + checkAttributes( line, + attributes, + { { "compatible", {} }, + { "index", { "0", "1", "2" } }, + { "heightDivisor", { "1", "2" } }, + { "widthDivisor", { "1", "2" } } }, + {} ); + checkElements( line, getChildElements( element ), {} ); + + formatData.planes.emplace_back( line ); + PlaneData & plane = formatData.planes.back(); + for ( auto const & attribute : attributes ) + { + if ( attribute.first == "compatible" ) + { + plane.compatible = attribute.second; + auto formatIt = m_enums.find( "VkFormat" ); + assert( formatIt != m_enums.end() ); + check( std::find_if( formatIt->second.values.begin(), + formatIt->second.values.end(), + [&plane]( EnumValueData const & evd ) + { return evd.name == plane.compatible; } ) != formatIt->second.values.end(), + line, + "encountered unknown format <" + plane.compatible + ">" ); + } + else if ( attribute.first == "index" ) + { + size_t index = std::stoi( attribute.second ); + check( index + 1 == formatData.planes.size(), line, "unexpected index <" + attribute.second + ">" ); + } + else if ( attribute.first == "heightDivisor" ) + { + plane.heightDivisor = attribute.second; + } + else if ( attribute.first == "widthDivisor" ) + { + plane.widthDivisor = attribute.second; + } + } +} + +void VulkanHppGenerator::readFormatsFormatSPIRVImageFormat( tinyxml2::XMLElement const * element, + FormatData & formatData ) +{ + int line = element->GetLineNum(); + std::map attributes = getAttributes( element ); + checkAttributes( line, attributes, { { "name", {} } }, {} ); + checkElements( line, getChildElements( element ), {} ); + + for ( auto const & attribute : attributes ) + { + assert( attribute.first == "name" ); + check( formatData.spirvImageFormat.empty(), line, "spirvimageformat <" + attribute.second + "> already specified" ); + formatData.spirvImageFormat = attribute.second; + } +} + std::pair VulkanHppGenerator::readNameAndType( tinyxml2::XMLElement const * element ) { @@ -13526,6 +13730,7 @@ void VulkanHppGenerator::readRegistry( tinyxml2::XMLElement const * element ) { "enums", false }, { "extensions", true }, { "feature", false }, + { "formats", true }, { "platforms", true }, { "spirvcapabilities", true }, { "spirvextensions", true }, @@ -13558,6 +13763,10 @@ void VulkanHppGenerator::readRegistry( tinyxml2::XMLElement const * element ) { readFeature( child ); } + else if ( value == "formats" ) + { + readFormats( child ); + } else if ( value == "platforms" ) { readPlatforms( child ); diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 6fe73b1..d299ac2 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -228,6 +228,44 @@ private: int xmlLine; }; + struct ComponentData + { + ComponentData( int line ) : xmlLine( line ) {} + + std::string bits; + std::string name; + std::string numericFormat; + std::string planeIndex; + int xmlLine; + }; + + struct PlaneData + { + PlaneData( int line ) : xmlLine( line ) {} + + std::string compatible; + std::string heightDivisor; + std::string widthDivisor; + int xmlLine; + }; + + struct FormatData + { + FormatData( int line ) : xmlLine( line ) {} + + std::string blockExtent; + std::string blockSize; + std::string chroma; + std::string classAttribute; + std::vector components; + std::string compressed; + std::string packed; + std::vector planes; + std::string spirvImageFormat; + std::string texelsPerBlock; + int xmlLine; + }; + struct FuncPointerArgumentData { FuncPointerArgumentData( std::string const & t, int line ) : type( t ), xmlLine( line ) {} @@ -1242,6 +1280,11 @@ private: void readFeatureRequireType( tinyxml2::XMLElement const * element, std::map::iterator featureIt, RequireData & requireData ); + void readFormats( tinyxml2::XMLElement const * element ); + void readFormatsFormat( tinyxml2::XMLElement const * element ); + void readFormatsFormatComponent( tinyxml2::XMLElement const * element, FormatData & formatData ); + void readFormatsFormatPlane( tinyxml2::XMLElement const * element, FormatData & formatData ); + void readFormatsFormatSPIRVImageFormat( tinyxml2::XMLElement const * element, FormatData & formatData ); std::pair readNameAndType( tinyxml2::XMLElement const * elements ); void readPlatforms( tinyxml2::XMLElement const * element ); void readPlatformsPlatform( tinyxml2::XMLElement const * element ); @@ -1314,6 +1357,7 @@ private: std::map m_extensions; std::map::const_iterator> m_extensionsByNumber; std::map m_features; + std::map m_formats; std::map m_funcPointers; std::map m_handles; std::set m_includes;