Конструкция позволяет связывать структуры вместе, чтобы расширения могли создавать дополнительные параметры для существующих вызовов, не мешая исходным структурам API и не мешая друг другу.
Почти каждая структура в Vulkan имеет sType
в качестве первого члена и pNext
в качестве второго члена.Это означает, что если у вас есть void*
и все, что вы знаете, это то, что это какая-то структура API Vulkan, вы можете безопасно прочитать первые 32 бита, и это будет VkStructureType
, и прочитать следующие 32 или 64 бита ион скажет вам, если есть другая структура в цепочке.
Так, например, есть структура VkMemoryAllocateInfo
для выделения памяти, которая имеет (помимо sType
и pNext
размер выделения и индекс кучи, из которого оно должно исходить. Но что, если я захочуиспользовать расширение «выделенное выделение». Затем мне также нужно заполнить структуру VkMemoryDedicatedAllocateInfo
дополнительной информацией. Но мне все равно нужно вызвать ту же самую функцию vkAllocateMemory
, которая принимает только VkMemoryAllocateInfo
... так где жеЯ поместил заполненную структуру VkMemoryDedicatedAllocateInfo
? Я поставил указатель на нее в поле pNext
VkMemoryAllocateInfo
.
Может быть, я также хочу поделиться этой памятью с некоторым кодом OpenGL. Есть расширениеэто позволяет вам сделать это, но вам нужно заполнить структуру VkExportMemoryAllocateInfo
и передать ее во время выделения. Ну, я могу сделать это, поместив ее в поле pNext
моей структуры VkMemoryDedicatedAllocateInfo
.Я могу создать цепочку таких структур, сколько захочу.
Вот действительно важная часть. Поскольку все структуры имеют sType
в качестве первого поля, расширение может перемещаться по этой цепочке.структур и найти те, о которых он заботится, не зная ничего о структурах, кроме того, что они всегда начинаются с sType
и pNext
.
Все это означает, что Vulkan можно расширить способами, которые изменяютповедение существующих функций, но без изменения самой функции или структур, которые ей передаются.
Вы можете спросить, почему все основные структуры имеют sType
и pNext
, даже если выпередавая их функциям с типизированными указателями, а не с пустыми указателями.Причина заключается в согласованности и потому, что вы никогда не знаете, когда существующая структура может потребоваться как часть цепочки для какого-то нового расширения.
Если в любом случае у нас нет никаких опций, почему этот параметр не просто неявно устанавливается при создании типа?
Поскольку C не является C ++.Нет способа объявить структуру в C и сказать, что эта часть структуры всегда будет иметь это значение.В C ++ вы можете объявить что-то как const и указать начальное значение по умолчанию.Фактически, одна из вещей, которые мне нравятся в привязках Vulkan C ++, это то, что вы можете навсегда забыть о sType
.Если вы используете расширения, вам все равно нужно заполнить pNext
соответствующим образом.