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