Итак, я хочу сделать две независимые сетки в Vulkan.Я работаю над текстурами, и первая сетка использует 4 из них, а вторая использует 5. Я делаю индексированные отрисовки.
Каждая сетка имеет свой собственный однородный буфер и массив сэмплеров, упакованные в отдельные наборы дескрипторов для простотыкаждый с привязкой для UBO и другой привязкой для сэмплеров.Следующий код выполняется для каждой сетки, где descriptorSet
- набор дескрипторов, связанных с одной сеткой.filepaths
- это вектор путей к изображениям, которые, в частности, использует сетка.
std::vector<VkWriteDescriptorSet> descriptorWrites;
descriptorWrites.resize(2);
VkDescriptorBufferInfo bufferInfo = {};
bufferInfo.buffer = buffers[i];
bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject);
descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[0].dstSet = descriptorSet;
descriptorWrites[0].dstBinding = 0;
descriptorWrites[0].dstArrayElement = 0;
descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
descriptorWrites[0].descriptorCount = 1;
descriptorWrites[0].pBufferInfo = &bufferInfo;
std::vector<VkDescriptorImageInfo> imageInfos;
imageInfos.resize(filepaths.size());
for (size_t j = 0; j < filepaths.size(); j++) {
imageInfos[j].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
imageInfos[j].imageView = imageViews[j];
imageInfos[j].sampler = samplers[j];
}
descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrites[1].dstSet = descriptorSet;
descriptorWrites[1].dstBinding = 1;
descriptorWrites[1].dstArrayElement = 0;
descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorWrites[1].descriptorCount = imageInfos.size();
descriptorWrites[1].pImageInfo = imageInfos.data();
vkUpdateDescriptorSets(devicesHandler->device, descriptorWrites.size(), descriptorWrites.data(), 0, nullptr);
Итак, чтобы рассказать Vulkan, как эти наборы дескрипторов расположены, мне, конечно, нужно два макета наборов дескрипторов, то есть по одному на сетку,которые отличаются привязкой для сэмплеров из-за разного размера filepaths
:
// <Stuff for binding 0 for UBO here>
// ...
VkDescriptorSetLayoutBinding layoutBinding = {};
layoutBinding.binding = 1;
layoutBinding.descriptorCount = filepaths.size();
layoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
layoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
Теперь, когда я создаю конвейер, мне нужно предоставить компоновку конвейера.Я делаю это следующим образом, где layouts
- это схемы набора дескрипторов мешей, вставленных в вектор .:
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = layouts.size();
pipelineLayoutInfo.pSetLayouts = layouts.data();
Наконец, перед рендерингом я связываю набор подходящих дескрипторов.* Наивно, я думаю, что способ определения макета конвейера - это путь (просто взятие всех задействованных макетов и передача их на pSetLayouts
), но это не работает.Я получаю ошибку:
descriptorSet #0 being bound is not compatible with overlapping descriptorSetLayout at index 0 of pipelineLayout 0x6e due to: DescriptorSetLayout 87 has 5 descriptors, but DescriptorSetLayout 88, which comes from pipelineLayout, has 6 descriptors.. The Vulkan spec states: Each element of pDescriptorSets must have been allocated with a VKDescriptorSetLayout that matches (is the same as, or identically defined as) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets.
Я также заметил, что если я уменьшу количество текстур, используемых с 5 до 4 во второй сетке, чтобы они соответствовали 4 из первой сеткитогда это работает.Так что мне интересно, нужно ли мне создавать конвейер для каждой возможной конфигурации макетов?То есть один конвейер с setLayoutCount
установленным на 4, а другой установленным на 5, и связать соответствующий, когда я собираюсь нарисовать одну сетку или другую?Это глупо?Я что-то упустил?
Стоит отметить, что если я рендерил каждую сетку в одиночку, все работает гладко.Проблема возникает, когда я помещаю их обоих в сцену.
Кроме того, я знаю, что буферы должны распределяться последовательно и с учетом выравнивания, и что то, что я делаю, это плохая практика - но я простопока не имею дело с этим.