From d507727fd7df89ef08749d54e3ca87af238695a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 11 Jun 2024 16:53:15 +0200 Subject: [PATCH] Add support for enumerating functions that originally take a struct with the vector information. (#1892) --- VulkanHppGenerator.cpp | 598 +++++++++++++++++++++++++++----------- VulkanHppGenerator.hpp | 26 +- vulkan/vulkan_funcs.hpp | 39 ++- vulkan/vulkan_handles.hpp | 17 +- vulkan/vulkan_raii.hpp | 13 +- 5 files changed, 498 insertions(+), 195 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 04a3ec6..221645b 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1718,6 +1718,14 @@ bool VulkanHppGenerator::containsUnion( std::string const & type ) const return found; } +bool VulkanHppGenerator::describesVector( StructureData const & structure, std::string const & type ) const +{ + return ( structure.members.size() == 4 ) && ( structure.members[0].name == "sType" ) && ( structure.members[1].name == "pNext" ) && + structure.members[2].type.isValue() && ( structure.members[2].type.type == "uint32_t" ) && + ( type.empty() ? true : ( structure.members[3].type.type == type ) ) && structure.members[3].type.isNonConstPointer() && + ( structure.members[3].lenMembers.size() == 1 ) && ( structure.members[3].lenMembers[0].second == 2 ); +} + std::vector VulkanHppGenerator::determineChainedReturnParams( std::vector const & params, std::vector const & returnParams ) const { std::vector chainedParams; @@ -1755,9 +1763,10 @@ std::vector VulkanHppGenerator::determineDataTypes( std::vector dataTypes; for ( auto rp : returnParams ) { + auto vectorParamIt = vectorParams.find( rp ); if ( templatedParams.contains( rp ) ) { - auto vectorParamIt = vectorParams.find( rp ); + assert( ( vectorParamIt == vectorParams.end() ) || !vectorParamIt->second.byStructure ); if ( ( vectorParamIt != vectorParams.end() ) && std::any_of( returnParams.begin(), returnParams.end(), [&vectorParamIt]( size_t rp ) noexcept { return rp == vectorParamIt->first; } ) && std::any_of( returnParams.begin(), returnParams.end(), [&vectorParamIt]( size_t rp ) noexcept { return rp == vectorParamIt->second.lenParam; } ) ) @@ -1769,6 +1778,10 @@ std::vector VulkanHppGenerator::determineDataTypes( std::vectorsecond.byStructure ) + { + dataTypes.push_back( trimEnd( stripPostfix( vectorMemberByStructure( params[rp].type.type ).type.compose( "VULKAN_HPP_NAMESPACE" ), "*" ) ) ); + } else { dataTypes.push_back( trimEnd( stripPostfix( params[rp].type.compose( "VULKAN_HPP_NAMESPACE" ), "*" ) ) ); @@ -1790,13 +1803,15 @@ size_t VulkanHppGenerator::determineDefaultStartIndex( std::vector co bool VulkanHppGenerator::determineEnumeration( std::map const & vectorParams, std::vector const & returnParams ) const { - // a command is considered to be enumerating some data, if for at least one vectorParam both, the data and the counter, are returnParams + // a command is considered to be enumerating some data, if for at least one vectorParam the data is a returnParam and either the vectorParams is specified by + // a structure or the lenParam is a returnParam as well return std::any_of( vectorParams.begin(), vectorParams.end(), [&returnParams]( auto const & vp ) { return std::any_of( returnParams.begin(), returnParams.end(), [&vp]( size_t rp ) { return rp == vp.first; } ) && - std::any_of( returnParams.begin(), returnParams.end(), [&vp]( size_t rp ) { return rp == vp.second.lenParam; } ); + ( vp.second.byStructure || + std::any_of( returnParams.begin(), returnParams.end(), [&vp]( size_t rp ) { return rp == vp.second.lenParam; } ) ); } ); } @@ -1838,22 +1853,41 @@ std::vector VulkanHppGenerator::determineReturnParams( std::vector const & command, std::string const & handleType ) const +{ + return isSupported( command.second.requiredBy ) && + std::any_of( command.second.params.begin(), + command.second.params.end(), + [this, &handleType]( ParamData const & pd ) { return isConstructorCandidate( pd, handleType ); } ); +} + +bool VulkanHppGenerator::isConstructorCandidate( ParamData const & paramData, std::string const & handleType ) const +{ + if ( paramData.type.isNonConstPointer() ) + { + if ( paramData.type.type == handleType ) + { + return true; + } + else + { + auto structIt = m_structs.find( paramData.type.type ); + if ( structIt != m_structs.end() ) + { + return describesVector( structIt->second, handleType ); + } + } + } + return false; +} + std::vector::const_iterator> VulkanHppGenerator::determineRAIIHandleConstructors( std::string const & handleType, std::map::const_iterator destructorIt ) const { std::vector::const_iterator> constructorIts; - auto isConstructorCandidate = [this, &handleType]( std::pair const & cd ) + for ( auto commandIt = m_commands.begin(); commandIt != m_commands.end(); ++commandIt ) { - return isSupported( cd.second.requiredBy ) && - std::any_of( cd.second.params.begin(), - cd.second.params.end(), - [&handleType]( ParamData const & pd ) { return ( pd.type.type == handleType ) && pd.type.isNonConstPointer(); } ); - }; - for ( auto commandIt = m_commands.begin(); commandIt != m_commands.end(); ) - { - // find the commands that get a non-const pointer to the handleType, that is, return a handle type - commandIt = std::find_if( commandIt, m_commands.end(), isConstructorCandidate ); - if ( commandIt != m_commands.end() ) + if ( isConstructorCandidate( *commandIt, handleType ) ) { // only commands that provide all information needed for the destructor can be considered a constructor! bool valid = true; @@ -1895,7 +1929,6 @@ std::vector::const_iterat { constructorIts.push_back( commandIt ); } - ++commandIt; } } return constructorIts; @@ -1968,16 +2001,19 @@ std::set VulkanHppGenerator::determineSkippedParams( std::vector VulkanHppGenerator::determ vpd.strideParam = params[i].strideParam.second; } } + else + { + auto structIt = m_structs.find( params[i].type.type ); + if ( ( structIt != m_structs.end() ) && !isStructureChainAnchor( params[i].type.type ) && describesVector( structIt->second ) ) + { + VectorParamData & vpd = vectorParams[i]; + vpd.byStructure = true; + vpd.lenParam = 2; + } + } } return vectorParams; } @@ -2431,6 +2477,12 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vectorsecond.byStructure ) + { + std::string type = stripPrefix( vectorMemberByStructure( params[sp].type.type ).type.type, "Vk" ); + assert( isupper( type[0] ) ); + arguments.push_back( type + "Allocator & " + startLowerCase( type ) + "Allocator" ); + } } } } @@ -3045,34 +3097,85 @@ std::string VulkanHppGenerator::generateCallSequence( std::string const & { std::string dispatcher = raii ? "getDispatcher()->" : "d."; - // first a special handling on vkGetDeviceFaultInfoEXT!! - if ( name == "vkGetDeviceFaultInfoEXT" ) + // first some special handling on vkCreatePipelineBinariesKHR and vkGetDeviceFaultInfoEXT!! + if ( name == "vkCreatePipelineBinariesKHR" ) + { +#if !defined( NDEBUG ) + auto paramIt = std::find_if( commandData.params.begin(), commandData.params.end(), []( ParamData const & pd ) { return pd.name == "pCreateInfo"; } ); + assert( paramIt != commandData.params.end() && ( paramIt->type.type == "VkPipelineBinaryCreateInfoKHR" ) ); + auto structIt = m_structs.find( "VkPipelineBinaryCreateInfoKHR" ); + assert( ( structIt != m_structs.end() ) && + std::any_of( structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "pipeline"; } ) && + std::any_of( + structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "pPipelineCreateInfo"; } ) ); + auto memberIt = + std::find_if( structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "pKeysAndDataInfo"; } ); + assert( memberIt != structIt->second.members.end() && ( memberIt->type.type == "VkPipelineBinaryKeysAndDataKHR" ) ); + structIt = m_structs.find( "VkPipelineBinaryKeysAndDataKHR" ); + assert( ( structIt != m_structs.end() ) && + std::any_of( structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "binaryCount"; } ) ); + structIt = m_structs.find( "VkPipelineBinaryHandlesInfoKHR" ); + assert( + ( structIt != m_structs.end() ) && + std::any_of( + structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "pipelineBinaryCount"; } ) && + std::any_of( structIt->second.members.begin(), structIt->second.members.end(), []( MemberData const & md ) { return md.name == "pPipelineBinaries"; } ) ); +#endif + + const std::string callSequenceTemplate = R"( VULKAN_HPP_NAMESPACE::Result result; + if ( createInfo.pKeysAndDataInfo ) + { + VULKAN_HPP_ASSERT( !createInfo.pipeline && !createInfo.pPipelineCreateInfo ); + pipelineBinaries.resize( createInfo.pKeysAndDataInfo->binaryCount ); + binaries.pipelineBinaryCount = createInfo.pKeysAndDataInfo->binaryCount; + binaries.pPipelineBinaries = pipelineBinaries.data(); + result = static_cast( ${dispatcher}${vkCommand}( ${callArguments} ) ); + } + else + { + VULKAN_HPP_ASSERT( !createInfo.pipeline ^ !createInfo.pPipelineCreateInfo ); + result = static_cast( ${dispatcher}${vkCommand}( ${callArguments} ) ); + if ( result == VULKAN_HPP_NAMESPACE::Result::eSuccess ) + { + pipelineBinaries.resize( binaries.pipelineBinaryCount ); + binaries.pPipelineBinaries = pipelineBinaries.data(); + result = static_cast( ${dispatcher}${vkCommand}( ${callArguments} ) ); + } + } +)"; + + std::string callArguments = + generateCallArgumentsEnhanced( commandData, initialSkipCount, false, singularParams, templatedParams, raii, raiiFactory, flavourFlags ); + + return replaceWithMap( callSequenceTemplate, { { "callArguments", callArguments }, { "dispatcher", dispatcher }, { "vkCommand", name } } ); + } + else if ( name == "vkGetDeviceFaultInfoEXT" ) { const std::string callSequenceTemplate = R"( VULKAN_HPP_NAMESPACE::Result result; do - { - result = static_cast( ${dispatcher}vkGetDeviceFaultInfoEXT( m_device, reinterpret_cast( &faultCounts ), nullptr ) ); - if ( result == VULKAN_HPP_NAMESPACE::Result::eSuccess ) { - std::free( faultInfo.pAddressInfos ); - if ( faultCounts.addressInfoCount ) + result = static_cast( ${dispatcher}vkGetDeviceFaultInfoEXT( m_device, reinterpret_cast( &faultCounts ), nullptr ) ); + if ( result == VULKAN_HPP_NAMESPACE::Result::eSuccess ) { - faultInfo.pAddressInfos = reinterpret_cast( std::malloc( faultCounts.addressInfoCount * sizeof( VULKAN_HPP_NAMESPACE::DeviceFaultAddressInfoEXT ) ) ); + std::free( faultInfo.pAddressInfos ); + if ( faultCounts.addressInfoCount ) + { + faultInfo.pAddressInfos = reinterpret_cast( std::malloc( faultCounts.addressInfoCount * sizeof( VULKAN_HPP_NAMESPACE::DeviceFaultAddressInfoEXT ) ) ); + } + std::free( faultInfo.pVendorInfos ); + if ( faultCounts.vendorInfoCount ) + { + faultInfo.pVendorInfos = reinterpret_cast( std::malloc( faultCounts.vendorInfoCount * sizeof( VULKAN_HPP_NAMESPACE::DeviceFaultVendorInfoEXT ) ) ); + } + std::free( faultInfo.pVendorBinaryData ); + if ( faultCounts.vendorBinarySize ) + { + faultInfo.pVendorBinaryData = std::malloc( faultCounts.vendorBinarySize ); + } + result = static_cast( ${dispatcher}vkGetDeviceFaultInfoEXT( m_device, reinterpret_cast( &faultCounts ), reinterpret_cast( &faultInfo ) ) ); } - std::free( faultInfo.pVendorInfos ); - if ( faultCounts.vendorInfoCount ) - { - faultInfo.pVendorInfos = reinterpret_cast( std::malloc( faultCounts.vendorInfoCount * sizeof( VULKAN_HPP_NAMESPACE::DeviceFaultVendorInfoEXT ) ) ); - } - std::free( faultInfo.pVendorBinaryData ); - if ( faultCounts.vendorBinarySize ) - { - faultInfo.pVendorBinaryData = std::malloc( faultCounts.vendorBinarySize ); - } - result = static_cast( ${dispatcher}vkGetDeviceFaultInfoEXT( m_device, reinterpret_cast( &faultCounts ), reinterpret_cast( &faultInfo ) ) ); - } - } while ( result == VULKAN_HPP_NAMESPACE::Result::eIncomplete );)"; + } while ( result == VULKAN_HPP_NAMESPACE::Result::eIncomplete );)"; return replaceWithMap( callSequenceTemplate, { { "dispatcher", dispatcher } } ); } @@ -3091,8 +3194,21 @@ std::string VulkanHppGenerator::generateCallSequence( std::string const & std::string firstCallArguments = generateCallArgumentsEnhanced( commandData, initialSkipCount, true, {}, templatedParams, raii, raiiFactory, flavourFlags ); std::string secondCallArguments = generateCallArgumentsEnhanced( commandData, initialSkipCount, false, {}, templatedParams, raii, raiiFactory, flavourFlags ); - std::string vectorName = startLowerCase( stripPrefix( commandData.params[vectorParamIt->first].name, "p" ) ); - std::string vectorSize = startLowerCase( stripPrefix( commandData.params[vectorParamIt->second.lenParam].name, "p" ) ); + std::string vectorName, vectorSize; + if ( vectorParamIt->second.byStructure ) + { + auto structIt = m_structs.find( commandData.params[vectorParamIt->first].type.type ); + assert( structIt != m_structs.end() ); + vectorName = structIt->second.members.back().name; + vectorSize = startLowerCase( stripPrefix( commandData.params[vectorParamIt->first].name, "p" ) ) + "." + + structIt->second.members[vectorParamIt->second.lenParam].name; + } + else + { + vectorName = commandData.params[vectorParamIt->first].name; + vectorSize = startLowerCase( stripPrefix( commandData.params[vectorParamIt->second.lenParam].name, "p" ) ); + } + vectorName = startLowerCase( stripPrefix( vectorName, "p" ) ); if ( ( flavourFlags & CommandFlavourFlagBits::chained ) && needsStructureChainResize( vectorParams, chainedReturnParams ) ) { @@ -3208,18 +3324,35 @@ std::string VulkanHppGenerator::generateCallSequence( std::string const & } else { + std::string resizeInstructions; + if ( vectorParamIt->second.byStructure ) + { + std::string const resizeInstructionTemplate = R"(${vectorName}.resize( ${vectorSize} ); + ${structName}.${pointerName} = ${vectorName}.data();)"; + + resizeInstructions = replaceWithMap( resizeInstructionTemplate, + { { "pointerName", "p" + startUpperCase( vectorName ) }, + { "structName", startLowerCase( stripPrefix( commandData.params[vectorParamIt->first].name, "p" ) ) }, + { "vectorName", vectorName }, + { "vectorSize", vectorSize } } ); + } + else + { + std::string const resizeInstructionTemplate = R"(${vectorName}.resize( ${vectorSize} );)"; + resizeInstructions = replaceWithMap( resizeInstructionTemplate, { { "vectorName", vectorName }, { "vectorSize", vectorSize } } ); + } + // no need to enumerate here, just two calls assert( commandData.returnType == "void" ); std::string const callSequenceTemplate = R"(${dispatcher}${vkCommand}( ${firstCallArguments} ); - ${vectorName}.resize( ${vectorSize} ); + ${resizeInstructions} ${dispatcher}${vkCommand}( ${secondCallArguments} );)"; return replaceWithMap( callSequenceTemplate, { { "dispatcher", dispatcher }, { "firstCallArguments", firstCallArguments }, + { "resizeInstructions", resizeInstructions }, { "secondCallArguments", secondCallArguments }, - { "vectorName", vectorName }, - { "vectorSize", vectorSize }, { "vkCommand", name } } ); } } @@ -3438,7 +3571,7 @@ std::string VulkanHppGenerator::generateCommandEnhanced( std::string const & std::string dataDeclarations = generateDataDeclarations( commandData, returnParams, vectorParams, templatedParams, flavourFlags, false, dataTypes, dataType, returnType, returnVariable ); std::string dataPreparation = - generateDataPreparation( commandData, initialSkipCount, returnParams, vectorParams, templatedParams, flavourFlags, enumerating ); + generateDataPreparation( commandData, initialSkipCount, returnParams, vectorParams, templatedParams, flavourFlags, enumerating, dataTypes ); std::string dataSizeChecks = generateDataSizeChecks( commandData, returnParams, dataTypes, vectorParams, templatedParams, singular ); std::string callSequence = generateCallSequence( name, commandData, returnParams, vectorParams, initialSkipCount, singularParams, templatedParams, chainedReturnParams, flavourFlags, false, false ); @@ -3688,6 +3821,28 @@ std::string VulkanHppGenerator::generateCommandResultMultiSuccessWithErrors1Retu } } } + else if ( isStructureChainAnchor( commandData.params[returnParam].type.type ) ) + { + std::map vectorParams = determineVectorParams( commandData.params ); + if ( vectorParams.empty() ) + { +#if 0 + // needs to be verified ... + return generateCommandSetInclusive( name, + commandData, + initialSkipCount, + definition, + { returnParam }, + vectorParams, + false, + { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::chained }, + raii, + false, + { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::chained } ); +#endif + return ""; + } + } else if ( isHandleType( commandData.params[returnParam].type.type ) ) { std::map vectorParams = determineVectorParams( commandData.params ); @@ -3719,25 +3874,22 @@ std::string VulkanHppGenerator::generateCommandResultMultiSuccessWithErrors1Retu } } } - else if ( isStructureChainAnchor( commandData.params[returnParam].type.type ) ) + else if ( isHandleTypeByStructure( commandData.params[returnParam].type.type ) ) { std::map vectorParams = determineVectorParams( commandData.params ); - if ( vectorParams.empty() ) + if ( vectorParams.size() == 1 ) { -#if 0 - // needs to be verified ... return generateCommandSetInclusive( name, commandData, initialSkipCount, definition, { returnParam }, vectorParams, - false, - { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::chained }, - raii, false, - { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::chained } ); -#endif - return ""; + true, + { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::withAllocator }, + raii, + true, + { CommandFlavourFlagBits::enhanced } ); } } else @@ -4009,7 +4161,7 @@ std::string VulkanHppGenerator::generateCommandResultSingleSuccessNoErrors( { return generateCommandSet( definition, generateCommandStandard( name, commandData, initialSkipCount, definition ), - { generateCommandEnhanced( name, commandData, initialSkipCount, definition, vectorParams, {} ) } ); + { generateCommandEnhanced( name, commandData, initialSkipCount, definition, vectorParams, {}, {} ) } ); } } } @@ -4462,7 +4614,7 @@ std::string VulkanHppGenerator::generateCommandSetExclusive( else { return generateCommandSet( generateCommandStandard( name, commandData, initialSkipCount, definition ), - generateCommandEnhanced( name, commandData, initialSkipCount, definition, {}, {} ) ); + generateCommandEnhanced( name, commandData, initialSkipCount, definition, {}, {}, {} ) ); } } @@ -4618,7 +4770,7 @@ std::string VulkanHppGenerator::generateCommandValue( { return generateCommandSet( definition, generateCommandStandard( name, commandData, initialSkipCount, definition ), - { generateCommandEnhanced( name, commandData, initialSkipCount, definition, vectorParams, returnParams ) } ); + { generateCommandEnhanced( name, commandData, initialSkipCount, definition, vectorParams, returnParams, {} ) } ); } } } @@ -4745,16 +4897,18 @@ std::string VulkanHppGenerator::generateCommandVoid1Return( case 1: if ( returnParam == vectorParams.begin()->first ) { - if ( !raii ) - { - // you get a vector of stuff, with the size being one of the parameters - return generateCommandSet( - definition, - generateCommandStandard( name, commandData, initialSkipCount, definition ), - { generateCommandEnhanced( name, commandData, initialSkipCount, definition, vectorParams, { returnParam } ), - generateCommandEnhanced( - name, commandData, initialSkipCount, definition, vectorParams, { returnParam }, CommandFlavourFlagBits::withAllocator ) } ); - } + // you get a vector of stuff, with the size being one of the parameters + return generateCommandSetInclusive( name, + commandData, + initialSkipCount, + definition, + { returnParam }, + vectorParams, + false, + { CommandFlavourFlagBits::enhanced, CommandFlavourFlagBits::withAllocator }, + raii, + false, + { CommandFlavourFlagBits::enhanced } ); } else { @@ -5795,17 +5949,36 @@ std::string VulkanHppGenerator::generateDataDeclarations1Return( CommandData con } else { - std::string allocator = stripPrefix( dataTypes[0], "VULKAN_HPP_NAMESPACE::" ) + "Allocator"; - std::string vectorAllocator = ( ( flavourFlags & CommandFlavourFlagBits::withAllocator ) && !( flavourFlags & CommandFlavourFlagBits::unique ) ) - ? ( ", " + startLowerCase( allocator ) ) - : ""; - std::string vectorSize = getVectorSize( commandData.params, vectorParams, returnParams[0], dataTypes[0], templatedParams ); + std::string allocator = stripPrefix( dataTypes[0], "VULKAN_HPP_NAMESPACE::" ) + "Allocator"; + if ( vectorParamIt->second.byStructure ) + { + std::string vectorAllocator = ( ( flavourFlags & CommandFlavourFlagBits::withAllocator ) && !( flavourFlags & CommandFlavourFlagBits::unique ) ) + ? ( "( " + startLowerCase( allocator ) + " )" ) + : ""; - std::string const dataDeclarationsTemplate = R"(${dataType} ${returnVariable}( ${vectorSize}${vectorAllocator} );)"; + std::string const dataDeclarationTemplate = R"(${dataType} ${returnVariable}${vectorAllocator}; + ${structType} ${structVariable};)"; - return replaceWithMap( - dataDeclarationsTemplate, - { { "dataType", dataType }, { "returnVariable", returnVariable }, { "vectorAllocator", vectorAllocator }, { "vectorSize", vectorSize } } ); + return replaceWithMap( dataDeclarationTemplate, + { { "dataType", dataType }, + { "returnVariable", returnVariable }, + { "structType", stripPostfix( commandData.params[vectorParamIt->first].type.compose( "VULKAN_HPP_NAMESPACE" ), "*" ) }, + { "structVariable", startLowerCase( stripPrefix( commandData.params[vectorParamIt->first].name, "p" ) ) }, + { "vectorAllocator", stripPrefix( vectorAllocator, "," ) } } ); + } + else + { + std::string vectorAllocator = ( ( flavourFlags & CommandFlavourFlagBits::withAllocator ) && !( flavourFlags & CommandFlavourFlagBits::unique ) ) + ? ( ", " + startLowerCase( allocator ) ) + : ""; + std::string vectorSize = getVectorSize( commandData.params, vectorParams, returnParams[0], dataTypes[0], templatedParams ); + + std::string const dataDeclarationsTemplate = R"(${dataType} ${returnVariable}( ${vectorSize}${vectorAllocator} );)"; + + return replaceWithMap( + dataDeclarationsTemplate, + { { "dataType", dataType }, { "returnVariable", returnVariable }, { "vectorAllocator", vectorAllocator }, { "vectorSize", vectorSize } } ); + } } } else @@ -6044,7 +6217,8 @@ std::string VulkanHppGenerator::generateDataPreparation( CommandData const & std::map const & vectorParams, std::set const & templatedParams, CommandFlavourFlags flavourFlags, - bool enumerating ) const + bool enumerating, + std::vector const & dataTypes ) const { const bool chained = flavourFlags & CommandFlavourFlagBits::chained; const bool singular = flavourFlags & CommandFlavourFlagBits::singular; @@ -6134,34 +6308,45 @@ std::string VulkanHppGenerator::generateDataPreparation( CommandData const & } else if ( unique && !singular && ( returnParams.size() == 1 ) && vectorParams.contains( returnParams[0] ) ) { - assert( !enumerating ); - std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : ""; - std::string deleterDefinition; - std::vector lenParts = tokenize( commandData.params[returnParams[0]].lenExpression, "->" ); - switch ( lenParts.size() ) + std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : ""; + std::string deleterDefinition, vectorName, vectorSize; + vectorParamIt = vectorParams.find( returnParams[0] ); + if ( vectorParamIt != vectorParams.end() && vectorParamIt->second.byStructure ) { - case 1: deleterDefinition = "ObjectDestroy<" + className + ", Dispatch> deleter( *this, allocator, d )"; break; - case 2: - { - auto vpiIt = vectorParams.find( returnParams[0] ); - assert( vpiIt != vectorParams.end() ); - std::string poolType, poolName; - std::tie( poolType, poolName ) = getPoolTypeAndName( commandData.params[vpiIt->second.lenParam].type.type ); - assert( !poolType.empty() ); - poolType = stripPrefix( poolType, "Vk" ); - poolName = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + poolName; - deleterDefinition = "PoolFree<" + className + ", " + poolType + ", Dispatch> deleter( *this, " + poolName + ", d )"; - } - break; - default: assert( false ); break; + deleterDefinition = "ObjectDestroy<" + className + ", Dispatch> deleter( *this, allocator, d )"; + auto structIt = m_structs.find( commandData.params[returnParams[0]].type.type ); + assert( structIt != m_structs.end() ); + vectorName = startLowerCase( stripPrefix( structIt->second.members.back().name, "p" ) ); + vectorSize = vectorName + ".size()"; + } + else + { + std::vector lenParts = tokenize( commandData.params[returnParams[0]].lenExpression, "->" ); + switch ( lenParts.size() ) + { + case 1: deleterDefinition = "ObjectDestroy<" + className + ", Dispatch> deleter( *this, allocator, d )"; break; + case 2: + { + auto vpiIt = vectorParams.find( returnParams[0] ); + assert( vpiIt != vectorParams.end() ); + std::string poolType, poolName; + std::tie( poolType, poolName ) = getPoolTypeAndName( commandData.params[vpiIt->second.lenParam].type.type ); + assert( !poolType.empty() ); + poolType = stripPrefix( poolType, "Vk" ); + poolName = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + poolName; + deleterDefinition = "PoolFree<" + className + ", " + poolType + ", Dispatch> deleter( *this, " + poolName + ", d )"; + } + break; + default: assert( false ); break; + } + vectorName = startLowerCase( stripPrefix( commandData.params[returnParams[0]].name, "p" ) ); + vectorSize = getVectorSize( commandData.params, vectorParams, returnParams[0], commandData.params[returnParams[0]].type.type, templatedParams ); } - std::string handleType = stripPrefix( commandData.params[returnParams[0]].type.type, "Vk" ); - std::string uniqueVectorName = "unique" + stripPrefix( commandData.params[returnParams[0]].name, "p" ); + std::string handleType = stripPrefix( dataTypes[0], "VULKAN_HPP_NAMESPACE::" ); std::string vectorAllocator = ( flavourFlags & CommandFlavourFlagBits::withAllocator ) ? ( "( " + startLowerCase( handleType ) + "Allocator )" ) : ""; - std::string vectorName = startLowerCase( stripPrefix( commandData.params[returnParams[0]].name, "p" ) ); std::string elementName = stripPluralS( vectorName ); - std::string vectorSize = getVectorSize( commandData.params, vectorParams, returnParams[0], commandData.params[returnParams[0]].type.type, templatedParams ); + std::string uniqueVectorName = "unique" + startUpperCase( vectorName ); std::string const dataPreparationTemplate = R"(std::vector, ${handleType}Allocator> ${uniqueVectorName}${vectorAllocator}; @@ -8250,7 +8435,9 @@ std::string VulkanHppGenerator::generateRAIIFactoryReturnStatements( std::vector std::string successCodePassToElement = ( enumerating ? ( successCodes.size() <= 2 ) : ( successCodes.size() <= 1 ) ) ? "" : ", result"; if ( returnType.starts_with( "std::vector" ) ) { - std::string const & returnTemplate = R"(${returnType} ${returnVariable}RAII; + assert( !successCodes.empty() ); + + std::string const & returnTemplate = R"(${returnType} ${returnVariable}RAII; ${returnVariable}RAII.reserve( ${returnVariable}.size() ); for ( auto & ${element} : ${returnVariable} ) { @@ -8258,10 +8445,9 @@ std::string VulkanHppGenerator::generateRAIIFactoryReturnStatements( std::vector } return ${returnVariable}RAII; )"; - std::string element = stripPluralS( returnVariable ); - std::string handleConstructorArguments = generateRAIIHandleSingularConstructorArguments( *handleIt, params, true ); - assert( !successCodes.empty() ); + std::string element = stripPluralS( returnVariable ); + std::string handleConstructorArguments = generateRAIIHandleSingularConstructorArguments( *handleIt, params, vkType, element ); return replaceWithMap( returnTemplate, { { "element", element }, @@ -8274,7 +8460,8 @@ std::string VulkanHppGenerator::generateRAIIFactoryReturnStatements( std::vector { std::string const & returnTemplate = "return ${returnType}( *this, ${handleConstructorArguments}${successCodePassToElement} );"; - std::string handleConstructorArguments = generateRAIIHandleSingularConstructorArguments( *handleIt, params, singular ); + std::string handleConstructorArguments = + generateRAIIHandleSingularConstructorArguments( *handleIt, params, vkType, singular ? stripPluralS( returnVariable ) : returnVariable ); return replaceWithMap( returnTemplate, { { "returnType", returnType }, @@ -8654,7 +8841,7 @@ ${vectorSizeCheck} std::string dataDeclarations = generateDataDeclarations( commandData, returnParams, vectorParams, templatedParams, flavourFlags, true, dataTypes, dataType, returnType, returnVariable ); std::string dataPreparation = - generateDataPreparation( commandData, initialSkipCount, returnParams, vectorParams, templatedParams, flavourFlags, enumerating ); + generateDataPreparation( commandData, initialSkipCount, returnParams, vectorParams, templatedParams, flavourFlags, enumerating, dataTypes ); std::string dataSizeChecks = generateDataSizeChecks( commandData, returnParams, dataTypes, vectorParams, templatedParams, singular ); std::string resultCheck = generateResultCheck( commandData, className, "::", commandName, enumerating ); std::string returnStatement = generateReturnStatement( name, @@ -8714,7 +8901,9 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandFactory( std::string co bool definition, CommandFlavourFlags flavourFlags ) const { - assert( isHandleType( commandData.params[returnParams.back()].type.type ) ); + assert( isHandleType( commandData.params[returnParams.back()].type.type ) || + ( vectorParams.contains( returnParams.back() ) && vectorParams.find( returnParams.back() )->second.byStructure && + isHandleType( vectorMemberByStructure( commandData.params[returnParams.back()].type.type ).type.type ) ) ); assert( ( returnParams.size() == 1 ) || ( ( returnParams.size() == 2 ) && ( vectorParams.size() == 1 ) && ( returnParams[0] == vectorParams.begin()->second.lenParam ) && ( returnParams[1] == vectorParams.begin()->first ) ) ); @@ -8726,9 +8915,20 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandFactory( std::string co std::set singularParams = singular ? determineSingularParams( returnParams.back(), vectorParams ) : std::set(); std::string argumentList = generateRAIIHandleCommandFactoryArgumentList( commandData.params, skippedParams, definition, singular ); std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, flavourFlags ); - std::string handleType = stripPostfix( commandData.params[returnParams.back()].type.compose( "VULKAN_HPP_NAMESPACE::VULKAN_HPP_RAII_NAMESPACE" ), " *" ); - std::string noexceptString = enumerating ? "" : "VULKAN_HPP_RAII_CREATE_NOEXCEPT"; - std::string returnType = handleType; + + std::string handleType; + if ( ( vectorParams.size() == 1 ) && vectorParams.begin()->second.byStructure ) + { + assert( vectorParams.begin()->first == returnParams.back() ); + handleType = vectorMemberByStructure( commandData.params.back().type.type ).type.compose( "VULKAN_HPP_NAMESPACE::VULKAN_HPP_RAII_NAMESPACE" ); + } + else + { + handleType = commandData.params[returnParams.back()].type.compose( "VULKAN_HPP_NAMESPACE::VULKAN_HPP_RAII_NAMESPACE" ); + } + handleType = stripPostfix( handleType, " *" ); + std::string noexceptString = enumerating ? "" : "VULKAN_HPP_RAII_CREATE_NOEXCEPT"; + std::string returnType = handleType; if ( vectorParams.contains( returnParams.back() ) && !singular ) { noexceptString = ""; @@ -8740,12 +8940,22 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandFactory( std::string co { std::string callSequence = generateCallSequence( name, commandData, returnParams, vectorParams, initialSkipCount, singularParams, {}, {}, flavourFlags, true, true ); - std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : "Context"; - std::vector dataTypes = determineDataTypes( commandData.params, vectorParams, returnParams, {} ); - std::string dataType = combineDataTypes( vectorParams, returnParams, enumerating, dataTypes, flavourFlags, true ); - std::string returnVariable = generateReturnVariable( commandData, returnParams, vectorParams, flavourFlags ); - std::string returnStatements = generateRAIIFactoryReturnStatements( - commandData.params, commandData.successCodes, commandData.params[returnParams.back()].type.type, enumerating, returnType, returnVariable, singular ); + std::string className = initialSkipCount ? stripPrefix( commandData.params[initialSkipCount - 1].type.type, "Vk" ) : "Context"; + std::vector dataTypes = determineDataTypes( commandData.params, vectorParams, returnParams, {} ); + std::string dataType = combineDataTypes( vectorParams, returnParams, enumerating, dataTypes, flavourFlags, true ); + std::string returnVariable = generateReturnVariable( commandData, returnParams, vectorParams, flavourFlags ); + std::string vulkanType; + auto vectorParamIt = vectorParams.find( returnParams.back() ); + if ( ( vectorParamIt != vectorParams.end() ) && vectorParamIt->second.byStructure ) + { + vulkanType = vectorMemberByStructure( commandData.params[returnParams.back()].type.type ).type.type; + } + else + { + vulkanType = commandData.params[returnParams.back()].type.type; + } + std::string returnStatements = + generateRAIIFactoryReturnStatements( commandData.params, commandData.successCodes, vulkanType, enumerating, returnType, returnVariable, singular ); std::string dataDeclarations = generateDataDeclarations( commandData, returnParams, vectorParams, {}, flavourFlags, true, dataTypes, dataType, returnType, returnVariable ); std::string vkType = commandData.params[returnParams.back()].type.type; @@ -8973,12 +9183,18 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorArguments( std::pai { // this is supposed to be the returned size on an enumeration function! #if !defined( NDEBUG ) - assert( ( param.type.type == "size_t" ) || ( param.type.type == "uint32_t" ) ); - auto typeIt = std::find_if( constructorIt->second.params.begin(), - constructorIt->second.params.end(), - [&handle]( ParamData const & pd ) { return pd.type.type == handle.first; } ); - assert( typeIt != constructorIt->second.params.end() ); - assert( typeIt->lenExpression == param.name ); + if ( ( param.type.type == "size_t" ) || ( param.type.type == "uint32_t" ) ) + { + auto typeIt = std::find_if( constructorIt->second.params.begin(), + constructorIt->second.params.end(), + [&handle]( ParamData const & pd ) { return pd.type.type == handle.first; } ); + assert( typeIt != constructorIt->second.params.end() ); + assert( typeIt->lenExpression == param.name ); + } + else + { + assert( vectorMemberByStructure( param.type.type ).type.type == handle.first ); + } #endif continue; } @@ -9176,12 +9392,19 @@ std::pair VulkanHppGenerator::generateRAIIHandleConstr switch ( returnParams.size() ) { case 1: - assert( isHandleType( constructorIt->second.params[returnParams[0]].type.type ) ); { std::map vectorParams = determineVectorParams( constructorIt->second.params ); - if ( vectorParams.size() == 2 ) + if ( isHandleType( constructorIt->second.params[returnParams[0]].type.type ) ) { - return generateRAIIHandleConstructor1Return2Vector( handle, constructorIt, enter, leave, returnParams[0], vectorParams ); + if ( vectorParams.size() == 2 ) + { + return generateRAIIHandleConstructor1Return2Vector( handle, constructorIt, enter, leave, returnParams[0], vectorParams ); + } + } + else if ( ( vectorParams.size() == 1 ) && ( vectorParams.begin()->first == returnParams[0] ) && vectorParams.begin()->second.byStructure ) + { + assert( isHandleTypeByStructure( constructorIt->second.params[returnParams[0]].type.type ) ); + return std::make_pair( "", generateRAIIHandleConstructorByCall( handle, constructorIt, enter, leave, true, false ) ); } } break; @@ -9282,7 +9505,8 @@ std::string VulkanHppGenerator::generateRAIIHandleConstructorByCall( std::pairsecond.params.back().type.type == handle.first ); + assert( ( constructorIt->second.params.back().type.type == handle.first ) || + ( vectorMemberByStructure( constructorIt->second.params.back().type.type ).type.type == handle.first ) ); const std::string constructorTemplate = R"( @@ -9703,15 +9927,10 @@ ${raiiHandles} std::string VulkanHppGenerator::generateRAIIHandleSingularConstructorArguments( std::pair const & handle, std::vector const & params, - bool singular ) const + std::string const & argumentType, + std::string const & argumentName ) const { - std::string arguments = startLowerCase( stripPrefix( params.back().name, "p" ) ); - if ( singular ) - { - arguments = stripPluralS( arguments ); - } - assert( params.back().type.type.starts_with( "Vk" ) ); - arguments = "*reinterpret_cast<" + params.back().type.type + " *>( &" + arguments + " )"; + std::string arguments = "*reinterpret_cast<" + argumentType + " *>( &" + argumentName + " )"; if ( handle.second.destructorIt != m_commands.end() ) { auto [parentType, parentName] = getParentTypeAndName( handle ); @@ -10154,7 +10373,15 @@ std::string VulkanHppGenerator::generateReturnVariable( CommandData const & } else { - returnVariable = startLowerCase( stripPrefix( commandData.params[returnParams[0]].name, "p" ) ); + auto vectorParamIt = vectorParams.find( returnParams[0] ); + if ( ( vectorParamIt != vectorParams.end() ) && vectorParamIt->second.byStructure ) + { + returnVariable = startLowerCase( stripPrefix( vectorMemberByStructure( commandData.params[returnParams[0]].type.type ).name, "p" ) ); + } + else + { + returnVariable = startLowerCase( stripPrefix( commandData.params[returnParams[0]].name, "p" ) ); + } if ( singular ) { returnVariable = stripPluralS( returnVariable ); @@ -11573,7 +11800,7 @@ std::string VulkanHppGenerator::generateSuccessCode( std::string const & code ) std::string VulkanHppGenerator::generateSuccessCodeList( std::vector const & successCodes, bool enumerating ) const { std::string successCodeList; - size_t skipSize = enumerating ? 2 : 1; + size_t skipSize = ( enumerating && ( 1 < successCodes.size() ) && ( successCodes[1] == "VK_INCOMPLETE" ) ) ? 2 : 1; if ( skipSize < successCodes.size() ) { successCodeList = ", { " + generateSuccessCode( successCodes[0] ); @@ -12232,41 +12459,52 @@ std::string VulkanHppGenerator::getVectorSize( std::vector const & std::string const & returnParamType, std::set const & templatedParams ) const { - std::string vectorSize; - std::vector lenParts = tokenize( params[returnParam].lenExpression, "->" ); - switch ( lenParts.size() ) + std::string vectorSize; + auto returnVectorIt = vectorParams.find( returnParam ); + assert( returnVectorIt != vectorParams.end() ); + if ( returnVectorIt->second.byStructure ) { - case 1: - { - std::string const & len = lenParts[0]; - size_t lenIdx = - std::distance( params.begin(), std::find_if( params.begin(), params.end(), [&len]( ParamData const & pd ) { return pd.name == len; } ) ); - assert( lenIdx < params.size() ); - // look for the len, not being the len of the return param, but of an other vector param - auto lenVectorParamIt = - std::find_if( vectorParams.begin(), - vectorParams.end(), - [&lenIdx, &returnParam]( auto const & vpi ) { return ( vpi.first != returnParam ) && ( vpi.second.lenParam == lenIdx ); } ); - if ( lenVectorParamIt == vectorParams.end() ) + auto structIt = m_structs.find( params[returnParam].type.type ); + assert( structIt != m_structs.end() ); + vectorSize = startLowerCase( stripPrefix( params[returnParam].name, "p" ) ) + "." + structIt->second.members[returnVectorIt->second.lenParam].name; + } + else + { + std::vector lenParts = tokenize( params[returnParam].lenExpression, "->" ); + switch ( lenParts.size() ) + { + case 1: { - vectorSize = lenParts[0]; - if ( templatedParams.contains( returnParam ) ) + std::string const & len = lenParts[0]; + size_t lenIdx = + std::distance( params.begin(), std::find_if( params.begin(), params.end(), [&len]( ParamData const & pd ) { return pd.name == len; } ) ); + assert( lenIdx < params.size() ); + // look for the len, not being the len of the return param, but of an other vector param + auto lenVectorParamIt = + std::find_if( vectorParams.begin(), + vectorParams.end(), + [&lenIdx, &returnParam]( auto const & vpi ) { return ( vpi.first != returnParam ) && ( vpi.second.lenParam == lenIdx ); } ); + if ( lenVectorParamIt == vectorParams.end() ) { - vectorSize += " / sizeof( " + returnParamType + " )"; + vectorSize = lenParts[0]; + if ( templatedParams.contains( returnParam ) ) + { + vectorSize += " / sizeof( " + returnParamType + " )"; + } + } + else + { + assert( !templatedParams.contains( returnParam ) ); + vectorSize = startLowerCase( stripPrefix( params[lenVectorParamIt->first].name, "p" ) ) + ".size()"; } } - else - { - assert( !templatedParams.contains( returnParam ) ); - vectorSize = startLowerCase( stripPrefix( params[lenVectorParamIt->first].name, "p" ) ) + ".size()"; - } - } - break; - case 2: - assert( vectorParams.contains( returnParam ) ); - vectorSize = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1]; - break; - default: assert( false ); break; + break; + case 2: + assert( vectorParams.contains( returnParam ) ); + vectorSize = startLowerCase( stripPrefix( lenParts[0], "p" ) ) + "." + lenParts[1]; + break; + default: assert( false ); break; + } } assert( !vectorSize.empty() ); return vectorSize; @@ -12468,6 +12706,12 @@ bool VulkanHppGenerator::isHandleType( std::string const & type ) const return type.starts_with( "Vk" ) && ( findByNameOrAlias( m_handles, type ) != m_handles.end() ); } +bool VulkanHppGenerator::isHandleTypeByStructure( std::string const & type ) const +{ + auto structIt = m_structs.find( type ); + return ( structIt != m_structs.end() ) && describesVector( structIt->second ) && isHandleType( structIt->second.members[3].type.type ); +} + bool VulkanHppGenerator::isLenByStructMember( std::string const & name, std::vector const & params ) const { // check if name specifies a member of a struct @@ -15363,6 +15607,14 @@ std::string VulkanHppGenerator::toString( TypeCategory category ) } } +VulkanHppGenerator::MemberData const & VulkanHppGenerator::vectorMemberByStructure( std::string const & structureType ) const +{ + auto structIt = m_structs.find( structureType ); + assert( structIt != m_structs.end() ); + assert( describesVector( structIt->second ) ); + return structIt->second.members.back(); +} + void VulkanHppGenerator::EnumData::addEnumAlias( int line, std::string const & name, std::string const & alias, std::string const & protect, bool supported ) { auto aliasIt = findByName( valueAliases, name ); diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index c56ce20..e10d01a 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -385,6 +385,7 @@ private: { size_t lenParam = INVALID_INDEX; size_t strideParam = INVALID_INDEX; + bool byStructure = false; }; struct MacroVisitor final : tinyxml2::XMLVisitor @@ -450,6 +451,7 @@ private: bool containsFuncPointer( std::string const & type ) const; bool containsFloatingPoints( std::vector const & members ) const; bool containsUnion( std::string const & type ) const; + bool describesVector( StructureData const & structure, std::string const & type = "" ) const; std::vector determineChainedReturnParams( std::vector const & params, std::vector const & returnParams ) const; std::vector determineConstPointerParams( std::vector const & params ) const; std::vector determineDataTypes( std::vector const & params, @@ -564,7 +566,7 @@ private: bool definition, std::map const & vectorParams, std::vector const & returnParams, - CommandFlavourFlags flavourFlags = {} ) const; + CommandFlavourFlags flavourFlags ) const; std::string generateCommandName( std::string const & vulkanCommandName, std::vector const & params, size_t initialSkipCount, @@ -695,7 +697,8 @@ private: std::map const & vectorParams, std::set const & templatedParams, CommandFlavourFlags flavourFlags, - bool enumerating ) const; + bool enumerating, + std::vector const & dataTypes ) const; std::string generateDataSizeChecks( CommandData const & commandData, std::vector const & returnParams, std::vector const & returnParamTypes, @@ -842,7 +845,8 @@ private: std::string generateRAIIHandles() const; std::string generateRAIIHandleSingularConstructorArguments( std::pair const & handle, std::vector const & params, - bool singular ) const; + std::string const & argumentType, + std::string const & argumentName ) const; template std::string generateReplacedExtensionsList( Predicate p, Extraction e ) const; std::string generateResultAssignment( CommandData const & commandData ) const; @@ -938,12 +942,15 @@ private: bool handleRemovalType( std::string const & type, std::vector & requireData ); bool hasLen( MemberData const & md, std::vector const & members ) const; bool hasParentHandle( std::string const & handle, std::string const & parent ) const; - bool isDeviceCommand( CommandData const & commandData ) const; - bool isExtension( std::string const & name ) const; - bool isFeature( std::string const & name ) const; - bool isHandleType( std::string const & type ) const; - bool isLenByStructMember( std::string const & name, std::vector const & params ) const; - bool isLenByStructMember( std::string const & name, ParamData const & param ) const; + bool isConstructorCandidate( std::pair const & command, std::string const & handleType ) const; + bool isConstructorCandidate( ParamData const & paramData, std::string const & handleType ) const; + bool isDeviceCommand( CommandData const & commandData ) const; + bool isExtension( std::string const & name ) const; + bool isFeature( std::string const & name ) const; + bool isHandleType( std::string const & type ) const; + bool isHandleTypeByStructure( std::string const & type ) const; + bool isLenByStructMember( std::string const & name, std::vector const & params ) const; + bool isLenByStructMember( std::string const & name, ParamData const & param ) const; bool isMultiSuccessCodeConstructor( std::vector::const_iterator> const & constructorIts ) const; bool isParam( std::string const & name, std::vector const & params ) const; bool isStructMember( std::string const & name, std::vector const & memberData ) const; @@ -1033,6 +1040,7 @@ private: bool skipLeadingGrandParent( std::pair const & handle ) const; std::string stripPluralS( std::string const & name ) const; std::string toString( TypeCategory category ); + MemberData const & vectorMemberByStructure( std::string const & structureType ) const; private: std::string m_api; diff --git a/vulkan/vulkan_funcs.hpp b/vulkan/vulkan_funcs.hpp index 04cc282..c7d8817 100644 --- a/vulkan/vulkan_funcs.hpp +++ b/vulkan/vulkan_funcs.hpp @@ -25908,19 +25908,48 @@ namespace VULKAN_HPP_NAMESPACE } #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE - template - VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV - Device::getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, Dispatch const & d ) const VULKAN_HPP_NOEXCEPT + template + VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE std::vector + Device::getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, Dispatch const & d ) const { VULKAN_HPP_ASSERT( d.getVkHeaderVersion() == VK_HEADER_VERSION ); # if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 ) VULKAN_HPP_ASSERT( d.vkGetLatencyTimingsNV && "Function requires " ); # endif - VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV latencyMarkerInfo; + std::vector timings; + VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV latencyMarkerInfo; + d.vkGetLatencyTimingsNV( m_device, static_cast( swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); + timings.resize( latencyMarkerInfo.timingCount ); + latencyMarkerInfo.pTimings = timings.data(); d.vkGetLatencyTimingsNV( m_device, static_cast( swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); - return latencyMarkerInfo; + return timings; + } + + template < + typename LatencyTimingsFrameReportNVAllocator, + typename Dispatch, + typename std::enable_if::value, + int>::type> + VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE std::vector + Device::getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, + LatencyTimingsFrameReportNVAllocator & latencyTimingsFrameReportNVAllocator, + Dispatch const & d ) const + { + VULKAN_HPP_ASSERT( d.getVkHeaderVersion() == VK_HEADER_VERSION ); +# if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 ) + VULKAN_HPP_ASSERT( d.vkGetLatencyTimingsNV && "Function requires " ); +# endif + + std::vector timings( latencyTimingsFrameReportNVAllocator ); + VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV latencyMarkerInfo; + d.vkGetLatencyTimingsNV( m_device, static_cast( swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); + timings.resize( latencyMarkerInfo.timingCount ); + latencyMarkerInfo.pTimings = timings.data(); + d.vkGetLatencyTimingsNV( m_device, static_cast( swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); + + return timings; } #endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */ diff --git a/vulkan/vulkan_handles.hpp b/vulkan/vulkan_handles.hpp index 7718087..1377e6c 100644 --- a/vulkan/vulkan_handles.hpp +++ b/vulkan/vulkan_handles.hpp @@ -14470,10 +14470,19 @@ namespace VULKAN_HPP_NAMESPACE VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV * pLatencyMarkerInfo, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const VULKAN_HPP_NOEXCEPT; #ifndef VULKAN_HPP_DISABLE_ENHANCED_MODE - template - VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV - getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, - Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const VULKAN_HPP_NOEXCEPT; + template , + typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE> + VULKAN_HPP_NODISCARD std::vector + getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const; + template < + typename LatencyTimingsFrameReportNVAllocator = std::allocator, + typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE, + typename std::enable_if::value, + int>::type = 0> + VULKAN_HPP_NODISCARD std::vector + getLatencyTimingsNV( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, + LatencyTimingsFrameReportNVAllocator & latencyTimingsFrameReportNVAllocator, + Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const; #endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */ #if defined( VK_USE_PLATFORM_SCREEN_QNX ) diff --git a/vulkan/vulkan_raii.hpp b/vulkan/vulkan_raii.hpp index b8c654f..5b82f31 100644 --- a/vulkan/vulkan_raii.hpp +++ b/vulkan/vulkan_raii.hpp @@ -11501,7 +11501,7 @@ namespace VULKAN_HPP_NAMESPACE void setLatencyMarkerNV( const VULKAN_HPP_NAMESPACE::SetLatencyMarkerInfoNV & latencyMarkerInfo ) const VULKAN_HPP_NOEXCEPT; - VULKAN_HPP_NODISCARD VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV getLatencyTimingsNV() const VULKAN_HPP_NOEXCEPT; + VULKAN_HPP_NODISCARD std::vector getLatencyTimingsNV() const; private: VULKAN_HPP_NAMESPACE::Device m_device = {}; @@ -22699,15 +22699,20 @@ namespace VULKAN_HPP_NAMESPACE reinterpret_cast( &latencyMarkerInfo ) ); } - VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV SwapchainKHR::getLatencyTimingsNV() const VULKAN_HPP_NOEXCEPT + VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE std::vector SwapchainKHR::getLatencyTimingsNV() const { VULKAN_HPP_ASSERT( getDispatcher()->vkGetLatencyTimingsNV && "Function requires " ); - VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV latencyMarkerInfo; + std::vector timings; + VULKAN_HPP_NAMESPACE::GetLatencyMarkerInfoNV latencyMarkerInfo; + getDispatcher()->vkGetLatencyTimingsNV( + static_cast( m_device ), static_cast( m_swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); + timings.resize( latencyMarkerInfo.timingCount ); + latencyMarkerInfo.pTimings = timings.data(); getDispatcher()->vkGetLatencyTimingsNV( static_cast( m_device ), static_cast( m_swapchain ), reinterpret_cast( &latencyMarkerInfo ) ); - return latencyMarkerInfo; + return timings; } VULKAN_HPP_INLINE void Queue::notifyOutOfBandNV( const VULKAN_HPP_NAMESPACE::OutOfBandQueueTypeInfoNV & queueTypeInfo ) const VULKAN_HPP_NOEXCEPT