Vulkan - Descriptor Set на каждый объект (или нет?)
Решил разобраться с Vulkan, и столкнулся с одним недопониманием. В Vulkan есть такое понятие как дескрипторы (точнее наборы дескрипторов - DescriptorSet). Они описывают доступ к каким-либо ресурсам (буферам, изображениям) из шейдеров. При этом, наборы дескрипторов выделяются из дескрипторного пула (DescriptorPool), и при создании дескрипторного пула нужно указывать какое конкретно кол-во дескрипторных наборов можно выделить из этого пула (maxSets).
Затем, когда мы уже записываем команды в командный буфер, мы привязываем дескрипторный набор (который связан с конкретным ресурсами), привязываем буферы вершин и индексов, а затем вызываем команду рисования.
И вот тут возникает вопрос
Если рассуждать таким образом, что на каждый объект (меш) есть свой дескрипторный набор, который привязываем перед отрисовкой этого объекта, получается, чтобы каждый объект мог обладать, например, своим собственным материалом (текстурами и прочими значениями), нужно для каждого объекта аллоцировать свой Descriptor Set? Если это так - то откуда можно знать максимальное количество этих самых дескрипторных наборов, при создании пула, если не известно сколько мне потребуется объектов на сцене? Может быть я не правильно рассуждаю, и дескрипторный набор может быть один для всех этих объектов, просто перед отрисовкой каждого объекта нужно делать обновление набора vkUpdateDescriptorSets? Или свой набор на каждый объект - это вполне нормально, и можно просто с запасом задать maxSets при создании пула?
И второй момент
Есть еще такой тип дескриптора, как "динамический UBO буфер", и когда мы привязываем дескрипторный набор с таким буфером, то мы указываем динамическое смещение:
// Набор динамических смещений для набора с динамическим дескриптором
std::vector<uint32_t> dynamicOffsets = {
primitiveIndex * static_cast<uint32_t>(this->device_.GetDynamicAlignment<glm::mat4>())
};
// Набор дескрипторов, которые привязываем
std::vector<VkDescriptorSet> descriptorSets = {
descriptorSetMain
};
// Привязать наборы дескрипторов
vkCmdBindDescriptorSets(
commandBuffers[i],
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout,
0,
(uint32_t)descriptorSets.size(),
descriptorSets.data(),
(uint32_t)dynamicOffsets.size(),
dynamicOffsets.data());
// Привязать буфер вершин
VkDeviceSize offsets[1] = { 0 };
vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, &(primitives[primitiveIndex].vertexBuffer.vkBuffer), offsets);
// Привязать буфер индексов
vkCmdBindIndexBuffer(commandBuffers[i], primitives[primitiveIndex].indexBuffer.vkBuffer, 0, VK_INDEX_TYPE_UINT32);
// Отрисовка геометрии
vkCmdDrawIndexed(commandBuffers[i], primitives[primitiveIndex].indexBuffer.count, 1, 0, 0, 0);
Здесь получается, что перед каждым рисованием объекта, я привязываю как бы один и тот же дескрипторный набор, но благодаря смещению, в шейдере во время рисования очередного меша, привязке соответствует своя часть буфера, связанного с дескриптором. Но возникает вопрос - если можно (если это допустимо и правильно) аллоцировать на каждый объект свой дескрипторный набор, в чем смысл подхода с динамическим смещением? А если это все таки НЕ допустимо или не правильно, и нельзя выделять особо много наборов, то почему аналогичную штуку нельзя проворачивать с текстурными дескрипторами? Хотелось бы просто понять как это всё делать правильно.
Заранее спасибо.