Browse Source

Vk: add a helper for connecting just one structure.

Without the extra overhead of Reference.
pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
bd56ed2d51
  1. 28
      src/Magnum/Vk/Implementation/structureHelpers.h
  2. 20
      src/Magnum/Vk/Test/StructureHelpersTest.cpp

28
src/Magnum/Vk/Implementation/structureHelpers.h

@ -39,24 +39,36 @@ namespace Magnum { namespace Vk { namespace Implementation {
accident. Thus no "give me the first structure of this type" or "remove any
structure of this type from the chain". */
/* Meant to be used for connecting a longer chain of structures. Anything
that was connected to the `next` pointer before is reconnected to
`structure.pNext`; the `next` reference is rebound to the `structure.pNext`
field connected so it can be passed to another structureConnect() again. */
template<class T> inline void structureConnect(Containers::Reference<void*>& next, T& structure, VkStructureType type) {
/* Connecting one structure to a pNext chain. Anything that was connected to
the `next` pointer before is reconnected to `structure.pNext` */
template<class T> inline void structureConnectOne(void*& next, T& structure, VkStructureType type) {
void* const previousNext = next;
*next = &structure;
next = &structure;
structure.sType = type;
structure.pNext = previousNext;
next = structure.pNext;
}
template<class T> inline void structureConnect(Containers::Reference<const void*>& next, T& structure, VkStructureType type) {
template<class T> inline void structureConnectOne(const void*& next, T& structure, VkStructureType type) {
/* There's no better way as the pNext are either const void* or void*
and it's a mess. For example VkDeviceCreateInfo has const void* but it
can point to VkPhysicalDeviceFeatures2 which then has void* as it's
primarily an output structure. So we'll just drop all const-correctness
and operate on void*. */
structureConnectOne(const_cast<void*&>(next), structure, type);
}
/* Meant to be used for connecting a longer chain of structures. Anything
that was connected to the `next` pointer before is reconnected to
`structure.pNext`; the `next` reference is rebound to the `structure.pNext`
field connected so it can be passed to another structureConnect() again. */
template<class T> inline void structureConnect(Containers::Reference<void*>& next, T& structure, VkStructureType type) {
structureConnectOne(*next, structure, type);
next = structure.pNext;
}
template<class T> inline void structureConnect(Containers::Reference<const void*>& next, T& structure, VkStructureType type) {
/* Same reasoning as in structureConnectOne(), we just drop all
const-correctness and operate on void*. */
structureConnect(reinterpret_cast<Containers::Reference<void*>&>(next), structure, type);
}

20
src/Magnum/Vk/Test/StructureHelpersTest.cpp

@ -32,6 +32,7 @@ namespace Magnum { namespace Vk { namespace Test { namespace {
struct StructureHelpersTest: TestSuite::Tester {
explicit StructureHelpersTest();
template<class T> void connectOne();
template<class T> void connect();
template<class T> void find();
template<class T> void disconnectChain();
@ -39,6 +40,8 @@ struct StructureHelpersTest: TestSuite::Tester {
StructureHelpersTest::StructureHelpersTest() {
addTests<StructureHelpersTest>({
&StructureHelpersTest::connectOne<VkDeviceCreateInfo>,
&StructureHelpersTest::connectOne<VkPhysicalDeviceFeatures2>,
&StructureHelpersTest::connect<VkDeviceCreateInfo>,
&StructureHelpersTest::connect<VkPhysicalDeviceFeatures2>,
&StructureHelpersTest::find<VkDeviceCreateInfo>,
@ -55,6 +58,23 @@ template<> struct Type<void*> {
static const char* name() { return "void*"; }
};
template<class T> void StructureHelpersTest::connectOne() {
typedef typename std::remove_reference<decltype(T{}.pNext)>::type NextType;
setTestCaseTemplateName(Type<NextType>::name());
VkPhysicalDeviceVariablePointersFeatures variableFeatures{};
T info{};
info.pNext = &variableFeatures;
VkPhysicalDeviceMultiviewFeatures multiviewFeatures{};
Implementation::structureConnectOne(info.pNext, multiviewFeatures, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES);
CORRADE_COMPARE(info.pNext, &multiviewFeatures);
CORRADE_COMPARE(multiviewFeatures.sType, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES);
/* The pre-existing next pointer should be preserved */
CORRADE_COMPARE(multiviewFeatures.pNext, &variableFeatures);
}
template<class T> void StructureHelpersTest::connect() {
typedef typename std::remove_reference<decltype(T{}.pNext)>::type NextType;
setTestCaseTemplateName(Type<NextType>::name());

Loading…
Cancel
Save