SpiecsEngine
 
Loading...
Searching...
No Matches
VulkanDescriptor.cpp
Go to the documentation of this file.
1/**
2* @file VulkanDescriptor.cpp.
3* @brief The VulkanDescriptorPool and VulkanDescriptorSet Class Implementation.
4* @author Spices.
5*/
6
7#include "Pchheader.h"
9#include "..\..\..\assets\Shaders\src\Header\ShaderCommon.h"
10
11namespace Spices {
12
16 VkDescriptorType descriptorType ,
17 uint32_t count
18 )
19 {
21
22 m_PoolSizes.push_back({ descriptorType, count });
23 m_MaxSets += count;
24 return *this;
25 }
26
30 VkDescriptorPoolCreateFlags flags
31 )
32 {
34
35 m_PoolFlags = flags;
36 return *this;
37 }
38
39 std::shared_ptr<VulkanDescriptorPool>
41 Build(VulkanState& vulkanState) const
42 {
44
45 /**
46 * @brief Instance a VulkanDescriptorPool.
47 */
48 return std::make_shared<VulkanDescriptorPool>(vulkanState, m_MaxSets, m_PoolFlags, m_PoolSizes);
49 }
50
52 VulkanState& vulkanState ,
53 uint32_t maxSets ,
54 VkDescriptorPoolCreateFlags poolFlags ,
55 const std::vector<VkDescriptorPoolSize>& poolSizes
56 )
57 : VulkanObject(vulkanState)
58 {
60
61 /**
62 * @brief Instance a VkDescriptorPoolCreateInfo.
63 */
64 VkDescriptorPoolCreateInfo descriptorPoolInfo{};
65 descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
66 descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
67 descriptorPoolInfo.pPoolSizes = poolSizes.data();
68 descriptorPoolInfo.maxSets = maxSets;
69 descriptorPoolInfo.flags = poolFlags;
70
71 /**
72 * @brief Create a VkDescriptorPool.
73 */
74 VK_CHECK(vkCreateDescriptorPool(vulkanState.m_Device, &descriptorPoolInfo, nullptr, &m_DescriptorPool));
75 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_POOL, reinterpret_cast<uint64_t>(m_DescriptorPool), vulkanState.m_Device, "SpicesEngineDescriptorPool")
76 }
77
79 {
81
82 /**
83 * @brief Destroy DescriptorPool.
84 */
85 vkDestroyDescriptorPool(m_VulkanState.m_Device, m_DescriptorPool, nullptr);
86 }
87
89 {
91
92 /**
93 * @brief Reset DescriptorPool.
94 */
95 vkResetDescriptorPool(m_VulkanState.m_Device, m_DescriptorPool, 0);
96 }
97
99 {
101
102 /**
103 * @brief Destroy DescriptorSetLayout.
104 */
105 vkDestroyDescriptorSetLayout(m_VulkanState.m_Device, m_Layout, nullptr);
106 }
107
109 const std::unordered_map<uint32_t, VkDescriptorSetLayoutBinding>& bindings,
110 const std::string& caption
111 )
112 {
114
115 /**
116 * @brief Get linear binding data and flags.
117 */
118 std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings{};
119 std::vector<VkDescriptorBindingFlags> setBindingFlags{};
120
121 for (auto& kv : bindings)
122 {
123 setLayoutBindings.push_back(kv.second);
124
125 switch (kv.second.descriptorType)
126 {
127 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
128 setBindingFlags.push_back(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT); /* @brief VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT not support VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT. */
129 break;
130 default:
131 setBindingFlags.push_back(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT);
132 break;
133 }
134 }
135
136 /**
137 * @breif Instance a VkDescriptorSetLayoutBindingFlagsCreateInfo.
138 */
139 VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlags{};
140 bindingFlags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
141 bindingFlags.pNext = nullptr;
142 bindingFlags.pBindingFlags = setBindingFlags.data();
143 bindingFlags.bindingCount = static_cast<uint32_t>(setBindingFlags.size());
144
145 /**
146 * @breif Instance a VkDescriptorSetLayoutCreateInfo.
147 */
148 VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{};
149 descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
150 descriptorSetLayoutCreateInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
151 descriptorSetLayoutCreateInfo.pBindings = setLayoutBindings.data();
152 descriptorSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; /* @brief Create if from a descriptor pool that has update after bind. */
153 descriptorSetLayoutCreateInfo.pNext = &bindingFlags;
154
155 /**
156 * @brief Create DescriptorSetLayout.
157 */
158 VK_CHECK(vkCreateDescriptorSetLayout(m_VulkanState.m_Device, &descriptorSetLayoutCreateInfo, nullptr, &m_Layout))
159 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, reinterpret_cast<uint64_t>(m_Layout), m_VulkanState.m_Device, "DescriptorSetLayout" + caption)
160 }
161
163 const std::unordered_map<uint32_t, VkDescriptorSetLayoutBinding>& bindings ,
164 const std::string& caption
165 )
166 {
168
169 /**
170 * @brief Get linear binding data and flags.
171 */
172 std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings{};
173 std::vector<VkDescriptorBindingFlags> setBindingFlags{};
174
175 for (auto& kv : bindings)
176 {
177 setLayoutBindings.push_back(kv.second);
178
179 switch (kv.second.descriptorType)
180 {
181 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
182 setBindingFlags.push_back(VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT);
183 break;
184 default:
185 SPICES_CORE_ERROR("BindLess only support COMBINED_IMAGE_SAMPLER type binding")
186 break;
187 }
188 }
189
190 /**
191 * @breif Instance a VkDescriptorSetLayoutBindingFlagsCreateInfo.
192 */
193 VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlags{};
194 bindingFlags.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
195 bindingFlags.pNext = nullptr;
196 bindingFlags.pBindingFlags = setBindingFlags.data();
197 bindingFlags.bindingCount = static_cast<uint32_t>(setBindingFlags.size());
198
199 /**
200 * @breif Instance a VkDescriptorSetLayoutCreateInfo.
201 */
202 VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{};
203 descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
204 descriptorSetLayoutCreateInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
205 descriptorSetLayoutCreateInfo.pBindings = setLayoutBindings.data();
206 descriptorSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; /* @brief Create if from a descriptor pool that has update after bind. */
207 descriptorSetLayoutCreateInfo.pNext = &bindingFlags;
208
209 /**
210 * @brief Create DescriptorSetLayout.
211 */
212 VK_CHECK(vkCreateDescriptorSetLayout(m_VulkanState.m_Device, &descriptorSetLayoutCreateInfo, nullptr, &m_Layout))
213 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, reinterpret_cast<uint64_t>(m_Layout), m_VulkanState.m_Device, "DescriptorSetLayout" + caption)
214 }
215
217 {
219
220 /**
221 * @brief Free DescriptorSet.
222 */
223 vkFreeDescriptorSets(m_VulkanState.m_Device, m_Pool->GetPool(), 1, &m_DescriptorSet);
224 }
225
227 uint32_t binding ,
228 VkDescriptorType descriptorType ,
229 VkShaderStageFlags stageFlags ,
230 uint32_t count
231 )
232 {
234
235 /**
236 * @brief Instance a VkDescriptorSetLayoutBinding.
237 */
238 VkDescriptorSetLayoutBinding layoutBinding{};
239 layoutBinding.binding = binding;
240 layoutBinding.descriptorType = descriptorType;
241 layoutBinding.descriptorCount = count;
242 layoutBinding.stageFlags = stageFlags;
243
244 m_Bindings[binding] = layoutBinding;
245 }
246
247 void VulkanDescriptorSet::BuildDescriptorSet(const std::string& creatorName)
248 {
250
251 /**
252 * @brief Build DescriptorSetLayout.
253 */
254 m_Layout.BuildDescriptorSetLayout(m_Bindings, creatorName);
255
256 /**
257 * @brief Instance a VkDescriptorSetAllocateInfo.
258 */
259 VkDescriptorSetAllocateInfo allocInfo{};
260 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
261 allocInfo.descriptorPool = m_Pool->GetPool();
262 allocInfo.pSetLayouts = &m_Layout.Get();
263 allocInfo.descriptorSetCount = 1;
264
265 /**
266 * @brief Allocate DescriptorSet.
267 */
268 VK_CHECK(vkAllocateDescriptorSets(m_VulkanState.m_Device, &allocInfo, &m_DescriptorSet))
269 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET, reinterpret_cast<uint64_t>(m_DescriptorSet), m_VulkanState.m_Device, "DescriptorSet" + creatorName)
270 }
271
272 void VulkanDescriptorSet::BuildBindLessTextureDescriptorSet(const std::string& creatorName)
273 {
275
276 /**
277 * @brief Build DescriptorSetLayout.
278 */
279 m_Layout.BuildBindLessTextureDescriptorSetLayout(m_Bindings, creatorName);
280
281 /**
282 * @brief Instance a VkDescriptorSetVariableDescriptorCountAllocateInfo.
283 */
284 constexpr uint32_t maxBinding = SpicesShader::BINDLESS_TEXTURE_MAXNUM;
285 VkDescriptorSetVariableDescriptorCountAllocateInfo countInfo{};
286 countInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
287 countInfo.descriptorSetCount = 1;
288 countInfo.pDescriptorCounts = &maxBinding;
289
290 /**
291 * @brief Instance a VkDescriptorSetAllocateInfo.
292 */
293 VkDescriptorSetAllocateInfo allocInfo{};
294 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
295 allocInfo.descriptorPool = m_Pool->GetPool();
296 allocInfo.pSetLayouts = &m_Layout.Get();
297 allocInfo.descriptorSetCount = 1;
298 allocInfo.pNext = &countInfo;
299
300 /**
301 * @brief Allocate DescriptorSet.
302 */
303 VK_CHECK(vkAllocateDescriptorSets(m_VulkanState.m_Device, &allocInfo, &m_DescriptorSet))
304 DEBUGUTILS_SETOBJECTNAME(VK_OBJECT_TYPE_DESCRIPTOR_SET, reinterpret_cast<uint64_t>(m_DescriptorSet), m_VulkanState.m_Device, "DescriptorSet" + creatorName)
305 }
306
308 ImageInfo& imageInfo ,
309 BufferInfo& bufferInfo ,
310 const VkAccelerationStructureKHR& accel
311 ) const
312 {
314
315 for(auto& pair : m_Bindings)
316 {
317 /**
318 * @brief Instance a VkWriteDescriptorSet.
319 */
320 VkWriteDescriptorSet write{};
321 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
322 write.dstBinding = pair.first;
323 write.dstSet = m_DescriptorSet;
324 write.descriptorType = pair.second.descriptorType;
325
326 switch(write.descriptorType)
327 {
328 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
329 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
330 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
331 write.pImageInfo = imageInfo[pair.first].data();
332 write.descriptorCount = static_cast<uint32_t>(imageInfo[pair.first].size());
333 break;
334 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
335 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
336 write.pBufferInfo = &bufferInfo[pair.first];
337 write.descriptorCount = 1;
338 break;
339 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
340 VkWriteDescriptorSetAccelerationStructureKHR descASInfo {};
341 descASInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
342 descASInfo.accelerationStructureCount = 1;
343 descASInfo.pAccelerationStructures = &accel;
344
345 write.pNext = &descASInfo;
346 write.descriptorCount = 1;
347 break;
348 }
349
350 /**
351 * @brief Update DescriptorSet.
352 */
353 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
354 }
355 }
356
357 void VulkanDescriptorSet::UpdateDescriptorSet(BufferInfo& bufferInfo) const
358 {
360
361 for (auto& pair : m_Bindings)
362 {
363 /**
364 * @brief Instance a VkWriteDescriptorSet.
365 */
366 VkWriteDescriptorSet write {};
367 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
368 write.dstBinding = pair.first;
369 write.dstSet = m_DescriptorSet;
370 write.descriptorType = pair.second.descriptorType;
371 write.pBufferInfo = &bufferInfo[pair.first];
372 write.descriptorCount = 1;
373
374 /**
375 * @brief Update DescriptorSet.
376 */
377 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
378 }
379 }
380
381 void VulkanDescriptorSet::UpdateDescriptorSet(ImageInfo& imageInfo) const
382 {
384
385 for (auto& pair : m_Bindings)
386 {
387 /**
388 * @brief Instance a VkWriteDescriptorSet.
389 */
390 VkWriteDescriptorSet write {};
391 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
392 write.dstBinding = pair.first;
393 write.dstSet = m_DescriptorSet;
394 write.descriptorType = pair.second.descriptorType;
395 write.pImageInfo = imageInfo[pair.first].data();
396 write.descriptorCount = static_cast<uint32_t>(imageInfo[pair.first].size());
397
398 /**
399 * @brief Update DescriptorSet.
400 */
401 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
402 }
403 }
404
405 void VulkanDescriptorSet::UpdateDescriptorSet(uint32_t binding, std::shared_ptr<VulkanBuffer> buffer) const
406 {
408
409 VkDescriptorType type = m_Bindings.find(binding)->second.descriptorType;
410
411 assert(type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
412
413 /**
414 * @brief Instance a VkWriteDescriptorSet.
415 */
416 VkWriteDescriptorSet write{};
417 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
418 write.dstBinding = binding;
419 write.dstSet = m_DescriptorSet;
420 write.descriptorType = type;
421 write.pBufferInfo = buffer->GetBufferInfo();
422 write.descriptorCount = 1;
423
424 /**
425 * @brief Update DescriptorSet.
426 */
427 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
428 }
429
430 void VulkanDescriptorSet::UpdateDescriptorSet(uint32_t binding, const VkAccelerationStructureKHR& accel) const
431 {
433
434 VkDescriptorType type = m_Bindings.find(binding)->second.descriptorType;
435
436 assert(type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
437
438 /**
439 * @brief Instance a VkWriteDescriptorSetAccelerationStructureKHR.
440 */
441 VkWriteDescriptorSetAccelerationStructureKHR descASInfo {};
442 descASInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
443 descASInfo.accelerationStructureCount = 1;
444 descASInfo.pAccelerationStructures = &accel;
445
446 /**
447 * @brief Instance a VkWriteDescriptorSet.
448 */
449 VkWriteDescriptorSet write{};
450 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
451 write.dstBinding = binding;
452 write.dstSet = m_DescriptorSet;
453 write.descriptorType = type;
454 write.pNext = &descASInfo;
455 write.descriptorCount = 1;
456
457 /**
458 * @brief Update DescriptorSet.
459 */
460 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
461 }
462
464 {
466
467 for (auto& pair : m_Bindings)
468 {
469 /**
470 * @brief Instance a VkWriteDescriptorSet.
471 */
472 VkWriteDescriptorSet write {};
473 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
474 write.dstBinding = pair.first;
475 write.dstSet = m_DescriptorSet;
476 write.descriptorType = pair.second.descriptorType;
477 write.pImageInfo = imageInfo[pair.first].data();
478 write.descriptorCount = static_cast<uint32_t>(imageInfo[pair.first].size());
479 write.dstArrayElement = 10;
480
481 /**
482 * @brief Update DescriptorSet.
483 */
484 vkUpdateDescriptorSets(m_VulkanState.m_Device, 1, &write, 0, nullptr);
485 }
486 }
487}
#define SPICES_PROFILE_ZONE
#define VK_CHECK(expr)
Vulkan Check macro. Verify Vulkan API Effectiveness.
Definition VulkanUtils.h:68
This Class is a Wrapper of VulkanBuffer.
Builder & SetPoolFlags(VkDescriptorPoolCreateFlags flags)
Add a type identify to VkDescriptorPool.
Builder & AddPoolSize(VkDescriptorType descriptorType, uint32_t count)
Add a size of specific descriptor type.
std::shared_ptr< VulkanDescriptorPool > Build(VulkanState &vulkanState) const
Build a shared pointer of VulkanDescriptorPool.
uint32_t m_MaxSets
The max descriptor set nums that this pool can assign.
VulkanDescriptorPool::Builder Class. This class is defines how to build a VulkanDescriptorPool.
VulkanDescriptorPool(VulkanState &vulkanState, uint32_t maxSets, VkDescriptorPoolCreateFlags poolFlags, const std::vector< VkDescriptorPoolSize > &poolSizes)
Constructor Function.
virtual ~VulkanDescriptorPool() override
Destructor Function.
void ResetPool() const
Reset this pool.
VulkanDescriptorPool Class. This class is the wrapper of VkDescriptorPool.
void BuildDescriptorSetLayout(const std::unordered_map< uint32_t, VkDescriptorSetLayoutBinding > &bindings, const std::string &caption="")
Build a VkDescriptorSetLayout with bindings.
virtual ~VulkanDescriptorSetLayout() override
Destructor Function.
void BuildBindLessTextureDescriptorSetLayout(const std::unordered_map< uint32_t, VkDescriptorSetLayoutBinding > &bindings, const std::string &caption="")
Build a bindLess texture VkDescriptorSetLayout with bindings.
This Class is a Wrapper of VkDescriptorSetLayout. Usually used as a member variable in VulkanDescript...
void BuildBindLessTextureDescriptorSet(const std::string &creatorName)
Build this bind less.
void UpdateBindLessTextureDescriptorSet(ImageInfo &imageInfo) const
Update this bind less descriptor set.
virtual ~VulkanDescriptorSet() override
Destructor Function.
void UpdateDescriptorSet(ImageInfo &imageInfo, BufferInfo &bufferInfo, const VkAccelerationStructureKHR &accel=VK_NULL_HANDLE) const
Update this descriptor set.
void AddBinding(uint32_t binding, VkDescriptorType descriptorType, VkShaderStageFlags stageFlags, uint32_t count=1)
Add a binding to this descriptor set.
void UpdateDescriptorSet(uint32_t binding, const VkAccelerationStructureKHR &accel) const
Update this descriptor set.
void UpdateDescriptorSet(BufferInfo &bufferInfo) const
Update this descriptor set.
void UpdateDescriptorSet(uint32_t binding, std::shared_ptr< VulkanBuffer > buffer) const
Update this descriptor set.
void BuildDescriptorSet(const std::string &creatorName)
Build this.
This Class is a wrapper of VkDescriptorSet.
VulkanObject(VulkanState &vulkanState)
Constructor Function. Init member variables.
VulkanObject Class. This class defines the basic behaves of VulkanObject. When we create an new Vulka...
This struct contains all Vulkan object in used global.
Definition VulkanUtils.h:74