Flutter Engine
 
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
242
243 std::shared_ptr<const IdleWaiter> GetIdleWaiter() const override {
244 return idle_waiter_vk_;
245 }
246
247 private:
248 struct DeviceHolderImpl : public DeviceHolderVK {
249 // |DeviceHolder|
250 const vk::Device& GetDevice() const override { return device.get(); }
251 // |DeviceHolder|
252 const vk::PhysicalDevice& GetPhysicalDevice() const override {
253 return physical_device;
254 }
255
256 ~DeviceHolderImpl() {
257 if (!owned) {
258 instance.release();
259 device.release();
260 }
261 }
262
263 vk::UniqueInstance instance;
264 vk::PhysicalDevice physical_device;
265 vk::UniqueDevice device;
266 bool owned = true;
267 };
268
269 std::shared_ptr<DeviceHolderImpl> device_holder_;
270 std::unique_ptr<DriverInfoVK> driver_info_;
271 std::unique_ptr<DebugReportVK> debug_report_;
272 std::shared_ptr<Allocator> allocator_;
273 std::shared_ptr<ShaderLibraryVK> shader_library_;
274 std::shared_ptr<SamplerLibraryVK> sampler_library_;
275 std::shared_ptr<PipelineLibraryVK> pipeline_library_;
276 std::shared_ptr<YUVConversionLibraryVK> yuv_conversion_library_;
277 QueuesVK queues_;
278 std::shared_ptr<const Capabilities> device_capabilities_;
279 std::shared_ptr<FenceWaiterVK> fence_waiter_;
280 std::shared_ptr<ResourceManagerVK> resource_manager_;
281 std::shared_ptr<DescriptorPoolRecyclerVK> descriptor_pool_recycler_;
282 std::shared_ptr<CommandPoolRecyclerVK> command_pool_recycler_;
283 std::string device_name_;
284 std::shared_ptr<fml::ConcurrentMessageLoop> raster_message_loop_;
285 std::shared_ptr<GPUTracerVK> gpu_tracer_;
286 std::shared_ptr<CommandQueue> command_queue_vk_;
287 std::shared_ptr<const IdleWaiter> idle_waiter_vk_;
288 WorkaroundsVK workarounds_;
289
290 using DescriptorPoolMap =
291 std::unordered_map<std::thread::id, std::shared_ptr<DescriptorPoolVK>>;
292
293 mutable Mutex desc_pool_mutex_;
294 mutable DescriptorPoolMap IPLR_GUARDED_BY(desc_pool_mutex_)
295 cached_descriptor_pool_;
296 bool should_enable_surface_control_ = false;
297 bool should_batch_cmd_buffers_ = false;
298 std::vector<std::shared_ptr<CommandBuffer>> pending_command_buffers_;
299
300 const uint64_t hash_;
301
302 bool is_valid_ = false;
303
304 explicit ContextVK(const Flags& flags);
305
306 void Setup(Settings settings);
307
308 ContextVK(const ContextVK&) = delete;
309
310 ContextVK& operator=(const ContextVK&) = delete;
311};
312
313} // namespace impeller
314
315#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CONTEXT_VK_H_
To do anything rendering related with Impeller, you need a context.
Definition context.h:65
void SetOffscreenFormat(PixelFormat pixel_format)
std::shared_ptr< const IdleWaiter > GetIdleWaiter() const override
Definition context_vk.h:243
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...
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