From 45e06d1753514e9368aaebe2ed079aa88285bafc Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Thu, 10 Dec 2020 17:23:44 +0100 Subject: [PATCH] Special handling for detecting mutual exclusive len usage on structures. --- VulkanHppGenerator.cpp | 64 +++++++++++++++++++++++++++++++----------- VulkanHppGenerator.hpp | 19 +++++++------ vulkan/vulkan.hpp | 8 +++--- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index d2af0a6..8d2afc5 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -5683,8 +5683,8 @@ void VulkanHppGenerator::appendStructConstructorsEnhanced( std::string & { // len arguments just have an initalizer, from the ArrayProxyNoTemporaries size initializers += - ( firstArgument ? ": " : ", " ) + mit->name + "( " + generateLenInitializer( mit, litit ) + " )"; - sizeChecks += generateSizeCheck( litit->second, stripPrefix( structData.first, "Vk" ), prefix ); + ( firstArgument ? ": " : ", " ) + mit->name + "( " + generateLenInitializer( mit, litit, structData.second.mutualExclusiveLens ) + " )"; + sizeChecks += generateSizeCheck( litit->second, stripPrefix( structData.first, "Vk" ), prefix, structData.second.mutualExclusiveLens ); } else if ( std::find( memberIts.begin(), memberIts.end(), mit ) != memberIts.end() ) { @@ -7035,15 +7035,13 @@ std::string const & VulkanHppGenerator::getVulkanLicenseHeader() const std::string VulkanHppGenerator::generateLenInitializer( std::vector::const_iterator mit, std::map::const_iterator, - std::vector::const_iterator>>::const_iterator litit ) const + std::vector::const_iterator>>::const_iterator litit, + bool mutualExclusiveLens ) const { std::string initializer; - if ( ( 1 < litit->second.size() ) && - ( std::find_if( litit->second.begin(), litit->second.end(), []( std::vector::const_iterator it ) { - return !it->noAutoValidity; - } ) == litit->second.end() ) ) + if (mutualExclusiveLens) { - // there are multiple arrays related to this len, all marked with noautovalidity + // there are multiple mutually exclusive arrays related to this len for ( size_t i = 0; i + 1 < litit->second.size(); i++ ) { auto arrayIt = litit->second[i]; @@ -7121,17 +7119,16 @@ std::pair VulkanHppGenerator::generateProtection( std: std::string VulkanHppGenerator::generateSizeCheck( std::vector::const_iterator> const & arrayIts, std::string const & structName, - std::string const & prefix ) const + std::string const & prefix, + bool mutualExclusiveLens ) const { std::string sizeCheck; if ( 1 < arrayIts.size() ) { std::string assertionText, throwText; - if ( std::find_if( arrayIts.begin(), arrayIts.end(), []( std::vector::const_iterator it ) { - return !it->noAutoValidity; - } ) == arrayIts.end() ) + if (mutualExclusiveLens) { - // all the arrays are marked with noautovalidity -> exactly one of them has to be non-empty + // exactly one of the arrays has to be non-empty std::string sum; for ( size_t first = 0; first + 1 < arrayIts.size(); ++first ) { @@ -7147,10 +7144,6 @@ std::string } else { - // none of the arrays should be marked with noautovalidity ! - assert( std::find_if( arrayIts.begin(), arrayIts.end(), []( std::vector::const_iterator it ) { - return it->noAutoValidity; - } ) == arrayIts.end() ); for ( size_t first = 0; first + 1 < arrayIts.size(); ++first ) { assert( beginsWith( arrayIts[first]->name, "p" ) ); @@ -9163,6 +9156,43 @@ void VulkanHppGenerator::readStruct( tinyxml2::XMLElement const * } it->second.subStruct = determineSubStruct( *it ); + // check if multiple structure members use the very same (not empty) len attribute + static std::set mutualExclusiveStructs = { "VkAccelerationStructureBuildGeometryInfoKHR", + "VkWriteDescriptorSet" }; + static std::set multipleLenStructs = { "VkIndirectCommandsLayoutTokenNV", + "VkPresentInfoKHR", + "VkSemaphoreWaitInfo", + "VkSubmitInfo", + "VkSubpassDescription", + "VkSubpassDescription2", + "VkWin32KeyedMutexAcquireReleaseInfoKHR", + "VkWin32KeyedMutexAcquireReleaseInfoNV" }; + for ( size_t i = 0; i < it->second.members.size(); ++i ) + { + if ( !it->second.members[i].len.empty() && ( it->second.members[i].len.front() != "null-terminated" ) ) + { + for ( size_t j = i + 1; j < it->second.members.size(); ++j ) + { + if ( !it->second.members[j].len.empty() && + ( it->second.members[i].len.front() == it->second.members[j].len.front() ) ) + { + if ( mutualExclusiveStructs.find( it->first ) != mutualExclusiveStructs.end() ) + { + it->second.mutualExclusiveLens = true; + } + else + { + warn( + multipleLenStructs.find( it->first ) != multipleLenStructs.end(), + line, + "Encountered structure <" + it->first + + "> with multiple members referencing the same member for len. Need to be checked if they are supposed to be mutually exclusive." ); + } + } + } + } + } + m_extendedStructs.insert( structExtends.begin(), structExtends.end() ); check( m_types.insert( std::make_pair( name, ( category == "struct" ) ? TypeCategory::Struct : TypeCategory::Union ) ) diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index c757be6..698778a 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -241,9 +241,10 @@ private: { StructureData( std::vector const & extends, int line ) : structExtends( extends ), xmlLine( line ) {} - bool allowDuplicate = false; - bool isUnion = false; - bool returnedOnly = false; + bool allowDuplicate = false; + bool isUnion = false; + bool returnedOnly = false; + bool mutualExclusiveLens = false; std::vector members; std::vector structExtends; std::set aliases; @@ -648,16 +649,18 @@ private: std::vector determineConstPointerParamIndices( std::vector const & params ) const; std::vector determineNonConstPointerParamIndices( std::vector const & params ) const; std::map determineVectorParamIndicesNew( std::vector const & params ) const; - std::string generateLenInitializer( - std::vector::const_iterator mit, - std::map::const_iterator, - std::vector::const_iterator>>::const_iterator litit ) const; + std::string + generateLenInitializer( std::vector::const_iterator mit, + std::map::const_iterator, + std::vector::const_iterator>>::const_iterator litit, + bool mutualExclusiveLens ) const; std::pair generateProtection( std::string const & feature, std::set const & extension ) const; std::pair generateProtection( std::string const & type, bool isAliased ) const; std::string generateSizeCheck( std::vector::const_iterator> const & arrayIts, std::string const & structName, - std::string const & prefix ) const; + std::string const & prefix, + bool mutualExclusiveLens ) const; std::set getPlatforms( std::set const & extensions ) const; std::pair getPoolTypeAndName( std::string const & type ) const; std::string getVectorSize( std::vector const & params, diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index c6d57b6..abaffe4 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -17844,19 +17844,19 @@ namespace VULKAN_HPP_NAMESPACE , mode( mode_ ) , srcAccelerationStructure( srcAccelerationStructure_ ) , dstAccelerationStructure( dstAccelerationStructure_ ) - , geometryCount( static_cast( geometries_.size() ) ) + , geometryCount( static_cast( !geometries_.empty() ? geometries_.size() : pGeometries_.size() ) ) , pGeometries( geometries_.data() ) , ppGeometries( pGeometries_.data() ) , scratchData( scratchData_ ) { # ifdef VULKAN_HPP_NO_EXCEPTIONS - VULKAN_HPP_ASSERT( geometries_.empty() || pGeometries_.empty() || ( geometries_.size() == pGeometries_.size() ) ); + VULKAN_HPP_ASSERT( ( !geometries_.empty() + !pGeometries_.empty() ) == 1 ); # else - if ( !geometries_.empty() && !pGeometries_.empty() && ( geometries_.size() != pGeometries_.size() ) ) + if ( ( !geometries_.empty() + !pGeometries_.empty() ) != 1 ) { throw LogicError( VULKAN_HPP_NAMESPACE_STRING - "::AccelerationStructureBuildGeometryInfoKHR::AccelerationStructureBuildGeometryInfoKHR: !geometries_.empty() && !pGeometries_.empty() && ( geometries_.size() != pGeometries_.size() )" ); + "::AccelerationStructureBuildGeometryInfoKHR::AccelerationStructureBuildGeometryInfoKHR: ( !geometries_.empty() + !pGeometries_.empty() ) != 1" ); } # endif /*VULKAN_HPP_NO_EXCEPTIONS*/ }