From b075d67fbcedabf654b2de4aea375d16be27d05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Mon, 7 May 2018 16:44:32 +0200 Subject: [PATCH] Add constructor for structures which kind of extends some other structures (like Offset3D extending Offset2D) (#213) --- VulkanHppGenerator.cpp | 135 +++++++++++++++++++++++++++++++---------- VulkanHppGenerator.hpp | 3 + vulkan/vulkan.hpp | 51 ++++++++++++++++ 3 files changed, 156 insertions(+), 33 deletions(-) diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index 627c3c1..2884d06 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -1570,6 +1570,23 @@ std::string const& VulkanHppGenerator::getVulkanLicenseHeader() const return m_vulkanLicenseHeader; } +bool VulkanHppGenerator::isSubStruct(std::pair const& nsd, std::string const& name, StructData const& structData) +{ + if ((nsd.first != name) && (nsd.second.members.size() < structData.members.size()) && (structData.members[0].name != "sType")) + { + bool equal = true; + for (size_t i = 0; i < nsd.second.members.size() && equal; i++) + { + equal = (nsd.second.members[i].type == structData.members[i].type) && (nsd.second.members[i].name == structData.members[i].name); + } + if (equal) + { + return true; + } + } + return false; +} + void VulkanHppGenerator::linkCommandToHandle(CommandData & commandData) { // first, find the handle named like the type of the first argument @@ -2694,6 +2711,15 @@ void VulkanHppGenerator::readTypeStruct(tinyxml2::XMLElement const* element, boo assert(m_vkTypes.find(name) == m_vkTypes.end()); m_vkTypes.insert(name); + + for (auto const& s : m_structs) + { + if (isSubStruct(s, name, it->second)) + { + it->second.subStruct = s.first; + break; // just take the very first candidate as a subStruct, skip any possible others! + } + } } } @@ -3951,39 +3977,7 @@ void VulkanHppGenerator::writeStructConstructor(std::ostream & os, std::string c bool listedArgument = false; for (size_t i = 0; i < structData.members.size(); i++) { - if (listedArgument) - { - os << ", "; - } - // skip members 'pNext' and 'sType', as they are never explicitly set - if ((structData.members[i].name != "pNext") && (structData.members[i].name != "sType")) - { - // find a default value for the given pure type - std::map::const_iterator defaultIt = defaultValues.find(structData.members[i].pureType); - assert(defaultIt != defaultValues.end()); - - if (structData.members[i].arraySize.empty()) - { - // the arguments name get a trailing '_', to distinguish them from the actual struct members - // pointer arguments get a nullptr as default - os << structData.members[i].type << " " << structData.members[i].name << "_ = " << (structData.members[i].type.back() == '*' ? "nullptr" : defaultIt->second); - } - else - { - // array members are provided as const reference to a std::array - // the arguments name get a trailing '_', to distinguish them from the actual struct members - // list as many default values as there are elements in the array - os << "std::array<" << structData.members[i].type << "," << structData.members[i].arraySize << "> const& " << structData.members[i].name << "_ = { { " << defaultIt->second; - size_t n = atoi(structData.members[i].arraySize.c_str()); - assert(0 < n); - for (size_t j = 1; j < n; j++) - { - os << ", " << defaultIt->second; - } - os << " } }"; - } - listedArgument = true; - } + listedArgument = writeStructConstructorArgument(os, listedArgument, structData.members[i], defaultValues); } os << " )" << std::endl; @@ -4022,6 +4016,43 @@ void VulkanHppGenerator::writeStructConstructor(std::ostream & os, std::string c } os << " }\n\n"; + if (!structData.subStruct.empty()) + { + auto const& subStruct = m_structs.find(structData.subStruct); + assert(subStruct != m_structs.end()); + + std::string subStructArgumentName = startLowerCase(strip(subStruct->first, "vk")); + + os << " explicit " << name << "( " << subStruct->first << " const& " << subStructArgumentName; + for (size_t i = subStruct->second.members.size(); i < structData.members.size(); i++) + { + writeStructConstructorArgument(os, true, structData.members[i], defaultValues); + } + os << " )" << std::endl; + + bool firstArgument = true; + std::string templateString = " ${sep} ${member}( ${value} )\n"; + for (size_t i = 0; i < subStruct->second.members.size(); i++) + { + assert(structData.members[i].arraySize.empty()); + std::string sep = firstArgument ? ":" : ","; + std::string member = structData.members[i].name; + std::string value = subStructArgumentName + "." + subStruct->second.members[i].name; + + os << replaceWithMap(templateString, { { "sep", sep },{ "member", member },{ "value", value } }); + firstArgument = false; + } + for (size_t i = subStruct->second.members.size(); i < structData.members.size(); i++) + { + assert(structData.members[i].arraySize.empty()); + std::string member = structData.members[i].name; + std::string value = structData.members[i].name + "_"; // the elements are initialized by the corresponding argument (with trailing '_', as mentioned above) + + os << replaceWithMap(templateString, { { "sep", "," },{ "member", member },{ "value", value } }); + } + os << " {}" << std::endl << std::endl; + } + std::string templateString = R"( ${name}( Vk${name} const & rhs ) { @@ -4038,6 +4069,44 @@ void VulkanHppGenerator::writeStructConstructor(std::ostream & os, std::string c os << replaceWithMap(templateString, { { "name", name } }); } +bool VulkanHppGenerator::writeStructConstructorArgument(std::ostream & os, bool listedArgument, MemberData const& memberData, std::map const& defaultValues) +{ + if (listedArgument) + { + os << ", "; + } + // skip members 'pNext' and 'sType', as they are never explicitly set + if ((memberData.name != "pNext") && (memberData.name != "sType")) + { + // find a default value for the given pure type + std::map::const_iterator defaultIt = defaultValues.find(memberData.pureType); + assert(defaultIt != defaultValues.end()); + + if (memberData.arraySize.empty()) + { + // the arguments name get a trailing '_', to distinguish them from the actual struct members + // pointer arguments get a nullptr as default + os << memberData.type << " " << memberData.name << "_ = " << (memberData.type.back() == '*' ? "nullptr" : defaultIt->second); + } + else + { + // array members are provided as const reference to a std::array + // the arguments name get a trailing '_', to distinguish them from the actual struct members + // list as many default values as there are elements in the array + os << "std::array<" << memberData.type << "," << memberData.arraySize << "> const& " << memberData.name << "_ = { { " << defaultIt->second; + size_t n = atoi(memberData.arraySize.c_str()); + assert(0 < n); + for (size_t j = 1; j < n; j++) + { + os << ", " << defaultIt->second; + } + os << " } }"; + } + listedArgument = true; + } + return listedArgument; +} + void VulkanHppGenerator::writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData) { if (memberData.type != "StructureType") // filter out StructureType, which is supposed to be immutable ! diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index acbed3c..3d02b89 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -186,6 +186,7 @@ class VulkanHppGenerator std::string protect; std::vector structExtends; std::string alias; + std::string subStruct; }; #if !defined(NDEBUG) @@ -213,6 +214,7 @@ class VulkanHppGenerator void determineTemplateParam(CommandData & commandData); void determineVectorParams(CommandData & commandData); std::string generateCall(CommandData const& commandData, bool firstCall, bool singular); + bool isSubStruct(std::pair const& nsd, std::string const& name, StructData const& structData); void linkCommandToHandle(CommandData & commandData); bool readCommandParam(tinyxml2::XMLElement const* element, std::set & dependencies, std::vector & params); tinyxml2::XMLNode const* readCommandParamType(tinyxml2::XMLNode const* node, ParamData& param); @@ -269,6 +271,7 @@ class VulkanHppGenerator void writeFunctionHeaderReturnType(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool singular, bool unique, bool isStructureChain); void writeFunctionHeaderTemplate(std::ostream & os, std::string const& indentation, CommandData const& commandData, bool enhanced, bool unique, bool withDefault, bool isStructureChain); void writeStructConstructor(std::ostream & os, std::string const& name, StructData const& structData, std::map const& defaultValues); + bool writeStructConstructorArgument(std::ostream & os, bool listedArgument, MemberData const& memberData, std::map const& defaultValues); void writeStructSetter(std::ostream & os, std::string const& structureName, MemberData const& memberData); void writeStructureChainValidation(std::ostream & os, DependencyData const& dependencyData); void writeThrowExceptions(std::ostream& os, EnumData const& enumData); diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 3ea82c8..249da81 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -4810,6 +4810,12 @@ public: { } + explicit Offset3D( Offset2D const& offset2D, int32_t z_ = 0 ) + : x( offset2D.x ) + , y( offset2D.y ) + , z( z_ ) + {} + Offset3D( VkOffset3D const & rhs ) { memcpy( this, &rhs, sizeof( Offset3D ) ); @@ -4921,6 +4927,12 @@ public: { } + explicit Extent3D( Extent2D const& extent2D, uint32_t depth_ = 0 ) + : width( extent2D.width ) + , height( extent2D.height ) + , depth( depth_ ) + {} + Extent3D( VkExtent3D const & rhs ) { memcpy( this, &rhs, sizeof( Extent3D ) ); @@ -6614,6 +6626,12 @@ public: { } + explicit RectLayerKHR( Rect2D const& rect2D, uint32_t layer_ = 0 ) + : offset( rect2D.offset ) + , extent( rect2D.extent ) + , layer( layer_ ) + {} + RectLayerKHR( VkRectLayerKHR const & rhs ) { memcpy( this, &rhs, sizeof( RectLayerKHR ) ); @@ -24953,6 +24971,12 @@ public: { } + explicit ObjectTablePipelineEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, Pipeline pipeline_ = Pipeline() ) + : type( objectTableEntryNVX.type ) + , flags( objectTableEntryNVX.flags ) + , pipeline( pipeline_ ) + {} + ObjectTablePipelineEntryNVX( VkObjectTablePipelineEntryNVX const & rhs ) { memcpy( this, &rhs, sizeof( ObjectTablePipelineEntryNVX ) ); @@ -25014,6 +25038,13 @@ public: { } + explicit ObjectTableDescriptorSetEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, PipelineLayout pipelineLayout_ = PipelineLayout(), DescriptorSet descriptorSet_ = DescriptorSet() ) + : type( objectTableEntryNVX.type ) + , flags( objectTableEntryNVX.flags ) + , pipelineLayout( pipelineLayout_ ) + , descriptorSet( descriptorSet_ ) + {} + ObjectTableDescriptorSetEntryNVX( VkObjectTableDescriptorSetEntryNVX const & rhs ) { memcpy( this, &rhs, sizeof( ObjectTableDescriptorSetEntryNVX ) ); @@ -25082,6 +25113,12 @@ public: { } + explicit ObjectTableVertexBufferEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, Buffer buffer_ = Buffer() ) + : type( objectTableEntryNVX.type ) + , flags( objectTableEntryNVX.flags ) + , buffer( buffer_ ) + {} + ObjectTableVertexBufferEntryNVX( VkObjectTableVertexBufferEntryNVX const & rhs ) { memcpy( this, &rhs, sizeof( ObjectTableVertexBufferEntryNVX ) ); @@ -25143,6 +25180,13 @@ public: { } + explicit ObjectTableIndexBufferEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, Buffer buffer_ = Buffer(), IndexType indexType_ = IndexType::eUint16 ) + : type( objectTableEntryNVX.type ) + , flags( objectTableEntryNVX.flags ) + , buffer( buffer_ ) + , indexType( indexType_ ) + {} + ObjectTableIndexBufferEntryNVX( VkObjectTableIndexBufferEntryNVX const & rhs ) { memcpy( this, &rhs, sizeof( ObjectTableIndexBufferEntryNVX ) ); @@ -25212,6 +25256,13 @@ public: { } + explicit ObjectTablePushConstantEntryNVX( ObjectTableEntryNVX const& objectTableEntryNVX, PipelineLayout pipelineLayout_ = PipelineLayout(), ShaderStageFlags stageFlags_ = ShaderStageFlags() ) + : type( objectTableEntryNVX.type ) + , flags( objectTableEntryNVX.flags ) + , pipelineLayout( pipelineLayout_ ) + , stageFlags( stageFlags_ ) + {} + ObjectTablePushConstantEntryNVX( VkObjectTablePushConstantEntryNVX const & rhs ) { memcpy( this, &rhs, sizeof( ObjectTablePushConstantEntryNVX ) );