Introduce functions vk::StructureChain::unlink<ClassType>() and vk::StructureChain::relink<ClassType>(). (#441)

Resolves #439.
This commit is contained in:
Andreas Süßenbach 2019-11-28 15:58:15 +01:00 committed by Markus Tavenrath
parent e40eb90980
commit f2058303cb
4 changed files with 122 additions and 0 deletions

View File

@ -191,6 +191,9 @@ vk::StructureChain<vk::MemoryAllocateInfo, vk::MemoryDedicatedAllocateInfo> c =
};
```
If one of the structures of a StructureChain is to be removed, maybe due to some optional settings, you can use the function ```vk::StructureChain::unlink<ClassType>()```. It modifies the StructureChain such that the specified structure isn't part of the pNext-chain any more. Note, that the actual memory layout of the StructureChain is not modified by that function.
In case that very same structure has to be re-added to the StructureChain again, use ```vk::StructureChain::relink<ClassType>()```.
Sometimes the user has to pass a preallocated structure chain to query information. For those cases there are two corresponding getter functions. One with a variadic template generating a structure chain of at least two elements to construct the return value:
```

View File

@ -4739,6 +4739,18 @@ int main( int argc, char **argv )
static const bool valid = true;
};
template<typename Type, class...>
struct isPartOfStructureChain
{
static const bool valid = false;
};
template<typename Type, typename Head, typename... Tail>
struct isPartOfStructureChain<Type, Head, Tail...>
{
static const bool valid = std::is_same<Type, Head>::value || isPartOfStructureChain<Type, Tail...>::valid;
};
template <class Element>
class StructureChainElement
{
@ -4785,6 +4797,45 @@ int main( int argc, char **argv )
);
}
template<typename ClassType>
void unlink() VULKAN_HPP_NOEXCEPT
{
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::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<StructureElements...>>::type>::value, "It's not allowed to unlink the first element!");
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>());
assert(ptr != nullptr);
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
assert(*ppNext != nullptr);
while (*ppNext != ptr)
{
ppNext = &(*ppNext)->pNext;
assert(*ppNext != nullptr); // fires, if the ClassType member has already been unlinked !
}
assert(*ppNext == ptr);
*ppNext = (*ppNext)->pNext;
}
template <typename ClassType>
void relink() VULKAN_HPP_NOEXCEPT
{
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::valid, "Can't relink Structure that's not part of this StructureChain!");
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!");
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>());
assert(ptr != nullptr);
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
assert(*ppNext != nullptr);
#if !defined(NDEBUG)
while (*ppNext)
{
assert(*ppNext != ptr); // fires, if the ClassType member has not been unlinked before
ppNext = &(*ppNext)->pNext;
}
ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
#endif
ptr->pNext = *ppNext;
*ppNext = ptr;
}
private:
template<typename List, typename X>
void link() VULKAN_HPP_NOEXCEPT

View File

@ -43,6 +43,7 @@ int main(int /*argc*/, char ** /*argv*/)
vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1);
vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo));
VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance);
vk::PhysicalDevice physicalDevice = instance->enumeratePhysicalDevices().front();
// some valid StructureChains
@ -61,6 +62,22 @@ int main(int /*argc*/, char ** /*argv*/)
//vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceIDProperties> x;
//vk::StructureChain<vk::PhysicalDeviceIDProperties, vk::PhysicalDeviceProperties2> x;
// unlink a struct from a StructureChain
sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>();
// some invalid unlink calls
//sc7.unlink<vk::PhysicalDeviceMaintenance3Properties>(); // assertion fires on trying to unlink some already unlinked structure
//sc7.unlink<vk::PhysicalDeviceProperties2>();
//sc1.unlink<vk::PhysicalDeviceMaintenance3Properties>();
// re-link a struct
sc7.relink<vk::PhysicalDeviceMaintenance3Properties>();
// invalid re-linking
//sc7.relink<vk::PhysicalDeviceProperties2>();
//sc1.relink<vk::PhysicalDeviceMaintenance3Properties>();
//sc1.relink<vk::PhysicalDeviceIDProperties>(); // assertion fires on trying to relink some structure that hasn't been unlinked
// simple call, passing structures in
vk::PhysicalDeviceFeatures2 pdf;
physicalDevice.getFeatures2(&pdf);

View File

@ -431,6 +431,18 @@ namespace VULKAN_HPP_NAMESPACE
static const bool valid = true;
};
template<typename Type, class...>
struct isPartOfStructureChain
{
static const bool valid = false;
};
template<typename Type, typename Head, typename... Tail>
struct isPartOfStructureChain<Type, Head, Tail...>
{
static const bool valid = std::is_same<Type, Head>::value || isPartOfStructureChain<Type, Tail...>::valid;
};
template <class Element>
class StructureChainElement
{
@ -477,6 +489,45 @@ namespace VULKAN_HPP_NAMESPACE
);
}
template<typename ClassType>
void unlink() VULKAN_HPP_NOEXCEPT
{
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::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<StructureElements...>>::type>::value, "It's not allowed to unlink the first element!");
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>());
assert(ptr != nullptr);
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
assert(*ppNext != nullptr);
while (*ppNext != ptr)
{
ppNext = &(*ppNext)->pNext;
assert(*ppNext != nullptr); // fires, if the ClassType member has already been unlinked !
}
assert(*ppNext == ptr);
*ppNext = (*ppNext)->pNext;
}
template <typename ClassType>
void relink() VULKAN_HPP_NOEXCEPT
{
static_assert(isPartOfStructureChain<ClassType, StructureElements...>::valid, "Can't relink Structure that's not part of this StructureChain!");
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!");
VkBaseOutStructure * ptr = reinterpret_cast<VkBaseOutStructure*>(&get<ClassType>());
assert(ptr != nullptr);
VkBaseOutStructure ** ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
assert(*ppNext != nullptr);
#if !defined(NDEBUG)
while (*ppNext)
{
assert(*ppNext != ptr); // fires, if the ClassType member has not been unlinked before
ppNext = &(*ppNext)->pNext;
}
ppNext = &(reinterpret_cast<VkBaseOutStructure*>(this)->pNext);
#endif
ptr->pNext = *ppNext;
*ppNext = ptr;
}
private:
template<typename List, typename X>
void link() VULKAN_HPP_NOEXCEPT