| Flutter Impeller |

context_vk.h
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 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CONTEXT_VK_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CONTEXT_VK_H_
7
8 #include <memory>
9
10 #include "flutter/fml/concurrent_message_loop.h"
11 #include "flutter/fml/mapping.h"
12 #include "flutter/fml/unique_fd.h"
13 #include "impeller/base/backend_cast.h"
14 #include "impeller/base/strings.h"
15 #include "impeller/core/formats.h"
16 #include "impeller/core/runtime_types.h"
17 #include "impeller/renderer/backend/vulkan/command_pool_vk.h"
18 #include "impeller/renderer/backend/vulkan/device_holder_vk.h"
19 #include "impeller/renderer/backend/vulkan/driver_info_vk.h"
20 #include "impeller/renderer/backend/vulkan/pipeline_library_vk.h"
21 #include "impeller/renderer/backend/vulkan/queue_vk.h"
22 #include "impeller/renderer/backend/vulkan/sampler_library_vk.h"
23 #include "impeller/renderer/backend/vulkan/shader_library_vk.h"
24 #include "impeller/renderer/backend/vulkan/workarounds_vk.h"
25 #include "impeller/renderer/capabilities.h"
26 #include "impeller/renderer/command_buffer.h"
27 #include "impeller/renderer/command_queue.h"
28 #include "impeller/renderer/context.h"
29
30 namespace impeller {
31
32 bool HasValidationLayers();
33
34 class CommandEncoderFactoryVK;
35 class CommandEncoderVK;
36 class CommandPoolRecyclerVK;
37 class DebugReportVK;
38 class FenceWaiterVK;
39 class ResourceManagerVK;
40 class SurfaceContextVK;
41 class GPUTracerVK;
42 class DescriptorPoolRecyclerVK;
43 class CommandQueueVK;
44 class DescriptorPoolVK;
45
46 class IdleWaiterVK : public IdleWaiter {
47 public:
48 explicit IdleWaiterVK(std::weak_ptr<DeviceHolderVK> device_holder)
49 : device_holder_(std::move(device_holder)) {}
50
51 void WaitIdle() const override {
52 std::shared_ptr<DeviceHolderVK> strong_device_holder_ =
53 device_holder_.lock();
54 if (strong_device_holder_ && strong_device_holder_->GetDevice()) {
55 [[maybe_unused]] auto result =
56 strong_device_holder_->GetDevice().waitIdle();
57 }
58 }
59
60 private:
61 std::weak_ptr<DeviceHolderVK> device_holder_;
62 };
63
64 class ContextVK final : public Context,
65 public BackendCast<ContextVK, Context>,
66 public std::enable_shared_from_this<ContextVK> {
67 public:
68 /// Embedder Stuff
69 struct EmbedderData {
70 VkInstance instance;
71 VkPhysicalDevice physical_device;
72 VkDevice device;
73 uint32_t queue_family_index;
74 VkQueue queue;
75 std::vector<std::string> instance_extensions;
76 std::vector<std::string> device_extensions;
77 };
78
79 struct Settings {
80 PFN_vkGetInstanceProcAddr proc_address_callback = nullptr;
81 std::vector<std::shared_ptr<fml::Mapping>> shader_libraries_data;
82 fml::UniqueFD cache_directory;
83 bool enable_validation = false;
84 bool enable_gpu_tracing = false;
85 bool enable_surface_control = false;
86 /// If validations are requested but cannot be enabled, log a fatal error.
87 bool fatal_missing_validations = false;
88
89 std::optional<EmbedderData> embedder_data;
90
91 Settings() = default;
92
93 Settings(Settings&&) = default;
94 };
95
96 /// Choose the number of worker threads the context_vk will create.
97 ///
98 /// Visible for testing.
99 static size_t ChooseThreadCountForWorkers(size_t hardware_concurrency);
100
101 static std::shared_ptr<ContextVK> Create(Settings settings);
102
103 uint64_t GetHash() const { return hash_; }
104
105 // |Context|
106 ~ContextVK() override;
107
108 // |Context|
109 BackendType GetBackendType() const override;
110
111 // |Context|
112 std::string DescribeGpuModel() const override;
113
114 // |Context|
115 bool IsValid() const override;
116
117 // |Context|
118 std::shared_ptr<Allocator> GetResourceAllocator() const override;
119
120 // |Context|
121 std::shared_ptr<ShaderLibrary> GetShaderLibrary() const override;
122
123 // |Context|
124 std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const override;
125
126 // |Context|
127 std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const override;
128
129 // |Context|
130 std::shared_ptr<CommandBuffer> CreateCommandBuffer() const override;
131
132 // |Context|
133 const std::shared_ptr<const Capabilities>& GetCapabilities() const override;
134
135 // |Context|
136 virtual bool SubmitOnscreen(
137 std::shared_ptr<CommandBuffer> cmd_buffer) override;
138
139 const std::shared_ptr<YUVConversionLibraryVK>& GetYUVConversionLibrary()
140 const;
141
142 // |Context|
143 void Shutdown() override;
144
145 const WorkaroundsVK& GetWorkarounds() const;
146
147 void SetOffscreenFormat(PixelFormat pixel_format);
148
149 template <typename T>
150 bool SetDebugName(T handle, std::string_view label) const {
151 return SetDebugName(GetDevice(), handle, label);
152 }
153
154 template <typename T>
155 bool SetDebugName(T handle,
156 std::string_view label,
157 std::string_view trailing) const {
158 if (!HasValidationLayers()) {
159 // No-op if validation layers are not enabled.
160 return true;
161 }
162 std::string combined = SPrintF("%s %s", label.data(), trailing.data());
163 return SetDebugName(GetDevice(), handle, combined);
164 }
165
166 template <typename T>
167 static bool SetDebugName(const vk::Device& device,
168 T handle,
169 std::string_view label) {
170 if (!HasValidationLayers()) {
171 // No-op if validation layers are not enabled.
172 return true;
173 }
174
175 auto c_handle = static_cast<typename T::CType>(handle);
176
177 vk::DebugUtilsObjectNameInfoEXT info;
178 info.objectType = T::objectType;
179 info.pObjectName = label.data();
180 info.objectHandle = reinterpret_cast<decltype(info.objectHandle)>(c_handle);
181
182 if (device.setDebugUtilsObjectNameEXT(info) != vk::Result::eSuccess) {
183 VALIDATION_LOG << "Unable to set debug name: " << label;
184 return false;
185 }
186
187 return true;
188 }
189
190 std::shared_ptr<DeviceHolderVK> GetDeviceHolder() const {
191 return device_holder_;
192 }
193
194 vk::Instance GetInstance() const;
195
196 const vk::Device& GetDevice() const;
197
198 const std::unique_ptr<DriverInfoVK>& GetDriverInfo() const;
199
200 const std::shared_ptr<fml::ConcurrentTaskRunner>
201 GetConcurrentWorkerTaskRunner() const;
202
203 std::shared_ptr<SurfaceContextVK> CreateSurfaceContext();
204
205 const std::shared_ptr<QueueVK>& GetGraphicsQueue() const;
206
207 vk::PhysicalDevice GetPhysicalDevice() const;
208
209 std::shared_ptr<FenceWaiterVK> GetFenceWaiter() const;
210
211 std::shared_ptr<ResourceManagerVK> GetResourceManager() const;
212
213 std::shared_ptr<CommandPoolRecyclerVK> GetCommandPoolRecycler() const;
214
215 std::shared_ptr<DescriptorPoolRecyclerVK> GetDescriptorPoolRecycler() const;
216
217 std::shared_ptr<CommandQueue> GetCommandQueue() const override;
218
219 std::shared_ptr<GPUTracerVK> GetGPUTracer() const;
220
221 void RecordFrameEndTime() const;
222
223 // |Context|
224 void InitializeCommonlyUsedShadersIfNeeded() const override;
225
226 // |Context|
227 void DisposeThreadLocalCachedResources() override;
228
229 /// @brief Whether the Android Surface control based swapchain should be
230 /// enabled
231 bool GetShouldEnableSurfaceControlSwapchain() const;
232
233 // | Context |
234 bool EnqueueCommandBuffer(
235 std::shared_ptr<CommandBuffer> command_buffer) override;
236
237 // | Context |
238 bool FlushCommandBuffers() override;
239
240 RuntimeStageBackend GetRuntimeStageBackend() const override;
241
242 std::shared_ptr<const IdleWaiter> GetIdleWaiter() const override {
243 return idle_waiter_vk_;
244 }
245
246 private:
247 struct DeviceHolderImpl : public DeviceHolderVK {
248 // |DeviceHolder|
249 const vk::Device& GetDevice() const override { return device.get(); }
250 // |DeviceHolder|
251 const vk::PhysicalDevice& GetPhysicalDevice() const override {
252 return physical_device;
253 }
254
255 ~DeviceHolderImpl() {
256 if (!owned) {
257 instance.release();
258 device.release();
259 }
260 }
261
262 vk::UniqueInstance instance;
263 vk::PhysicalDevice physical_device;
264 vk::UniqueDevice device;
265 bool owned = true;
266 };
267
268 std::shared_ptr<DeviceHolderImpl> device_holder_;
269 std::unique_ptr<DriverInfoVK> driver_info_;
270 std::unique_ptr<DebugReportVK> debug_report_;
271 std::shared_ptr<Allocator> allocator_;
272 std::shared_ptr<ShaderLibraryVK> shader_library_;
273 std::shared_ptr<SamplerLibraryVK> sampler_library_;
274 std::shared_ptr<PipelineLibraryVK> pipeline_library_;
275 std::shared_ptr<YUVConversionLibraryVK> yuv_conversion_library_;
276 QueuesVK queues_;
277 std::shared_ptr<const Capabilities> device_capabilities_;
278 std::shared_ptr<FenceWaiterVK> fence_waiter_;
279 std::shared_ptr<ResourceManagerVK> resource_manager_;
280 std::shared_ptr<DescriptorPoolRecyclerVK> descriptor_pool_recycler_;
281 std::shared_ptr<CommandPoolRecyclerVK> command_pool_recycler_;
282 std::string device_name_;
283 std::shared_ptr<fml::ConcurrentMessageLoop> raster_message_loop_;
284 std::shared_ptr<GPUTracerVK> gpu_tracer_;
285 std::shared_ptr<CommandQueue> command_queue_vk_;
286 std::shared_ptr<const IdleWaiter> idle_waiter_vk_;
287 WorkaroundsVK workarounds_;
288
289 using DescriptorPoolMap =
290 std::unordered_map<std::thread::id, std::shared_ptr<DescriptorPoolVK>>;
291
292 mutable Mutex desc_pool_mutex_;
293 mutable DescriptorPoolMap IPLR_GUARDED_BY(desc_pool_mutex_)
294 cached_descriptor_pool_;
295 bool should_enable_surface_control_ = false;
296 bool should_batch_cmd_buffers_ = false;
297 std::vector<std::shared_ptr<CommandBuffer>> pending_command_buffers_;
298
299 const uint64_t hash_;
300
301 bool is_valid_ = false;
302
303 ContextVK();
304
305 void Setup(Settings settings);
306
307 ContextVK(const ContextVK&) = delete;
308
309 ContextVK& operator=(const ContextVK&) = delete;
310 };
311
312 } // namespace impeller
313
314 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CONTEXT_VK_H_
impeller::ContextVK::GetCapabilities
const std::shared_ptr< const Capabilities > & GetCapabilities() const override
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
Definition: context_vk.cc:612
impeller::DeviceHolderVK
Holds a strong reference to the underlying logical Vulkan device. This comes in handy when the contex...
Definition: device_holder_vk.h:18
impeller::ContextVK::GetConcurrentWorkerTaskRunner
const std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner() const
Definition: context_vk.cc:592
impeller::ContextVK::EmbedderData::instance_extensions
std::vector< std::string > instance_extensions
Definition: context_vk.h:75
impeller::ContextVK::Settings::enable_gpu_tracing
bool enable_gpu_tracing
Definition: context_vk.h:84
impeller::ContextVK::GetDeviceHolder
std::shared_ptr< DeviceHolderVK > GetDeviceHolder() const
Definition: context_vk.h:190
impeller::ContextVK::GetRuntimeStageBackend
RuntimeStageBackend GetRuntimeStageBackend() const override
Retrieve the runtime stage for this context type.
Definition: context_vk.cc:737
impeller::ContextVK::SetDebugName
static bool SetDebugName(const vk::Device &device, T handle, std::string_view label)
Definition: context_vk.h:167
impeller::ContextVK::GetCommandQueue
std::shared_ptr< CommandQueue > GetCommandQueue() const override
Return the graphics queue for submitting command buffers.
Definition: context_vk.cc:646
impeller::ContextVK::EmbedderData::instance
VkInstance instance
Definition: context_vk.h:70
impeller::Context::BackendType
BackendType
Definition: context.h:48
impeller::ContextVK::EmbedderData::device
VkDevice device
Definition: context_vk.h:72
impeller::ContextVK::IsValid
bool IsValid() const override
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
Definition: context_vk.cc:513
impeller::ContextVK::GetInstance
vk::Instance GetInstance() const
Definition: context_vk.cc:583
impeller::ContextVK::Settings::enable_validation
bool enable_validation
Definition: context_vk.h:83
impeller::ContextVK::GetPhysicalDevice
vk::PhysicalDevice GetPhysicalDevice() const
Definition: context_vk.cc:620
impeller::IdleWaiter
Definition: idle_waiter.h:14
impeller::ContextVK::GetResourceAllocator
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
Definition: context_vk.cc:517
impeller::ContextVK::GetBackendType
BackendType GetBackendType() const override
Get the graphics backend of an Impeller context.
Definition: context_vk.cc:139
command_queue.h
impeller::ContextVK::CreateCommandBuffer
std::shared_ptr< CommandBuffer > CreateCommandBuffer() const override
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
Definition: context_vk.cc:533
formats.h
impeller::ContextVK::GetHash
uint64_t GetHash() const
Definition: context_vk.h:103
impeller::ContextVK::RecordFrameEndTime
void RecordFrameEndTime() const
impeller::ContextVK::FlushCommandBuffers
bool FlushCommandBuffers() override
Flush all pending command buffers.
Definition: context_vk.cc:660
impeller::ContextVK::GetWorkarounds
const WorkaroundsVK & GetWorkarounds() const
Definition: context_vk.cc:745
impeller::ContextVK::GetIdleWaiter
std::shared_ptr< const IdleWaiter > GetIdleWaiter() const override
Definition: context_vk.h:242
runtime_types.h
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
device_holder_vk.h
command_pool_vk.h
pipeline_library_vk.h
impeller::ContextVK::Settings
Definition: context_vk.h:79
impeller::ContextVK::EmbedderData::device_extensions
std::vector< std::string > device_extensions
Definition: context_vk.h:76
impeller::ContextVK::Settings::fatal_missing_validations
bool fatal_missing_validations
If validations are requested but cannot be enabled, log a fatal error.
Definition: context_vk.h:87
impeller::ContextVK::CreateSurfaceContext
std::shared_ptr< SurfaceContextVK > CreateSurfaceContext()
Definition: context_vk.cc:608
workarounds_vk.h
impeller::ContextVK::GetShouldEnableSurfaceControlSwapchain
bool GetShouldEnableSurfaceControlSwapchain() const
Whether the Android Surface control based swapchain should be enabled.
Definition: context_vk.cc:733
impeller::ContextVK::GetShaderLibrary
std::shared_ptr< ShaderLibrary > GetShaderLibrary() const override
Returns the library of shaders used to specify the programmable stages of a pipeline.
Definition: context_vk.cc:521
impeller::ContextVK::Settings::enable_surface_control
bool enable_surface_control
Definition: context_vk.h:85
impeller::RuntimeStageBackend
RuntimeStageBackend
Definition: runtime_types.h:16
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::ContextVK::Settings::proc_address_callback
PFN_vkGetInstanceProcAddr proc_address_callback
Definition: context_vk.h:80
impeller::ContextVK::GetGraphicsQueue
const std::shared_ptr< QueueVK > & GetGraphicsQueue() const
Definition: context_vk.cc:616
impeller::ContextVK::GetDescriptorPoolRecycler
std::shared_ptr< DescriptorPoolRecyclerVK > GetDescriptorPoolRecycler() const
Definition: context_vk.cc:641
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label, std::string_view trailing) const
Definition: context_vk.h:155
backend_cast.h
impeller::ContextVK::Settings::shader_libraries_data
std::vector< std::shared_ptr< fml::Mapping > > shader_libraries_data
Definition: context_vk.h:81
queue_vk.h
impeller::IdleWaiterVK::WaitIdle
void WaitIdle() const override
Definition: context_vk.h:51
capabilities.h
impeller::ContextVK::Create
static std::shared_ptr< ContextVK > Create(Settings settings)
Definition: context_vk.cc:105
impeller::ContextVK::Settings::Settings
Settings()=default
driver_info_vk.h
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:150
strings.h
impeller::ContextVK::GetCommandPoolRecycler
std::shared_ptr< CommandPoolRecyclerVK > GetCommandPoolRecycler() const
Definition: context_vk.cc:632
impeller::ContextVK::GetGPUTracer
std::shared_ptr< GPUTracerVK > GetGPUTracer() const
Definition: context_vk.cc:637
shader_library_vk.h
impeller::ContextVK
Definition: context_vk.h:64
impeller::WorkaroundsVK
A non-exhaustive set of driver specific workarounds.
Definition: workarounds_vk.h:13
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
command_buffer.h
impeller::ContextVK::InitializeCommonlyUsedShadersIfNeeded
void InitializeCommonlyUsedShadersIfNeeded() const override
Definition: context_vk.cc:677
impeller::ContextVK::~ContextVK
~ContextVK() override
Definition: context_vk.cc:132
impeller::ContextVK::Settings::cache_directory
fml::UniqueFD cache_directory
Definition: context_vk.h:82
impeller::ContextVK::GetSamplerLibrary
std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const override
Returns the library of combined image samplers used in shaders.
Definition: context_vk.cc:525
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
std
Definition: comparable.h:95
impeller::ContextVK::GetDevice
const vk::Device & GetDevice() const
Definition: context_vk.cc:587
impeller::BackendCast
Definition: backend_cast.h:11
impeller::ContextVK::ChooseThreadCountForWorkers
static size_t ChooseThreadCountForWorkers(size_t hardware_concurrency)
Definition: context_vk.cc:115
impeller::ContextVK::EmbedderData
Embedder Stuff.
Definition: context_vk.h:69
impeller::ContextVK::GetResourceManager
std::shared_ptr< ResourceManagerVK > GetResourceManager() const
Definition: context_vk.cc:628
impeller::ContextVK::GetDriverInfo
const std::unique_ptr< DriverInfoVK > & GetDriverInfo() const
Definition: context_vk.cc:729
impeller::ContextVK::SubmitOnscreen
virtual bool SubmitOnscreen(std::shared_ptr< CommandBuffer > cmd_buffer) override
Submit the command buffer that renders to the onscreen surface.
Definition: context_vk.cc:741
impeller::ContextVK::EmbedderData::queue_family_index
uint32_t queue_family_index
Definition: context_vk.h:73
context.h
impeller::ContextVK::GetYUVConversionLibrary
const std::shared_ptr< YUVConversionLibraryVK > & GetYUVConversionLibrary() const
Definition: context_vk.cc:725
impeller::ContextVK::EmbedderData::physical_device
VkPhysicalDevice physical_device
Definition: context_vk.h:71
impeller::ContextVK::GetPipelineLibrary
std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const override
Returns the library of pipelines used by render or compute commands.
Definition: context_vk.cc:529
impeller::ContextVK::DescribeGpuModel
std::string DescribeGpuModel() const override
Definition: context_vk.cc:509
impeller::ContextVK::GetFenceWaiter
std::shared_ptr< FenceWaiterVK > GetFenceWaiter() const
Definition: context_vk.cc:624
impeller::IdleWaiterVK
Definition: context_vk.h:46
impeller::ContextVK::SetOffscreenFormat
void SetOffscreenFormat(PixelFormat pixel_format)
Definition: context_vk.cc:504
impeller::ContextVK::EnqueueCommandBuffer
bool EnqueueCommandBuffer(std::shared_ptr< CommandBuffer > command_buffer) override
Enqueue command_buffer for submission by the end of the frame.
Definition: context_vk.cc:650
sampler_library_vk.h
impeller::HasValidationLayers
bool HasValidationLayers()
Definition: context_vk.cc:53
impeller::ContextVK::Shutdown
void Shutdown() override
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
Definition: context_vk.cc:596
impeller
Definition: allocation.cc:12
impeller::IdleWaiterVK::IdleWaiterVK
IdleWaiterVK(std::weak_ptr< DeviceHolderVK > device_holder)
Definition: context_vk.h:48
impeller::ContextVK::EmbedderData::queue
VkQueue queue
Definition: context_vk.h:74
impeller::ContextVK::Settings::embedder_data
std::optional< EmbedderData > embedder_data
Definition: context_vk.h:89
impeller::ContextVK::DisposeThreadLocalCachedResources
void DisposeThreadLocalCachedResources() override
Definition: context_vk.cc:716