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

Commit f0235af

Browse files
Reverts "[Impeller] one descriptor pool per frame. (#55939)" (#55959)
Reverts: #55939 Initiated by: jonahwilliams Reason for reverting: failing on scenario test Original PR Author: jonahwilliams Reviewed By: {matanlurey} This change reverts the following previous change: Creating descriptor pools is expensive, no need to have more than one per frame. The lifecycle of the descriptor pool is exactly the same as the cmd pool, which indicates that we can probably do some consolidation/refactoring in the future. Fixes flutter/flutter#157115
1 parent 7525656 commit f0235af

File tree

10 files changed

+40
-138
lines changed

10 files changed

+40
-138
lines changed

impeller/renderer/backend/vulkan/command_buffer_vk.cc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ namespace impeller {
2222
CommandBufferVK::CommandBufferVK(
2323
std::weak_ptr<const Context> context,
2424
std::weak_ptr<const DeviceHolderVK> device_holder,
25-
std::shared_ptr<TrackedObjectsVK> tracked_objects)
25+
std::shared_ptr<TrackedObjectsVK> tracked_objects,
26+
std::shared_ptr<FenceWaiterVK> fence_waiter)
2627
: CommandBuffer(std::move(context)),
2728
device_holder_(std::move(device_holder)),
28-
tracked_objects_(std::move(tracked_objects)) {}
29+
tracked_objects_(std::move(tracked_objects)),
30+
fence_waiter_(std::move(fence_waiter)) {}
2931

3032
CommandBufferVK::~CommandBufferVK() = default;
3133

@@ -210,8 +212,4 @@ void CommandBufferVK::InsertDebugMarker(std::string_view label) const {
210212
}
211213
}
212214

213-
DescriptorPoolVK& CommandBufferVK::GetDescriptorPool() const {
214-
return tracked_objects_->GetDescriptorPool();
215-
}
216-
217215
} // namespace impeller

impeller/renderer/backend/vulkan/command_buffer_vk.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include "fml/status_or.h"
99
#include "impeller/base/backend_cast.h"
1010
#include "impeller/renderer/backend/vulkan/command_queue_vk.h"
11-
#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
1211
#include "impeller/renderer/backend/vulkan/device_holder_vk.h"
1312
#include "impeller/renderer/backend/vulkan/texture_source_vk.h"
1413
#include "impeller/renderer/backend/vulkan/tracked_objects_vk.h"
@@ -82,19 +81,18 @@ class CommandBufferVK final
8281
// Visible for testing.
8382
bool IsTracking(const std::shared_ptr<const Texture>& texture) const;
8483

85-
// Visible for testing.
86-
DescriptorPoolVK& GetDescriptorPool() const;
87-
8884
private:
8985
friend class ContextVK;
9086
friend class CommandQueueVK;
9187

9288
std::weak_ptr<const DeviceHolderVK> device_holder_;
9389
std::shared_ptr<TrackedObjectsVK> tracked_objects_;
90+
std::shared_ptr<FenceWaiterVK> fence_waiter_;
9491

9592
CommandBufferVK(std::weak_ptr<const Context> context,
9693
std::weak_ptr<const DeviceHolderVK> device_holder,
97-
std::shared_ptr<TrackedObjectsVK> tracked_objects);
94+
std::shared_ptr<TrackedObjectsVK> tracked_objects,
95+
std::shared_ptr<FenceWaiterVK> fence_waiter);
9896

9997
// |CommandBuffer|
10098
void SetLabel(std::string_view label) const override;

impeller/renderer/backend/vulkan/command_pool_vk.cc

Lines changed: 23 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <utility>
1010

1111
#include "impeller/renderer/backend/vulkan/context_vk.h"
12-
#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
1312
#include "impeller/renderer/backend/vulkan/resource_manager_vk.h"
1413

1514
#include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep.
@@ -156,6 +155,10 @@ void CommandPoolVK::Destroy() {
156155
collected_buffers_.clear();
157156
}
158157

