Flutter Engine
The Flutter Engine
MtlCaps.mm
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
13#include "src/gpu/SwizzlePriv.h"
23#include "src/sksl/SkSLUtil.h"
24
25namespace skgpu::graphite {
26
27MtlCaps::MtlCaps(const id<MTLDevice> device, const ContextOptions& options)
28 : Caps() {
29 this->initGPUFamily(device);
30 this->initCaps(device);
31 this->initShaderCaps();
32
33 this->initFormatTable(device);
34
35 // Metal-specific MtlCaps
36
37 this->finishInitialization(options);
38}
39
40bool MtlCaps::GetGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group) {
41#if SKGPU_GRAPHITE_METAL_SDK_VERSION >= 220
42 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
43 // Apple Silicon
44#if SKGPU_GRAPHITE_METAL_SDK_VERSION >= 230
45 if ([device supportsFamily:MTLGPUFamilyApple7]) {
46 *gpuFamily = GPUFamily::kApple;
47 *group = 7;
48 return true;
49 }
50#endif
51#ifdef SK_BUILD_FOR_IOS
52 if ([device supportsFamily:MTLGPUFamilyApple6]) {
53 *gpuFamily = GPUFamily::kApple;
54 *group = 6;
55 return true;
56 }
57 if ([device supportsFamily:MTLGPUFamilyApple5]) {
58 *gpuFamily = GPUFamily::kApple;
59 *group = 5;
60 return true;
61 }
62 if ([device supportsFamily:MTLGPUFamilyApple4]) {
63 *gpuFamily = GPUFamily::kApple;
64 *group = 4;
65 return true;
66 }
67 if ([device supportsFamily:MTLGPUFamilyApple3]) {
68 *gpuFamily = GPUFamily::kApple;
69 *group = 3;
70 return true;
71 }
72 if ([device supportsFamily:MTLGPUFamilyApple2]) {
73 *gpuFamily = GPUFamily::kApple;
74 *group = 2;
75 return true;
76 }
77 if ([device supportsFamily:MTLGPUFamilyApple1]) {
78 *gpuFamily = GPUFamily::kApple;
79 *group = 1;
80 return true;
81 }
82#endif
83
84 // Older Macs
85#if SKGPU_GRAPHITE_METAL_SDK_VERSION >= 300
86 // TODO: replace with Metal 3 definitions
87 SkASSERT([device supportsFamily:MTLGPUFamilyMac2]);
88 *gpuFamily = GPUFamily::kMac;
89 *group = 2;
90 return true;
91#else
92 // At the moment MacCatalyst families have the same features as Mac,
93 // so we treat them the same
94 if ([device supportsFamily:MTLGPUFamilyMac2] ||
95 [device supportsFamily:MTLGPUFamilyMacCatalyst2]) {
96 *gpuFamily = GPUFamily::kMac;
97 *group = 2;
98 return true;
99 }
100 if ([device supportsFamily:MTLGPUFamilyMac1] ||
101 [device supportsFamily:MTLGPUFamilyMacCatalyst1]) {
102 *gpuFamily = GPUFamily::kMac;
103 *group = 1;
104 return true;
105 }
106#endif
107 }
108#endif
109
110 // No supported GPU families were found
111 return false;
112}
113
114void MtlCaps::initGPUFamily(id<MTLDevice> device) {
115 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
116 if (GetGPUFamily(device, &fGPUFamily, &fFamilyGroup)) {
117 return;
118 }
119 }
120
121 // We don't know what this is, fall back to minimum defaults
122#ifdef SK_BUILD_FOR_MAC
123 fGPUFamily = GPUFamily::kMac;
124 fFamilyGroup = 1;
125#else
126 fGPUFamily = GPUFamily::kApple;
127 fFamilyGroup = 1;
128#endif
129}
130
131void MtlCaps::initCaps(const id<MTLDevice> device) {
132#if defined(GRAPHITE_TEST_UTILS)
133 this->setDeviceName([[device name] UTF8String]);
134#endif
135
136 if (this->isMac() || fFamilyGroup >= 3) {
137 fMaxTextureSize = 16384;
138 } else {
139 fMaxTextureSize = 8192;
140 }
141
142 // We use constant address space for our uniform buffers which has various alignment
143 // requirements for the offset when binding the buffer. On MacOS Intel the offset must align
144 // to 256. On iOS or Apple Silicon we must align to the max of the data type consumed by the
145 // vertex function or 4 bytes, or we can ignore the data type and just use 16 bytes.
146 //
147 // On Mac, all copies must be aligned to at least 4 bytes; on iOS there is no alignment.
148 if (this->isMac()) {
151 } else {
154 }
155
159
160 // Metal does not distinguish between uniform and storage buffers.
162
165
166 fComputeSupport = true;
167
168 if (@available(macOS 10.12, iOS 14.0, tvOS 14.0, *)) {
169 fClampToBorderSupport = (this->isMac() || fFamilyGroup >= 7);
170 } else {
171 fClampToBorderSupport = false;
172 }
173
174 // Init sample counts. All devices support 1 (i.e. 0 in skia).
175 fColorSampleCounts.push_back(1);
176 if (![device.name containsString:@"Intel"]) {
177 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
178 for (auto sampleCnt : {2, 4, 8}) {
179 if ([device supportsTextureSampleCount:sampleCnt]) {
180 fColorSampleCounts.push_back(sampleCnt);
181 }
182 }
183 }
184 }
185}
186
187void MtlCaps::initShaderCaps() {
189
190 // Dual source blending requires Metal 1.2.
191 if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
193 }
194
195 // Setting this true with the assumption that this cap will eventually mean we support varying
196 // precisions and not just via modifiers.
199
202
203 if (@available(macOS 11.0, *)) {
204 if (this->isApple()) {
205 shaderCaps->fFBFetchSupport = true;
206 shaderCaps->fFBFetchColorName = "sk_LastFragColor";
207 }
208 }
209
213
214 // Metal uses IEEE floats so assuming those values here.
216
217 shaderCaps->fFloatBufferArrayName = "fsGradientBuffer";
218}
219
220// Define this so we can use it to initialize arrays and work around
221// the fact that these pixel formats are not always available.
222#define kMTLPixelFormatB5G6R5Unorm MTLPixelFormat(40)
223#define kMTLPixelFormatABGR4Unorm MTLPixelFormat(42)
224#define kMTLPixelFormatETC2_RGB8 MTLPixelFormat(180)
225
226// These are all the valid MTLPixelFormats that we currently support in Skia. They are roughly
227// ordered from most frequently used to least to improve look up times in arrays.
228static constexpr MTLPixelFormat kMtlFormats[] = {
229 MTLPixelFormatRGBA8Unorm,
230 MTLPixelFormatR8Unorm,
231 MTLPixelFormatA8Unorm,
232 MTLPixelFormatBGRA8Unorm,
234 MTLPixelFormatRGBA16Float,
235 MTLPixelFormatR16Float,
236 MTLPixelFormatRG8Unorm,
237 MTLPixelFormatRGB10A2Unorm,
238 // MTLPixelFormatBGR10A2Unorm
240 MTLPixelFormatRGBA8Unorm_sRGB,
241 MTLPixelFormatR16Unorm,
242 MTLPixelFormatRG16Unorm,
244#ifdef SK_BUILD_FOR_MAC
245 MTLPixelFormatBC1_RGBA,
246#endif
247 MTLPixelFormatRGBA16Unorm,
248 MTLPixelFormatRG16Float,
249
250 MTLPixelFormatStencil8,
251 MTLPixelFormatDepth16Unorm,
252 MTLPixelFormatDepth32Float,
253#ifdef SK_BUILD_FOR_MAC
254 MTLPixelFormatDepth24Unorm_Stencil8,
255#endif
256 MTLPixelFormatDepth32Float_Stencil8,
257
258 MTLPixelFormatInvalid,
259};
260
261void MtlCaps::setColorType(SkColorType colorType, std::initializer_list<MTLPixelFormat> formats) {
262 int idx = static_cast<int>(colorType);
263 for (auto it = formats.begin(); it != formats.end(); ++it) {
264 const auto& info = this->getFormatInfo(*it);
265 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
266 if (info.fColorTypeInfos[i].fColorType == colorType) {
267 fColorTypeToFormatTable[idx] = *it;
268 return;
269 }
270 }
271 }
272}
273
274size_t MtlCaps::GetFormatIndex(MTLPixelFormat pixelFormat) {
275 static_assert(std::size(kMtlFormats) == MtlCaps::kNumMtlFormats,
276 "Size of kMtlFormats array must match static value in header");
277 for (size_t i = 0; i < MtlCaps::kNumMtlFormats; ++i) {
278 if (kMtlFormats[i] == pixelFormat) {
279 return i;
280 }
281 }
282 return GetFormatIndex(MTLPixelFormatInvalid);
283}
284
285void MtlCaps::initFormatTable(const id<MTLDevice> device) {
286 FormatInfo* info;
287
288 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
289 if (this->isApple()) {
290 SkASSERT(kMTLPixelFormatB5G6R5Unorm == MTLPixelFormatB5G6R5Unorm);
291 SkASSERT(kMTLPixelFormatABGR4Unorm == MTLPixelFormatABGR4Unorm);
292 }
293 }
294
295 // Format: RGBA8Unorm
296 {
297 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm)];
298 info->fFlags = FormatInfo::kAllFlags;
299 info->fColorTypeInfoCount = 2;
300 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
301 int ctIdx = 0;
302 // Format: RGBA8Unorm, Surface: kRGBA_8888
303 {
304 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
305 ctInfo.fColorType = kRGBA_8888_SkColorType;
307 }
308 // Format: RGBA8Unorm, Surface: kRGB_888x
309 {
310 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
311 ctInfo.fColorType = kRGB_888x_SkColorType;
312 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
313 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
314 }
315 }
316
317 // Format: R8Unorm
318 {
319 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR8Unorm)];
320 info->fFlags = FormatInfo::kAllFlags;
321 info->fColorTypeInfoCount = 3;
322 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
323 int ctIdx = 0;
324 // Format: R8Unorm, Surface: kR8_unorm
325 {
326 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
327 ctInfo.fColorType = kR8_unorm_SkColorType;
329 }
330 // Format: R8Unorm, Surface: kAlpha_8
331 {
332 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
333 ctInfo.fColorType = kAlpha_8_SkColorType;
335 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
336 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
337 }
338 // Format: R8Unorm, Surface: kGray_8
339 {
340 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
341 ctInfo.fColorType = kGray_8_SkColorType;
342 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
343 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
344 }
345 }
346
347 // Format: A8Unorm
348 {
349 info = &fFormatTable[GetFormatIndex(MTLPixelFormatA8Unorm)];
350 info->fFlags = FormatInfo::kTexturable_Flag;
351 info->fColorTypeInfoCount = 1;
352 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
353 int ctIdx = 0;
354 // Format: A8Unorm, Surface: kAlpha_8
355 {
356 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
357 ctInfo.fColorType = kAlpha_8_SkColorType;
359 }
360 }
361
362 // Format: BGRA8Unorm
363 {
364 info = &fFormatTable[GetFormatIndex(MTLPixelFormatBGRA8Unorm)];
365 info->fFlags = FormatInfo::kAllFlags;
366 info->fColorTypeInfoCount = 1;
367 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
368 int ctIdx = 0;
369 // Format: BGRA8Unorm, Surface: kBGRA_8888
370 {
371 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
372 ctInfo.fColorType = kBGRA_8888_SkColorType;
374 }
375 }
376
377 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
378 if (this->isApple()) {
379 // Format: B5G6R5Unorm
380 {
381 info = &fFormatTable[GetFormatIndex(MTLPixelFormatB5G6R5Unorm)];
382 info->fFlags = FormatInfo::kAllFlags;
383 info->fColorTypeInfoCount = 1;
384 info->fColorTypeInfos =
385 std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
386 int ctIdx = 0;
387 // Format: B5G6R5Unorm, Surface: kBGR_565
388 {
389 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
390 ctInfo.fColorType = kRGB_565_SkColorType;
391 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
393 }
394 }
395
396 // Format: ABGR4Unorm
397 {
398 info = &fFormatTable[GetFormatIndex(MTLPixelFormatABGR4Unorm)];
399 info->fFlags = FormatInfo::kAllFlags;
400 info->fColorTypeInfoCount = 1;
401 info->fColorTypeInfos =
402 std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
403 int ctIdx = 0;
404 // Format: ABGR4Unorm, Surface: kABGR_4444
405 {
406 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
407 ctInfo.fColorType = kARGB_4444_SkColorType;
408 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
410 }
411 }
412 }
413 }
414
415 // Format: RGBA8Unorm_sRGB
416 {
417 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm_sRGB)];
418 info->fFlags = FormatInfo::kAllFlags;
419 info->fColorTypeInfoCount = 1;
420 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
421 int ctIdx = 0;
422 // Format: RGBA8Unorm_sRGB, Surface: kSRGBA_8888
423 {
424 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
425 ctInfo.fColorType = kSRGBA_8888_SkColorType;
427 }
428 }
429
430 // Format: RGB10A2Unorm
431 {
432 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGB10A2Unorm)];
433 if (this->isMac() || fFamilyGroup >= 3) {
434 info->fFlags = FormatInfo::kAllFlags;
435 } else {
436 info->fFlags = FormatInfo::kTexturable_Flag;
437 }
438 info->fColorTypeInfoCount = 1;
439 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
440 int ctIdx = 0;
441 // Format: RGB10A2Unorm, Surface: kRGBA_1010102
442 {
443 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
444 ctInfo.fColorType = kRGBA_1010102_SkColorType;
446 }
447 }
448
449 // Format: RGBA16Float
450 {
451 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Float)];
452 info->fFlags = FormatInfo::kAllFlags;
453 info->fColorTypeInfoCount = 2;
454 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
455 int ctIdx = 0;
456 // Format: RGBA16Float, Surface: RGBA_F16
457 {
458 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
459 ctInfo.fColorType = kRGBA_F16_SkColorType;
461 }
462 // Format: RGBA16Float, Surface: RGBA_F16Norm
463 {
464 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
465 ctInfo.fColorType = kRGBA_F16Norm_SkColorType;
467 }
468 }
469
470 // Format: R16Float
471 {
472 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Float)];
473 info->fFlags = FormatInfo::kAllFlags;
474 info->fColorTypeInfoCount = 1;
475 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
476 int ctIdx = 0;
477 // Format: R16Float, Surface: kA16_float
478 {
479 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
480 ctInfo.fColorType = kA16_float_SkColorType;
482 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
483 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
484 }
485 }
486
487 // Format: RG8Unorm
488 {
489 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG8Unorm)];
490 info->fFlags = FormatInfo::kAllFlags;
491 info->fColorTypeInfoCount = 1;
492 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
493 int ctIdx = 0;
494 // Format: RG8Unorm, Surface: kR8G8_unorm
495 {
496 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
497 ctInfo.fColorType = kR8G8_unorm_SkColorType;
499 }
500 }
501
502 // Format: RGBA16Unorm
503 {
504 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Unorm)];
505 if (this->isMac()) {
506 info->fFlags = FormatInfo::kAllFlags;
507 } else {
508 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
509 }
510 info->fColorTypeInfoCount = 1;
511 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
512 int ctIdx = 0;
513 // Format: RGBA16Unorm, Surface: kR16G16B16A16_unorm
514 {
515 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
516 ctInfo.fColorType = kR16G16B16A16_unorm_SkColorType;
518 }
519 }
520
521 // Format: RG16Float
522 {
523 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Float)];
524 info->fFlags = FormatInfo::kAllFlags;
525 info->fColorTypeInfoCount = 1;
526 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
527 int ctIdx = 0;
528 // Format: RG16Float, Surface: kR16G16_float
529 {
530 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
531 ctInfo.fColorType = kR16G16_float_SkColorType;
533 }
534 }
535
536 // Format: R16Unorm
537 {
538 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Unorm)];
539 if (this->isMac()) {
540 info->fFlags = FormatInfo::kAllFlags;
541 } else {
542 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
543 }
544 info->fColorTypeInfoCount = 1;
545 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
546 int ctIdx = 0;
547 // Format: R16Unorm, Surface: kA16_unorm
548 {
549 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
550 ctInfo.fColorType = kA16_unorm_SkColorType;
552 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
553 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
554 }
555 }
556
557 // Format: RG16Unorm
558 {
559 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Unorm)];
560 if (this->isMac()) {
561 info->fFlags = FormatInfo::kAllFlags;
562 } else {
563 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
564 }
565 info->fColorTypeInfoCount = 1;
566 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
567 int ctIdx = 0;
568 // Format: RG16Unorm, Surface: kR16G16_unorm
569 {
570 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
571 ctInfo.fColorType = kR16G16_unorm_SkColorType;
573 }
574 }
575
576 // Format: ETC2_RGB8
577 {
578 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
579 if (this->isApple()) {
580 info = &fFormatTable[GetFormatIndex(MTLPixelFormatETC2_RGB8)];
581 info->fFlags = FormatInfo::kTexturable_Flag;
582 info->fColorTypeInfoCount = 1;
583 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
584 int ctIdx = 0;
585 // Format: ETC2_RGB8, Surface: kRGB_888x
586 {
587 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
588 ctInfo.fColorType = kRGB_888x_SkColorType;
589 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
590 }
591 }
592 }
593 }
594
595 // Format: BC1_RGBA
596 {
597#ifdef SK_BUILD_FOR_MAC
598 if (this->isMac()) {
599 info = &fFormatTable[GetFormatIndex(MTLPixelFormatBC1_RGBA)];
600 info->fFlags = FormatInfo::kTexturable_Flag;
601 info->fColorTypeInfoCount = 1;
602 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
603 int ctIdx = 0;
604 // Format: BC1_RGBA, Surface: kRGBA_8888
605 {
606 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
607 ctInfo.fColorType = kRGBA_8888_SkColorType;
608 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
609 }
610 }
611#endif
612 }
613
614 /*
615 * Non-color formats
616 */
617
618 // Format: Stencil8
619 {
620 info = &fFormatTable[GetFormatIndex(MTLPixelFormatStencil8)];
621 info->fFlags = FormatInfo::kMSAA_Flag;
622 info->fColorTypeInfoCount = 0;
623 }
624
625 // Format: Depth16Unorm
626 {
627 info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth16Unorm)];
628 info->fFlags = FormatInfo::kMSAA_Flag;
629 if (this->isMac() || fFamilyGroup >= 3) {
630 info->fFlags |= FormatInfo::kResolve_Flag;
631 }
632 info->fColorTypeInfoCount = 0;
633 }
634
635 // Format: Depth32Float
636 {
637 info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth32Float)];
638 info->fFlags = FormatInfo::kMSAA_Flag;
639 if (this->isMac() || fFamilyGroup >= 3) {
640 info->fFlags |= FormatInfo::kResolve_Flag;
641 }
642 info->fColorTypeInfoCount = 0;
643 }
644
645 // Format: Depth24Unorm_Stencil8
646 {
647#ifdef SK_BUILD_FOR_MAC
648 if (this->isMac() && [device isDepth24Stencil8PixelFormatSupported]) {
649 info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth24Unorm_Stencil8)];
650 info->fFlags = FormatInfo::kMSAA_Flag | FormatInfo::kResolve_Flag;
651 info->fColorTypeInfoCount = 0;
652 }
653#endif
654 }
655
656 // Format: Depth32Float_Stencil8
657 {
658 info = &fFormatTable[GetFormatIndex(MTLPixelFormatDepth32Float_Stencil8)];
659 info->fFlags = FormatInfo::kMSAA_Flag;
660 if (this->isMac() || fFamilyGroup >= 3) {
661 info->fFlags |= FormatInfo::kResolve_Flag;
662 }
663 info->fColorTypeInfoCount = 0;
664 }
665
666 ////////////////////////////////////////////////////////////////////////////
667 // Map SkColorTypes (used for creating SkSurfaces) to MTLPixelFormats. The order in which the
668 // formats are passed into the setColorType function indicates the priority in selecting which
669 // format we use for a given SkColorType.
670
671 std::fill_n(fColorTypeToFormatTable, kSkColorTypeCnt, MTLPixelFormatInvalid);
672
673 this->setColorType(kAlpha_8_SkColorType, { MTLPixelFormatR8Unorm,
674 MTLPixelFormatA8Unorm });
675 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
676 if (this->isApple()) {
677 this->setColorType(kRGB_565_SkColorType, {MTLPixelFormatB5G6R5Unorm});
678 this->setColorType(kARGB_4444_SkColorType, { MTLPixelFormatABGR4Unorm });
679 }
680 }
681
682 this->setColorType(kRGBA_8888_SkColorType, { MTLPixelFormatRGBA8Unorm });
683 this->setColorType(kRGB_888x_SkColorType, { MTLPixelFormatRGBA8Unorm });
684 this->setColorType(kBGRA_8888_SkColorType, { MTLPixelFormatBGRA8Unorm });
685 this->setColorType(kRGBA_1010102_SkColorType, { MTLPixelFormatRGB10A2Unorm });
686 // kBGRA_1010102_SkColorType
687 // kRGB_101010x_SkColorType
688 // kBGR_101010x_SkColorType
689 // kBGR_101010x_XR_SkColorType
690 this->setColorType(kGray_8_SkColorType, { MTLPixelFormatR8Unorm });
691 this->setColorType(kRGBA_F16Norm_SkColorType, { MTLPixelFormatRGBA16Float });
692 this->setColorType(kRGBA_F16_SkColorType, { MTLPixelFormatRGBA16Float });
693 // kRGBA_F32_SkColorType
694 this->setColorType(kR8G8_unorm_SkColorType, { MTLPixelFormatRG8Unorm });
695 this->setColorType(kA16_float_SkColorType, { MTLPixelFormatR16Float });
696 this->setColorType(kR16G16_float_SkColorType, { MTLPixelFormatRG16Float });
697 this->setColorType(kA16_unorm_SkColorType, { MTLPixelFormatR16Unorm });
698 this->setColorType(kR16G16_unorm_SkColorType, { MTLPixelFormatRG16Unorm });
699 this->setColorType(kR16G16B16A16_unorm_SkColorType,{ MTLPixelFormatRGBA16Unorm });
700 this->setColorType(kSRGBA_8888_SkColorType, { MTLPixelFormatRGBA8Unorm_sRGB });
701 this->setColorType(kR8_unorm_SkColorType, { MTLPixelFormatR8Unorm });
702
703}
704
706 Mipmapped mipmapped,
707 Protected,
708 Renderable renderable) const {
709 MTLTextureUsage usage = MTLTextureUsageShaderRead;
710 if (renderable == Renderable::kYes) {
711 usage |= MTLTextureUsageRenderTarget;
712 }
713
714 MtlPixelFormat format = this->getFormatFromColorType(colorType);
715 if (format == MTLPixelFormatInvalid) {
716 return {};
717 }
718
720 info.fSampleCount = 1;
721 info.fMipmapped = mipmapped;
722 info.fFormat = format;
723 info.fUsage = usage;
724 info.fStorageMode = MTLStorageModePrivate;
725 info.fFramebufferOnly = false;
726
727 return info;
728}
729
731 Mipmapped mipmapped) const {
733 if (!textureInfo.getMtlTextureInfo(&info)) {
734 return {};
735 }
736
737 info.fSampleCount = 1;
738 info.fMipmapped = mipmapped;
739 info.fUsage = MTLTextureUsageShaderRead;
740 info.fStorageMode = MTLStorageModePrivate;
741 info.fFramebufferOnly = false;
742
743 return info;
744}
745
746namespace {
747MTLPixelFormat format_from_compression(SkTextureCompressionType compression) {
748 switch (compression) {
752#ifdef SK_BUILD_FOR_MAC
753 return MTLPixelFormatBC1_RGBA;
754#endif
755 default:
756 return MTLPixelFormatInvalid;
757 }
758}
759}
760
762 Mipmapped mipmapped,
763 Protected) const {
764 MTLTextureUsage usage = MTLTextureUsageShaderRead;
765
766 MtlPixelFormat format = format_from_compression(compression);
767 if (format == MTLPixelFormatInvalid) {
768 return {};
769 }
770
772 info.fSampleCount = 1;
773 info.fMipmapped = mipmapped;
774 info.fFormat = format;
775 info.fUsage = usage;
776 info.fStorageMode = MTLStorageModePrivate;
777 info.fFramebufferOnly = false;
778
779 return info;
780}
781
782MTLStorageMode MtlCaps::getDefaultMSAAStorageMode(Discardable discardable) const {
783 // Try to use memoryless if it's available (only on new Apple silicon)
784 if (discardable == Discardable::kYes && this->isApple()) {
785 if (@available(macOS 11.0, iOS 10.0, tvOS 10.0, *)) {
786 return MTLStorageModeMemoryless;
787 }
788 }
789 // If it's not discardable or not available, private is the best option
790 return MTLStorageModePrivate;
791}
792
794 Discardable discardable) const {
795 if (fDefaultMSAASamples <= 1) {
796 return {};
797 }
798 const MtlTextureSpec& singleSpec = singleSampledInfo.mtlTextureSpec();
799 if (!this->isRenderable((MTLPixelFormat)singleSpec.fFormat, fDefaultMSAASamples)) {
800 return {};
801 }
802
803 MTLTextureUsage usage = MTLTextureUsageRenderTarget;
804
806 info.fSampleCount = fDefaultMSAASamples;
807 info.fMipmapped = Mipmapped::kNo;
808 info.fFormat = singleSpec.fFormat;
809 info.fUsage = usage;
810 info.fStorageMode = this->getDefaultMSAAStorageMode(discardable);
811 info.fFramebufferOnly = false;
812
813 return info;
814}
815
816MTLPixelFormat MtlCaps::getFormatFromDepthStencilFlags(
818 // TODO: Decide if we want to change this to always return a combined depth and stencil format
819 // to allow more sharing of depth stencil allocations.
820 if (mask == DepthStencilFlags::kDepth) {
821 // Graphite only needs 16-bits for depth values, so save some memory. If needed for
822 // workarounds, MTLPixelFormatDepth32Float is also available.
823 return MTLPixelFormatDepth16Unorm;
824 } else if (mask == DepthStencilFlags::kStencil) {
825 return MTLPixelFormatStencil8;
826 } else if (mask == DepthStencilFlags::kDepthStencil) {
827#if defined(SK_BUILD_FOR_MAC)
828 if (SkToBool(this->getFormatInfo(MTLPixelFormatDepth24Unorm_Stencil8).fFlags)) {
829 return MTLPixelFormatDepth24Unorm_Stencil8;
830 }
831#endif
832 return MTLPixelFormatDepth32Float_Stencil8;
833 }
834 SkASSERT(false);
835 return MTLPixelFormatInvalid;
836}
837
839 SkEnumBitMask<DepthStencilFlags> depthStencilType,
840 uint32_t sampleCount,
841 Protected) const {
843 info.fSampleCount = sampleCount;
844 info.fMipmapped = Mipmapped::kNo;
845 info.fFormat = this->getFormatFromDepthStencilFlags(depthStencilType);
846 info.fUsage = MTLTextureUsageRenderTarget;
847 info.fStorageMode = this->getDefaultMSAAStorageMode(Discardable::kYes);
848 info.fFramebufferOnly = false;
849
850 return info;
851}
852
854 // Storage textures are currently always sampleable from a shader.
855 MTLPixelFormat format = static_cast<MTLPixelFormat>(this->getFormatFromColorType(colorType));
856 if (format == MTLPixelFormatInvalid) {
857 return {};
858 }
859
860 const FormatInfo& formatInfo = this->getFormatInfo(format);
861 if (!SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags)) {
862 return {};
863 }
864
865 MTLTextureUsage usage = MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead;
867 info.fSampleCount = 1;
868 info.fMipmapped = Mipmapped::kNo;
869 info.fFormat = format;
870 info.fUsage = usage;
871 info.fStorageMode = MTLStorageModePrivate;
872 info.fFramebufferOnly = false;
873
874 return info;
875}
876
877const Caps::ColorTypeInfo* MtlCaps::getColorTypeInfo(
878 SkColorType ct, const TextureInfo& textureInfo) const {
879 MTLPixelFormat mtlFormat = static_cast<MTLPixelFormat>(textureInfo.mtlTextureSpec().fFormat);
880 if (mtlFormat == MTLPixelFormatInvalid) {
881 return nullptr;
882 }
883
884 const FormatInfo& info = this->getFormatInfo(mtlFormat);
885 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
886 const ColorTypeInfo& ctInfo = info.fColorTypeInfos[i];
887 if (ctInfo.fColorType == ct) {
888 return &ctInfo;
889 }
890 }
891
892 return nullptr;
893}
894
897
899 const RenderPassDesc& renderPassDesc) const {
900 UniqueKey pipelineKey;
901 {
902 // 5 uint32_t's (render step id, paint id, uint64 renderpass desc, uint16 write swizzle key)
904 kGraphicsPipelineKeyData32Count, "GraphicsPipeline");
905 // add GraphicsPipelineDesc key
906 builder[0] = pipelineDesc.renderStepID();
907 builder[1] = pipelineDesc.paintParamsID().asUInt();
908
909 // add RenderPassDesc key
910 uint64_t renderPassKey = this->getRenderPassDescKey(renderPassDesc);
911 builder[2] = renderPassKey & 0xFFFFFFFF;
912 builder[3] = (renderPassKey >> 32) & 0xFFFFFFFF;
913 builder[4] = renderPassDesc.fWriteSwizzle.asKey();
914
915 builder.finish();
916 }
917
918 return pipelineKey;
919}
920
922 GraphicsPipelineDesc* pipelineDesc,
923 RenderPassDesc* renderPassDesc,
924 const RendererProvider* rendererProvider) const {
925 struct UnpackedKeyData {
926 // From the GraphicsPipelineDesc
927 uint32_t fRenderStepID = 0;
928 UniquePaintParamsID fPaintParamsID;
929
930 // From the RenderPassDesc
931 MtlPixelFormat fColorFormat = 0;
932 uint32_t fColorSampleCount = 1;
933
934 MtlPixelFormat fDSFormat = 0;
935 uint32_t fDSSampleCount = 1;
936
937 Swizzle fWriteSwizzle;
938 } keyData;
939
942
943 const uint32_t* rawKeyData = key.data();
944
945 keyData.fRenderStepID = rawKeyData[0];
946 keyData.fPaintParamsID = rawKeyData[1] ? UniquePaintParamsID(rawKeyData[1])
948
949 keyData.fDSFormat = static_cast<MtlPixelFormat>((rawKeyData[2] >> 16) & 0xFFFF);
950 keyData.fDSSampleCount = rawKeyData[2] & 0xFFFF;
951
952 keyData.fColorFormat = static_cast<MtlPixelFormat>((rawKeyData[3] >> 16) & 0xFFFF);
953 keyData.fColorSampleCount = rawKeyData[3] & 0xFFFF;
954
955 keyData.fWriteSwizzle = SwizzleCtorAccessor::Make(rawKeyData[4]);
956
957 // Recreate the RenderPassDesc
958 SkASSERT(keyData.fColorSampleCount == keyData.fDSSampleCount);
959
960 MTLPixelFormat dsFormat = (MTLPixelFormat) keyData.fDSFormat;
962 if (MtlFormatIsDepth(dsFormat)) {
963 dsFlags |= DepthStencilFlags::kDepth;
964 }
965 if (MtlFormatIsStencil(dsFormat)) {
967 }
968
969 MtlTextureInfo mtlInfo(keyData.fColorSampleCount,
971 keyData.fColorFormat,
972 MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget,
973 MTLStorageModePrivate,
974 /* framebufferOnly= */ false);
975 TextureInfo info(mtlInfo);
976
977 *renderPassDesc = RenderPassDesc::Make(this,
978 info,
981 dsFlags,
982 /* clearColor= */ { .0f, .0f, .0f, .0f },
983 /* requiresMSAA= */ keyData.fColorSampleCount > 1,
984 keyData.fWriteSwizzle);
985
986 // Recreate the GraphicsPipelineDesc
987 const RenderStep* renderStep = rendererProvider->lookup(keyData.fRenderStepID);
988
989 UniquePaintParamsID paintID = renderStep->performsShading() ? keyData.fPaintParamsID
991
992 *pipelineDesc = GraphicsPipelineDesc(renderStep, paintID);
993
994 return true;
995}
996
997uint64_t MtlCaps::getRenderPassDescKey(const RenderPassDesc& renderPassDesc) const {
998 MtlTextureInfo colorInfo, depthStencilInfo;
999 renderPassDesc.fColorAttachment.fTextureInfo.getMtlTextureInfo(&colorInfo);
1000 renderPassDesc.fDepthStencilAttachment.fTextureInfo.getMtlTextureInfo(&depthStencilInfo);
1001 SkASSERT(colorInfo.fFormat < 65535 && depthStencilInfo.fFormat < 65535);
1002 uint32_t colorAttachmentKey = colorInfo.fFormat << 16 | colorInfo.fSampleCount;
1003 uint32_t dsAttachmentKey = depthStencilInfo.fFormat << 16 | depthStencilInfo.fSampleCount;
1004 return (((uint64_t) colorAttachmentKey) << 32) | dsAttachmentKey;
1005}
1006
1008 UniqueKey pipelineKey;
1009 {
1010 static const skgpu::UniqueKey::Domain kComputePipelineDomain = UniqueKey::GenerateDomain();
1011 // The key is made up of a single uint32_t corresponding to the compute step ID.
1012 UniqueKey::Builder builder(&pipelineKey, kComputePipelineDomain, 1, "ComputePipeline");
1013 builder[0] = pipelineDesc.computeStep()->uniqueID();
1014
1015 // TODO(b/240615224): The local work group size should factor into the key on platforms
1016 // that don't support specialization constants and require the workgroup/threadgroup size to
1017 // be specified in the shader text (D3D12, Vulkan 1.0, and OpenGL).
1018
1019 builder.finish();
1020 }
1021 return pipelineKey;
1022}
1023
1024uint32_t MtlCaps::channelMask(const TextureInfo& info) const {
1025 return skgpu::MtlFormatChannels((MTLPixelFormat)info.mtlTextureSpec().fFormat);
1026}
1027
1028bool MtlCaps::onIsTexturable(const TextureInfo& info) const {
1029 if (!info.isValid()) {
1030 return false;
1031 }
1032 if (!(info.mtlTextureSpec().fUsage & MTLTextureUsageShaderRead)) {
1033 return false;
1034 }
1035 if (info.mtlTextureSpec().fFramebufferOnly) {
1036 return false;
1037 }
1038 return this->isTexturable((MTLPixelFormat)info.mtlTextureSpec().fFormat);
1039}
1040
1041bool MtlCaps::isTexturable(MTLPixelFormat format) const {
1042 const FormatInfo& formatInfo = this->getFormatInfo(format);
1043 return SkToBool(FormatInfo::kTexturable_Flag & formatInfo.fFlags);
1044}
1045
1047 return info.isValid() &&
1048 (info.mtlTextureSpec().fUsage & MTLTextureUsageRenderTarget) &&
1049 this->isRenderable((MTLPixelFormat)info.mtlTextureSpec().fFormat, info.numSamples());
1050}
1051
1052bool MtlCaps::isRenderable(MTLPixelFormat format, uint32_t sampleCount) const {
1053 return sampleCount <= this->maxRenderTargetSampleCount(format);
1054}
1055
1057 if (!info.isValid()) {
1058 return false;
1059 }
1060 if (!(info.mtlTextureSpec().fUsage & MTLTextureUsageShaderWrite)) {
1061 return false;
1062 }
1063 if (info.mtlTextureSpec().fFramebufferOnly) {
1064 return false;
1065 }
1066 const FormatInfo& formatInfo =
1067 this->getFormatInfo((MTLPixelFormat)info.mtlTextureSpec().fFormat);
1068 return info.numSamples() == 1 && SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags);
1069}
1070
1071uint32_t MtlCaps::maxRenderTargetSampleCount(MTLPixelFormat format) const {
1072 const FormatInfo& formatInfo = this->getFormatInfo(format);
1073 if (!SkToBool(formatInfo.fFlags & FormatInfo::kRenderable_Flag)) {
1074 return 0;
1075 }
1076 if (SkToBool(formatInfo.fFlags & FormatInfo::kMSAA_Flag)) {
1077 return fColorSampleCounts[fColorSampleCounts.size() - 1];
1078 } else {
1079 return 1;
1080 }
1081}
1082
1083bool MtlCaps::supportsWritePixels(const TextureInfo& texInfo) const {
1084 MtlTextureInfo mtlInfo;
1085 texInfo.getMtlTextureInfo(&mtlInfo);
1086 if (mtlInfo.fFramebufferOnly) {
1087 return false;
1088 }
1089
1090 if (texInfo.numSamples() > 1) {
1091 return false;
1092 }
1093
1094 return true;
1095}
1096
1097bool MtlCaps::supportsReadPixels(const TextureInfo& texInfo) const {
1098 MtlTextureInfo mtlInfo;
1099 texInfo.getMtlTextureInfo(&mtlInfo);
1100 if (mtlInfo.fFramebufferOnly) {
1101 return false;
1102 }
1103
1104 // We disallow reading back directly from compressed textures.
1105 if (MtlFormatIsCompressed((MTLPixelFormat)mtlInfo.fFormat)) {
1106 return false;
1107 }
1108
1109 if (texInfo.numSamples() > 1) {
1110 return false;
1111 }
1112
1113 return true;
1114}
1115
1116std::pair<SkColorType, bool /*isRGBFormat*/> MtlCaps::supportedWritePixelsColorType(
1117 SkColorType dstColorType,
1118 const TextureInfo& dstTextureInfo,
1119 SkColorType srcColorType) const {
1120 MtlTextureInfo mtlInfo;
1121 dstTextureInfo.getMtlTextureInfo(&mtlInfo);
1122
1123 const FormatInfo& info = this->getFormatInfo((MTLPixelFormat)mtlInfo.fFormat);
1124 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1125 const auto& ctInfo = info.fColorTypeInfos[i];
1126 if (ctInfo.fColorType == dstColorType) {
1127 return {dstColorType, false};
1128 }
1129 }
1130 return {kUnknown_SkColorType, false};
1131}
1132
1133std::pair<SkColorType, bool /*isRGBFormat*/> MtlCaps::supportedReadPixelsColorType(
1134 SkColorType srcColorType,
1135 const TextureInfo& srcTextureInfo,
1136 SkColorType dstColorType) const {
1137 MtlTextureInfo mtlInfo;
1138 srcTextureInfo.getMtlTextureInfo(&mtlInfo);
1139
1140 // TODO: handle compressed formats
1141 if (MtlFormatIsCompressed((MTLPixelFormat)mtlInfo.fFormat)) {
1142 SkASSERT(this->isTexturable((MTLPixelFormat)mtlInfo.fFormat));
1143 return {kUnknown_SkColorType, false};
1144 }
1145
1146 const FormatInfo& info = this->getFormatInfo((MTLPixelFormat)mtlInfo.fFormat);
1147 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1148 const auto& ctInfo = info.fColorTypeInfos[i];
1149 if (ctInfo.fColorType == srcColorType) {
1150 return {srcColorType, false};
1151 }
1152 }
1153 return {kUnknown_SkColorType, false};
1154}
1155
1157 const TextureInfo& info,
1159 Shareable shareable,
1160 GraphiteResourceKey* key) const {
1161 const MtlTextureSpec& mtlSpec = info.mtlTextureSpec();
1162
1163 SkASSERT(!dimensions.isEmpty());
1164
1165 // A MTLPixelFormat is an NSUInteger type which is documented to be 32 bits in 32 bit
1166 // applications and 64 bits in 64 bit applications. So it should fit in an uint64_t, but adding
1167 // the assert heere to make sure.
1168 static_assert(sizeof(MTLPixelFormat) <= sizeof(uint64_t));
1169 SkASSERT(mtlSpec.fFormat != MTLPixelFormatInvalid);
1170 uint64_t formatKey = static_cast<uint64_t>(mtlSpec.fFormat);
1171
1172 uint32_t samplesKey = SamplesToKey(info.numSamples());
1173 // We don't have to key the number of mip levels because it is inherit in the combination of
1174 // isMipped and dimensions.
1175 bool isMipped = info.mipmapped() == Mipmapped::kYes;
1176 Protected isProtected = info.isProtected();
1177 bool isFBOnly = mtlSpec.fFramebufferOnly;
1178
1179 // Confirm all the below parts of the key can fit in a single uint32_t. The sum of the shift
1180 // amounts in the asserts must be less than or equal to 32.
1181 SkASSERT(samplesKey < (1u << 3));
1182 SkASSERT(static_cast<uint32_t>(isMipped) < (1u << 1));
1183 SkASSERT(static_cast<uint32_t>(isProtected) < (1u << 1));
1184 SkASSERT(mtlSpec.fUsage < (1u << 5));
1185 SkASSERT(mtlSpec.fStorageMode < (1u << 2));
1186 SkASSERT(static_cast<uint32_t>(isFBOnly) < (1u << 1));
1187
1188 // We need two uint32_ts for dimensions, 2 for format, and 1 for the rest of the key;
1189 static int kNum32DataCnt = 2 + 2 + 1;
1190
1191 GraphiteResourceKey::Builder builder(key, type, kNum32DataCnt, shareable);
1192
1193 builder[0] = dimensions.width();
1194 builder[1] = dimensions.height();
1195 builder[2] = formatKey & 0xFFFFFFFF;
1196 builder[3] = (formatKey >> 32) & 0xFFFFFFFF;
1197 builder[4] = (samplesKey << 0) |
1198 (static_cast<uint32_t>(isMipped) << 3) |
1199 (static_cast<uint32_t>(isProtected) << 4) |
1200 (static_cast<uint32_t>(mtlSpec.fUsage) << 5) |
1201 (static_cast<uint32_t>(mtlSpec.fStorageMode) << 10)|
1202 (static_cast<uint32_t>(isFBOnly) << 12);
1203
1204}
1205
1206} // namespace skgpu::graphite
const char * options
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define kMTLPixelFormatB5G6R5Unorm
Definition: MtlCaps.mm:222
#define kMTLPixelFormatETC2_RGB8
Definition: MtlCaps.mm:224
#define kMTLPixelFormatABGR4Unorm
Definition: MtlCaps.mm:223
uint16_t fFlags
Definition: ShapeLayer.cpp:106
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition: SkColorType.h:50
@ kR8_unorm_SkColorType
Definition: SkColorType.h:54
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition: SkColorType.h:43
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition: SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kSRGBA_8888_SkColorType
Definition: SkColorType.h:53
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:25
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition: SkColorType.h:45
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:27
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition: SkColorType.h:49
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition: SkColorType.h:36
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition: SkColorType.h:46
static constexpr int kSkColorTypeCnt
Definition: SkColorType.h:68
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
SkTextureCompressionType
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
GLenum type
static Swizzle Make(uint16_t key)
Definition: SwizzlePriv.h:21
constexpr uint16_t asKey() const
Definition: Swizzle.h:43
static constexpr Swizzle RGB1()
Definition: Swizzle.h:69
static Domain GenerateDomain()
Definition: ResourceKey.cpp:27
size_t fRequiredStorageBufferAlignment
Definition: Caps.h:359
size_t fRequiredUniformBufferAlignment
Definition: Caps.h:358
bool fStorageBufferPreferred
Definition: Caps.h:370
bool fClampToBorderSupport
Definition: Caps.h:365
bool fComputeSupport
Definition: Caps.h:375
std::unique_ptr< SkSL::ShaderCaps > fShaderCaps
Definition: Caps.h:363
bool fStorageBufferSupport
Definition: Caps.h:369
static uint32_t SamplesToKey(uint32_t numSamples)
Definition: Caps.h:314
void finishInitialization(const ContextOptions &)
Definition: Caps.cpp:29
size_t fRequiredTransferBufferAlignment
Definition: Caps.h:360
const SkSL::ShaderCaps * shaderCaps() const
Definition: Caps.h:75
ResourceBindingRequirements fResourceBindingReqs
Definition: Caps.h:383
int fDefaultMSAASamples
Definition: Caps.h:357
const ComputeStep * computeStep() const
uint32_t uniqueID() const
Definition: ComputeStep.h:241
UniquePaintParamsID paintParamsID() const
void buildKeyForTexture(SkISize dimensions, const TextureInfo &, ResourceType, Shareable, GraphiteResourceKey *) const override
Definition: MtlCaps.mm:1156
TextureInfo getDefaultMSAATextureInfo(const TextureInfo &singleSampledInfo, Discardable discardable) const override
Definition: MtlCaps.mm:793
TextureInfo getTextureInfoForSampledCopy(const TextureInfo &textureInfo, Mipmapped mipmapped) const override
Definition: MtlCaps.mm:730
TextureInfo getDefaultCompressedTextureInfo(SkTextureCompressionType, Mipmapped mipmapped, Protected) const override
Definition: MtlCaps.mm:761
bool extractGraphicsDescs(const UniqueKey &, GraphicsPipelineDesc *, RenderPassDesc *, const RendererProvider *) const override
Definition: MtlCaps.mm:921
bool isStorage(const TextureInfo &) const override
Definition: MtlCaps.mm:1056
TextureInfo getDefaultSampledTextureInfo(SkColorType, Mipmapped mipmapped, Protected, Renderable) const override
Definition: MtlCaps.mm:705
MtlCaps(const id< MTLDevice >, const ContextOptions &)
Definition: MtlCaps.mm:27
bool isApple() const
Definition: MtlCaps.h:60
TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask< DepthStencilFlags >, uint32_t sampleCount, Protected) const override
Definition: MtlCaps.mm:838
bool isMac() const
Definition: MtlCaps.h:59
TextureInfo getDefaultStorageTextureInfo(SkColorType) const override
Definition: MtlCaps.mm:853
UniqueKey makeComputePipelineKey(const ComputePipelineDesc &) const override
Definition: MtlCaps.mm:1007
uint64_t getRenderPassDescKey(const RenderPassDesc &) const
Definition: MtlCaps.mm:997
bool isRenderable(const TextureInfo &) const override
Definition: MtlCaps.mm:1046
uint32_t channelMask(const TextureInfo &) const override
Definition: MtlCaps.mm:1024
UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc &, const RenderPassDesc &) const override
Definition: MtlCaps.mm:898
const RenderStep * lookup(uint32_t uniqueID) const
static UniquePaintParamsID InvalidID()
VkDevice device
Definition: main.cc:53
if(end==-1)
uint32_t uint32_t * format
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
unsigned int MtlPixelFormat
uint32_t ResourceType
static const int kGraphicsPipelineKeyData32Count
Definition: MtlCaps.mm:896
static constexpr MTLPixelFormat kMtlFormats[]
Definition: MtlCaps.mm:228
static const skgpu::UniqueKey::Domain kGraphicsPipelineDomain
Definition: MtlCaps.mm:895
uint32_t MtlFormatChannels(MTLPixelFormat mtlFormat)
Definition: MtlUtils.mm:102
Renderable
Definition: GpuTypes.h:69
bool MtlFormatIsStencil(MTLPixelFormat format)
Definition: MtlUtils.mm:47
Mipmapped
Definition: GpuTypes.h:53
bool MtlFormatIsDepth(MTLPixelFormat format)
Definition: MtlUtils.mm:33
bool MtlFormatIsCompressed(MTLPixelFormat mtlFormat)
Definition: MtlUtils.mm:60
Protected
Definition: GpuTypes.h:61
static void usage(char *argv0)
Definition: SkSize.h:16
bool isEmpty() const
Definition: SkSize.h:31
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
bool fFBFetchSupport
Definition: SkSLUtil.h:93
bool fDualSourceBlendingSupport
Definition: SkSLUtil.h:84
const char * fFloatBufferArrayName
Definition: SkSLUtil.h:160
bool fInfinitySupport
Definition: SkSLUtil.h:103
const char * fFBFetchColorName
Definition: SkSLUtil.h:158
bool fShaderDerivativeSupport
Definition: SkSLUtil.h:85
bool fFlatInterpolationSupport
Definition: SkSLUtil.h:96
bool fIntegerSupport
Definition: SkSLUtil.h:89
bool fInverseHyperbolicSupport
Definition: SkSLUtil.h:92
bool fNonsquareMatrixSupport
Definition: SkSLUtil.h:90
bool fFloatIs32Bits
Definition: SkSLUtil.h:100
bool fUsesPrecisionModifiers
Definition: SkSLUtil.h:95
AttachmentDesc fDepthStencilAttachment
static RenderPassDesc Make(const Caps *caps, const TextureInfo &targetInfo, LoadOp loadOp, StoreOp storeOp, SkEnumBitMask< DepthStencilFlags > depthStencilFlags, const std::array< float, 4 > &clearColor, bool requiresMSAA, Swizzle writeSwizzle)