30

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

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

4

1 回答 1

40

他们有一个,因此该pNext领域确实有效。

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

这些字段至关重要,因为链表是用pNext指针构建的……它们是void*s。它们没有固定类型。实现确定非 NULLpNext指针指向什么的方式是检查存储在那里的前 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,那就是新的。

当然,如前所述,这还没有成功。1.0 后的 Vulkan 版本选择合并扩展结构而不是替换现有的结构。但是选择就在那里。

于 2016-04-01T03:03:27.993 回答