Я хочу нарисовать два объекта вулканом. Для этого я следую процедуре, в которой вы создаете два разных набора дескрипторов для каждой модели. Однако меня смущают структуры, которые определяют необходимое количество наборов дескрипторов. Вот что меня смущает:
указание счетчика дескрипторов в VkDescriptorSetLayoutBinding
VkDescriptorSetLayoutBinding stagingLayoutBinding = {};
...
stagingLayoutBinding.descriptorCount = 1; <- i have one mat4 element for each descriptors
указание счетчика дескрипторов в VkDescriptorPoolSize
VkDescriptorPoolSize stagingPoolSize = {};
...
stagingPoolSize.descriptorCount = static_cast<uint32_t>(model.size()); <- allocate two descriptor sets from one descriptor pool
определение максимальных наборов в VkDescriptorPoolCreateInfo
VkDescriptorPoolCreateInfo poolInfo = {};
...
poolInfo.maxSets = model.size(); <- max descriptor sets = 2
наконец, указав создание набора дескрипторов в 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 !");
}
Я предполагаю, что я где-то кормлю неправильный счетчик набора дескрипторов.
Проблема, вероятно, здесь:
allocInfo.descriptorSetCount = static_cast<uint32_t>(model.size());
Если вы хотите нарисовать 2 объекта, я предполагаю, что model.size()
вернет 2
. Тем не менее, вы предоставляете только один макет набора дескрипторов:
VkDescriptorSetLayout layouts[] = { descriptorSetLayout };
Если вы хотите выделить 2 (или более) набора дескрипторов, вам необходимо предоставить 2 (или более) макета набора дескрипторов. Если вы хотите, чтобы наборы дескрипторов совместно использовали макет, вам просто нужно предоставить один и тот же макет несколько раз.
Что касается непонятных полей:
descriptorCount
структуры VkDescriptorSetLayoutBinding
- это количество дескрипторов, содержащихся в привязке, к которым осуществляется доступ в шейдере в виде массива. Обычно здесь предоставляется 1
, если только вы не хотите создать массив дескрипторов заданного типа (например, массив выборочных изображений), тогда вам нужно указать большее значение.descriptorCount
в VkDescriptorPoolSize
указывает, сколько дескрипторов данного типа может быть выделено из данного пула. Это значение не зависит от общего количества наборов дескрипторов, например, вы можете создать пул дескрипторов, из которого вы можете выделить всего 3 набора дескрипторов, но всего 2 образа хранилища.maxSets
структуры VkDescriptorPoolCreateInfo
определяет, сколько наборов дескрипторов может быть выделено из данного пула (общее количество наборов, которые могут быть выделены из пула). Опять же, это значение определяет «целые» наборы, в то время как предыдущее значение (из маркера 2) определяет конкретные дескрипторы.descriptorSetCount
структуры VkDescriptorSetAllocateInfo
указывает, сколько наборов дескрипторов вы хотите выделить в данный момент (во время вызова функции vkAllocateDescriptorSets()
). Например, вы можете создать пул, из которого вы можете выделить 10 наборов дескрипторов, но вы хотите выделить только один набор дескрипторов за раз, вызывая функцию vkAllocateDescriptorSets()
10 раз.@BulBul &descriptorSetLayout
указывает на один макет набора дескрипторов. У вас должно получиться что-то вроде: VkDescriptorSetLayout layouts[] = { descriptorSetLayout, descriptorSetLayout };
и allocInfo.pSetLayouts = layouts;
.
это сработало для меня, теперь я лучше понимаю наборы дескрипторов, спасибо за вашу помощь.
Я хочу выделить два набора дескрипторов, используя один макет набора дескрипторов, поэтому мне нужно установить
allocInfo.descriptorSetCount = 2
(по которому model.size () возвращает 2), я также изменилallocInfo.pSetLayouts = &descriptorSetLayout;
, но все равно получаю ту же ошибку, дляvkAllocateDescriptorSets()
я должен создать цикл for для распределения? или мой текущий код в порядке?