Неоднозначность количества наборов дескрипторов в Vulkan

Я хочу нарисовать два объекта вулканом. Для этого я следую процедуре, в которой вы создаете два разных набора дескрипторов для каждой модели. Однако меня смущают структуры, которые определяют необходимое количество наборов дескрипторов. Вот что меня смущает:

  1. указание счетчика дескрипторов в VkDescriptorSetLayoutBinding

    VkDescriptorSetLayoutBinding stagingLayoutBinding = {};
    ...
    stagingLayoutBinding.descriptorCount = 1;   <- i have one mat4 element for each descriptors 
    
  2. указание счетчика дескрипторов в VkDescriptorPoolSize

    VkDescriptorPoolSize stagingPoolSize = {};
    ...
    stagingPoolSize.descriptorCount = static_cast<uint32_t>(model.size());  <- allocate two descriptor sets from one descriptor pool
    
  3. определение максимальных наборов в VkDescriptorPoolCreateInfo

    VkDescriptorPoolCreateInfo poolInfo = {};
    ...
    poolInfo.maxSets = model.size();   <- max descriptor sets = 2
    
  4. наконец, указав создание набора дескрипторов в VkDescriptorSetAllocateInfo

    VkDescriptorSetAllocateInfo allocInfo = {};
    ...
    allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
    

однако на vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data()) выдается исключение, и сообщение отладки на уровне проверки выглядит следующим образом: -

validation Layer: Object: 0xcccccccccccccccc (Type = 20) | Invalid DescriptorSetLayout Object 0xcccccccccccccccc. The spec valid usage text states 'pSetLayouts must be a valid pointer to an array of descriptorSetCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkDescriptorSetAllocateInfo-pSetLayouts-parameter)

мой код создания дескриптора выглядит следующим образом:

    VkDescriptorSetLayout layouts[] = { descriptorSetLayout };

    descriptorSet.resize(model.size());
    VkDescriptorSetAllocateInfo allocInfo = {};
    allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    allocInfo.descriptorPool = descriptorPool[0];
    allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
    allocInfo.pSetLayouts = layouts;

    if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSet.data()) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to allocate descriptor set !");
    }

Я предполагаю, что я где-то кормлю неправильный счетчик набора дескрипторов.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
8
0
1 520
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема, вероятно, здесь:

allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());

Если вы хотите нарисовать 2 объекта, я предполагаю, что model.size() вернет 2. Тем не менее, вы предоставляете только один макет набора дескрипторов:

VkDescriptorSetLayout layouts[] = { descriptorSetLayout };

Если вы хотите выделить 2 (или более) набора дескрипторов, вам необходимо предоставить 2 (или более) макета набора дескрипторов. Если вы хотите, чтобы наборы дескрипторов совместно использовали макет, вам просто нужно предоставить один и тот же макет несколько раз.

Что касается непонятных полей:

  1. Член descriptorCount структуры VkDescriptorSetLayoutBinding - это количество дескрипторов, содержащихся в привязке, к которым осуществляется доступ в шейдере в виде массива. Обычно здесь предоставляется 1, если только вы не хотите создать массив дескрипторов заданного типа (например, массив выборочных изображений), тогда вам нужно указать большее значение.
  2. Член descriptorCount в VkDescriptorPoolSize указывает, сколько дескрипторов данного типа может быть выделено из данного пула. Это значение не зависит от общего количества наборов дескрипторов, например, вы можете создать пул дескрипторов, из которого вы можете выделить всего 3 набора дескрипторов, но всего 2 образа хранилища.
  3. Член maxSets структуры VkDescriptorPoolCreateInfo определяет, сколько наборов дескрипторов может быть выделено из данного пула (общее количество наборов, которые могут быть выделены из пула). Опять же, это значение определяет «целые» наборы, в то время как предыдущее значение (из маркера 2) определяет конкретные дескрипторы.
  4. Член descriptorSetCount структуры VkDescriptorSetAllocateInfo указывает, сколько наборов дескрипторов вы хотите выделить в данный момент (во время вызова функции vkAllocateDescriptorSets()). Например, вы можете создать пул, из которого вы можете выделить 10 наборов дескрипторов, но вы хотите выделить только один набор дескрипторов за раз, вызывая функцию vkAllocateDescriptorSets() 10 раз.

Я хочу выделить два набора дескрипторов, используя один макет набора дескрипторов, поэтому мне нужно установить allocInfo.descriptorSetCount = 2 (по которому model.size () возвращает 2), я также изменил allocInfo.pSetLayouts = &descriptorSetLayout;, но все равно получаю ту же ошибку, для vkAllocateDescriptorSets() я должен создать цикл for для распределения? или мой текущий код в порядке?

BulBul 07.08.2018 14:18

@BulBul &descriptorSetLayout указывает на один макет набора дескрипторов. У вас должно получиться что-то вроде: VkDescriptorSetLayout layouts[] = { descriptorSetLayout, descriptorSetLayout }; и allocInfo.pSetLayouts = layouts;.

Ekzuzy 07.08.2018 17:26

это сработало для меня, теперь я лучше понимаю наборы дескрипторов, спасибо за вашу помощь.

BulBul 07.08.2018 17:54

Другие вопросы по теме