11#include "vulkan/vulkan_enums.hpp"
12#include "vulkan/vulkan_handles.hpp"
27 .texture_bindings = 256u,
28 .storage_bindings = 32,
29 .subpass_bindings = 4u
38 vk::UniqueDescriptorPool&&
pool,
39 std::weak_ptr<DescriptorPoolRecyclerVK> recycler)
40 : pool_(
std::move(
pool)), recycler_(
std::move(recycler)) {}
43 auto const recycler = recycler_.lock();
53 recycler->Reclaim(std::move(pool_));
62 vk::UniqueDescriptorPool pool_;
63 uint32_t allocated_capacity_;
64 std::weak_ptr<DescriptorPoolRecyclerVK> recycler_;
68 : context_(
std::move(context)) {}
75 auto const context = context_.lock();
79 auto const recycler = context->GetDescriptorPoolRecycler();
84 for (
auto i = 0u; i < pools_.size(); i++) {
85 auto reset_pool_when_dropped =
89 context->GetResourceManager(), std::move(reset_pool_when_dropped));
95 const vk::DescriptorSetLayout& layout,
98 CreateNewPool(context_vk);
101 vk::DescriptorSetAllocateInfo set_info;
102 set_info.setDescriptorPool(pools_.back().get());
103 set_info.setPSetLayouts(&layout);
104 set_info.setDescriptorSetCount(1);
106 vk::DescriptorSet set;
107 auto result = context_vk.
GetDevice().allocateDescriptorSets(&set_info, &set);
108 if (
result == vk::Result::eErrorOutOfPoolMemory) {
110 CreateNewPool(context_vk);
111 set_info.setDescriptorPool(pools_.back().get());
112 result = context_vk.
GetDevice().allocateDescriptorSets(&set_info, &set);
115 if (
result != vk::Result::eSuccess) {
127 "Failed to create descriptor pool");
129 pools_.emplace_back(std::move(new_pool));
135 auto strong_context = context_.lock();
136 if (!strong_context) {
139 auto device = strong_context->GetDevice();
143 Lock recycled_lock(recycled_mutex_);
146 recycled_.push_back(std::move(
pool));
153 auto recycled_pool = Reuse();
154 if (recycled_pool.has_value()) {
155 return std::move(recycled_pool.value());
160vk::UniqueDescriptorPool DescriptorPoolRecyclerVK::Create() {
161 auto strong_context = context_.lock();
162 if (!strong_context) {
167 std::vector<vk::DescriptorPoolSize> pools = {
168 vk::DescriptorPoolSize{vk::DescriptorType::eCombinedImageSampler,
170 vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer,
172 vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer,
174 vk::DescriptorPoolSize{vk::DescriptorType::eInputAttachment,
176 vk::DescriptorPoolCreateInfo pool_info;
181 pool_info.setPoolSizes(pools);
183 strong_context->GetDevice().createDescriptorPoolUnique(pool_info);
184 if (
result != vk::Result::eSuccess) {
187 return std::move(
pool);
190std::optional<vk::UniqueDescriptorPool> DescriptorPoolRecyclerVK::Reuse() {
191 Lock lock(recycled_mutex_);
192 if (recycled_.empty()) {
196 auto recycled = std::move(recycled_[recycled_.size() - 1]);
197 recycled_.pop_back();
BackgroundDescriptorPoolVK(BackgroundDescriptorPoolVK &&)=default
BackgroundDescriptorPoolVK(vk::UniqueDescriptorPool &&pool, std::weak_ptr< DescriptorPoolRecyclerVK > recycler)
~BackgroundDescriptorPoolVK()
const vk::Device & GetDevice() const
std::shared_ptr< DescriptorPoolRecyclerVK > GetDescriptorPoolRecycler() const
vk::UniqueDescriptorPool Get()
Gets a descriptor pool.
void Reclaim(vk::UniqueDescriptorPool &&pool)
Returns the descriptor pool to be reset on a background thread.
static constexpr size_t kMaxRecycledPools
The maximum number of descriptor pools this recycler will hold onto.
DescriptorPoolVK(std::weak_ptr< const ContextVK > context)
fml::StatusOr< vk::DescriptorSet > AllocateDescriptorSets(const vk::DescriptorSetLayout &layout, const ContextVK &context_vk)
A unique handle to a resource which will be reclaimed by the specified resource manager.
static const constexpr DescriptorPoolSize kDefaultBindingSize
Descriptor pools are always allocated with the following sizes.