跳到主要内容

pNext和sType用法

刚接触 Vulkan 的你可能会注意到 Vulkan Spec 中无处不在的pNextsType变量。 pNext主要用于扩展功能的衍生结构体。void* pNext在结构体之间创建链接,loader、layer和驱动使用VkStructureType sType来获知传入的pNext结构体类型。

两种基本结构体

Vulkan API 提供了两种基本结构VkBaseInStructureVkBaseOutStructure,用来遍历结构指针链表。

对loader、layer和驱动程序来说,VkBaseInStructureInpNextconst * 只读的,VkBaseOutStructureOutpNext是用来将数据返回给应用程序。

设置pNext示例

// An example with two simple structures, "a" and "b"
typedef struct VkA {
VkStructureType sType;
void* pNext;
uint32_t value;
} VkA;

typedef struct VkB {
VkStructureType sType;
void* pNext;
uint32_t value;
} VkB;

// A Vulkan Function that takes struct "a" as an argument
// This function is in charge of populating the values
void vkGetValue(VkA* pA);

// Define "a" and "b" and set their sType
struct VkB b = {};
b.sType = VK_STRUCTURE_TYPE_B;

struct VkA a = {};
a.sType = VK_STRUCTURE_TYPE_A;

// Set the pNext pointer from "a" to "b"
a.pNext = (void*)&b;

// Pass "a" to the function
vkGetValue(&a);

// Use the values which were both set from vkGetValue()
printf("VkA value = %u \n", a.value);
printf("VkB value = %u \n", b.value);

读取pNext示例

这个示例说明了loader、layer和驱动是如何找到pNext的链式结构的:

void vkGetValue(VkA* pA) {

VkBaseOutStructure* next = reinterpret_cast<VkBaseOutStructure*>(pA->pNext);
while (next != nullptr) {
switch (next->sType) {

case VK_STRUCTURE_TYPE_B:
VkB* pB = reinterpret_cast<VkB*>(next);
// This is where the "b.value" above got set
pB->value = 42;
break;

case VK_STRUCTURE_TYPE_C:
// Can chain as many structures as supported
VkC* pC = reinterpret_cast<VkC*>(next);
SomeFunction(pC);
break;

default:
LOG("Unsupported sType %d", next->sType);
}

// This works because the first two values of all chainable Vulkan structs
// are "sType" and "pNext" making the offsets the same for pNext
next = reinterpret_cast<VkBaseOutStructure*>(next->pNext);
}

// ...
}