From 7e1161da9b7d74af20e7a1ad26bb27033421d614 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Tue, 25 Jan 2022 16:57:56 +0100 Subject: [PATCH] Generalize command generation for a specific type of commands Commands returning void, that are supposed to enumerate one vector of data is generalized to also support void-data by a templated type. --- VulkanHppGenerator.cpp | 187 +++++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 80 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 6b669e7..7beea3a 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -2461,9 +2461,11 @@ std::string VulkanHppGenerator::generateArgumentListEnhanced( std::vector vectorParams = determineVectorParams( commandData.params ); + if ( vectorParams.size() == 1 ) { - std::map vectorParams = determineVectorParams( commandData.params ); - if ( vectorParams.size() == 1 ) + if ( returnParamIndices[0] == vectorParams.begin()->second ) { - if ( returnParamIndices[0] == vectorParams.begin()->second ) + if ( returnParamIndices[1] == vectorParams.begin()->first ) { - if ( returnParamIndices[1] == vectorParams.begin()->first ) + if ( isStructureChainAnchor( commandData.params[returnParamIndices[1]].type.type ) ) { return generateCommandSetStandardEnhancedWithAllocatorChained( definition, @@ -5813,18 +5815,7 @@ std::string VulkanHppGenerator::generateCommandVoid2Return( std::string const & generateCommandVoidEnumerateChained( name, commandData, initialSkipCount, definition, *vectorParams.begin(), returnParamIndices, true ) ); } - } - } - } - else if ( ( commandData.params[returnParamIndices[1]].type.type != "void" ) && - !isHandleType( commandData.params[returnParamIndices[1]].type.type ) ) - { - std::map vectorParams = determineVectorParams( commandData.params ); - if ( vectorParams.size() == 1 ) - { - if ( returnParamIndices[0] == vectorParams.begin()->second ) - { - if ( returnParamIndices[1] == vectorParams.begin()->first ) + else if ( !isHandleType( commandData.params[returnParamIndices[1]].type.type ) ) { return generateCommandSetStandardEnhancedWithAllocator( definition, @@ -5849,32 +5840,46 @@ std::string VulkanHppGenerator::generateCommandVoidEnumerate( std::string const std::vector const & returnParamIndices, bool withAllocators ) const { - assert( commandData.params[0].type.type == commandData.handle && ( commandData.returnType == "void" ) && - commandData.successCodes.empty() && commandData.errorCodes.empty() ); - std::set skippedParams = determineSkippedParams( commandData.params, initialSkipCount, { vectorParamIndex }, returnParamIndices, false ); - std::string argumentList = - generateArgumentListEnhanced( commandData.params, skippedParams, {}, {}, definition, withAllocators, false, true ); + std::set templatedParams = determineVoidPointerParams( commandData.params ); + std::string argumentList = generateArgumentListEnhanced( + commandData.params, skippedParams, {}, templatedParams, definition, withAllocators, false, true ); + std::string argumentTemplates = generateArgumentTemplates( commandData.params, templatedParams, false ); std::string commandName = generateCommandName( name, commandData.params, initialSkipCount, m_tags ); - std::string vectorElementType = stripPrefix( commandData.params[vectorParamIndex.first].type.type, "Vk" ); + std::string vectorElementType = ( templatedParams.find( vectorParamIndex.first ) == templatedParams.end() ) + ? stripPrefix( commandData.params[vectorParamIndex.first].type.type, "Vk" ) + : ( stripPrefix( commandData.params[vectorParamIndex.first].name, "p" ) + "Type" ); if ( definition ) { const std::string functionTemplate = - R"( template + R"( template <${argumentTemplates}typename ${vectorElementType}Allocator, typename Dispatch${typenameCheck}> VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE std::vector<${vectorElementType}, ${vectorElementType}Allocator> ${className}${classSeparator}${commandName}( ${argumentList} ) const { VULKAN_HPP_ASSERT( d.getVkHeaderVersion() == VK_HEADER_VERSION ); std::vector<${vectorElementType}, ${vectorElementType}Allocator> ${vectorName}${vectorAllocator}; ${counterType} ${counterName}; - d.${vkCommand}( ${firstCallArguments} ); - ${vectorName}.resize( ${counterName} ); + d.${vkCommand}( ${firstCallArguments} );${templateArgumentSizeAssert} + ${vectorName}.resize( ${vectorSize} ); d.${vkCommand}( ${secondCallArguments} ); - VULKAN_HPP_ASSERT( ${counterName} <= ${vectorName}.size() ); + VULKAN_HPP_ASSERT( ${counterName} <= ${vectorName}.size()${timesTemplateTypeSize} ); return ${vectorName}; })"; + std::string counterName = startLowerCase( stripPrefix( commandData.params[vectorParamIndex.second].name, "p" ) ); + std::string templateArgumentSizeAssert, timesTemplateTypeSize, vectorSize; + if ( templatedParams.find( vectorParamIndex.first ) == templatedParams.end() ) + { + vectorSize = counterName; + } + else + { + templateArgumentSizeAssert = + "\n VULKAN_HPP_ASSERT( " + counterName + " % sizeof( " + vectorElementType + " ) == 0 );"; + timesTemplateTypeSize = " * sizeof( " + vectorElementType + " )"; + vectorSize = counterName + " / sizeof( " + vectorElementType + " )"; + } std::string vectorName = startLowerCase( stripPrefix( commandData.params[vectorParamIndex.first].name, "p" ) ); std::string typenameCheck = withAllocators ? ( ", typename B, typename std::enable_if, typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE${typenameCheck}> + R"( template <${argumentTemplates}typename ${vectorElementType}Allocator = std::allocator<${vectorElementType}>, typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE${typenameCheck}> VULKAN_HPP_NODISCARD std::vector<${vectorElementType}, ${vectorElementType}Allocator> ${commandName}( ${argumentList} ) const;)"; std::string typenameCheck = withAllocators @@ -5916,6 +5923,7 @@ std::string VulkanHppGenerator::generateCommandVoidEnumerate( std::string const return replaceWithMap( functionTemplate, { { "argumentList", argumentList }, + { "argumentTemplates", argumentTemplates }, { "commandName", commandName }, { "typenameCheck", typenameCheck }, { "vectorElementType", vectorElementType } } ); @@ -6853,7 +6861,8 @@ std::string VulkanHppGenerator::generateFunctionCall( std::string const & assert( commandData.params[it->first].type.postfix.back() == '*' ); if ( ( returnParam == it->first ) && twoStep && firstCall ) { - // this parameter is the return parameter, and it's the first call of a two-step algorithm -> just just nullptr + // this parameter is the return parameter, and it's the first call of a two-step algorithm -> just just + // nullptr str += "nullptr"; } else @@ -6888,7 +6897,8 @@ std::string VulkanHppGenerator::generateFunctionCall( std::string const & // this parameter is a count parameter for a vector parameter // the corresponding vector parameter is not the return parameter, or it's not a two-step algorithm // for the non-singular version, the count is the size of the vector parameter - // -> use the vector parameter name without leading 'p' to get the size (in number of elements, not in bytes) + // -> use the vector parameter name without leading 'p' to get the size (in number of elements, not in + // bytes) assert( commandData.params[it->first].name[0] == 'p' ); str += startLowerCase( stripPrefix( commandData.params[it->first].name, "p" ) ) + ".size() "; if ( it->first == templateParamIndex ) @@ -9779,23 +9789,19 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandVoid( case 2: if ( commandIt->second.params[returnParamIndices[0]].type.type == "uint32_t" ) { - if ( ( commandIt->second.params[returnParamIndices[1]].type.type != "void" ) && - !isHandleType( commandIt->second.params[returnParamIndices[1]].type.type ) ) + std::map vectorParams = determineVectorParams( commandIt->second.params ); + if ( vectorParams.size() == 1 ) { - std::map vectorParams = determineVectorParams( commandIt->second.params ); - if ( vectorParams.size() == 1 ) + if ( returnParamIndices[0] == vectorParams.begin()->second ) { - if ( returnParamIndices[0] == vectorParams.begin()->second ) + if ( returnParamIndices[1] == vectorParams.begin()->first ) { - if ( returnParamIndices[1] == vectorParams.begin()->first ) + str = generateRAIIHandleCommandVoid2ReturnEnumerateValue( + commandIt, initialSkipCount, vectorParams, returnParamIndices, definition ); + if ( isStructureChainAnchor( commandIt->second.params[returnParamIndices[1]].type.type ) ) { - str = generateRAIIHandleCommandVoid2ReturnEnumerateValue( + str += generateRAIIHandleCommandVoid2ReturnEnumerateChain( commandIt, initialSkipCount, vectorParams, returnParamIndices, definition ); - if ( isStructureChainAnchor( commandIt->second.params[returnParamIndices[1]].type.type ) ) - { - str += generateRAIIHandleCommandVoid2ReturnEnumerateChain( - commandIt, initialSkipCount, vectorParams, returnParamIndices, definition ); - } } } } @@ -10074,28 +10080,30 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandVoid2ReturnEnumerateVal std::vector const & returnParamIndices, bool definition ) const { - assert( returnParamIndices.size() == 2 ); - assert( vectorParams.size() == 1 ); - std::set skippedParams = determineSkippedParams( commandIt->second.params, initialSkipCount, vectorParams, returnParamIndices, false ); - std::string argumentList = - generateArgumentListEnhanced( commandIt->second.params, skippedParams, {}, {}, definition, false, false, false ); + std::set templatedParams = determineVoidPointerParams( commandIt->second.params ); + std::string argumentList = generateArgumentListEnhanced( + commandIt->second.params, skippedParams, {}, templatedParams, definition, false, false, false ); + std::string argumentTemplates = generateArgumentTemplates( commandIt->second.params, templatedParams, true ); std::string commandName = generateCommandName( commandIt->first, commandIt->second.params, initialSkipCount, m_tags ); std::string vectorElementType = - stripPostfix( commandIt->second.params[vectorParams.begin()->first].type.compose( "VULKAN_HPP_NAMESPACE" ), "*" ); + ( templatedParams.find( vectorParams.begin()->first ) == templatedParams.end() ) + ? stripPostfix( commandIt->second.params[vectorParams.begin()->first].type.compose( "VULKAN_HPP_NAMESPACE" ), + "*" ) + : ( stripPrefix( commandIt->second.params[vectorParams.begin()->first].name, "p" ) + "Type" ); if ( definition ) { const std::string definitionTemplate = - R"( + R"(${argumentTemplates} VULKAN_HPP_NODISCARD VULKAN_HPP_INLINE std::vector<${vectorElementType}> ${className}::${commandName}( ${argumentList} ) const VULKAN_HPP_NOEXCEPT {${functionPointerCheck} ${counterType} ${counterName}; - getDispatcher()->${vkCommand}( ${firstCallArguments} ); - std::vector<${vectorElementType}> ${vectorName}( ${counterName} ); + getDispatcher()->${vkCommand}( ${firstCallArguments} );${templateArgumentSizeAssert} + std::vector<${vectorElementType}> ${vectorName}( ${vectorSize} ); getDispatcher()->${vkCommand}( ${secondCallArguments} ); - VULKAN_HPP_ASSERT( ${counterName} == ${vectorName}.size() ); + VULKAN_HPP_ASSERT( ${counterName} == ${vectorName}.size()${timesTemplateTypeSize} ); return ${vectorName}; } )"; @@ -10103,15 +10111,28 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandVoid2ReturnEnumerateVal std::string counterName = startLowerCase( stripPrefix( commandIt->second.params[vectorParams.begin()->second].name, "p" ) ); std::string firstCallArguments = - generateCallArgumentsEnhanced( commandIt->second, initialSkipCount, true, {}, {}, true ); + generateCallArgumentsEnhanced( commandIt->second, initialSkipCount, true, {}, templatedParams, true ); std::string secondCallArguments = - generateCallArgumentsEnhanced( commandIt->second, initialSkipCount, false, {}, {}, true ); + generateCallArgumentsEnhanced( commandIt->second, initialSkipCount, false, {}, templatedParams, true ); + std::string templateArgumentSizeAssert, timesTemplateTypeSize, vectorSize; + if ( templatedParams.find( vectorParams.begin()->first ) == templatedParams.end() ) + { + vectorSize = counterName; + } + else + { + templateArgumentSizeAssert = + "\n VULKAN_HPP_ASSERT( " + counterName + " % sizeof( " + vectorElementType + " ) == 0 );"; + timesTemplateTypeSize = " * sizeof( " + vectorElementType + " )"; + vectorSize = counterName + " / sizeof( " + vectorElementType + " )"; + } std::string vectorName = startLowerCase( stripPrefix( commandIt->second.params[vectorParams.begin()->first].name, "p" ) ); return replaceWithMap( definitionTemplate, { { "argumentList", argumentList }, + { "argumentTemplates", argumentTemplates }, { "className", stripPrefix( commandIt->second.params[initialSkipCount - 1].type.type, "Vk" ) }, { "commandName", commandName }, { "counterName", counterName }, @@ -10119,19 +10140,23 @@ std::string VulkanHppGenerator::generateRAIIHandleCommandVoid2ReturnEnumerateVal { "firstCallArguments", firstCallArguments }, { "functionPointerCheck", generateFunctionPointerCheck( commandIt->first, commandIt->second.referencedIn ) }, { "secondCallArguments", secondCallArguments }, + { "templateArgumentSizeAssert", templateArgumentSizeAssert }, + { "timesTemplateTypeSize", timesTemplateTypeSize }, { "vectorElementType", vectorElementType }, { "vectorName", vectorName }, + { "vectorSize", vectorSize }, { "vkCommand", commandIt->first } } ); } else { std::string const declarationTemplate = - R"( + R"(${argumentTemplates} VULKAN_HPP_NODISCARD std::vector<${vectorElementType}> ${commandName}( ${argumentList} ) const VULKAN_HPP_NOEXCEPT; )"; return replaceWithMap( declarationTemplate, { { "argumentList", argumentList }, + { "argumentTemplates", argumentTemplates }, { "commandName", commandName }, { "vectorElementType", vectorElementType } } ); } @@ -12326,12 +12351,13 @@ std::tuple } else { - // as we don't have any meaningful default initialization values, everything can be initialized by just '{}' ! + // as we don't have any meaningful default initialization values, everything can be initialized by just '{}' + // ! assert( member.arraySizes.empty() || member.bitCount.empty() ); if ( !member.bitCount.empty() ) { - members += " : " + member.bitCount; // except for bitfield members, where no default member initializatin is - // supported (up to C++20) + members += " : " + member.bitCount; // except for bitfield members, where no default member initializatin + // is supported (up to C++20) } else { @@ -12566,8 +12592,8 @@ std::string VulkanHppGenerator::generateUnion( std::pairtype ).second ) { - // VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a uint32_t - // constructor. + // VkBool32 is aliased to uint32_t. Don't create a VkBool32 constructor if the union also contains a + // uint32_t constructor. if ( memberIt->type.type == "VkBool32" ) { if ( findStructMemberItByType( "uint32_t", structure.second.members ) != structure.second.members.end() ) @@ -13533,8 +13559,8 @@ void VulkanHppGenerator::readExtensionsExtension( tinyxml2::XMLElement const * e { if ( platform.empty() ) { - // for now, having the attribute provisional="true" implies attribute platform="provisional" to get stuff - // protected by VK_ENABLE_BETA_EXTENSIONS + // for now, having the attribute provisional="true" implies attribute platform="provisional" to get + // stuff protected by VK_ENABLE_BETA_EXTENSIONS platform = "provisional"; } check( @@ -15791,8 +15817,8 @@ void checkAttributes( int line, std::map> const & required, std::map> const & optional ) { - // check if all required attributes are included and if there is a set of allowed values, check if the actual value - // is part of that set + // check if all required attributes are included and if there is a set of allowed values, check if the actual + // value is part of that set for ( auto const & r : required ) { auto attributesIt = attributes.find( r.first ); @@ -15801,8 +15827,8 @@ void checkAttributes( int line, line, "unexpected attribute value <" + attributesIt->second + "> in attribute <" + r.first + ">" ); } - // check if all not required attributes or optional, and if there is a set of allowed values, check if the actual - // value is part of that set + // check if all not required attributes or optional, and if there is a set of allowed values, check if the + // actual value is part of that set for ( auto const & a : attributes ) { if ( required.find( a.first ) == required.end() ) @@ -15913,7 +15939,8 @@ std::pair prefix = toUpperCase( name ) + "_"; } - // if the enum name contains a tag move it from the prefix to the postfix to generate correct enum value names. + // if the enum name contains a tag move it from the prefix to the postfix to generate correct enum value + // names. for ( auto const & tag : tags ) { if ( endsWith( prefix, tag + "_" ) ) @@ -16003,8 +16030,8 @@ std::string generateStandardArrayWrapper( std::string const & type, std::vector< std::string generateSuccessCode( std::string const & code, std::set const & tags ) { std::string tag = findTag( tags, code ); - // on each success code: prepend 'VULKAN_HPP_NAMESPACE::Result::e', strip "VK_" and a tag, convert it to camel case, - // and add the tag again + // on each success code: prepend 'VULKAN_HPP_NAMESPACE::Result::e', strip "VK_" and a tag, convert it to camel + // case, and add the tag again return "VULKAN_HPP_NAMESPACE::Result::e" + toCamelCase( stripPostfix( stripPrefix( code, "VK_" ), tag ) ) + tag; }