Я пытаюсь создать один конвейер с макетом, в котором требуется две привязки, динамическая UBO и привязка изображения / сэмплера. Я хочу, чтобы каждое связывание происходило из отдельного набора дескрипторов, поэтому я бы связывал два набора дескрипторов на вызов вызова. Один набор дескрипторов предназначен для текстуры каждого объекта, другой - для динамического UBO (общего для объектов). Я хочу иметь возможность сделать что-то вроде этого в части рендеринга:
commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
for (int ii = 0; ii < mActiveQuads; ii++)
{
uint32_t dynamicOffset = ii * static_cast<uint32_t>(dynamicAlignment);
// bind texture for this quad
commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, sharedPipelineLayout, 0, 1,
&swapResources[current_buffer].textureDescriptors[ii], 1, &dynamicOffset);
// draw the dynamic UBO with offset for this quad
commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, sharedPipelineLayout, 0, 1,
&swapResources[current_buffer].quadDescriptor, 1, &dynamicOffset);
commandBuffer.draw(2 * 3, 1, 0, 0);
}
Но, похоже, это не работает. Прежде всего, я не уверен, что понял все о наборах дескрипторов и схемах конвейера, чтобы знать, разрешено ли то, что я делаю. Имеет ли это смысл? Что я могу создать конвейер с макетом привязки 2, но создать каждый дескриптор, чтобы заполнить только одну из этих привязок каждый, а затем связать два дескриптора для каждого вызова отрисовки для этого конвейера?
Если это разрешено. Вот как я создаю конвейер и дескрипторы:
vk::DescriptorSetLayoutBinding const layout_bindings[2] = { vk::DescriptorSetLayoutBinding()
.setBinding(0)
.setDescriptorType(vk::DescriptorType::eUniformBufferDynamic)
.setDescriptorCount(1)
.setStageFlags(vk::ShaderStageFlagBits::eVertex)
.setPImmutableSamplers(nullptr),
vk::DescriptorSetLayoutBinding()
.setBinding(1)
.setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
.setDescriptorCount(1)//texture_count)
.setStageFlags(vk::ShaderStageFlagBits::eFragment)
.setPImmutableSamplers(nullptr) };
// note binding count is 1 here
auto const descriptor_layout = vk::DescriptorSetLayoutCreateInfo().setBindingCount(1).setPBindings(&layout_bindings[0]); // using the first part of the above layout
device.createDescriptorSetLayout(&descriptor_layout, nullptr, &quadDescriptorLayout);
// note binding count is 1 here
auto const descriptor_layout2 = vk::DescriptorSetLayoutCreateInfo().setBindingCount(1).setPBindings(&layout_bindings[1]); // using the second part of the above layout
device.createDescriptorSetLayout(&descriptor_layout2, nullptr, &textureDescriptorLayout);
// Now create the pipeline, note we use both the bindings above with
// layout count = 2
auto const pPipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo().setSetLayoutCount(2).setPSetLayouts(desc_layout);
device.createPipelineLayout(&pPipelineLayoutCreateInfo, nullptr, &sharedPipelineLayout);
и сами дескрипторы:
// alloc quad descriptor
alloc_info =
vk::DescriptorSetAllocateInfo()
.setDescriptorPool(desc_pool)
.setDescriptorSetCount(1)
.setPSetLayouts(&quadDescriptorLayout);
// texture descriptors(multiple descriptors, one per quad object)
alloc_info =
vk::DescriptorSetAllocateInfo()
.setDescriptorPool(desc_pool)
.setDescriptorSetCount(1)
.setPSetLayouts(&textureDescriptorLayout);
Раньше, когда текстура и UBO в одном наборе дескрипторов работали нормально, я мог видеть несколько четырехугольников, но все они использовали одну текстуру. Когда я разделяю текстуры на другой набор дескрипторов, тогда я получаю зависшее приложение. При попытке отправить графическую очередь я получаю сообщение об ошибке «устройство потеряно».
Любое понимание того, возможно ли это сделать или что я делаю что-то не так в моей настройке, будет очень признательно. Большое спасибо!
Ниже добавлен код шейдера:
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(binding = 0) uniform UniformBufferObject {
mat4 mvp;
vec4 position[6];
vec4 attr[6];
} ubo;
layout(location = 0) out vec2 fragTexCoord;
void main() {
gl_Position = ubo.mvp *ubo.position[gl_VertexIndex];
fragTexCoord = vec2(ubo.attr[gl_VertexIndex].x, ubo.attr[gl_VertexIndex].y);
}
Пиксельный шейдер:
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(set=0, binding = 1) uniform sampler2D texSampler;
layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
void main() {
outColor = texture(texSampler, fragTexCoord);
}