66 std::vector<vk::DescriptorSetLayout>& outLayouts,
67 std::vector<vk::DescriptorSet>& outDescriptorSets)
69 vk::Device device =
m_ctx->getDevice();
72 for (
auto& layout : outLayouts) {
74 device.destroyDescriptorSetLayout(layout);
79 if (!outDescriptorSets.empty()) {
81 device.freeDescriptorSets(descriptorPool->getPool(), outDescriptorSets);
82 outDescriptorSets.clear();
83 }
catch (
const vk::SystemError& e) {
87 std::map<uint32_t, std::vector<vk::DescriptorSetLayoutBinding>> setBindings;
91 auto uniformLayout = vkConstBuffer->
layout();
92 auto [setIndex, binding] =
m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
94 vk::DescriptorSetLayoutBinding layoutBinding;
95 layoutBinding.setBinding(binding);
96 layoutBinding.setDescriptorType(vk::DescriptorType::eUniformBuffer);
97 layoutBinding.setDescriptorCount(1);
100 setBindings[setIndex].push_back(layoutBinding);
104 auto [setIndex, binding] =
m_ctx->getGenerator()->getTextureBinding(element);
106 vk::DescriptorSetLayoutBinding layoutBinding;
107 layoutBinding.setBinding(binding);
108 layoutBinding.setDescriptorType(vk::DescriptorType::eSampledImage);
109 layoutBinding.setDescriptorCount(1);
112 setBindings[setIndex].push_back(layoutBinding);
116 auto [setIndex, binding] =
m_ctx->getGenerator()->getSamplerBinding(element);
118 vk::DescriptorSetLayoutBinding layoutBinding;
119 layoutBinding.setBinding(binding);
120 layoutBinding.setDescriptorType(vk::DescriptorType::eSampler);
121 layoutBinding.setDescriptorCount(1);
124 setBindings[setIndex].push_back(layoutBinding);
127 if (setBindings.empty()) {
129 outDescriptorSets.clear();
133 uint32_t maxSetIndex = setBindings.rbegin()->first;
135 vk::DescriptorSetLayoutCreateInfo emptyLayoutInfo(
136 vk::DescriptorSetLayoutCreateFlags(),
140 vk::DescriptorSetLayout emptyLayout;
142 emptyLayout = device.createDescriptorSetLayout(emptyLayoutInfo);
143 }
catch (
const vk::SystemError& e) {
144 throw std::runtime_error(
"Failed to create empty descriptor set layout: " + std::string(e.what()));
147 outLayouts.resize(maxSetIndex + 1, emptyLayout);
149 for (
const auto& [setIndex, bindings] : setBindings) {
150 vk::DescriptorSetLayoutCreateInfo layoutInfo;
151 layoutInfo.setBindingCount(
static_cast<uint32_t
>(bindings.size()));
152 layoutInfo.setPBindings(bindings.data());
155 if (outLayouts[setIndex] != emptyLayout) {
156 device.destroyDescriptorSetLayout(outLayouts[setIndex]);
158 outLayouts[setIndex] = device.createDescriptorSetLayout(layoutInfo);
159 }
catch (
const vk::SystemError& e) {
160 for (
auto& layout : outLayouts) {
162 device.destroyDescriptorSetLayout(layout);
166 throw std::runtime_error(
"Failed to create descriptor set layout: " + std::string(e.what()));
170 vk::DescriptorSetAllocateInfo allocInfo;
171 allocInfo.setDescriptorPool(descriptorPool->getPool());
172 allocInfo.setDescriptorSetCount(
static_cast<uint32_t
>(outLayouts.size()));
173 allocInfo.setPSetLayouts(outLayouts.data());
175 outDescriptorSets = device.allocateDescriptorSets(allocInfo);
176 }
catch (
const vk::SystemError& e) {
177 for (
auto& layout : outLayouts) {
179 device.destroyDescriptorSetLayout(layout);
183 throw std::runtime_error(
"Failed to allocate descriptor sets for frame " +
184 std::to_string(frameIdx) +
": " + std::string(e.what()));
217 vk::Device device =
m_ctx->getDevice();
219 std::vector<vk::WriteDescriptorSet> descriptorWrites;
222 std::vector<vk::DescriptorBufferInfo> bufferInfos;
225 std::vector<vk::DescriptorImageInfo> textureInfos;
228 std::vector<vk::DescriptorImageInfo> samplerInfos;
234 auto uniformLayout = constBuffer->
layout();
235 auto [setIndex, binding] =
m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
241 bufferInfos.push_back(constBuffer->currentBufferInfoWithoutUpdata());
243 vk::WriteDescriptorSet descriptorWrite;
245 descriptorWrite.setDstBinding(binding);
246 descriptorWrite.setDstArrayElement(0);
247 descriptorWrite.setDescriptorType(vk::DescriptorType::eUniformBuffer);
248 descriptorWrite.setDescriptorCount(1);
249 descriptorWrite.setPBufferInfo(&bufferInfos[bufferInfos.size() - 1]);
251 descriptorWrites.push_back(descriptorWrite);
254 for (
auto& [element, texture ] :
m_textures) {
256 auto [setIndex, binding] =
m_ctx->getGenerator()->getTextureBinding(element);
262 vk::DescriptorImageInfo imageInfo;
263 imageInfo.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
264 imageInfo.setImageView(vkTexture->view());
265 imageInfo.setSampler(
nullptr);
266 textureInfos.push_back(imageInfo);
268 vk::WriteDescriptorSet descriptorWrite;
270 descriptorWrite.setDstBinding(binding);
271 descriptorWrite.setDstArrayElement(0);
272 descriptorWrite.setDescriptorType(vk::DescriptorType::eSampledImage);
273 descriptorWrite.setDescriptorCount(1);
274 descriptorWrite.setPImageInfo(&textureInfos[textureInfos.size() - 1]);
276 descriptorWrites.push_back(descriptorWrite);
279 for (
size_t i = 0; i <
m_samplers.size(); ++i) {
282 auto [setIndex, binding] =
m_ctx->getGenerator()->getSamplerBinding(element);
288 vk::DescriptorImageInfo samplerInfo;
289 samplerInfo.setSampler(vkSampler->getSampler());
290 samplerInfo.setImageView(
nullptr);
291 samplerInfo.setImageLayout(vk::ImageLayout::eUndefined);
292 samplerInfos.push_back(samplerInfo);
294 vk::WriteDescriptorSet descriptorWrite;
296 descriptorWrite.setDstBinding(binding);
297 descriptorWrite.setDstArrayElement(0);
298 descriptorWrite.setDescriptorType(vk::DescriptorType::eSampler);
299 descriptorWrite.setDescriptorCount(1);
300 descriptorWrite.setPImageInfo(&samplerInfos[samplerInfos.size() - 1]);
302 descriptorWrites.push_back(descriptorWrite);
305 if (!descriptorWrites.empty()) {
306 device.updateDescriptorSets(descriptorWrites,
nullptr);