| Flutter Impeller |

context_mtl.mm
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 #include "impeller/renderer/backend/metal/context_mtl.h"
6 #include <Metal/Metal.h>
7
8 #include <memory>
9
10 #include "flutter/fml/concurrent_message_loop.h"
11 #include "flutter/fml/file.h"
12 #include "flutter/fml/logging.h"
13 #include "flutter/fml/paths.h"
14 #include "flutter/fml/synchronization/sync_switch.h"
15 #include "impeller/core/formats.h"
16 #include "impeller/core/runtime_types.h"
17 #include "impeller/core/sampler_descriptor.h"
18 #include "impeller/renderer/backend/metal/gpu_tracer_mtl.h"
19 #include "impeller/renderer/backend/metal/sampler_library_mtl.h"
20 #include "impeller/renderer/capabilities.h"
21
22 namespace impeller {
23
24 static bool DeviceSupportsFramebufferFetch(id<MTLDevice> device) {
25 #if FML_OS_IOS_SIMULATOR
26 // The iOS simulator lies about supporting framebuffer fetch.
27 return false;
28 #else // FML_OS_IOS_SIMULATOR
29 // According to
30 // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf, Apple2
31 // corresponds to iOS GPU family 2, which supports A8 devices.
32 return [device supportsFamily:MTLGPUFamilyApple2];
33 #endif // FML_OS_IOS_SIMULATOR
34 }
35
36 static bool DeviceSupportsComputeSubgroups(id<MTLDevice> device) {
37 // Refer to the "SIMD-scoped reduction operations" feature in the table
38 // below: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
39 return [device supportsFamily:MTLGPUFamilyApple7] ||
40 [device supportsFamily:MTLGPUFamilyMac2];
41 }
42
43 // See "Extended Range and wide color pixel formats" in the metal feature set
44 // tables.
45 static bool DeviceSupportsExtendedRangeFormats(id<MTLDevice> device) {
46 return [device supportsFamily:MTLGPUFamilyApple3];
47 }
48
49 static std::unique_ptr<Capabilities> InferMetalCapabilities(
50 id<MTLDevice> device,
51 PixelFormat color_format) {
52 return CapabilitiesBuilder()
53 .SetSupportsOffscreenMSAA(true)
54 .SetSupportsSSBO(true)
55 .SetSupportsTextureToTextureBlits(true)
56 .SetSupportsDecalSamplerAddressMode(true)
57 .SetSupportsFramebufferFetch(DeviceSupportsFramebufferFetch(device))
58 .SetDefaultColorFormat(color_format)
59 .SetDefaultStencilFormat(PixelFormat::kS8UInt)
60 .SetDefaultDepthStencilFormat(PixelFormat::kD32FloatS8UInt)
61 .SetSupportsCompute(true)
62 .SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device))
63 .SetSupportsReadFromResolve(true)
64 .SetSupportsDeviceTransientTextures(true)
65 .SetDefaultGlyphAtlasFormat(PixelFormat::kA8UNormInt)
66 .SetSupportsTriangleFan(false)
67 .SetMaximumRenderPassAttachmentSize(DeviceMaxTextureSizeSupported(device))
68 .SetSupportsExtendedRangeFormats(
69 DeviceSupportsExtendedRangeFormats(device))
70 #if FML_OS_IOS && !TARGET_OS_SIMULATOR
71 .SetMinimumUniformAlignment(16)
72 #else
73 .SetMinimumUniformAlignment(256)
74 #endif // FML_OS_IOS && !TARGET_OS_SIMULATOR
75 .Build();
76 }
77
78 ContextMTL::ContextMTL(
79 const Flags& flags,
80 id<MTLDevice> device,
81 id<MTLCommandQueue> command_queue,
82 NSArray<id<MTLLibrary>>* shader_libraries,
83 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
84 std::optional<PixelFormat> pixel_format_override)
85 : Context(flags),
86 device_(device),
87 command_queue_(command_queue),
88 is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)) {
89 // Validate device.
90 if (!device_) {
91 VALIDATION_LOG << "Could not set up valid Metal device.";
92 return;
93 }
94
95 sync_switch_observer_.reset(new SyncSwitchObserver(*this));
96 is_gpu_disabled_sync_switch_->AddObserver(sync_switch_observer_.get());
97
98 // Setup the shader library.
99 {
100 if (shader_libraries == nil) {
101 VALIDATION_LOG << "Shader libraries were null.";
102 return;
103 }
104
105 // std::make_shared disallowed because of private friend ctor.
106 auto library = std::shared_ptr<ShaderLibraryMTL>(
107 new ShaderLibraryMTL(shader_libraries));
108 if (!library->IsValid()) {
109 VALIDATION_LOG << "Could not create valid Metal shader library.";
110 return;
111 }
112 shader_library_ = std::move(library);
113 }
114
115 // Setup the pipeline library.
116 {
117 pipeline_library_ =
118 std::shared_ptr<PipelineLibraryMTL>(new PipelineLibraryMTL(device_));
119 }
120
121 // Setup the sampler library.
122 {
123 sampler_library_ =
124 std::shared_ptr<SamplerLibraryMTL>(new SamplerLibraryMTL(device_));
125 }
126
127 // Setup the resource allocator.
128 {
129 resource_allocator_ = std::shared_ptr<AllocatorMTL>(
130 new AllocatorMTL(device_, "Impeller Permanents Allocator"));
131 if (!resource_allocator_) {
132 VALIDATION_LOG << "Could not set up the resource allocator.";
133 return;
134 }
135 }
136
137 device_capabilities_ =
138 InferMetalCapabilities(device_, pixel_format_override.has_value()
139 ? pixel_format_override.value()
140 : PixelFormat::kB8G8R8A8UNormInt);
141 command_queue_ip_ = std::make_shared<CommandQueue>();
142 #ifdef IMPELLER_DEBUG
143 gpu_tracer_ = std::make_shared<GPUTracerMTL>();
144 capture_manager_ = std::make_shared<ImpellerMetalCaptureManager>(device_);
145 #endif // IMPELLER_DEBUG
146 is_valid_ = true;
147 }
148
149 static NSArray<id<MTLLibrary>>* MTLShaderLibraryFromFilePaths(
150 id<MTLDevice> device,
151 const std::vector<std::string>& libraries_paths) {
152 NSMutableArray<id<MTLLibrary>>* found_libraries = [NSMutableArray array];
153 for (const auto& library_path : libraries_paths) {
154 if (!fml::IsFile(library_path)) {
155 VALIDATION_LOG << "Shader library does not exist at path '"
156 << library_path << "'";
157 return nil;
158 }
159 NSError* shader_library_error = nil;
160 auto library = [device newLibraryWithFile:@(library_path.c_str())
161 error:&shader_library_error];
162 if (!library) {
163 FML_LOG(ERROR) << "Could not create shader library: "
164 << shader_library_error.localizedDescription.UTF8String;
165 return nil;
166 }
167 [found_libraries addObject:library];
168 }
169 return found_libraries;
170 }
171
172 static NSArray<id<MTLLibrary>>* MTLShaderLibraryFromFileData(
173 id<MTLDevice> device,
174 const std::vector<std::shared_ptr<fml::Mapping>>& libraries_data,
175 const std::string& label) {
176 NSMutableArray<id<MTLLibrary>>* found_libraries = [NSMutableArray array];
177 for (const auto& library_data : libraries_data) {
178 if (library_data == nullptr) {
179 FML_LOG(ERROR) << "Shader library data was null.";
180 return nil;
181 }
182
183 __block auto data = library_data;
184
185 auto dispatch_data =
186 ::dispatch_data_create(library_data->GetMapping(), // buffer
187 library_data->GetSize(), // size
188 dispatch_get_main_queue(), // queue
189 ^() {
190 // We just need a reference.
191 data.reset();
192 } // destructor
193 );
194 if (!dispatch_data) {
195 FML_LOG(ERROR) << "Could not wrap shader data in dispatch data.";
196 return nil;
197 }
198
199 NSError* shader_library_error = nil;
200 auto library = [device newLibraryWithData:dispatch_data
201 error:&shader_library_error];
202 if (!library) {
203 FML_LOG(ERROR) << "Could not create shader library: "
204 << shader_library_error.localizedDescription.UTF8String;
205 return nil;
206 }
207 if (!label.empty()) {
208 library.label = @(label.c_str());
209 }
210 [found_libraries addObject:library];
211 }
212 return found_libraries;
213 }
214
215 static id<MTLDevice> CreateMetalDevice() {
216 return ::MTLCreateSystemDefaultDevice();
217 }
218
219 static id<MTLCommandQueue> CreateMetalCommandQueue(id<MTLDevice> device) {
220 auto command_queue = device.newCommandQueue;
221 if (!command_queue) {
222 VALIDATION_LOG << "Could not set up the command queue.";
223 return nullptr;
224 }
225 command_queue.label = @"Impeller Command Queue";
226 return command_queue;
227 }
228
229 std::shared_ptr<ContextMTL> ContextMTL::Create(
230 const Flags& flags,
231 const std::vector<std::string>& shader_library_paths,
232 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch) {
233 auto device = CreateMetalDevice();
234 auto command_queue = CreateMetalCommandQueue(device);
235 if (!command_queue) {
236 return nullptr;
237 }
238 auto context = std::shared_ptr<ContextMTL>(new ContextMTL(
239 flags, device, command_queue,
240 MTLShaderLibraryFromFilePaths(device, shader_library_paths),
241 std::move(is_gpu_disabled_sync_switch)));
242 if (!context->IsValid()) {
243 FML_LOG(ERROR) << "Could not create Metal context.";
244 return nullptr;
245 }
246 return context;
247 }
248
249 std::shared_ptr<ContextMTL> ContextMTL::Create(
250 const Flags& flags,
251 const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
252 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
253 const std::string& library_label,
254 std::optional<PixelFormat> pixel_format_override) {
255 auto device = CreateMetalDevice();
256 auto command_queue = CreateMetalCommandQueue(device);
257 if (!command_queue) {
258 return nullptr;
259 }
260 auto context = std::shared_ptr<ContextMTL>(new ContextMTL(
261 flags, device, command_queue,
262 MTLShaderLibraryFromFileData(device, shader_libraries_data,
263 library_label),
264 std::move(is_gpu_disabled_sync_switch), pixel_format_override));
265 if (!context->IsValid()) {
266 FML_LOG(ERROR) << "Could not create Metal context.";
267 return nullptr;
268 }
269 return context;
270 }
271
272 std::shared_ptr<ContextMTL> ContextMTL::Create(
273 const Flags& flags,
274 id<MTLDevice> device,
275 id<MTLCommandQueue> command_queue,
276 const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
277 std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
278 const std::string& library_label) {
279 auto context = std::shared_ptr<ContextMTL>(
280 new ContextMTL(flags, device, command_queue,
281 MTLShaderLibraryFromFileData(device, shader_libraries_data,
282 library_label),
283 std::move(is_gpu_disabled_sync_switch)));
284 if (!context->IsValid()) {
285 FML_LOG(ERROR) << "Could not create Metal context.";
286 return nullptr;
287 }
288 return context;
289 }
290
291 ContextMTL::~ContextMTL() {
292 is_gpu_disabled_sync_switch_->RemoveObserver(sync_switch_observer_.get());
293 }
294
295 Context::BackendType ContextMTL::GetBackendType() const {
296 return Context::BackendType::kMetal;
297 }
298
299 // |Context|
300 std::string ContextMTL::DescribeGpuModel() const {
301 return std::string([[device_ name] UTF8String]);
302 }
303
304 // |Context|
305 bool ContextMTL::IsValid() const {
306 return is_valid_;
307 }
308
309 // |Context|
310 std::shared_ptr<ShaderLibrary> ContextMTL::GetShaderLibrary() const {
311 return shader_library_;
312 }
313
314 // |Context|
315 std::shared_ptr<PipelineLibrary> ContextMTL::GetPipelineLibrary() const {
316 return pipeline_library_;
317 }
318
319 // |Context|
320 std::shared_ptr<SamplerLibrary> ContextMTL::GetSamplerLibrary() const {
321 return sampler_library_;
322 }
323
324 // |Context|
325 std::shared_ptr<CommandBuffer> ContextMTL::CreateCommandBuffer() const {
326 return CreateCommandBufferInQueue(command_queue_);
327 }
328
329 // |Context|
330 void ContextMTL::Shutdown() {}
331
332 #ifdef IMPELLER_DEBUG
333 std::shared_ptr<GPUTracerMTL> ContextMTL::GetGPUTracer() const {
334 return gpu_tracer_;
335 }
336 #endif // IMPELLER_DEBUG
337
338 std::shared_ptr<const fml::SyncSwitch> ContextMTL::GetIsGpuDisabledSyncSwitch()
339 const {
340 return is_gpu_disabled_sync_switch_;
341 }
342
343 std::shared_ptr<CommandBuffer> ContextMTL::CreateCommandBufferInQueue(
344 id<MTLCommandQueue> queue) const {
345 if (!IsValid()) {
346 return nullptr;
347 }
348
349 auto buffer = std::shared_ptr<CommandBufferMTL>(
350 new CommandBufferMTL(weak_from_this(), device_, queue));
351 if (!buffer->IsValid()) {
352 return nullptr;
353 }
354 return buffer;
355 }
356
357 std::shared_ptr<Allocator> ContextMTL::GetResourceAllocator() const {
358 return resource_allocator_;
359 }
360
361 id<MTLDevice> ContextMTL::GetMTLDevice() const {
362 return device_;
363 }
364
365 const std::shared_ptr<const Capabilities>& ContextMTL::GetCapabilities() const {
366 return device_capabilities_;
367 }
368
369 void ContextMTL::SetCapabilities(
370 const std::shared_ptr<const Capabilities>& capabilities) {
371 device_capabilities_ = capabilities;
372 }
373
374 // |Context|
375 bool ContextMTL::UpdateOffscreenLayerPixelFormat(PixelFormat format) {
376 device_capabilities_ = InferMetalCapabilities(device_, format);
377 return true;
378 }
379
380 id<MTLCommandBuffer> ContextMTL::CreateMTLCommandBuffer(
381 const std::string& label) const {
382 auto buffer = [command_queue_ commandBuffer];
383 if (!label.empty()) {
384 [buffer setLabel:@(label.data())];
385 }
386 return buffer;
387 }
388
389 void ContextMTL::StoreTaskForGPU(const fml::closure& task,
390 const fml::closure& failure) {
391 std::vector<PendingTasks> failed_tasks;
392 {
393 Lock lock(tasks_awaiting_gpu_mutex_);
394 tasks_awaiting_gpu_.push_back(PendingTasks{task, failure});
395 int32_t failed_task_count =
396 tasks_awaiting_gpu_.size() - kMaxTasksAwaitingGPU;
397 if (failed_task_count > 0) {
398 failed_tasks.reserve(failed_task_count);
399 failed_tasks.insert(failed_tasks.end(),
400 std::make_move_iterator(tasks_awaiting_gpu_.begin()),
401 std::make_move_iterator(tasks_awaiting_gpu_.begin() +
402 failed_task_count));
403 tasks_awaiting_gpu_.erase(
404 tasks_awaiting_gpu_.begin(),
405 tasks_awaiting_gpu_.begin() + failed_task_count);
406 }
407 }
408 for (const PendingTasks& task : failed_tasks) {
409 if (task.failure) {
410 task.failure();
411 }
412 }
413 }
414
415 void ContextMTL::FlushTasksAwaitingGPU() {
416 std::deque<PendingTasks> tasks_awaiting_gpu;
417 {
418 Lock lock(tasks_awaiting_gpu_mutex_);
419 std::swap(tasks_awaiting_gpu, tasks_awaiting_gpu_);
420 }
421 std::vector<PendingTasks> tasks_to_queue;
422 for (const auto& task : tasks_awaiting_gpu) {
423 is_gpu_disabled_sync_switch_->Execute(fml::SyncSwitch::Handlers()
424 .SetIfFalse([&] { task.task(); })
425 .SetIfTrue([&] {
426 // Lost access to the GPU
427 // immediately after it was
428 // activated. This may happen if
429 // the app was quickly
430 // foregrounded/backgrounded
431 // from a push notification.
432 // Store the tasks on the
433 // context again.
434 tasks_to_queue.push_back(task);
435 }));
436 }
437 if (!tasks_to_queue.empty()) {
438 Lock lock(tasks_awaiting_gpu_mutex_);
439 tasks_awaiting_gpu_.insert(tasks_awaiting_gpu_.end(),
440 tasks_to_queue.begin(), tasks_to_queue.end());
441 }
442 }
443
444 ContextMTL::SyncSwitchObserver::SyncSwitchObserver(ContextMTL& parent)
445 : parent_(parent) {}
446
447 void ContextMTL::SyncSwitchObserver::OnSyncSwitchUpdate(bool new_is_disabled) {
448 if (!new_is_disabled) {
449 parent_.FlushTasksAwaitingGPU();
450 }
451 }
452
453 // |Context|
454 std::shared_ptr<CommandQueue> ContextMTL::GetCommandQueue() const {
455 return command_queue_ip_;
456 }
457
458 // |Context|
459 RuntimeStageBackend ContextMTL::GetRuntimeStageBackend() const {
460 return RuntimeStageBackend::kMetal;
461 }
462
463 #ifdef IMPELLER_DEBUG
464 const std::shared_ptr<ImpellerMetalCaptureManager>
465 ContextMTL::GetCaptureManager() const {
466 return capture_manager_;
467 }
468 #endif // IMPELLER_DEBUG
469
470 ImpellerMetalCaptureManager::ImpellerMetalCaptureManager(id<MTLDevice> device) {
471 current_capture_scope_ = [[MTLCaptureManager sharedCaptureManager]
472 newCaptureScopeWithDevice:device];
473 [current_capture_scope_ setLabel:@"Impeller Frame"];
474 }
475
476 bool ImpellerMetalCaptureManager::CaptureScopeActive() const {
477 return scope_active_;
478 }
479
480 void ImpellerMetalCaptureManager::StartCapture() {
481 if (scope_active_) {
482 return;
483 }
484 scope_active_ = true;
485 [current_capture_scope_ beginScope];
486 }
487
488 void ImpellerMetalCaptureManager::FinishCapture() {
489 FML_DCHECK(scope_active_);
490 [current_capture_scope_ endScope];
491 scope_active_ = false;
492 }
493
494 } // namespace impeller
capabilities.h
impeller::CapabilitiesBuilder
Definition: capabilities.h:144
impeller::CapabilitiesBuilder::SetDefaultColorFormat
CapabilitiesBuilder & SetDefaultColorFormat(PixelFormat value)
Definition: capabilities.cc:216
impeller::CapabilitiesBuilder::SetSupportsComputeSubgroups
CapabilitiesBuilder & SetSupportsComputeSubgroups(bool value)
Definition: capabilities.cc:210
impeller::CapabilitiesBuilder::SetMinimumUniformAlignment
CapabilitiesBuilder & SetMinimumUniformAlignment(size_t value)
Definition: capabilities.cc:275
impeller::CapabilitiesBuilder::SetSupportsTextureToTextureBlits
CapabilitiesBuilder & SetSupportsTextureToTextureBlits(bool value)
Definition: capabilities.cc:193
impeller::CapabilitiesBuilder::SetDefaultStencilFormat
CapabilitiesBuilder & SetDefaultStencilFormat(PixelFormat value)
Definition: capabilities.cc:222
impeller::CapabilitiesBuilder::SetSupportsDeviceTransientTextures
CapabilitiesBuilder & SetSupportsDeviceTransientTextures(bool value)
Definition: capabilities.cc:246
impeller::CapabilitiesBuilder::SetSupportsTriangleFan
CapabilitiesBuilder & SetSupportsTriangleFan(bool value)
Definition: capabilities.cc:258
impeller::CapabilitiesBuilder::SetSupportsFramebufferFetch
CapabilitiesBuilder & SetSupportsFramebufferFetch(bool value)
Definition: capabilities.cc:199
impeller::CapabilitiesBuilder::SetSupportsDecalSamplerAddressMode
CapabilitiesBuilder & SetSupportsDecalSamplerAddressMode(bool value)
Definition: capabilities.cc:240
impeller::CapabilitiesBuilder::SetSupportsOffscreenMSAA
CapabilitiesBuilder & SetSupportsOffscreenMSAA(bool value)
Definition: capabilities.cc:183
impeller::CapabilitiesBuilder::SetSupportsSSBO
CapabilitiesBuilder & SetSupportsSSBO(bool value)
Definition: capabilities.cc:188
impeller::CapabilitiesBuilder::SetMaximumRenderPassAttachmentSize
CapabilitiesBuilder & SetMaximumRenderPassAttachmentSize(ISize size)
Definition: capabilities.cc:263
impeller::CapabilitiesBuilder::SetSupportsExtendedRangeFormats
CapabilitiesBuilder & SetSupportsExtendedRangeFormats(bool value)
Definition: capabilities.cc:269
impeller::CapabilitiesBuilder::SetDefaultGlyphAtlasFormat
CapabilitiesBuilder & SetDefaultGlyphAtlasFormat(PixelFormat value)
Definition: capabilities.cc:252
impeller::CapabilitiesBuilder::SetSupportsCompute
CapabilitiesBuilder & SetSupportsCompute(bool value)
Definition: capabilities.cc:205
impeller::CapabilitiesBuilder::Build
std::unique_ptr< Capabilities > Build()
Definition: capabilities.cc:287
impeller::CapabilitiesBuilder::SetDefaultDepthStencilFormat
CapabilitiesBuilder & SetDefaultDepthStencilFormat(PixelFormat value)
Definition: capabilities.cc:228
impeller::CapabilitiesBuilder::SetSupportsReadFromResolve
CapabilitiesBuilder & SetSupportsReadFromResolve(bool value)
Definition: capabilities.cc:234
impeller::Context::BackendType
BackendType
Definition: context.h:67
impeller::ContextMTL
Definition: context_mtl.h:67
impeller::ContextMTL::GetCommandQueue
std::shared_ptr< CommandQueue > GetCommandQueue() const override
Return the graphics queue for submitting command buffers.
Definition: context_mtl.mm:454
impeller::ContextMTL::GetRuntimeStageBackend
RuntimeStageBackend GetRuntimeStageBackend() const override
Retrieve the runtime stage for this context type.
Definition: context_mtl.mm:459
impeller::ImpellerMetalCaptureManager::ImpellerMetalCaptureManager
ImpellerMetalCaptureManager(id< MTLDevice > device)
Construct a new capture manager from the provided Metal device.
Definition: context_mtl.mm:470
impeller::ImpellerMetalCaptureManager::FinishCapture
void FinishCapture()
End the current capture scope.
Definition: context_mtl.mm:488
impeller::ImpellerMetalCaptureManager::CaptureScopeActive
bool CaptureScopeActive() const
Definition: context_mtl.mm:476
impeller::ImpellerMetalCaptureManager::StartCapture
void StartCapture()
Begin a new capture scope, no-op if the scope has already started.
Definition: context_mtl.mm:480
impeller::Lock
Definition: thread.h:72
formats.h
gpu_tracer_mtl.h
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161
impeller
Definition: allocation.cc:12
impeller::DeviceSupportsExtendedRangeFormats
static bool DeviceSupportsExtendedRangeFormats(id< MTLDevice > device)
Definition: context_mtl.mm:45
impeller::RuntimeStageBackend
RuntimeStageBackend
Definition: runtime_types.h:16
impeller::RuntimeStageBackend::kMetal
@ kMetal
impeller::MTLShaderLibraryFromFileData
static NSArray< id< MTLLibrary > > * MTLShaderLibraryFromFileData(id< MTLDevice > device, const std::vector< std::shared_ptr< fml::Mapping >> &libraries_data, const std::string &label)
Definition: context_mtl.mm:172
impeller::CreateMetalDevice
static id< MTLDevice > CreateMetalDevice()
Definition: context_mtl.mm:215
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::DeviceMaxTextureSizeSupported
ISize DeviceMaxTextureSizeSupported(id< MTLDevice > device)
Definition: allocator_mtl.mm:25
impeller::CreateCommandBuffer
static id< MTLCommandBuffer > CreateCommandBuffer(id< MTLCommandQueue > queue)
Definition: command_buffer_mtl.mm:117
impeller::MTLShaderLibraryFromFilePaths
static NSArray< id< MTLLibrary > > * MTLShaderLibraryFromFilePaths(id< MTLDevice > device, const std::vector< std::string > &libraries_paths)
Definition: context_mtl.mm:149
impeller::CreateMetalCommandQueue
static id< MTLCommandQueue > CreateMetalCommandQueue(id< MTLDevice > device)
Definition: context_mtl.mm:219
impeller::InferMetalCapabilities
static std::unique_ptr< Capabilities > InferMetalCapabilities(id< MTLDevice > device, PixelFormat color_format)
Definition: context_mtl.mm:49
impeller::DeviceSupportsComputeSubgroups
static bool DeviceSupportsComputeSubgroups(id< MTLDevice > device)
Definition: context_mtl.mm:36
impeller::DeviceSupportsFramebufferFetch
static bool DeviceSupportsFramebufferFetch(id< MTLDevice > device)
Definition: context_mtl.mm:24
std
Definition: comparable.h:95
context_mtl.h
runtime_types.h
sampler_descriptor.h
sampler_library_mtl.h
impeller::Flags
Definition: flags.h:9
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91