| Flutter Impeller |

descriptor_pool_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
6
7 #include "flutter/fml/trace_event.h"
8 #include "impeller/base/allocation.h"
9 #include "impeller/base/validation.h"
10
11 namespace impeller {
12
13 DescriptorPoolVK::DescriptorPoolVK(
14 const std::weak_ptr<const DeviceHolder>& device_holder)
15 : device_holder_(device_holder) {
16 FML_DCHECK(device_holder.lock());
17 }
18
19 DescriptorPoolVK::~DescriptorPoolVK() = default;
20
21 static vk::UniqueDescriptorPool CreatePool(const vk::Device& device,
22 uint32_t pool_count) {
23 TRACE_EVENT0("impeller", "CreateDescriptorPool");
24 std::vector<vk::DescriptorPoolSize> pools = {
25 {vk::DescriptorType::eCombinedImageSampler, pool_count},
26 {vk::DescriptorType::eUniformBuffer, pool_count},
27 {vk::DescriptorType::eStorageBuffer, pool_count}};
28
29 vk::DescriptorPoolCreateInfo pool_info;
30 pool_info.setMaxSets(pools.size() * pool_count);
31 pool_info.setPoolSizes(pools);
32
33 auto [result, pool] = device.createDescriptorPoolUnique(pool_info);
34 if (result != vk::Result::eSuccess) {
35 VALIDATION_LOG << "Unable to create a descriptor pool";
36 }
37 return std::move(pool);
38 }
39
40 std::optional<vk::DescriptorSet> DescriptorPoolVK::AllocateDescriptorSet(
41 const vk::DescriptorSetLayout& layout,
42 size_t command_count) {
43 if (pools_.empty()) {
44 pool_size_ = command_count;
45 }
46 return AllocateDescriptorSet(layout);
47 }
48
49 std::optional<vk::DescriptorSet> DescriptorPoolVK::AllocateDescriptorSet(
50 const vk::DescriptorSetLayout& layout) {
51 auto pool = GetDescriptorPool();
52 if (!pool) {
53 return std::nullopt;
54 }
55 vk::DescriptorSetAllocateInfo set_info;
56 set_info.setDescriptorPool(pool.value());
57 set_info.setSetLayouts(layout);
58 std::shared_ptr<const DeviceHolder> strong_device = device_holder_.lock();
59 if (!strong_device) {
60 return std::nullopt;
61 }
62 auto [result, sets] =
63 strong_device->GetDevice().allocateDescriptorSets(set_info);
64 if (result == vk::Result::eErrorOutOfPoolMemory) {
65 return GrowPool() ? AllocateDescriptorSet(layout) : std::nullopt;
66 }
67 if (result != vk::Result::eSuccess) {
68 VALIDATION_LOG << "Could not allocate descriptor sets: "
69 << vk::to_string(result);
70 return std::nullopt;
71 }
72 return sets[0];
73 }
74
75 std::optional<vk::DescriptorPool> DescriptorPoolVK::GetDescriptorPool() {
76 if (pools_.empty()) {
77 return GrowPool() ? GetDescriptorPool() : std::nullopt;
78 }
79 return *pools_.back();
80 }
81
82 bool DescriptorPoolVK::GrowPool() {
83 const auto new_pool_size = Allocation::NextPowerOfTwoSize(pool_size_ + 1u);
84 std::shared_ptr<const DeviceHolder> strong_device = device_holder_.lock();
85 if (!strong_device) {
86 return false;
87 }
88 auto new_pool = CreatePool(strong_device->GetDevice(), new_pool_size);
89 if (!new_pool) {
90 return false;
91 }
92 pool_size_ = new_pool_size;
93 pools_.push(std::move(new_pool));
94 return true;
95 }
96
97 } // namespace impeller
allocation.h
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:42
impeller::DescriptorPoolVK::~DescriptorPoolVK
~DescriptorPoolVK()
validation.h
impeller::DescriptorPoolVK::AllocateDescriptorSet
std::optional< vk::DescriptorSet > AllocateDescriptorSet(const vk::DescriptorSetLayout &layout, size_t command_count)
Definition: descriptor_pool_vk.cc:40
impeller::CreatePool
static vk::UniqueDescriptorPool CreatePool(const vk::Device &device, uint32_t pool_count)
Definition: descriptor_pool_vk.cc:21
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
std
Definition: comparable.h:98
impeller::DescriptorPoolVK::DescriptorPoolVK
DescriptorPoolVK(const std::weak_ptr< const DeviceHolder > &device_holder)
Definition: descriptor_pool_vk.cc:13
descriptor_pool_vk.h
impeller
Definition: aiks_context.cc:10