From 16ace53e0259a0f0a9e371e03c6502475b7dfd8f Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Tue, 17 Nov 2020 09:51:55 +0100 Subject: [PATCH] Add support for functions that enumerate chained structures. --- VulkanHppGenerator.cpp | 175 ++++++++++++++++++++++++++++++++++------- VulkanHppGenerator.hpp | 6 ++ 2 files changed, 153 insertions(+), 28 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index d6d5c37..b30f645 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1176,7 +1176,16 @@ void VulkanHppGenerator::appendCommand( std::string & str, if ( !isHandleType( commandData.params[nonConstPointerParamIndices[0]].type.type ) && !isStructureChainAnchor( commandData.params[nonConstPointerParamIndices[0]].type.type ) ) { - if ( !isStructureChainAnchor( commandData.params[nonConstPointerParamIndices[1]].type.type ) ) + if ( isStructureChainAnchor( commandData.params[nonConstPointerParamIndices[1]].type.type ) ) + { + if ( ( commandData.returnType == "VkResult" ) || ( commandData.returnType == "void" ) ) + { + appendCommandVectorChained( + str, name, commandData, definition, vectorParamIndices, nonConstPointerParamIndices ); + appendedFunction = true; + } + } + else { // non of the return parameters is a StructureChain // Note: if the vector returned holds handles, the function does not create them, but just gets them @@ -1218,12 +1227,6 @@ void VulkanHppGenerator::appendCommand( std::string & str, break; } } - else if ( commandData.returnType == "void" ) - { - appendCommandVectorChained( - str, name, commandData, definition, vectorParamIndices, nonConstPointerParamIndices ); - appendedFunction = true; - } } break; case 3: @@ -1589,7 +1592,7 @@ void VulkanHppGenerator::appendCommandVectorChained( std::string & std::map const & vectorParamIndices, std::vector const & returnParamIndices ) const { - assert( commandData.returnType == "void" ); + assert( ( commandData.returnType == "VkResult" ) || ( commandData.returnType == "void" ) ); assert( vectorParamIndices.size() == 1 ); std::string const functionTemplate = R"( @@ -1605,25 +1608,35 @@ ${leave})"; std::string enter, leave; std::tie( enter, leave ) = generateProtection( commandData.feature, commandData.extensions ); - str += - replaceWithMap( functionTemplate, - std::map( - { { "commandEnhanced", - constructCommandVoidEnumerate( - name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, false ) }, - { "commandEnhancedChained", - constructCommandVoidEnumerateChained( - name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, false ) }, - { "commandEnhancedChainedWithAllocator", - constructCommandVoidEnumerateChained( - name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, true ) }, - { "commandEnhancedWithAllocator", - constructCommandVoidEnumerate( - name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, true ) }, - { "commandStandard", constructCommandStandard( name, commandData, definition ) }, - { "enter", enter }, - { "leave", leave }, - { "newlineOnDefinition", definition ? "\n" : "" } } ) ); + str += replaceWithMap( + functionTemplate, + std::map( + { { "commandEnhanced", + ( commandData.returnType == "VkResult" ) + ? constructCommandResultEnumerate( name, commandData, definition, *vectorParamIndices.begin(), false ) + : constructCommandVoidEnumerate( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, false ) }, + { "commandEnhancedChained", + ( commandData.returnType == "VkResult" ) + ? constructCommandResultEnumerateChained( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, false ) + : constructCommandVoidEnumerateChained( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, false ) }, + { "commandEnhancedChainedWithAllocator", + ( commandData.returnType == "VkResult" ) + ? constructCommandResultEnumerateChained( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, true ) + : constructCommandVoidEnumerateChained( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, true ) }, + { "commandEnhancedWithAllocator", + ( commandData.returnType == "VkResult" ) + ? constructCommandResultEnumerate( name, commandData, definition, *vectorParamIndices.begin(), true ) + : constructCommandVoidEnumerate( + name, commandData, definition, *vectorParamIndices.begin(), returnParamIndices, true ) }, + { "commandStandard", constructCommandStandard( name, commandData, definition ) }, + { "enter", enter }, + { "leave", leave }, + { "newlineOnDefinition", definition ? "\n" : "" } } ) ); } void VulkanHppGenerator::appendCommandVectorDeprecated( std::string & str, @@ -3635,6 +3648,112 @@ std::string VulkanHppGenerator::constructCommandResultEnumerate( std::string con } } +std::string + VulkanHppGenerator::constructCommandResultEnumerateChained( std::string const & name, + CommandData const & commandData, + bool definition, + std::pair const & vectorParamIndex, + std::vector const & returnParamIndices, + bool withAllocator ) const +{ + assert( commandData.returnType == "VkResult" ); + assert( ( commandData.successCodes.size() == 2 ) && ( commandData.successCodes[0] == "VK_SUCCESS" ) && + ( commandData.successCodes[1] == "VK_INCOMPLETE" ) ); + + std::set skippedParams = + determineSkippedParams( commandData.handle, commandData.params, { vectorParamIndex }, returnParamIndices, false ); + + std::string argumentList = + constructArgumentListEnhanced( commandData.params, skippedParams, INVALID_INDEX, definition, withAllocator, true ); + std::string commandName = determineCommandName( name, commandData.params[0].type.type ); + std::string nodiscard = determineNoDiscard( 1 < commandData.successCodes.size(), 1 < commandData.errorCodes.size() ); + assert( beginsWith( commandData.params[vectorParamIndex.first].type.type, "Vk" ) ); + std::string vectorElementType = + "VULKAN_HPP_NAMESPACE::" + stripPrefix( commandData.params[vectorParamIndex.first].type.type, "Vk" ); + std::string allocatorType = startUpperCase( vectorElementType ) + "Allocator"; + + if ( definition ) + { + const std::string functionTemplate = + R"( template + ${nodiscard}VULKAN_HPP_INLINE typename ResultValueType>::type ${className}${classSeparator}${commandName}( ${argumentList} ) const + { + std::vector returnVector${structureChainAllocator}; + std::vector<${vectorElementType}> ${vectorName}; + ${counterType} ${counterName}; + Result result; + do + { + result = static_cast( d.${vkCommand}( ${firstCallArguments} ) ); + if ( ( result == Result::eSuccess ) && ${counterName} ) + { + returnVector.resize( ${counterName} ); + ${vectorName}.resize( ${counterName} ); + for ( ${counterType} i = 0; i < ${counterName}; i++ ) + { + ${vectorName}[i].pNext = + returnVector[i].template get<${vectorElementType}>().pNext; + } + result = static_cast( d.${vkCommand}( ${secondCallArguments} ) ); + VULKAN_HPP_ASSERT( ${counterName} <= ${vectorName}.size() ); + } + } while ( result == Result::eIncomplete ); + if ( ( result == Result::eSuccess ) && ( ${counterName} < ${vectorName}.size() ) ) + { + returnVector.resize( ${counterName} ); + ${vectorName}.resize( ${counterName} ); + } + for ( ${counterType} i = 0; i < ${counterName}; i++ ) + { + returnVector[i].template get<${vectorElementType}>() = ${vectorName}[i]; + } + return createResultValue( result, returnVector, VULKAN_HPP_NAMESPACE_STRING"::${className}${classSeparator}${commandName}" ); + })"; + + std::string vectorName = startLowerCase( stripPrefix( commandData.params[vectorParamIndex.first].name, "p" ) ); + std::string typenameCheck = + withAllocator + ? ( ", typename B, typename std::enable_if::value, int>::type" ) + : ""; + + return replaceWithMap( + functionTemplate, + { { "argumentList", argumentList }, + { "className", commandData.handle.empty() ? "" : stripPrefix( commandData.handle, "Vk" ) }, + { "classSeparator", commandData.handle.empty() ? "" : "::" }, + { "commandName", commandName }, + { "counterName", startLowerCase( stripPrefix( commandData.params[vectorParamIndex.second].name, "p" ) ) }, + { "counterType", commandData.params[vectorParamIndex.second].type.type }, + { "firstCallArguments", + constructCallArgumentsEnhanced( commandData.handle, commandData.params, true, INVALID_INDEX ) }, + { "nodiscard", nodiscard }, + { "secondCallArguments", + constructCallArgumentsEnhanced( commandData.handle, commandData.params, false, INVALID_INDEX ) }, + { "structureChainAllocator", withAllocator ? ( ", structureChainAllocator" ) : "" }, + { "typenameCheck", typenameCheck }, + { "vectorElementType", vectorElementType }, + { "vectorName", vectorName }, + { "vkCommand", name } } ); + } + else + { + const std::string functionTemplate = + R"( template , typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE${typenameCheck}> + ${nodiscard}typename ResultValueType>::type ${commandName}( ${argumentList} ) const;)"; + + std::string typenameCheck = + withAllocator + ? ( ", typename B = StructureChainAllocator, typename std::enable_if::value, int>::type = 0" ) + : ""; + + return replaceWithMap( functionTemplate, + { { "argumentList", argumentList }, + { "commandName", commandName }, + { "nodiscard", nodiscard }, + { "typenameCheck", typenameCheck } } ); + } +} + std::string VulkanHppGenerator::constructCommandResultEnumerateTwoVectors( std::string const & name, CommandData const & commandData, @@ -7785,7 +7904,7 @@ void VulkanHppGenerator::readEnums( tinyxml2::XMLElement const * element ) check( it->second.values.empty(), line, "enum <" + name + "> already holds values" ); // mark it as a bitmask, if it is one - bool bitmask = ( type == "bitmask" ); + bool bitmask = ( type == "bitmask" ); check( !bitmask || std::find_if( m_bitmasks.begin(), m_bitmasks.end(), [&name]( auto const & bitmask ) { diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index af97c93..bf49f75 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -485,6 +485,12 @@ private: bool definition, std::pair const & vectorParamIndices, bool withAllocators ) const; + std::string constructCommandResultEnumerateChained( std::string const & name, + CommandData const & commandData, + bool definition, + std::pair const & vectorParamIndex, + std::vector const & returnParamIndices, + bool withAllocator ) const; std::string constructCommandResultEnumerateTwoVectors( std::string const & name, CommandData const & commandData, bool definition,