Fix descriptor pool fragmentation (#2949)

This commit is contained in:
Adrian Cojocaru
2024-10-22 18:45:02 +03:00
committed by GitHub
parent c098a12c37
commit 7ff0c71312
6 changed files with 160 additions and 92 deletions

View File

@@ -12,6 +12,7 @@
#include <mbgl/vulkan/uniform_buffer.hpp>
#include <mbgl/vulkan/renderer_backend.hpp>
#include <mbgl/vulkan/pipeline.hpp>
#include <mbgl/vulkan/descriptor_set.hpp>
#include <memory>
#include <optional>
@@ -135,21 +136,14 @@ public:
const std::unique_ptr<BufferResource>& getDummyVertexBuffer();
const std::unique_ptr<BufferResource>& getDummyUniformBuffer();
const std::unique_ptr<Texture2D>& getDummyTexture();
const vk::UniqueDescriptorSetLayout& getImageDescriptorSetLayout();
const vk::UniqueDescriptorSetLayout& buildUniformDescriptorSetLayout(vk::UniqueDescriptorSetLayout& layout,
size_t uniformCount,
const std::string& name);
const std::vector<vk::DescriptorSetLayout>& getDescriptorSetLayouts();
const vk::DescriptorSetLayout& getDescriptorSetLayout(DescriptorSetType type);
DescriptorPoolGrowable& getDescriptorPool(DescriptorSetType type);
const vk::UniquePipelineLayout& getGeneralPipelineLayout();
const vk::UniquePipelineLayout& getPushConstantPipelineLayout();
void bindDescriptorSet(DescriptorSetType type, const vk::DescriptorSet& descriptorSet);
uint8_t getCurrentFrameResourceIndex() const { return frameResourceIndex; }
const vk::UniqueDescriptorPool& getGlobalDescriptorPool() const;
void enqueueDeletion(std::function<void(const Context&)>&& function);
void enqueueDeletion(std::function<void(Context&)>&& function);
void submitOneTimeCommand(const std::function<void(const vk::UniqueCommandBuffer&)>& function) const;
void requestSurfaceUpdate() { surfaceUpdateRequested = true; }
@@ -162,7 +156,7 @@ private:
vk::UniqueSemaphore frameSemaphore;
vk::UniqueFence flightFrameFence;
std::vector<std::function<void(const Context&)>> deletionQueue;
std::vector<std::function<void(Context&)>> deletionQueue;
FrameResources(vk::UniqueCommandBuffer& cb,
vk::UniqueSemaphore&& surf,
@@ -173,17 +167,22 @@ private:
frameSemaphore(std::move(frame)),
flightFrameFence(std::move(flight)) {}
void runDeletionQueue(const Context&);
void runDeletionQueue(Context&);
};
void initFrameResources();
void destroyResources();
void buildImageDescriptorSetLayout();
void buildUniformDescriptorSetLayout(vk::UniqueDescriptorSetLayout& layout,
size_t uniformCount,
const std::string& name);
private:
RendererBackend& backend;
vulkan::UniformBufferArray globalUniformBuffers;
vk::UniqueDescriptorPool globalDescriptorPool;
std::unordered_map<DescriptorSetType, DescriptorPoolGrowable> descriptorPoolMap;
std::unique_ptr<BufferResource> dummyVertexBuffer;
std::unique_ptr<BufferResource> dummyUniformBuffer;
@@ -191,8 +190,7 @@ private:
vk::UniqueDescriptorSetLayout globalUniformDescriptorSetLayout;
vk::UniqueDescriptorSetLayout layerUniformDescriptorSetLayout;
vk::UniqueDescriptorSetLayout drawableUniformDescriptorSetLayout;
vk::UniqueDescriptorSetLayout imageDescriptorSetLayout;
std::vector<vk::DescriptorSetLayout> descriptorSetLayouts;
vk::UniqueDescriptorSetLayout drawableImageDescriptorSetLayout;
vk::UniquePipelineLayout generalPipelineLayout;
vk::UniquePipelineLayout pushConstantPipelineLayout;

View File

@@ -17,6 +17,32 @@ enum class DescriptorSetType : uint8_t {
Count,
};
struct DescriptorPoolGrowable {
struct PoolInfo {
vk::UniqueDescriptorPool pool;
uint32_t remainingSets{0};
PoolInfo(vk::UniqueDescriptorPool&& pool_, uint32_t remainingSets_)
: pool(std::move(pool_)),
remainingSets(remainingSets_) {}
};
const uint32_t maxSets{0};
const uint32_t descriptorsPerSet{0};
const float growFactor{1.5f};
std::vector<PoolInfo> pools;
int32_t currentPoolIndex{-1};
PoolInfo& current() { return pools[currentPoolIndex]; }
DescriptorPoolGrowable() = default;
DescriptorPoolGrowable(uint32_t maxSets_, uint32_t descriptorsPerSet_, float growFactor_ = 1.5f)
: maxSets(maxSets_),
descriptorsPerSet(descriptorsPerSet_),
growFactor(growFactor_) {}
};
class DescriptorSet {
public:
DescriptorSet(Context& context_, DescriptorSetType type_);
@@ -27,12 +53,16 @@ public:
void markDirty(bool value = true);
void bind(CommandEncoder& encoder);
protected:
void createDescriptorPool(DescriptorPoolGrowable& growablePool);
protected:
Context& context;
DescriptorSetType type;
std::vector<bool> dirty;
std::vector<vk::DescriptorSet> descriptorSets;
int32_t descriptorPoolIndex{-1};
};
class UniformDescriptorSet : public DescriptorSet {