81 std::vector<vk::DescriptorSetLayout>& outLayouts,
82 std::vector<vk::DescriptorSet>& outDescriptorSets)
84 vk::Device device =
m_ctx->getDevice();
88 for (
auto& layout : outLayouts) {
90 device.destroyDescriptorSetLayout(layout);
95 if (!outDescriptorSets.empty()) {
97 device.freeDescriptorSets(descriptorPool->getPool(), outDescriptorSets);
98 outDescriptorSets.clear();
99 }
catch (
const vk::SystemError& e) {
103 std::map<uint32_t, std::vector<vk::DescriptorSetLayoutBinding>> setBindings;
107 auto uniformLayout = vkConstBuffer->
layout();
108 auto [setIndex, binding] =
m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
110 vk::DescriptorSetLayoutBinding layoutBinding;
111 layoutBinding.setBinding(binding);
112 layoutBinding.setDescriptorType(vk::DescriptorType::eUniformBuffer);
113 layoutBinding.setDescriptorCount(1);
116 setBindings[setIndex].push_back(layoutBinding);
120 auto [setIndex, binding] =
m_ctx->getGenerator()->getTextureBinding(element);
122 vk::DescriptorSetLayoutBinding layoutBinding;
123 layoutBinding.setBinding(binding);
124 layoutBinding.setDescriptorType(vk::DescriptorType::eSampledImage);
125 layoutBinding.setDescriptorCount(1);
128 setBindings[setIndex].push_back(layoutBinding);
132 auto [setIndex, binding] =
m_ctx->getGenerator()->getSamplerBinding(element);
134 vk::DescriptorSetLayoutBinding layoutBinding;
135 layoutBinding.setBinding(binding);
136 layoutBinding.setDescriptorType(vk::DescriptorType::eSampler);
137 layoutBinding.setDescriptorCount(1);
140 setBindings[setIndex].push_back(layoutBinding);
143 if (setBindings.empty()) {
145 outDescriptorSets.clear();
149 uint32_t maxSetIndex = setBindings.rbegin()->first;
151 vk::DescriptorSetLayoutCreateInfo emptyLayoutInfo(
152 vk::DescriptorSetLayoutCreateFlags(),
156 vk::DescriptorSetLayout emptyLayout;
158 emptyLayout = device.createDescriptorSetLayout(emptyLayoutInfo);
159 }
catch (
const vk::SystemError& e) {
160 throw std::runtime_error(
"Failed to create empty descriptor set layout: " + std::string(e.what()));
163 outLayouts.resize(maxSetIndex + 1, emptyLayout);
165 for (
const auto& [setIndex, bindings] : setBindings) {
166 vk::DescriptorSetLayoutCreateInfo layoutInfo;
167 layoutInfo.setBindingCount(
static_cast<uint32_t
>(bindings.size()));
168 layoutInfo.setPBindings(bindings.data());
171 if (outLayouts[setIndex] != emptyLayout) {
172 device.destroyDescriptorSetLayout(outLayouts[setIndex]);
174 outLayouts[setIndex] = device.createDescriptorSetLayout(layoutInfo);
175 }
catch (
const vk::SystemError& e) {
176 for (
auto& layout : outLayouts) {
178 device.destroyDescriptorSetLayout(layout);
182 throw std::runtime_error(
"Failed to create descriptor set layout: " + std::string(e.what()));
186 vk::DescriptorSetAllocateInfo allocInfo;
187 allocInfo.setDescriptorPool(descriptorPool->getPool());
188 allocInfo.setDescriptorSetCount(
static_cast<uint32_t
>(outLayouts.size()));
189 allocInfo.setPSetLayouts(outLayouts.data());
191 outDescriptorSets = device.allocateDescriptorSets(allocInfo);
192 }
catch (
const vk::SystemError& e) {
193 for (
auto& layout : outLayouts) {
195 device.destroyDescriptorSetLayout(layout);
199 throw std::runtime_error(
"Failed to allocate descriptor sets for frame " +
200 std::to_string(frameIdx) +
": " + std::string(e.what()));
233 vk::Device device =
m_ctx->getDevice();
235 std::vector<vk::WriteDescriptorSet> descriptorWrites;
238 std::vector<vk::DescriptorBufferInfo> bufferInfos;
241 std::vector<vk::DescriptorImageInfo> textureInfos;
244 std::vector<vk::DescriptorImageInfo> samplerInfos;
250 auto uniformLayout = constBuffer->
layout();
251 auto [setIndex, binding] =
m_ctx->getGenerator()->getLayoutBinding(uniformLayout);
257 bufferInfos.push_back(constBuffer->currentBufferInfoWithoutUpdata());
259 vk::WriteDescriptorSet descriptorWrite;
261 descriptorWrite.setDstBinding(binding);
262 descriptorWrite.setDstArrayElement(0);
263 descriptorWrite.setDescriptorType(vk::DescriptorType::eUniformBuffer);
264 descriptorWrite.setDescriptorCount(1);
265 descriptorWrite.setPBufferInfo(&bufferInfos[bufferInfos.size() - 1]);
267 descriptorWrites.push_back(descriptorWrite);
270 for (
auto& [element, texture ] :
m_textures) {
272 auto [setIndex, binding] =
m_ctx->getGenerator()->getTextureBinding(element);
278 vk::DescriptorImageInfo imageInfo;
279 imageInfo.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
280 imageInfo.setImageView(vkTexture->view());
281 imageInfo.setSampler(
nullptr);
282 textureInfos.push_back(imageInfo);
284 vk::WriteDescriptorSet descriptorWrite;
286 descriptorWrite.setDstBinding(binding);
287 descriptorWrite.setDstArrayElement(0);
288 descriptorWrite.setDescriptorType(vk::DescriptorType::eSampledImage);
289 descriptorWrite.setDescriptorCount(1);
290 descriptorWrite.setPImageInfo(&textureInfos[textureInfos.size() - 1]);
292 descriptorWrites.push_back(descriptorWrite);
295 for (
size_t i = 0; i <
m_samplers.size(); ++i) {
298 auto [setIndex, binding] =
m_ctx->getGenerator()->getSamplerBinding(element);
304 vk::DescriptorImageInfo samplerInfo;
305 samplerInfo.setSampler(vkSampler->getSampler());
306 samplerInfo.setImageView(
nullptr);
307 samplerInfo.setImageLayout(vk::ImageLayout::eUndefined);
308 samplerInfos.push_back(samplerInfo);
310 vk::WriteDescriptorSet descriptorWrite;
312 descriptorWrite.setDstBinding(binding);
313 descriptorWrite.setDstArrayElement(0);
314 descriptorWrite.setDescriptorType(vk::DescriptorType::eSampler);
315 descriptorWrite.setDescriptorCount(1);
316 descriptorWrite.setPImageInfo(&samplerInfos[samplerInfos.size() - 1]);
318 descriptorWrites.push_back(descriptorWrite);
321 if (!descriptorWrites.empty()) {
322 device.updateDescriptorSets(descriptorWrites,
nullptr);