8 #include "flutter/fml/trace_event.h"
12 #include "vulkan/vulkan_enums.hpp"
13 #include "vulkan/vulkan_handles.hpp"
23 vk::UniqueDescriptorPool&& pool,
24 uint32_t allocated_capacity,
25 std::weak_ptr<DescriptorPoolRecyclerVK> recycler)
26 : pool_(
std::move(pool)),
27 allocated_capacity_(allocated_capacity),
28 recycler_(
std::move(recycler)) {}
31 auto const recycler = recycler_.lock();
41 recycler->Reclaim(std::move(pool_), allocated_capacity_);
50 vk::UniqueDescriptorPool pool_;
51 uint32_t allocated_capacity_;
52 std::weak_ptr<DescriptorPoolRecyclerVK> recycler_;
56 const std::weak_ptr<const ContextVK>& context)
58 FML_DCHECK(context.lock());
66 auto const context = context_.lock();
70 auto const recycler = context->GetDescriptorPoolRecycler();
76 std::move(pool_), allocated_capacity_, recycler);
79 context->GetResourceManager(), std::move(reset_pool_when_dropped));
82 fml::StatusOr<std::vector<vk::DescriptorSet>>
84 uint32_t buffer_count,
85 uint32_t sampler_count,
86 uint32_t subpass_count,
87 const std::vector<vk::DescriptorSetLayout>& layouts) {
88 std::shared_ptr<const ContextVK> strong_context = context_.lock();
89 if (!strong_context) {
90 return fml::Status(fml::StatusCode::kUnknown,
"No device");
92 auto minimum_capacity =
93 std::max(std::max(sampler_count, buffer_count), subpass_count);
94 auto [new_pool, capacity] =
95 strong_context->GetDescriptorPoolRecycler()->Get(minimum_capacity);
97 return fml::Status(fml::StatusCode::kUnknown,
98 "Failed to create descriptor pool");
100 pool_ = std::move(new_pool);
101 allocated_capacity_ = capacity;
103 vk::DescriptorSetAllocateInfo set_info;
104 set_info.setDescriptorPool(pool_.get());
105 set_info.setSetLayouts(layouts);
107 auto [result, sets] =
108 strong_context->GetDevice().allocateDescriptorSets(set_info);
109 if (result != vk::Result::eSuccess) {
111 << vk::to_string(result);
112 return fml::Status(fml::StatusCode::kUnknown,
"");
118 uint32_t allocated_capacity) {
120 auto strong_context = context_.lock();
121 if (!strong_context) {
124 auto device = strong_context->GetDevice();
125 device.resetDescriptorPool(pool.get());
128 Lock recycled_lock(recycled_mutex_);
131 recycled_.push_back(std::make_pair(std::move(pool), allocated_capacity));
142 std::optional<size_t> selected_index = std::nullopt;
143 for (
auto i = 0u; i < recycled_.size(); i++) {
144 const auto& [_, capacity] = recycled_[i];
145 if (capacity < allocated_capacity) {
150 if (selected_index.has_value()) {
151 recycled_[selected_index.value()] =
152 std::make_pair(std::move(pool), allocated_capacity);
160 auto rounded_capacity =
164 auto recycled_pool = Reuse(rounded_capacity);
165 if (recycled_pool.has_value()) {
166 return std::move(recycled_pool.value());
168 return Create(rounded_capacity);
172 uint32_t minimum_capacity) {
175 auto strong_context = context_.lock();
176 if (!strong_context) {
181 std::vector<vk::DescriptorPoolSize> pools = {
182 vk::DescriptorPoolSize{vk::DescriptorType::eCombinedImageSampler,
184 vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer,
186 vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer,
188 vk::DescriptorPoolSize{vk::DescriptorType::eInputAttachment,
190 vk::DescriptorPoolCreateInfo pool_info;
191 pool_info.setMaxSets(minimum_capacity + minimum_capacity);
192 pool_info.setPoolSizes(pools);
193 auto [result, pool] =
194 strong_context->GetDevice().createDescriptorPoolUnique(pool_info);
195 if (result != vk::Result::eSuccess) {
198 return std::make_pair(std::move(pool), minimum_capacity);
201 std::optional<DescriptorPoolAndSize> DescriptorPoolRecyclerVK::Reuse(
202 uint32_t minimum_capacity) {
205 Lock lock(recycled_mutex_);
207 std::optional<size_t> found_index = std::nullopt;
208 for (
auto i = 0u; i < recycled_.size(); i++) {
209 const auto& [_, capacity] = recycled_[i];
210 if (capacity >= minimum_capacity) {
215 if (!found_index.has_value()) {
218 auto pair = std::move(recycled_[found_index.value()]);
219 recycled_.erase(recycled_.begin() + found_index.value());