Vulkan:vk*CreateInfo 结构中的 sType 有什么意义?

Vulkan: What is the point of sType in vk*CreateInfo structs?

在新 Vulkan API 的所有创建信息结构 (vk*CreateInfo) 中,总是有一个 .sType 成员。如果价值只能是一件事,为什么会有这个?此外,Vulkan 规范非常明确,您只能使用 vk*CreateInfo 结构作为其相应 vkCreate* 函数的参数。似乎有点多余。我可以看到,如果驱动程序将此结构直接传递给 GPU,您可能需要拥有它(我确实注意到它始终是第一个成员)。但这对于应用程序来说似乎是一个非常糟糕的主意,因为如果驱动程序这样做,应用程序将更不容易出错,并且将 int 添加到结构之前似乎并不是一个计算效率极低的操作。我只是不明白它为什么存在。

TL;DR
为什么 vk*CreateInfo 结构有 .sType 成员?

他们有一个,因此 pNext 字段确实有效。

是的,API 采用具有正确 C 类型的结构,因此调用者和接收者都同意该结构是什么类型。但尤其是现在,许多这样的结构都有结构链表,这些结构为实现提供了额外的信息。这些扩展结构(尽管许多是 Vulkan 1.1/2 的核心)就像所有其他结构一样,具有自己的 sType 字段。

这些字段很重要,因为链表是用 pNext 指针构建的……它们是 void*。他们没有设定类型。实现确定非 NULL pNext 指针指向什么的方式是检查存储在那里的前 4 个字节。这是 sType 字段;它允许实现知道将指针转换为什么类型。

当然,API 采用的主要结构并不严格需要 sType 字段,因为它的类型是 API 本身的一部分。但是,这样做有一个假设的原因(它尚未在 Vulkan 版本中得到证实)。

更高版本的 Vulkan 可以扩展命令缓冲池等创建。但它会怎么做呢?好吧,他们可以添加一个全新的入口点:vkCreateCommandPool2。但是这个函数将具有与 vkCreateCommandPool 几乎完全相同的签名;唯一的区别是它们采用不同的 pCreateInfo 结构。

因此,您所要做的就是声明一个 VkCommandPoolCreateInfo2 结构。然后声明 vkCreateCommandPool 可以取任何一个。实现如何判断您传入了哪一个?

因为任何此类结构的前 4 个字节都是 sType。他们可以测试该值。如果值为 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,则为旧结构。如果是VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO_2,那就是新的。

当然,如前所述,这还没有成功; post-1.0 Vulkan 版本选择合并扩展结构而不是替换现有结构。但是选项是有的。