1 #include <msp/core/algorithm.h>
2 #include "descriptorpool.h"
4 #include "pipelinestate.h"
12 DescriptorPool::DescriptorPool(Device &d):
18 DescriptorPool::~DescriptorPool()
20 const VulkanFunctions &vk = device.get_functions();
22 for(VkDescriptorPool p: pools)
23 vk.DestroyDescriptorPool(p);
26 void DescriptorPool::add_pool(const Counts &counts)
28 const VulkanFunctions &vk = device.get_functions();
30 VkDescriptorPoolSize pool_sizes[2] = { };
31 pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
32 pool_sizes[0].descriptorCount = counts.buffers;
33 pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
34 pool_sizes[1].descriptorCount = counts.images;
36 VkDescriptorPoolCreateInfo pool_info = { };
37 pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
38 pool_info.maxSets = counts.sets;
39 pool_info.poolSizeCount = 2;
40 pool_info.pPoolSizes = pool_sizes;
42 VkDescriptorPool pool;
43 vk.CreateDescriptorPool(pool_info, pool);
44 pools.push_back(pool);
47 void DescriptorPool::begin_frame()
51 DestroyQueue &dq = device.get_destroy_queue();
52 for(VkDescriptorPool p: pools)
56 Counts capacity = used;
57 capacity += increment;
61 fill(s.begin(), s.end(), static_cast<VkDescriptorSet>(0));
67 unsigned DescriptorPool::get_descriptor_set_slot(const PipelineState &ps, unsigned index)
71 uint64_t hash = ps.compute_descriptor_set_hash(index);
72 auto i = lower_bound_member(slots, hash, &HashSlot::hash);
73 if(i!=slots.end() && i->hash==hash)
78 slots.emplace(i, hash, slot);
83 if(ps.is_descriptor_set_dynamic(index))
88 VkDescriptorSet DescriptorPool::get_descriptor_set(unsigned slot, const PipelineState &ps, unsigned index, unsigned frame)
90 if(!(slot&DYNAMIC_SLOT))
92 slot &= ~DYNAMIC_SLOT;
94 while(sets.size()<=frame)
95 sets.emplace_back(slots.size());
97 VkDescriptorSet &desc_set = sets[frame][slot];
101 const VulkanFunctions &vk = device.get_functions();
107 unsigned n_writes = ps.fill_descriptor_writes(index, frame, buffer);
108 VkWriteDescriptorSet *writes = reinterpret_cast<VkWriteDescriptorSet *>(buffer.data());
109 for(unsigned i=0; i<n_writes; ++i)
111 if(writes[i].descriptorType==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
113 if(writes[i].descriptorType==VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
119 VkDescriptorSetLayout layout = ps.get_descriptor_set_layout(index);
121 VkDescriptorSetAllocateInfo alloc_info = { };
122 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
123 alloc_info.descriptorPool = handle_cast<::VkDescriptorPool>(pools.back());
124 alloc_info.descriptorSetCount = 1;
125 alloc_info.pSetLayouts = handle_cast<::VkDescriptorSetLayout *>(&layout);
127 Result result = vk.AllocateDescriptorSets(alloc_info, &desc_set);
128 if(result==VK_ERROR_OUT_OF_POOL_MEMORY)
131 alloc_info.descriptorPool = handle_cast<::VkDescriptorPool>(pools.back());
132 vk.AllocateDescriptorSets(alloc_info, &desc_set);
135 for(unsigned i=0; i<n_writes; ++i)
136 writes[i].dstSet = handle_cast<::VkDescriptorSet>(desc_set);
138 vk.UpdateDescriptorSets(n_writes, writes, 0, 0);
144 DescriptorPool::Counts::Counts(unsigned s, unsigned b, unsigned i):
150 DescriptorPool::Counts &DescriptorPool::Counts::operator+=(const DescriptorPool::Counts &c)
153 buffers += c.buffers;