Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e3f817c

Browse files
authored
[Impeller] moved to one staging buffer pool (#44172)
I measured the pool usage while using the wonderous app after having consolidated the pools by printing capturing the pool usage after every call of `vmaCreateBuffer`. The max number of allocations ever seen in this pool were 1288704 B. Each of these pools are 32 MB. So this change removes 64MB from the baseline memory usage of a Vulkan Flutter engine. Worse case for a swapchain of 3 would be roughly 3 * 1.2 MB which is well within the limits of the 32 MB buffer. Using one pool also increases the likelihood that a buffer will have been more recently used which leads to better memory performance. This is safe to do since buffers will only be placed back into the pool after they are disposed of. ## patch used for measuring ```diff --- a/impeller/renderer/backend/vulkan/allocator_vk.cc +++ b/impeller/renderer/backend/vulkan/allocator_vk.cc @@ -474,6 +474,15 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer( &buffer_allocation_info // )}; + VmaStatistics pool_stats; + ::vmaGetPoolStatistics(allocator_.get(), staging_buffer_pool_.get().pool, + &pool_stats); + static uint64_t s_max = 0; + if (pool_stats.allocationBytes > s_max) { + s_max = pool_stats.allocationBytes; + FML_LOG(ERROR) << "pool max: " << s_max; + } + if (result != vk::Result::eSuccess) { VALIDATION_LOG << "Unable to allocate a device buffer: " << vk::to_string(result); ``` ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent ae535c0 commit e3f817c

File tree

2 files changed

+7
-15
lines changed

2 files changed

+7
-15
lines changed

impeller/renderer/backend/vulkan/allocator_vk.cc

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ static PoolVMA CreateBufferPool(VmaAllocator allocator) {
7373

7474
VmaPoolCreateInfo pool_create_info = {};
7575
pool_create_info.memoryTypeIndex = memTypeIndex;
76-
pool_create_info.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT |
77-
VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
76+
pool_create_info.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT;
7877

7978
VmaPool pool = {};
8079
result = vk::Result{::vmaCreatePool(allocator, &pool_create_info, &pool)};
@@ -161,10 +160,8 @@ AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
161160
VALIDATION_LOG << "Could not create memory allocator";
162161
return;
163162
}
164-
for (size_t i = 0u; i < staging_buffer_pools_.size(); i++) {
165-
staging_buffer_pools_[i].reset(CreateBufferPool(allocator));
166-
created_buffer_pools_ &= staging_buffer_pools_[i].is_valid();
167-
}
163+
staging_buffer_pool_.reset(CreateBufferPool(allocator));
164+
created_buffer_pool_ &= staging_buffer_pool_.is_valid();
168165
allocator_.reset(allocator);
169166
supports_memoryless_textures_ = capabilities.SupportsMemorylessTextures();
170167
is_valid_ = true;
@@ -460,12 +457,9 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
460457
allocation_info.preferredFlags = static_cast<VkMemoryPropertyFlags>(
461458
ToVKBufferMemoryPropertyFlags(desc.storage_mode));
462459
allocation_info.flags = ToVmaAllocationBufferCreateFlags(desc.storage_mode);
463-
if (created_buffer_pools_ && desc.storage_mode == StorageMode::kHostVisible &&
460+
if (created_buffer_pool_ && desc.storage_mode == StorageMode::kHostVisible &&
464461
raster_thread_id_ == std::this_thread::get_id()) {
465-
allocation_info.pool =
466-
staging_buffer_pools_[frame_count_ % staging_buffer_pools_.size()]
467-
.get()
468-
.pool;
462+
allocation_info.pool = staging_buffer_pool_.get().pool;
469463
}
470464

471465
VkBuffer buffer = {};

impeller/renderer/backend/vulkan/allocator_vk.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,16 @@ class AllocatorVK final : public Allocator {
2626
private:
2727
friend class ContextVK;
2828

29-
static constexpr size_t kPoolCount = 3;
30-
3129
fml::RefPtr<vulkan::VulkanProcTable> vk_;
3230
UniqueAllocatorVMA allocator_;
33-
std::array<UniquePoolVMA, kPoolCount> staging_buffer_pools_;
31+
UniquePoolVMA staging_buffer_pool_;
3432
std::weak_ptr<Context> context_;
3533
std::weak_ptr<DeviceHolder> device_holder_;
3634
ISize max_texture_size_;
3735
bool is_valid_ = false;
3836
bool supports_memoryless_textures_ = false;
3937
// TODO(jonahwilliams): figure out why CI can't create these buffer pools.
40-
bool created_buffer_pools_ = true;
38+
bool created_buffer_pool_ = true;
4139
uint32_t frame_count_ = 0;
4240
std::thread::id raster_thread_id_;
4341

0 commit comments

Comments
 (0)