158+
// Associates a resource with a thread and context.
159+
using CommandPoolMap =
160+
std::unordered_map<uint64_t, std::shared_ptr<CommandPoolVK>>;
161+
159162
// CommandPoolVK Lifecycle:
160163
// 1. End of frame will reset the command pool (clearing this on a thread).
161164
// There will still be references to the command pool from the uncompleted
@@ -166,47 +169,17 @@ void CommandPoolVK::Destroy() {
166169
// available for reuse ("recycle").
167170
static thread_local std::unique_ptr<CommandPoolMap> tls_command_pool_map;
168171

169-
struct WeakThreadLocalData {
170-
std::weak_ptr<CommandPoolVK> command_pool;
171-
std::weak_ptr<DescriptorPoolVK> descriptor_pool;
172-
};
173-
174172
// Map each context to a list of all thread-local command pools associated
175173
// with that context.
176174
static Mutex g_all_pools_map_mutex;
177-
static std::unordered_map<const ContextVK*,
178-
std::vector<WeakThreadLocalData>> g_all_pools_map
175+
static std::unordered_map<
176+
const ContextVK*,
177+
std::vector<std::weak_ptr<CommandPoolVK>>> g_all_pools_map
179178
IPLR_GUARDED_BY(g_all_pools_map_mutex);
180179

181-
std::shared_ptr<DescriptorPoolVK> CommandPoolRecyclerVK::GetDescriptorPool() {
182-
const auto& strong_context = context_.lock();
183-
if (!strong_context) {
184-
return nullptr;
185-
}
186-
187-
// If there is a resource in used for this thread and context, return it.
188-
if (!tls_command_pool_map.get()) {
189-
tls_command_pool_map.reset(new CommandPoolMap());
190-
}
191-
CommandPoolMap& pool_map = *tls_command_pool_map.get();
192-
auto const hash = strong_context->GetHash();
193-
auto const it = pool_map.find(hash);
194-
if (it != pool_map.end()) {
195-
return it->second.descriptor_pool;
196-
}
197-
198-
const auto& result =
199-
InitializeThreadLocalResources(strong_context, pool_map, hash);
200-
if (result.has_value()) {
201-
return result->descriptor_pool;
202-
}
203-
204-
return nullptr;
205-
}
206-
207180
// TODO(matanlurey): Return a status_or<> instead of nullptr when we have one.
208181
std::shared_ptr<CommandPoolVK> CommandPoolRecyclerVK::Get() {
209-
const auto& strong_context = context_.lock();
182+
auto const strong_context = context_.lock();
210183
if (!strong_context) {
211184
return nullptr;
212185
}
@@ -219,40 +192,25 @@ std::shared_ptr<CommandPoolVK> CommandPoolRecyclerVK::Get() {
219192
auto const hash = strong_context->GetHash();
220193
auto const it = pool_map.find(hash);
221194
if (it != pool_map.end()) {
222-
return it->second.command_pool;
195+
return it->second;
223196
}
224197

225-
const auto& result =
226-
InitializeThreadLocalResources(strong_context, pool_map, hash);
227-
if (result.has_value()) {
228-
return result->command_pool;
229-
}
230-
231-
return nullptr;
232-
}
233-
234-
std::optional<ThreadLocalData>
235-
CommandPoolRecyclerVK::InitializeThreadLocalResources(
236-
const std::shared_ptr<ContextVK>& context,
237-
CommandPoolMap& pool_map,
238-
uint64_t pool_key) {
198+
// Otherwise, create a new resource and return it.
239199
auto data = Create();
240200
if (!data || !data->pool) {
241-
return std::nullopt;
201+
return nullptr;
242202
}
243203

244-
auto command_pool = std::make_shared<CommandPoolVK>(
204+
auto const resource = std::make_shared<CommandPoolVK>(
245205
std::move(data->pool), std::move(data->buffers), context_);
246-
auto descriptor_pool = std::make_shared<DescriptorPoolVK>(context_);
206+
pool_map.emplace(hash, resource);
207+
247208
{
248209
Lock all_pools_lock(g_all_pools_map_mutex);
249-
g_all_pools_map[context.get()].push_back(WeakThreadLocalData{
250-
.command_pool = command_pool, .descriptor_pool = descriptor_pool});
210+
g_all_pools_map[strong_context.get()].push_back(resource);
251211
}
252212

253-
return pool_map[pool_key] =
254-
ThreadLocalData{.command_pool = std::move(command_pool),
255-
.descriptor_pool = std::move(descriptor_pool)};
213+
return resource;
256214
}
257215

258216
// TODO(matanlurey): Return a status_or<> instead of nullopt when we have one.
@@ -335,13 +293,14 @@ void CommandPoolRecyclerVK::DestroyThreadLocalPools(const ContextVK* context) {
335293
Lock all_pools_lock(g_all_pools_map_mutex);
336294
auto found = g_all_pools_map.find(context);
337295
if (found != g_all_pools_map.end()) {
338-
for (auto& [command_pool, desc_pool] : found->second) {
339-
const auto& strong_pool = command_pool.lock();
340-
if (strong_pool) {
341-
// Delete all objects held by this pool. The destroyed pool will still
342-
// remain in its thread's TLS map until that thread exits.
343-
strong_pool->Destroy();
296+
for (auto& weak_pool : found->second) {
297+
auto pool = weak_pool.lock();
298+
if (!pool) {
299+
continue;
344300
}
301+
// Delete all objects held by this pool. The destroyed pool will still
302+
// remain in its thread's TLS map until that thread exits.
303+
pool->Destroy();
345304
}
346305
g_all_pools_map.erase(found);
347306
}

impeller/renderer/backend/vulkan/command_pool_vk.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <utility>
1111

1212
#include "impeller/base/thread.h"
13-
#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
1413
#include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep.
1514
#include "vulkan/vulkan_handles.hpp"
1615

@@ -77,14 +76,6 @@ class CommandPoolVK final {
7776
pool_mutex_);
7877
};
7978

80-
struct ThreadLocalData {
81-
std::shared_ptr<CommandPoolVK> command_pool;
82-
std::shared_ptr<DescriptorPoolVK> descriptor_pool;
83-
};
84-
85-
// Associates a resource with a thread and context.
86-
using CommandPoolMap = std::unordered_map<uint64_t, ThreadLocalData>;
87-
8879
//------------------------------------------------------------------------------
8980
/// @brief Creates and manages the lifecycle of |vk::CommandPool| objects.
9081
///
@@ -137,11 +128,6 @@ class CommandPoolRecyclerVK final
137128
/// @warning Returns a |nullptr| if a pool could not be created.
138129
std::shared_ptr<CommandPoolVK> Get();
139130

140-
/// @brief Gets a descriptor pool for the current thread.
141-
///
142-
/// @warning Returns a |nullptr| if a pool could not be created.
143-
std::shared_ptr<DescriptorPoolVK> GetDescriptorPool();
144-
145131
/// @brief Returns a command pool to be reset on a background thread.
146132
///
147133
/// @param[in] pool The pool to recycler.
@@ -167,13 +153,6 @@ class CommandPoolRecyclerVK final
167153
/// @returns Returns a |std::nullopt| if a pool was not available.
168154
std::optional<RecycledData> Reuse();
169155

170-
/// Create a DescriptorPoolVK and a CommandPoolVK and stash them in the TLS
171-
/// map.
172-
std::optional<ThreadLocalData> InitializeThreadLocalResources(
173-
const std::shared_ptr<ContextVK>& context,
174-
CommandPoolMap& pool_map,
175-
uint64_t pool_key);
176-
177156
CommandPoolRecyclerVK(const CommandPoolRecyclerVK&) = delete;
178157

179158
CommandPoolRecyclerVK& operator=(const CommandPoolRecyclerVK&) = delete;

impeller/renderer/backend/vulkan/context_vk.cc

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "fml/concurrent_message_loop.h"
88
#include "impeller/renderer/backend/vulkan/command_queue_vk.h"
9-
#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
109
#include "impeller/renderer/backend/vulkan/render_pass_builder_vk.h"
1110
#include "impeller/renderer/render_target.h"
1211

@@ -496,14 +495,9 @@ std::shared_ptr<CommandBuffer> ContextVK::CreateCommandBuffer() const {
496495
if (!tls_pool) {
497496
return nullptr;
498497
}
499-
auto tls_desc_pool = recycler->GetDescriptorPool();
500-
if (!tls_desc_pool) {
501-
return nullptr;
502-
}
503498

504499
auto tracked_objects = std::make_shared<TrackedObjectsVK>(
505-
weak_from_this(), std::move(tls_pool), tls_desc_pool,
506-
GetGPUTracer()->CreateGPUProbe());
500+
weak_from_this(), std::move(tls_pool), GetGPUTracer()->CreateGPUProbe());
507501
auto queue = GetGraphicsQueue();
508502

509503
if (!tracked_objects || !tracked_objects->IsValid() || !queue) {
@@ -522,9 +516,10 @@ std::shared_ptr<CommandBuffer> ContextVK::CreateCommandBuffer() const {
522516
tracked_objects->GetCommandBuffer());
523517

524518
return std::shared_ptr<CommandBufferVK>(new CommandBufferVK(
525-
shared_from_this(), //
526-
GetDeviceHolder(), //
527-
std::move(tracked_objects) //
519+
shared_from_this(), //
520+
GetDeviceHolder(), //
521+
std::move(tracked_objects), //
522+
GetFenceWaiter() //
528523
));
529524
}
530525

impeller/renderer/backend/vulkan/context_vk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
#include "flutter/fml/concurrent_message_loop.h"
1111
#include "flutter/fml/mapping.h"
1212
#include "flutter/fml/unique_fd.h"
13+
#include "fml/thread.h"
1314
#include "impeller/base/backend_cast.h"
1415
#include "impeller/base/strings.h"
1516
#include "impeller/core/formats.h"
17+
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
1618
#include "impeller/renderer/backend/vulkan/device_holder_vk.h"
1719
#include "impeller/renderer/backend/vulkan/driver_info_vk.h"
1820
#include "impeller/renderer/backend/vulkan/pipeline_library_vk.h"

impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "flutter/testing/testing.h" // IWYU pragma: keep.
66
#include "fml/closure.h"
77
#include "fml/synchronization/waitable_event.h"
8-
#include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
98
#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h"
109
#include "impeller/renderer/backend/vulkan/resource_manager_vk.h"
1110
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
@@ -124,27 +123,5 @@ TEST(DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded) {
124123
context->Shutdown();
125124
}
126125

127-
TEST(DescriptorPoolRecyclerVKTest, MultipleCommandBuffersShareDescriptorPool) {
128-
auto const context = MockVulkanContextBuilder().Build();
129-
130-
auto cmd_buffer_1 = context->CreateCommandBuffer();
131-
auto cmd_buffer_2 = context->CreateCommandBuffer();
132-
133-
CommandBufferVK& vk_1 = CommandBufferVK::Cast(*cmd_buffer_1);
134-
CommandBufferVK& vk_2 = CommandBufferVK::Cast(*cmd_buffer_2);
135-
136-
EXPECT_EQ(&vk_1.GetDescriptorPool(), &vk_2.GetDescriptorPool());
137-
138-
// Resetting resources creates a new pool.
139-
context->DisposeThreadLocalCachedResources();
140-
141-
auto cmd_buffer_3 = context->CreateCommandBuffer();
142-
CommandBufferVK& vk_3 = CommandBufferVK::Cast(*cmd_buffer_3);
143-
144-
EXPECT_NE(&vk_1.GetDescriptorPool(), &vk_3.GetDescriptorPool());
145-
146-
context->Shutdown();
147-
}
148-
149126
} // namespace testing
150127
} // namespace impeller

impeller/renderer/backend/vulkan/test/mock_vulkan_unittests.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include "flutter/testing/testing.h" // IWYU pragma: keep
66
#include "gtest/gtest.h"
7-
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
87
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
98
#include "vulkan/vulkan_enums.hpp"
109

impeller/renderer/backend/vulkan/tracked_objects_vk.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44

55
#include "impeller/renderer/backend/vulkan/tracked_objects_vk.h"
66

7-
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
87
#include "impeller/renderer/backend/vulkan/gpu_tracer_vk.h"
98

109
namespace impeller {
1110

1211
TrackedObjectsVK::TrackedObjectsVK(
1312
const std::weak_ptr<const ContextVK>& context,
1413
const std::shared_ptr<CommandPoolVK>& pool,
15-
std::shared_ptr<DescriptorPoolVK> descriptor_pool,
1614
std::unique_ptr<GPUProbe> probe)
17-
: desc_pool_(std::move(descriptor_pool)), probe_(std::move(probe)) {
15+
: desc_pool_(context), probe_(std::move(probe)) {
1816
if (!pool) {
1917
return;
2018
}
@@ -80,7 +78,7 @@ vk::CommandBuffer TrackedObjectsVK::GetCommandBuffer() const {
8078
}
8179

8280
DescriptorPoolVK& TrackedObjectsVK::GetDescriptorPool() {
83-
return *desc_pool_;
81+
return desc_pool_;
8482
}
8583

8684
GPUProbe& TrackedObjectsVK::GetGPUProbe() const {

impeller/renderer/backend/vulkan/tracked_objects_vk.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,12 @@
1414

1515
namespace impeller {
1616

17-
class CommandPoolVK;
18-
1917
/// @brief A per-frame object used to track resource lifetimes and allocate
2018
/// command buffers and descriptor sets.
2119
class TrackedObjectsVK {
2220
public:
2321
explicit TrackedObjectsVK(const std::weak_ptr<const ContextVK>& context,
2422
const std::shared_ptr<CommandPoolVK>& pool,
25-
std::shared_ptr<DescriptorPoolVK> descriptor_pool,
2623
std::unique_ptr<GPUProbe> probe);
2724

2825
~TrackedObjectsVK();
@@ -46,7 +43,7 @@ class TrackedObjectsVK {
4643
GPUProbe& GetGPUProbe() const;
4744

4845
private:
49-
std::shared_ptr<DescriptorPoolVK> desc_pool_;
46+
DescriptorPoolVK desc_pool_;
5047
// `shared_ptr` since command buffers have a link to the command pool.
5148
std::shared_ptr<CommandPoolVK> pool_;
5249
vk::UniqueCommandBuffer buffer_;

0 commit comments

Comments
 (0)