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 
6 
7 #include "flutter/fml/trace_event.h"
10 
11 namespace impeller {
12 
14  const std::weak_ptr<const DeviceHolder>& device_holder)
15  : device_holder_(device_holder) {
16  FML_DCHECK(device_holder.lock());
17 }
18 
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