From: Mikko Rasa Date: Fri, 18 Mar 2022 22:57:03 +0000 (+0200) Subject: Add files which were forgotten earlier X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=8e863afa468425807d53b9c935428029c3c8a15b Add files which were forgotten earlier These should have been in 370eb9e. --- diff --git a/source/backends/vulkan/descriptorpool.cpp b/source/backends/vulkan/descriptorpool.cpp new file mode 100644 index 00000000..5a9cd93e --- /dev/null +++ b/source/backends/vulkan/descriptorpool.cpp @@ -0,0 +1,159 @@ +#include +#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(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 buffer; + unsigned n_writes = ps.fill_descriptor_writes(index, frame, buffer); + VkWriteDescriptorSet *writes = reinterpret_cast(buffer.data()); + for(unsigned i=0; i(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(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 index 00000000..2e61f85b --- /dev/null +++ b/source/backends/vulkan/descriptorpool.h @@ -0,0 +1,64 @@ +#ifndef MSP_GL_DESCRIPTORPOOL_H_ +#define MSP_GL_DESCRIPTORPOOL_H_ + +#include +#include +#include +#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 pools; + std::vector> sets; + std::vector 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