]> git.tdb.fi Git - libs/gl.git/commitdiff
Add files which were forgotten earlier
authorMikko Rasa <tdb@tdb.fi>
Fri, 18 Mar 2022 22:57:03 +0000 (00:57 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 18 Mar 2022 22:57:57 +0000 (00:57 +0200)
These should have been in 370eb9e.

source/backends/vulkan/descriptorpool.cpp [new file with mode: 0644]
source/backends/vulkan/descriptorpool.h [new file with mode: 0644]

diff --git a/source/backends/vulkan/descriptorpool.cpp b/source/backends/vulkan/descriptorpool.cpp
new file mode 100644 (file)
index 0000000..5a9cd93
--- /dev/null
@@ -0,0 +1,159 @@
+#include <msp/core/algorithm.h>
+#include "descriptorpool.h"
+#include "device.h"
+#include "pipelinestate.h"
+#include "vulkan.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+DescriptorPool::DescriptorPool(Device &d):
+       device(d)
+{
+       add_pool(increment);
+}
+
+DescriptorPool::~DescriptorPool()
+{
+       const VulkanFunctions &vk = device.get_functions();
+
+       for(VkDescriptorPool p: pools)
+               vk.DestroyDescriptorPool(p);
+}
+
+void DescriptorPool::add_pool(const Counts &counts)
+{
+       const VulkanFunctions &vk = device.get_functions();
+
+       VkDescriptorPoolSize pool_sizes[2] = { };
+       pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+       pool_sizes[0].descriptorCount = counts.buffers;
+       pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       pool_sizes[1].descriptorCount = counts.images;
+
+       VkDescriptorPoolCreateInfo pool_info = { };
+       pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+       pool_info.maxSets = counts.sets;
+       pool_info.poolSizeCount = 2;
+       pool_info.pPoolSizes = pool_sizes;
+
+       VkDescriptorPool pool;
+       vk.CreateDescriptorPool(pool_info, pool);
+       pools.push_back(pool);
+}
+
+void DescriptorPool::begin_frame()
+{
+       if(pools.size()>1)
+       {
+               DestroyQueue &dq = device.get_destroy_queue();
+               for(VkDescriptorPool p: pools)
+                       dq.destroy(p);
+               pools.clear();
+
+               Counts capacity = used;
+               capacity += increment;
+               add_pool(capacity);
+
+               for(auto &s: sets)
+                       fill(s.begin(), s.end(), static_cast<VkDescriptorSet>(0));
+
+               used = Counts();
+       }
+}
+
+unsigned DescriptorPool::get_descriptor_set_slot(const PipelineState &ps, unsigned index)
+{
+       unsigned slot;
+
+       uint64_t hash = ps.compute_descriptor_set_hash(index);
+       auto i = lower_bound_member(slots, hash, &HashSlot::hash);
+       if(i!=slots.end() && i->hash==hash)
+               slot = i->slot;
+       else
+       {
+               slot = next_slot++;
+               slots.emplace(i, hash, slot);
+               for(auto &s: sets)
+                       s.push_back(0);
+       }
+
+       if(ps.is_descriptor_set_dynamic(index))
+               slot |= DYNAMIC_SLOT;
+       return slot;
+}
+
+VkDescriptorSet DescriptorPool::get_descriptor_set(unsigned slot, const PipelineState &ps, unsigned index, unsigned frame)
+{
+       if(!(slot&DYNAMIC_SLOT))
+               frame = 0;
+       slot &= ~DYNAMIC_SLOT;
+
+       while(sets.size()<=frame)
+               sets.emplace_back(slots.size());
+
+       VkDescriptorSet &desc_set = sets[frame][slot];
+       if(desc_set)
+               return desc_set;
+
+       const VulkanFunctions &vk = device.get_functions();
+
+       Counts alloc;
+       alloc.sets = 1;
+
+       vector<char> buffer;
+       unsigned n_writes = ps.fill_descriptor_writes(index, frame, buffer);
+       VkWriteDescriptorSet *writes = reinterpret_cast<VkWriteDescriptorSet *>(buffer.data());
+       for(unsigned i=0; i<n_writes; ++i)
+       {
+               if(writes[i].descriptorType==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
+                       ++alloc.buffers;
+               if(writes[i].descriptorType==VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+                       ++alloc.images;
+       }
+
+       used += alloc;
+
+       VkDescriptorSetLayout layout = ps.get_descriptor_set_layout(index);
+
+       VkDescriptorSetAllocateInfo alloc_info = { };
+       alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+       alloc_info.descriptorPool = handle_cast<::VkDescriptorPool>(pools.back());
+       alloc_info.descriptorSetCount = 1;
+       alloc_info.pSetLayouts = handle_cast<::VkDescriptorSetLayout *>(&layout);
+
+       Result result = vk.AllocateDescriptorSets(alloc_info, &desc_set);
+       if(result==VK_ERROR_OUT_OF_POOL_MEMORY)
+       {
+               add_pool(increment);
+               alloc_info.descriptorPool = handle_cast<::VkDescriptorPool>(pools.back());
+               vk.AllocateDescriptorSets(alloc_info, &desc_set);
+       }
+
+       for(unsigned i=0; i<n_writes; ++i)
+               writes[i].dstSet = handle_cast<::VkDescriptorSet>(desc_set);
+
+       vk.UpdateDescriptorSets(n_writes, writes, 0, 0);
+
+       return desc_set;
+}
+
+
+DescriptorPool::Counts::Counts(unsigned s, unsigned b, unsigned i):
+       sets(s),
+       buffers(b),
+       images(i)
+{ }
+
+DescriptorPool::Counts &DescriptorPool::Counts::operator+=(const DescriptorPool::Counts &c)
+{
+       sets += c.sets;
+       buffers += c.buffers;
+       images += c.images;
+       return *this;
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/backends/vulkan/descriptorpool.h b/source/backends/vulkan/descriptorpool.h
new file mode 100644 (file)
index 0000000..2e61f85
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef MSP_GL_DESCRIPTORPOOL_H_
+#define MSP_GL_DESCRIPTORPOOL_H_
+
+#include <cstdint>
+#include <vector>
+#include <msp/core/noncopyable.h>
+#include "handles.h"
+
+namespace Msp {
+namespace GL {
+
+class Device;
+class PipelineState;
+
+class DescriptorPool: public NonCopyable
+{
+private:
+       static constexpr unsigned DYNAMIC_SLOT = 0x80000000U;
+
+       struct Counts
+       {
+               unsigned sets = 0;
+               unsigned buffers = 0;
+               unsigned images = 0;
+
+               Counts() = default;
+               Counts(unsigned, unsigned, unsigned);
+
+               Counts &operator+=(const Counts &);
+       };
+
+       struct HashSlot
+       {
+               std::uint64_t hash;
+               unsigned slot;
+
+               HashSlot(std::uint64_t h, unsigned s): hash(h), slot(s) { }
+       };
+
+       Device &device;
+       std::vector<VkDescriptorPool> pools;
+       std::vector<std::vector<VkDescriptorSet>> sets;
+       std::vector<HashSlot> slots;
+       unsigned next_slot = 0;
+       Counts used;
+       Counts increment = { 100, 500, 500 };
+
+public:
+       DescriptorPool(Device &);
+       ~DescriptorPool();
+
+private:
+       void add_pool(const Counts &);
+
+public:
+       void begin_frame();
+       unsigned get_descriptor_set_slot(const PipelineState &, unsigned);
+       VkDescriptorSet get_descriptor_set(unsigned, const PipelineState &, unsigned, unsigned);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif