diff --git a/.ci.yaml b/.ci.yaml index 205edfe43306c..239cce546881e 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -506,6 +506,7 @@ targets: # Avoid using a Mac orchestrator to save ~5 minutes of Mac host time. - name: Linux mac_clangd recipe: engine_v2/engine_v2 + timeout: 90 # Do not remove(https://github.com/flutter/flutter/issues/144644) # Scheduler will fail to get the platform drone_dimensions: diff --git a/impeller/renderer/backend/vulkan/command_buffer_vk.cc b/impeller/renderer/backend/vulkan/command_buffer_vk.cc index abe4971298c28..e8341a352c8f9 100644 --- a/impeller/renderer/backend/vulkan/command_buffer_vk.cc +++ b/impeller/renderer/backend/vulkan/command_buffer_vk.cc @@ -22,12 +22,10 @@ namespace impeller { CommandBufferVK::CommandBufferVK( std::weak_ptr context, std::weak_ptr device_holder, - std::shared_ptr tracked_objects, - std::shared_ptr fence_waiter) + std::shared_ptr tracked_objects) : CommandBuffer(std::move(context)), device_holder_(std::move(device_holder)), - tracked_objects_(std::move(tracked_objects)), - fence_waiter_(std::move(fence_waiter)) {} + tracked_objects_(std::move(tracked_objects)) {} CommandBufferVK::~CommandBufferVK() = default; @@ -212,4 +210,8 @@ void CommandBufferVK::InsertDebugMarker(std::string_view label) const { } } +DescriptorPoolVK& CommandBufferVK::GetDescriptorPool() const { + return tracked_objects_->GetDescriptorPool(); +} + } // namespace impeller diff --git a/impeller/renderer/backend/vulkan/command_buffer_vk.h b/impeller/renderer/backend/vulkan/command_buffer_vk.h index 6a78787f1dce5..ef9dba2494975 100644 --- a/impeller/renderer/backend/vulkan/command_buffer_vk.h +++ b/impeller/renderer/backend/vulkan/command_buffer_vk.h @@ -8,6 +8,7 @@ #include "fml/status_or.h" #include "impeller/base/backend_cast.h" #include "impeller/renderer/backend/vulkan/command_queue_vk.h" +#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h" #include "impeller/renderer/backend/vulkan/device_holder_vk.h" #include "impeller/renderer/backend/vulkan/texture_source_vk.h" #include "impeller/renderer/backend/vulkan/tracked_objects_vk.h" @@ -81,18 +82,19 @@ class CommandBufferVK final // Visible for testing. bool IsTracking(const std::shared_ptr& texture) const; + // Visible for testing. + DescriptorPoolVK& GetDescriptorPool() const; + private: friend class ContextVK; friend class CommandQueueVK; std::weak_ptr device_holder_; std::shared_ptr tracked_objects_; - std::shared_ptr fence_waiter_; CommandBufferVK(std::weak_ptr context, std::weak_ptr device_holder, - std::shared_ptr tracked_objects, - std::shared_ptr fence_waiter); + std::shared_ptr tracked_objects); // |CommandBuffer| void SetLabel(std::string_view label) const override; diff --git a/impeller/renderer/backend/vulkan/context_vk.cc b/impeller/renderer/backend/vulkan/context_vk.cc index cfebbf7dd0278..eaef668e47412 100644 --- a/impeller/renderer/backend/vulkan/context_vk.cc +++ b/impeller/renderer/backend/vulkan/context_vk.cc @@ -3,9 +3,12 @@ // found in the LICENSE file. #include "impeller/renderer/backend/vulkan/context_vk.h" +#include +#include #include "fml/concurrent_message_loop.h" #include "impeller/renderer/backend/vulkan/command_queue_vk.h" +#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h" #include "impeller/renderer/backend/vulkan/render_pass_builder_vk.h" #include "impeller/renderer/render_target.h" @@ -30,6 +33,7 @@ #include "impeller/renderer/backend/vulkan/command_pool_vk.h" #include "impeller/renderer/backend/vulkan/command_queue_vk.h" #include "impeller/renderer/backend/vulkan/debug_report_vk.h" +#include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h" #include "impeller/renderer/backend/vulkan/fence_waiter_vk.h" #include "impeller/renderer/backend/vulkan/gpu_tracer_vk.h" #include "impeller/renderer/backend/vulkan/resource_manager_vk.h" @@ -497,8 +501,22 @@ std::shared_ptr ContextVK::CreateCommandBuffer() const { return nullptr; } + // look up a cached descriptor pool for the current frame and reuse it + // if it exists, otherwise create a new pool. + DescriptorPoolMap::iterator current_pool = + cached_descriptor_pool_.find(std::this_thread::get_id()); + std::shared_ptr descriptor_pool; + if (current_pool == cached_descriptor_pool_.end()) { + descriptor_pool = + (cached_descriptor_pool_[std::this_thread::get_id()] = + std::make_shared(weak_from_this())); + } else { + descriptor_pool = current_pool->second; + } + auto tracked_objects = std::make_shared( - weak_from_this(), std::move(tls_pool), GetGPUTracer()->CreateGPUProbe()); + weak_from_this(), std::move(tls_pool), std::move(descriptor_pool), + GetGPUTracer()->CreateGPUProbe()); auto queue = GetGraphicsQueue(); if (!tracked_objects || !tracked_objects->IsValid() || !queue) { @@ -517,10 +535,9 @@ std::shared_ptr ContextVK::CreateCommandBuffer() const { tracked_objects->GetCommandBuffer()); return std::shared_ptr(new CommandBufferVK( - shared_from_this(), // - GetDeviceHolder(), // - std::move(tracked_objects), // - GetFenceWaiter() // + shared_from_this(), // + GetDeviceHolder(), // + std::move(tracked_objects) // )); } @@ -651,6 +668,7 @@ void ContextVK::InitializeCommonlyUsedShadersIfNeeded() const { } void ContextVK::DisposeThreadLocalCachedResources() { + cached_descriptor_pool_.erase(std::this_thread::get_id()); command_pool_recycler_->Dispose(); } diff --git a/impeller/renderer/backend/vulkan/context_vk.h b/impeller/renderer/backend/vulkan/context_vk.h index 6fa473154cf33..91d4506312d0c 100644 --- a/impeller/renderer/backend/vulkan/context_vk.h +++ b/impeller/renderer/backend/vulkan/context_vk.h @@ -10,7 +10,6 @@ #include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/mapping.h" #include "flutter/fml/unique_fd.h" -#include "fml/thread.h" #include "impeller/base/backend_cast.h" #include "impeller/base/strings.h" #include "impeller/core/formats.h" @@ -40,6 +39,7 @@ class SurfaceContextVK; class GPUTracerVK; class DescriptorPoolRecyclerVK; class CommandQueueVK; +class DescriptorPoolVK; class ContextVK final : public Context, public BackendCast, @@ -224,12 +224,17 @@ class ContextVK final : public Context, std::shared_ptr device_capabilities_; std::shared_ptr fence_waiter_; std::shared_ptr resource_manager_; + std::shared_ptr descriptor_pool_recycler_; std::shared_ptr command_pool_recycler_; std::string device_name_; std::shared_ptr raster_message_loop_; std::shared_ptr gpu_tracer_; - std::shared_ptr descriptor_pool_recycler_; std::shared_ptr command_queue_vk_; + + using DescriptorPoolMap = + std::unordered_map>; + + mutable DescriptorPoolMap cached_descriptor_pool_; bool should_disable_surface_control_ = false; bool should_batch_cmd_buffers_ = false; std::vector> pending_command_buffers_; diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc b/impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc index 2deb9b3453642..fea47418dcdac 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk_unittests.cc @@ -5,6 +5,7 @@ #include "flutter/testing/testing.h" // IWYU pragma: keep. #include "fml/closure.h" #include "fml/synchronization/waitable_event.h" +#include "impeller/renderer/backend/vulkan/command_buffer_vk.h" #include "impeller/renderer/backend/vulkan/descriptor_pool_vk.h" #include "impeller/renderer/backend/vulkan/resource_manager_vk.h" #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h" @@ -123,5 +124,27 @@ TEST(DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded) { context->Shutdown(); } +TEST(DescriptorPoolRecyclerVKTest, MultipleCommandBuffersShareDescriptorPool) { + auto const context = MockVulkanContextBuilder().Build(); + + auto cmd_buffer_1 = context->CreateCommandBuffer(); + auto cmd_buffer_2 = context->CreateCommandBuffer(); + + CommandBufferVK& vk_1 = CommandBufferVK::Cast(*cmd_buffer_1); + CommandBufferVK& vk_2 = CommandBufferVK::Cast(*cmd_buffer_2); + + EXPECT_EQ(&vk_1.GetDescriptorPool(), &vk_2.GetDescriptorPool()); + + // Resetting resources creates a new pool. + context->DisposeThreadLocalCachedResources(); + + auto cmd_buffer_3 = context->CreateCommandBuffer(); + CommandBufferVK& vk_3 = CommandBufferVK::Cast(*cmd_buffer_3); + + EXPECT_NE(&vk_1.GetDescriptorPool(), &vk_3.GetDescriptorPool()); + + context->Shutdown(); +} + } // namespace testing } // namespace impeller diff --git a/impeller/renderer/backend/vulkan/surface_context_vk.cc b/impeller/renderer/backend/vulkan/surface_context_vk.cc index 64f369e3073f2..ca896f66aaba4 100644 --- a/impeller/renderer/backend/vulkan/surface_context_vk.cc +++ b/impeller/renderer/backend/vulkan/surface_context_vk.cc @@ -86,7 +86,7 @@ std::unique_ptr SurfaceContextVK::AcquireNextSurface() { impeller::PipelineLibraryVK::Cast(*pipeline_library) .DidAcquireSurfaceFrame(); } - parent_->GetCommandPoolRecycler()->Dispose(); + parent_->DisposeThreadLocalCachedResources(); parent_->GetResourceAllocator()->DebugTraceMemoryStatistics(); return surface; } diff --git a/impeller/renderer/backend/vulkan/test/mock_vulkan_unittests.cc b/impeller/renderer/backend/vulkan/test/mock_vulkan_unittests.cc index 2555994a8fd03..1688b12e49c46 100644 --- a/impeller/renderer/backend/vulkan/test/mock_vulkan_unittests.cc +++ b/impeller/renderer/backend/vulkan/test/mock_vulkan_unittests.cc @@ -4,6 +4,7 @@ #include "flutter/testing/testing.h" // IWYU pragma: keep #include "gtest/gtest.h" +#include "impeller/renderer/backend/vulkan/command_pool_vk.h" #include "impeller/renderer/backend/vulkan/test/mock_vulkan.h" #include "vulkan/vulkan_enums.hpp" diff --git a/impeller/renderer/backend/vulkan/tracked_objects_vk.cc b/impeller/renderer/backend/vulkan/tracked_objects_vk.cc index 47b8477309dcb..249d2483b01b9 100644 --- a/impeller/renderer/backend/vulkan/tracked_objects_vk.cc +++ b/impeller/renderer/backend/vulkan/tracked_objects_vk.cc @@ -4,6 +4,7 @@ #include "impeller/renderer/backend/vulkan/tracked_objects_vk.h" +#include "impeller/renderer/backend/vulkan/command_pool_vk.h" #include "impeller/renderer/backend/vulkan/gpu_tracer_vk.h" namespace impeller { @@ -11,8 +12,9 @@ namespace impeller { TrackedObjectsVK::TrackedObjectsVK( const std::weak_ptr& context, const std::shared_ptr& pool, + std::shared_ptr descriptor_pool, std::unique_ptr probe) - : desc_pool_(context), probe_(std::move(probe)) { + : desc_pool_(std::move(descriptor_pool)), probe_(std::move(probe)) { if (!pool) { return; } @@ -78,7 +80,7 @@ vk::CommandBuffer TrackedObjectsVK::GetCommandBuffer() const { } DescriptorPoolVK& TrackedObjectsVK::GetDescriptorPool() { - return desc_pool_; + return *desc_pool_; } GPUProbe& TrackedObjectsVK::GetGPUProbe() const { diff --git a/impeller/renderer/backend/vulkan/tracked_objects_vk.h b/impeller/renderer/backend/vulkan/tracked_objects_vk.h index b502eac1a2b20..8305f51160380 100644 --- a/impeller/renderer/backend/vulkan/tracked_objects_vk.h +++ b/impeller/renderer/backend/vulkan/tracked_objects_vk.h @@ -20,6 +20,7 @@ class TrackedObjectsVK { public: explicit TrackedObjectsVK(const std::weak_ptr& context, const std::shared_ptr& pool, + std::shared_ptr descriptor_pool, std::unique_ptr probe); ~TrackedObjectsVK(); @@ -43,7 +44,7 @@ class TrackedObjectsVK { GPUProbe& GetGPUProbe() const; private: - DescriptorPoolVK desc_pool_; + std::shared_ptr desc_pool_; // `shared_ptr` since command buffers have a link to the command pool. std::shared_ptr pool_; vk::UniqueCommandBuffer buffer_;