我正在阅读一些vulkan结构类型,这是许多示例之一,但是我将使用的是vkInstanceCreateInfo。该文档指出:
VkInstanceCreateInfo结构定义为:
app
然后在下面看到的选项中:
sType是此结构的类型
sType 必须为VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
如果我们仍然没有任何选项,为什么在创建类型时不只是隐式设置此参数?
注意:我意识到这不是vulkan API特有的。
更新:我不仅在谈论vulkan,还只是在讨论只能是某种类型的所有参数。
答案 0 :(得分:2)
该设计允许将结构链接在一起,以便扩展可以为现有调用创建其他参数,而不会干扰原始API结构,也不会彼此干扰。
Vulkan中的几乎每个结构的第一个成员为sType
,第二个成员为pNext
。这意味着,如果您有一个void*
并且只知道它是某种Vulkan API结构,则可以安全地读取前32位,它将是VkStructureType
并读取接下来的32位或64位,它将告诉您链中是否还有其他结构。
例如,有一个VkMemoryAllocateInfo
结构用于分配内存,除了sType
和pNext
之外,还有分配的大小和应该从中获得的堆索引。如果我想使用“专用分配”扩展名,那么我还需要用额外的信息填充VkMemoryDedicatedAllocateInfo
结构,但是我仍然需要调用只需要{{ 1}} ...那么我应该把填写的vkAllocateMemory
结构放在哪里呢?我将指针指向VkMemoryAllocateInfo
的{{1}}字段中。
也许我也想与一些OpenGL代码共享此内存。有一个扩展允许您执行此操作,但是您需要填写VkMemoryDedicatedAllocateInfo
结构并在分配期间将其传递。好的,我可以通过将其放在我的pNext
结构的VkMemoryAllocateInfo
字段中来实现。我可以根据需要创建一系列结构。
这是真正重要的部分。由于所有结构都以VkExportMemoryAllocateInfo
作为其第一个字段,因此扩展程序可以沿结构链进行导航并找到其关心的结构,而不用知道它们始终以pNext
和{ {1}}。
所有这些都意味着可以通过改变现有功能的行为来扩展Vulkan,而无需更改功能本身或传递给它的结构。
您可能会问为什么所有核心结构都具有VkMemoryDedicatedAllocateInfo
和sType
,即使您将它们传递给具有类型指针而不是void指针的函数。原因是一致性,并且因为您不知道何时需要将现有结构作为某些新扩展的链的一部分。
如果我们仍然没有任何选项,为什么在创建类型时不只是隐式设置此参数?
因为C不是C ++。没有办法在C中声明结构,并说该结构的这一部分将始终具有该值。在C ++中,您可以通过将某些内容声明为const并提供初始默认值来实现。实际上,我喜欢Vulkan C ++绑定的一件事是,您基本上可以永远忘记sType
。如果您使用扩展名,则仍需要根据需要填充pNext
。