Add support for "allowduplicate" attribute on chainable structures.

This commit is contained in:
asuessenbach 2020-05-11 11:52:25 +02:00 committed by Markus Tavenrath
parent 306d2ce9c3
commit 8958396a0c
4 changed files with 1361 additions and 815 deletions

View File

@ -3832,6 +3832,7 @@ void VulkanHppGenerator::appendStructure( std::string &
static const std::string structureTemplate = R"( struct ${structureName} static const std::string structureTemplate = R"( struct ${structureName}
{ {
${allowDuplicate}
${structureType} ${structureType}
${constructorAndSetters} ${constructorAndSetters}
@ -3854,14 +3855,17 @@ ${members}
)"; )";
std::string structureName = stripPrefix( structure.first, "Vk" ); std::string structureName = stripPrefix( structure.first, "Vk" );
std::string structureType; std::string allowDuplicate, structureType;
if ( !sTypeValue.empty() ) if ( !sTypeValue.empty() )
{ {
allowDuplicate = std::string( " static const bool allowDuplicate = " ) +
( structure.second.allowDuplicate ? "true;" : "false;" );
structureType = structureType =
" static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::" + sTypeValue + ";\n"; " static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::" + sTypeValue + ";\n";
} }
str += replaceWithMap( structureTemplate, str += replaceWithMap( structureTemplate,
{ { "structureName", structureName }, { { "allowDuplicate", allowDuplicate },
{ "structureName", structureName },
{ "structureType", structureType }, { "structureType", structureType },
{ "constructorAndSetters", constructorAndSetters }, { "constructorAndSetters", constructorAndSetters },
{ "vkName", structure.first }, { "vkName", structure.first },
@ -3932,8 +3936,8 @@ void VulkanHppGenerator::appendStructureChainValidation( std::string & str )
str += subEnter; str += subEnter;
} }
str += " template <> struct isStructureChainValid<" + stripPrefix( extendName, "Vk" ) + ", " + str += " template <> struct StructExtends<" + stripPrefix( structure.first, "Vk" ) + ", " +
stripPrefix( structure.first, "Vk" ) + ">{ enum { value = true }; };\n"; stripPrefix( extendName, "Vk" ) + ">{ enum { value = true }; };\n";
if ( leave != subLeave ) if ( leave != subLeave )
{ {
@ -6215,10 +6219,16 @@ void VulkanHppGenerator::readStruct( tinyxml2::XMLElement const *
std::string category, name; std::string category, name;
std::vector<std::string> structExtends; std::vector<std::string> structExtends;
bool allowDuplicate = false;
bool returnedOnly = false; bool returnedOnly = false;
for ( auto const & attribute : attributes ) for ( auto const & attribute : attributes )
{ {
if ( attribute.first == "category" ) if ( attribute.first == "allowduplicate" )
{
assert( attribute.second == "true" );
allowDuplicate = true;
}
else if ( attribute.first == "category" )
{ {
category = attribute.second; category = attribute.second;
} }
@ -6238,12 +6248,17 @@ void VulkanHppGenerator::readStruct( tinyxml2::XMLElement const *
} }
} }
assert( !name.empty() ); assert( !name.empty() );
// make this warn a check, as soon as vk.xml has been fixed on attribute "allowduplicate" !
warn( !allowDuplicate || !structExtends.empty(),
line,
"attribute <allowduplicate> is true, but no structures are listed in <structextends>" );
check( m_structures.find( name ) == m_structures.end(), line, "struct <" + name + "> already specfied" ); check( m_structures.find( name ) == m_structures.end(), line, "struct <" + name + "> already specfied" );
std::map<std::string, StructureData>::iterator it = std::map<std::string, StructureData>::iterator it =
m_structures.insert( std::make_pair( name, StructureData( structExtends, line ) ) ).first; m_structures.insert( std::make_pair( name, StructureData( structExtends, line ) ) ).first;
it->second.returnedOnly = returnedOnly; it->second.allowDuplicate = allowDuplicate;
it->second.isUnion = isUnion; it->second.isUnion = isUnion;
it->second.returnedOnly = returnedOnly;
for ( auto child : children ) for ( auto child : children )
{ {
@ -7261,186 +7276,227 @@ int main( int argc, char ** argv )
)"; )";
static const std::string classStructureChain = R"( static const std::string classStructureChain = R"(
template <typename X, typename Y> struct isStructureChainValid { enum { value = false }; }; template <typename X, typename Y> struct StructExtends { enum { value = false }; };
template <typename P, typename T>
struct TypeList
{
using list = P;
using last = T;
};
template <typename List, typename X>
struct extendCheck
{
static const bool valid = isStructureChainValid<typename List::last, X>::value || extendCheck<typename List::list,X>::valid;
};
template <typename T, typename X>
struct extendCheck<TypeList<void,T>,X>
{
static const bool valid = isStructureChainValid<T, X>::value;
};
template <typename X>
struct extendCheck<void,X>
{
static const bool valid = true;
};
template<typename Type, class...> template<typename Type, class...>
struct isPartOfStructureChain struct IsPartOfStructureChain
{ {
static const bool valid = false; static const bool valid = false;
}; };
template<typename Type, typename Head, typename... Tail> template<typename Type, typename Head, typename... Tail>
struct isPartOfStructureChain<Type, Head, Tail...> struct IsPartOfStructureChain<Type, Head, Tail...>
{ {
static const bool valid = std::is_same<Type, Head>::value || isPartOfStructureChain<Type, Tail...>::valid; static const bool valid = std::is_same<Type, Head>::value || IsPartOfStructureChain<Type, Tail...>::valid;
}; };
template <class Element> template <size_t Index, typename T, typename... ChainElements>
class StructureChainElement struct StructureChainContains
{ {
public: static const bool value = std::is_same<T, typename std::tuple_element<Index, std::tuple<ChainElements...>>::type>::value ||
explicit operator Element&() VULKAN_HPP_NOEXCEPT { return value; } StructureChainContains<Index - 1, T, ChainElements...>::value;
explicit operator const Element&() const VULKAN_HPP_NOEXCEPT { return value; }
private:
Element value;
}; };
template<typename ...StructureElements> template <typename T, typename... ChainElements>
class StructureChain : private StructureChainElement<StructureElements>... struct StructureChainContains<0, T, ChainElements...>
{
static const bool value = std::is_same<T, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value;
};
template <size_t Index, typename... ChainElements>
struct StructureChainValidation
{
using TestType = typename std::tuple_element<Index, std::tuple<ChainElements...>>::type;
static const bool valid =
StructExtends<TestType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value &&
( TestType::allowDuplicate || !StructureChainContains<Index - 1, TestType, ChainElements...>::value ) &&
StructureChainValidation<Index - 1, ChainElements...>::valid;
};
template <typename... ChainElements>
struct StructureChainValidation<0, ChainElements...>
{
static const bool valid = true;
};
template <typename... ChainElements>
class StructureChain : public std::tuple<ChainElements...>
{ {
public: public:
StructureChain() VULKAN_HPP_NOEXCEPT StructureChain() VULKAN_HPP_NOEXCEPT
{ {
link<void, StructureElements...>(); static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid,
"The structure chain is not valid!" );
link<sizeof...( ChainElements ) - 1>();
} }
StructureChain(StructureChain const &rhs) VULKAN_HPP_NOEXCEPT StructureChain( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT : std::tuple<ChainElements...>( rhs )
{ {
linkAndCopy<void, StructureElements...>(rhs); static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid,
"The structure chain is not valid!" );
link<sizeof...( ChainElements ) - 1>();
} }
StructureChain(StructureElements const &... elems) VULKAN_HPP_NOEXCEPT StructureChain( StructureChain && rhs ) VULKAN_HPP_NOEXCEPT
: std::tuple<ChainElements...>( std::forward<std::tuple<ChainElements...>>( rhs ) )
{ {
linkAndCopyElements<void, StructureElements...>(elems...); static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid,
"The structure chain is not valid!" );
link<sizeof...( ChainElements ) - 1>();
}
StructureChain( ChainElements const &... elems ) VULKAN_HPP_NOEXCEPT : std::tuple<ChainElements...>( elems... )
{
static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid,
"The structure chain is not valid!" );
link<sizeof...( ChainElements ) - 1>();
} }
StructureChain & operator=( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT StructureChain & operator=( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
{ {
linkAndCopy<void, StructureElements...>(rhs); std::tuple<ChainElements...>::operator=( rhs );
link<sizeof...( ChainElements ) - 1>();
return *this; return *this;
} }
template<typename ClassType> ClassType& get() VULKAN_HPP_NOEXCEPT { return static_cast<ClassType&>(*this);} StructureChain & operator=( StructureChain && rhs ) = delete;
template<typename ClassType> const ClassType& get() const VULKAN_HPP_NOEXCEPT { return static_cast<const ClassType&>(*this);} template <typename T, size_t Which = 0>
T & get() VULKAN_HPP_NOEXCEPT
template<typename ClassTypeA, typename ClassTypeB, typename ...ClassTypes>
std::tuple<ClassTypeA&, ClassTypeB&, ClassTypes&...> get()
{ {
return std::tie(get<ClassTypeA>(), get<ClassTypeB>(), get<ClassTypes>()...); return std::get<ChainElementIndex<0, T, Which, void, ChainElements...>::value>( *this );
} }
template<typename ClassTypeA, typename ClassTypeB, typename ...ClassTypes> template <typename T, size_t Which = 0>
std::tuple<const ClassTypeA&, const ClassTypeB&, const ClassTypes&...> get() const T const & get() const VULKAN_HPP_NOEXCEPT
{ {
return std::tie(get<ClassTypeA>(), get<ClassTypeB>(), get<ClassTypes>()...); return std::get<ChainElementIndex<0, T, Which, void, ChainElements...>::value>( *this );
} }
template<typename ClassType> template <typename T0, typename T1, typename... Ts>
void unlink() VULKAN_HPP_NOEXCEPT std::tuple<T0 &, T1 &, Ts &...> get() VULKAN_HPP_NOEXCEPT
{ {
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::valid, "Can't unlink Structure that's not part of this StructureChain!"); return std::tie( get<T0>(), get<T1>(), get<Ts>()... );
static_assert(!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<StructureElements...>>::type>::value, "It's not allowed to unlink the first element!");
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>());
VULKAN_HPP_ASSERT(ptr != nullptr);
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
VULKAN_HPP_ASSERT(*ppNext != nullptr);
while (*ppNext != ptr)
{
ppNext = &(*ppNext)->pNext;
VULKAN_HPP_ASSERT(*ppNext != nullptr); // fires, if the ClassType member has already been unlinked !
}
VULKAN_HPP_ASSERT(*ppNext == ptr);
*ppNext = (*ppNext)->pNext;
} }
template <typename ClassType> template <typename T0, typename T1, typename... Ts>
std::tuple<T0 const &, T1 const &, Ts const &...> get() const VULKAN_HPP_NOEXCEPT
{
return std::tie( get<T0>(), get<T1>(), get<Ts>()... );
}
template <typename ClassType, size_t Which = 0>
void relink() VULKAN_HPP_NOEXCEPT void relink() VULKAN_HPP_NOEXCEPT
{ {
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::valid, "Can't relink Structure that's not part of this StructureChain!"); static_assert( IsPartOfStructureChain<ClassType, ChainElements...>::valid,
static_assert(!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<StructureElements...>>::type>::value, "It's not allowed to have the first element unlinked!"); "Can't relink Structure that's not part of this StructureChain!" );
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>()); static_assert(
VULKAN_HPP_ASSERT(ptr != nullptr); !std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value || (Which != 0),
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext); "It's not allowed to have the first element unlinked!" );
VULKAN_HPP_ASSERT(*ppNext != nullptr);
#if !defined(NDEBUG) auto pNext = reinterpret_cast<VkBaseInStructure *>( &get<ClassType, Which>() );
while (*ppNext) VULKAN_HPP_ASSERT( !isLinked( pNext ) );
{ auto & headElement = std::get<0>( *this );
VULKAN_HPP_ASSERT(*ppNext != ptr); // fires, if the ClassType member has not been unlinked before pNext->pNext = reinterpret_cast<VkBaseInStructure const*>(headElement.pNext);
ppNext = &(*ppNext)->pNext; headElement.pNext = pNext;
} }
ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
#endif template <typename ClassType, size_t Which = 0>
ptr->pNext = *ppNext; void unlink() VULKAN_HPP_NOEXCEPT
*ppNext = ptr; {
static_assert( IsPartOfStructureChain<ClassType, ChainElements...>::valid,
"Can't unlink Structure that's not part of this StructureChain!" );
static_assert(
!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value || (Which != 0),
"It's not allowed to unlink the first element!" );
unlink<sizeof...( ChainElements ) - 1>( reinterpret_cast<VkBaseOutStructure const *>( &get<ClassType, Which>() ) );
} }
private: private:
template<typename List, typename X> template <int Index, typename T, int Which, typename, class First, class... Types>
void link() VULKAN_HPP_NOEXCEPT struct ChainElementIndex : ChainElementIndex<Index + 1, T, Which, void, Types...>
{};
template <int Index, typename T, int Which, class First, class... Types>
struct ChainElementIndex<Index,
T,
Which,
typename std::enable_if<!std::is_same<T, First>::value, void>::type,
First,
Types...> : ChainElementIndex<Index + 1, T, Which, void, Types...>
{};
template <int Index, typename T, int Which, class First, class... Types>
struct ChainElementIndex<Index,
T,
Which,
typename std::enable_if<std::is_same<T, First>::value, void>::type,
First,
Types...> : ChainElementIndex<Index + 1, T, Which - 1, void, Types...>
{};
template <int Index, typename T, class First, class... Types>
struct ChainElementIndex<Index,
T,
0,
typename std::enable_if<std::is_same<T, First>::value, void>::type,
First,
Types...> : std::integral_constant<int, Index>
{};
bool isLinked( VkBaseInStructure const * pNext )
{ {
static_assert(extendCheck<List, X>::valid, "The structure chain is not valid!"); VkBaseInStructure const * elementPtr = reinterpret_cast<VkBaseInStructure const*>(&std::get<0>( *this ));
while ( elementPtr )
{
if ( elementPtr->pNext == pNext )
{
return true;
}
elementPtr = elementPtr->pNext;
}
return false;
} }
template<typename List, typename X, typename Y, typename ...Z> template <size_t Index>
void link() VULKAN_HPP_NOEXCEPT typename std::enable_if<Index != 0, void>::type link() VULKAN_HPP_NOEXCEPT
{ {
static_assert(extendCheck<List,X>::valid, "The structure chain is not valid!"); auto & x = std::get<Index - 1>( *this );
X& x = static_cast<X&>(*this); x.pNext = &std::get<Index>( *this );
Y& y = static_cast<Y&>(*this); link<Index - 1>();
x.pNext = &y;
link<TypeList<List, X>, Y, Z...>();
} }
template<typename List, typename X> template <size_t Index>
void linkAndCopy(StructureChain const &rhs) VULKAN_HPP_NOEXCEPT typename std::enable_if<Index == 0, void>::type link() VULKAN_HPP_NOEXCEPT
{}
template <size_t Index>
typename std::enable_if<Index != 0, void>::type unlink( VkBaseOutStructure const * pNext ) VULKAN_HPP_NOEXCEPT
{ {
static_assert(extendCheck<List, X>::valid, "The structure chain is not valid!"); auto & element = std::get<Index>( *this );
static_cast<X&>(*this) = static_cast<X const &>(rhs); if ( element.pNext == pNext )
{
element.pNext = pNext->pNext;
}
else
{
unlink<Index - 1>( pNext );
}
} }
template<typename List, typename X, typename Y, typename ...Z> template <size_t Index>
void linkAndCopy(StructureChain const &rhs) VULKAN_HPP_NOEXCEPT typename std::enable_if<Index == 0, void>::type unlink( VkBaseOutStructure const * pNext ) VULKAN_HPP_NOEXCEPT
{ {
static_assert(extendCheck<List, X>::valid, "The structure chain is not valid!"); auto & element = std::get<0>( *this );
X& x = static_cast<X&>(*this); if ( element.pNext == pNext )
Y& y = static_cast<Y&>(*this); {
x = static_cast<X const &>(rhs); element.pNext = pNext->pNext;
x.pNext = &y;
linkAndCopy<TypeList<List, X>, Y, Z...>(rhs);
} }
else
template<typename List, typename X>
void linkAndCopyElements(X const &xelem) VULKAN_HPP_NOEXCEPT
{ {
static_assert(extendCheck<List, X>::valid, "The structure chain is not valid!"); VULKAN_HPP_ASSERT( false ); // fires, if the ClassType member has already been unlinked !
static_cast<X&>(*this) = xelem;
} }
template<typename List, typename X, typename Y, typename ...Z>
void linkAndCopyElements(X const &xelem, Y const &yelem, Z const &... zelem) VULKAN_HPP_NOEXCEPT
{
static_assert(extendCheck<List, X>::valid, "The structure chain is not valid!");
X& x = static_cast<X&>(*this);
Y& y = static_cast<Y&>(*this);
x = xelem;
x.pNext = &y;
linkAndCopyElements<TypeList<List, X>, Y, Z...>(yelem, zelem...);
} }
}; };
)"; )";

View File

@ -208,11 +208,12 @@ private:
struct StructureData struct StructureData
{ {
StructureData( std::vector<std::string> const & extends, int line ) StructureData( std::vector<std::string> const & extends, int line )
: returnedOnly( false ), isUnion( false ), structExtends( extends ), xmlLine( line ) : structExtends( extends ), xmlLine( line )
{} {}
bool returnedOnly; bool allowDuplicate = false;
bool isUnion; bool isUnion = false;
bool returnedOnly = false;
std::vector<MemberData> members; std::vector<MemberData> members;
std::vector<std::string> structExtends; std::vector<std::string> structExtends;
std::set<std::string> aliases; std::set<std::string> aliases;

View File

@ -72,29 +72,40 @@ int main( int /*argc*/, char ** /*argv*/ )
sc7; sc7;
// some invalid StructureChains // some invalid StructureChains
// clang-format off
//vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceMaintenance3Properties> x; //vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceMaintenance3Properties> x;
// vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceMaintenance3Properties, //vk::StructureChain<vk::PhysicalDeviceIDProperties,
// vk::PhysicalDevicePushDescriptorPropertiesKHR> x; vk::StructureChain<vk::PhysicalDeviceIDProperties, // vk::PhysicalDeviceMaintenance3Properties,
// vk::PhysicalDevicePushDescriptorPropertiesKHR, vk::PhysicalDeviceMaintenance3Properties> x; // vk::PhysicalDevicePushDescriptorPropertiesKHR>
// vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceIDProperties> // x;
// x; vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceProperties2> x; //vk::StructureChain<vk::PhysicalDeviceIDProperties,
// vk::PhysicalDevicePushDescriptorPropertiesKHR,
// vk::PhysicalDeviceMaintenance3Properties>
// x;
//vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceIDProperties> x;
//vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceProperties2> x;
// clang-format on
// unlink a struct from a StructureChain // unlink a struct from a StructureChain
sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>(); sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>();
// some invalid unlink calls // some invalid unlink calls
// clang-format off
//sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>(); // assertion fires on trying to unlink some already //sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>(); // assertion fires on trying to unlink some already
// unlinked structure sc7.unlink<vk::PhysicalDeviceProperties2>(); // // unlinked structure
//sc7.unlink<vk::PhysicalDeviceProperties2>();
//sc1.unlink<vk::PhysicalDeviceMaintenance3Properties>(); //sc1.unlink<vk::PhysicalDeviceMaintenance3Properties>();
// clang-format on
// re-link a struct // re-link a struct
sc7.relink<vk::PhysicalDeviceMaintenance3Properties>(); sc7.relink<vk::PhysicalDeviceMaintenance3Properties>();
// invalid re-linking // invalid re-linking
// clang-format off
//sc7.relink<vk::PhysicalDeviceProperties2>(); //sc7.relink<vk::PhysicalDeviceProperties2>();
//sc1.relink<vk::PhysicalDeviceMaintenance3Properties>(); //sc1.relink<vk::PhysicalDeviceMaintenance3Properties>();
// sc1.relink<vk::PhysicalDeviceIDProperties>(); // assertion fires on trying to relink some structure //sc1.relink<vk::PhysicalDeviceIDProperties>(); // assertion fires on trying to relink some structure that hasn't been unlinked
// that hasn't been unlinked // clang-format on
// simple call, passing structures in // simple call, passing structures in
vk::PhysicalDeviceFeatures2 pdf; vk::PhysicalDeviceFeatures2 pdf;
@ -125,6 +136,28 @@ int main( int /*argc*/, char ** /*argv*/ )
using AllocatorType = std::vector<StructureChain>::allocator_type; using AllocatorType = std::vector<StructureChain>::allocator_type;
auto qfd = physicalDevice.getQueueFamilyProperties2<StructureChain, AllocatorType>( VULKAN_HPP_DEFAULT_DISPATCHER ); auto qfd = physicalDevice.getQueueFamilyProperties2<StructureChain, AllocatorType>( VULKAN_HPP_DEFAULT_DISPATCHER );
unused( qfd ); unused( qfd );
// some tests with structures with allowDuplicate == true
// include them as soon as vk.xml has been fixed on attribute "allowduplicate" !
#if 0
vk::StructureChain<vk::DeviceCreateInfo, vk::DevicePrivateDataCreateInfoEXT, vk::DevicePrivateDataCreateInfoEXT>
dci0;
auto dci1( dci0 );
vk::DeviceCreateInfo dci;
vk::DevicePrivateDataCreateInfoEXT dpdci0;
vk::DevicePrivateDataCreateInfoEXT dpdci1;
vk::StructureChain<vk::DeviceCreateInfo, vk::DevicePrivateDataCreateInfoEXT, vk::DevicePrivateDataCreateInfoEXT>
dci2( dci, dpdci0, dpdci1 );
dci2 = dci1;
auto & dpdci = dci0.get<vk::DevicePrivateDataCreateInfoEXT, 1>();
auto const & dpdcic = dci0.get<vk::DevicePrivateDataCreateInfoEXT, 1>();
dci2.unlink<vk::DevicePrivateDataCreateInfoEXT, 1>();
dci2.relink<vk::DevicePrivateDataCreateInfoEXT, 1>();
#endif
} }
catch ( vk::SystemError const & err ) catch ( vk::SystemError const & err )
{ {

File diff suppressed because it is too large Load Diff