Почему некоторые типы структур позволяют нам устанавливать элементы, которые могут иметь только определенное значение? - PullRequest
0 голосов
/ 05 октября 2018

Я читал о некоторых типах структур vulkan, это один из многих примеров, но я буду использовать vkInstanceCreateInfo.Документация гласит:

Структура VkInstanceCreateInfo определяется как:

typedef struct VkInstanceCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkInstanceCreateFlags       flags;
    const VkApplicationInfo*    pApplicationInfo;
    uint32_t                    enabledLayerCount;
    const char* const*          ppEnabledLayerNames;
    uint32_t                    enabledExtensionCount;
    const char* const*          ppEnabledExtensionNames;
} VkInstanceCreateInfo;

Тогда ниже в опциях мы видим:

sTypeэто тип этой структурытип?

Примечание: я понимаю, что это не является чем-то конкретным для vulkan API.

Обновление: я не просто говорю конкретно о vulkan, просто все параметры, которые могут быть только определеннымитипа.

1 Ответ

0 голосов
/ 05 октября 2018

Конструкция позволяет связывать структуры вместе, чтобы расширения могли создавать дополнительные параметры для существующих вызовов, не мешая исходным структурам 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 соответствующим образом.

...