24 .texture_bindings = 256u,
25 .storage_bindings = 32,
26 .subpass_bindings = 4u
32void DescriptorPoolVK::Destroy() {
38 std::vector<vk::UniqueDescriptorPool> pools)
40 descriptor_sets_(
std::move(descriptor_sets)),
41 pools_(
std::move(pools)) {}
48 auto const context = context_.lock();
52 auto const recycler =
context->GetDescriptorPoolRecycler();
57 recycler->Reclaim(std::move(descriptor_sets_), std::move(pools_));
61 const vk::DescriptorSetLayout& layout,
64 DescriptorCacheMap::iterator existing = descriptor_sets_.find(pipeline_key);
65 if (existing != descriptor_sets_.end() && !existing->second.unused.empty()) {
66 auto descriptor_set = existing->second.unused.back();
67 existing->second.unused.pop_back();
68 existing->second.used.push_back(descriptor_set);
69 return descriptor_set;
73 CreateNewPool(context_vk);
76 vk::DescriptorSetAllocateInfo set_info;
77 set_info.setDescriptorPool(pools_.back().get());
78 set_info.setPSetLayouts(&layout);
79 set_info.setDescriptorSetCount(1);
81 vk::DescriptorSet set;
82 auto result = context_vk.
GetDevice().allocateDescriptorSets(&set_info, &set);
83 if (result == vk::Result::eErrorOutOfPoolMemory ||
85 result == vk::Result::eErrorFragmentedPool) {
87 CreateNewPool(context_vk);
88 set_info.setDescriptorPool(pools_.back().get());
89 result = context_vk.
GetDevice().allocateDescriptorSets(&set_info, &set);
93 lookup_result.first->second.used.push_back(set);
95 if (result != vk::Result::eSuccess) {
97 << vk::to_string(result);
107 "Failed to create descriptor pool");
109 pools_.emplace_back(std::move(new_pool));
115 std::vector<vk::UniqueDescriptorPool> pools) {
117 auto strong_context = context_.lock();
118 if (!strong_context) {
122 for (
auto& [_, cache] : descriptor_sets) {
123 cache.unused.insert(cache.unused.end(), cache.used.begin(),
130 Lock recycled_lock(recycled_mutex_);
132 auto& back_entry = recycled_.back();
133 back_entry->Destroy();
134 recycled_.pop_back();
136 recycled_.push_back(std::make_shared<DescriptorPoolVK>(
137 context_, std::move(descriptor_sets), std::move(pools)));
145vk::UniqueDescriptorPool DescriptorPoolRecyclerVK::Create() {
146 auto strong_context = context_.lock();
147 if (!strong_context) {
152 std::vector<vk::DescriptorPoolSize> pools = {
153 vk::DescriptorPoolSize{vk::DescriptorType::eCombinedImageSampler,
155 vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer,
157 vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer,
159 vk::DescriptorPoolSize{vk::DescriptorType::eInputAttachment,
161 vk::DescriptorPoolCreateInfo pool_info;
166 pool_info.setPoolSizes(pools);
167 auto [result, pool] =
168 strong_context->GetDevice().createDescriptorPoolUnique(pool_info);
169 if (result != vk::Result::eSuccess) {
172 return std::move(pool);
175std::shared_ptr<DescriptorPoolVK>
178 Lock recycled_lock(recycled_mutex_);
179 if (!recycled_.empty()) {
180 auto result = recycled_.back();
181 recycled_.pop_back();
185 return std::make_shared<DescriptorPoolVK>(context_);
const vk::Device & GetDevice() const
std::shared_ptr< DescriptorPoolRecyclerVK > GetDescriptorPoolRecycler() const
std::shared_ptr< DescriptorPoolVK > GetDescriptorPool()
void Reclaim(DescriptorCacheMap descriptor_sets, std::vector< vk::UniqueDescriptorPool > pools)
vk::UniqueDescriptorPool Get()
Gets a descriptor pool.
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, PipelineKey pipeline_key, const ContextVK &context_vk)
std::unordered_map< PipelineKey, DescriptorCache > DescriptorCacheMap
static const constexpr DescriptorPoolSize kDefaultBindingSize
Descriptor pools are always allocated with the following sizes.
std::shared_ptr< ContextGLES > context
Used and un-used descriptor sets.