У меня есть следующая форма в шейдерном конвейере:
макет (набор = 1, привязка = 0) униформа window_uniform_data_uniform {};
Теперь я хочу связать этот набор, поэтому я делаю:
vkCmdBindDescriptorSets(cmd_buffer->vk_buffer_handle, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS,
PipelineLayouts::GUI,
1, // THE UNIFORM BUFFER IS SET 1
1,
&DescriptorSets::GUI, 0, nullptr);
Когда я вызываю эту функцию, я получаю ошибку проверки:
Vulkan validation layer callback: Validation Error: [ VUID-VkPipelineLayoutCreateInfo-pSetLayouts-parameter ] Object 0: handle = 0x1acf6211460, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xb3f957d3 | Invalid VkDescriptorSetLayout Object 0x0. The Vulkan spec states: If setLayoutCount is not 0, pSetLayouts must be a valid pointer to an array of setLayoutCount valid VkDescriptorSetLayout handles
Причина, по которой я думаю, что это происходит, заключается в том, что в описании макета конвейера я говорю, что существует один набор макетов:
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &DescriptorSetLayouts::GUI;
Это имеет смысл для меня, потому что в шейдере у меня есть только set = 1, а не 0. Однако то, что я думаю, происходит в vkCmdBindDescriptorSets, которые я передаю (firstSet (1), descriptorSetCount(1) ), потому что я хочу только обновить набор 1. Вероятно, Vulkan просматривает элемент/позицию 1 схемы конвейера и видит, что она пуста или имеет недопустимые аргументы. Это верно?
Если это так, означает ли это, что если у меня есть описание в шейдере, для которого задано значение = 11, конвейер необходимо создать с 10 фиктивными макетами, даже если я никогда их не обновлю?
И вот вопрос о том, для чего нужны наборы дескрипторов.
@NicolBolas Я считаю, что правильно использую наборы, установите 0, который я буду использовать для определенных данных, установите 1 для другого типа данных. Но тогда у меня есть фрагментный шейдер, который использует только 1, а не 0, поэтому имеет смысл, что счетчик макета будет равен 1, поскольку этот шейдер использует только один. Кажется, в этом случае мне нужен макет фиктивного набора. Вам это кажется странным? Я имею в виду, я делаю что-то не так?
Опять возникает вопрос: почему используется только набор 1? Что означают эти наборы иметь в виду? Вы говорите, что они предназначены для определенного типа данных, но на самом деле не объясняете, что это такое. Вопрос, на который я ссылался, касается дизайна функции; как это вписывается в цели, которые вы пытаетесь достичь здесь?
@NicolBolas Скоро ли мы дойдем до стадии, когда выбор текстур будет в более свободной форме, например, что делают ссылка на буфер и расширения адреса? То есть вы можете хранить указатель на изображение в юниформ-буфере и выбирать это изображение из шейдера? Это позволит полностью обойти дескрипторы. Я полагаю, это то, что делают те расширения, о которых я упоминал, но они не работают с изображениями, не так ли?
Вы можете использовать набор сэмплеров. Они были основными начиная с Vulkan 1.0.
VkPipelineLayoutCreateInfo
есть элемент setLayoutCount
, но нет элемента "установить смещение". Макет конвейера имеет наборы дескрипторов setLayoutCount
с индексами в диапазоне [0, setLayoutCount
).
Ваш конвейер имеет набор 0, даже если шейдеры в этом конвейере никогда его не используют. Это все еще там.
Обратите внимание, что ошибка проверки, которую вы получаете, не из vkBindDescriptorSets
; это от VkPipelineLayoutCreateInfo
, скорее всего в призыве к vkCreatePipelineLayout
.
«если у меня есть описание в шейдере, установленном = 11» Игнорируя тот факт, что почти ни одна реализация Vulkan не поддерживает 12 наборов дескрипторов одновременно, зачем вам вообще это делать? Как вы думаете, что именно представляют собой разные наборы дескрипторов за?