vengine  0.1.0
3D graphics engine made with Vulkan
Loading...
Searching...
No Matches
descriptors.cpp
Go to the documentation of this file.
1#include <cassert>
2
4
5ven::DescriptorSetLayout::Builder &ven::DescriptorSetLayout::Builder::addBinding(const uint32_t binding, const VkDescriptorType descriptorType, const VkShaderStageFlags stageFlags, const uint32_t count)
6{
7 assert(m_bindings.count(binding) == 0 && "Binding already in use");
8 VkDescriptorSetLayoutBinding layoutBinding{};
9 layoutBinding.binding = binding;
10 layoutBinding.descriptorType = descriptorType;
11 layoutBinding.descriptorCount = count;
12 layoutBinding.stageFlags = stageFlags;
13 m_bindings[binding] = layoutBinding;
14 return *this;
15}
16
17ven::DescriptorSetLayout::DescriptorSetLayout(Device &device, const std::unordered_map<uint32_t, VkDescriptorSetLayoutBinding>& bindings) : m_device{device}, m_bindings{bindings}
18{
19 std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings{};
20 setLayoutBindings.reserve(bindings.size());
21for (auto kv : bindings) {
22 setLayoutBindings.push_back(kv.second);
23 }
24
25 VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo{};
26 descriptorSetLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
27 descriptorSetLayoutInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
28 descriptorSetLayoutInfo.pBindings = setLayoutBindings.data();
29
30 if (vkCreateDescriptorSetLayout(
32 &descriptorSetLayoutInfo,
33 nullptr,
34 &m_descriptorSetLayout) != VK_SUCCESS) {
35 throw std::runtime_error("failed to create descriptor set layout!");
36 }
37}
38
39ven::DescriptorPool::Builder &ven::DescriptorPool::Builder::addPoolSize(const VkDescriptorType descriptorType, const uint32_t count)
40{
41 m_poolSizes.push_back({descriptorType, count});
42 return *this;
43}
44
46{
47 m_poolFlags = flags;
48 return *this;
49}
51{
52 m_maxSets = count;
53 return *this;
54}
55
56ven::DescriptorPool::DescriptorPool(Device &device, const uint32_t maxSets, const VkDescriptorPoolCreateFlags poolFlags, const std::vector<VkDescriptorPoolSize> &poolSizes) : m_device{device}
57{
58 VkDescriptorPoolCreateInfo descriptorPoolInfo{};
59 descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
60 descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
61 descriptorPoolInfo.pPoolSizes = poolSizes.data();
62 descriptorPoolInfo.maxSets = maxSets;
63 descriptorPoolInfo.flags = poolFlags;
64
65 if (vkCreateDescriptorPool(m_device.device(), &descriptorPoolInfo, nullptr, &m_descriptorPool) !=
66 VK_SUCCESS) {
67 throw std::runtime_error("failed to create descriptor pool!");
68 }
69}
70
71bool ven::DescriptorPool::allocateDescriptor(const VkDescriptorSetLayout descriptorSetLayout, VkDescriptorSet &descriptor) const
72{
73 VkDescriptorSetAllocateInfo allocInfo{};
74 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
75 allocInfo.descriptorPool = m_descriptorPool;
76 allocInfo.pSetLayouts = &descriptorSetLayout;
77 allocInfo.descriptorSetCount = 1;
78
79 // Might want to create a "DescriptorPoolManager" class that handles this case, and builds
80 // a new pool whenever an old pool fills up. But this is beyond our current scope
81 return vkAllocateDescriptorSets(m_device.device(), &allocInfo, &descriptor) == VK_SUCCESS;
82}
83
84ven::DescriptorWriter &ven::DescriptorWriter::writeBuffer(const uint32_t binding, const VkDescriptorBufferInfo *bufferInfo)
85{
86 assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding");
87
88 const auto &bindingDescription = m_setLayout.m_bindings[binding];
89
90 assert(bindingDescription.descriptorCount == 1 && "Binding single descriptor info, but binding expects multiple");
91
92 VkWriteDescriptorSet write{};
93 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
94 write.descriptorType = bindingDescription.descriptorType;
95 write.dstBinding = binding;
96 write.pBufferInfo = bufferInfo;
97 write.descriptorCount = 1;
98
99 m_writes.push_back(write);
100 return *this;
101}
102
103ven::DescriptorWriter &ven::DescriptorWriter::writeImage(const uint32_t binding, const VkDescriptorImageInfo *imageInfo)
104{
105 assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding");
106
107 const VkDescriptorSetLayoutBinding &bindingDescription = m_setLayout.m_bindings[binding];
108
109 assert(bindingDescription.descriptorCount == 1 && "Binding single descriptor info, but binding expects multiple");
110
111 VkWriteDescriptorSet write{};
112 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
113 write.descriptorType = bindingDescription.descriptorType;
114 write.dstBinding = binding;
115 write.pImageInfo = imageInfo;
116 write.descriptorCount = 1;
117
118 m_writes.push_back(write);
119 return *this;
120}
121
122bool ven::DescriptorWriter::build(VkDescriptorSet &set)
123{
124 if (!m_pool.allocateDescriptor(m_setLayout.getDescriptorSetLayout(), set)) {
125 return false;
126 }
127 overwrite(set);
128 return true;
129}
130
131void ven::DescriptorWriter::overwrite(const VkDescriptorSet &set)
132{
133 for (auto &write : m_writes) {
134 write.dstSet = set;
135 }
136 vkUpdateDescriptorSets(m_pool.m_device.device(), static_cast<unsigned int>(m_writes.size()), m_writes.data(), 0, nullptr);
137}
This file contains the Descriptors class.
Builder & setPoolFlags(VkDescriptorPoolCreateFlags flags)
Builder & addPoolSize(VkDescriptorType descriptorType, uint32_t count)
Builder & setMaxSets(uint32_t count)
VkDescriptorPool m_descriptorPool
DescriptorPool(Device &device, uint32_t maxSets, VkDescriptorPoolCreateFlags poolFlags, const std::vector< VkDescriptorPoolSize > &poolSizes)
bool allocateDescriptor(VkDescriptorSetLayout descriptorSetLayout, VkDescriptorSet &descriptor) const
std::unordered_map< uint32_t, VkDescriptorSetLayoutBinding > m_bindings
Builder & addBinding(uint32_t binding, VkDescriptorType descriptorType, VkShaderStageFlags stageFlags, uint32_t count=1)
std::unordered_map< uint32_t, VkDescriptorSetLayoutBinding > m_bindings
DescriptorSetLayout(Device &device, const std::unordered_map< uint32_t, VkDescriptorSetLayoutBinding > &bindings)
VkDescriptorSetLayout m_descriptorSetLayout
Class for descriptor writer.
DescriptorWriter & writeImage(uint32_t binding, const VkDescriptorImageInfo *imageInfo)
DescriptorWriter & writeBuffer(uint32_t binding, const VkDescriptorBufferInfo *bufferInfo)
void overwrite(const VkDescriptorSet &set)
bool build(VkDescriptorSet &set)
VkDevice device() const
Definition Device.hpp:48