Flutter Engine
The Flutter Engine
GrMtlCaps.mm
Go to the documentation of this file.
1/*
2 * Copyright 2017 Google Inc.
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
10#include "include/core/SkRect.h"
16#include "src/gpu/KeyBuilder.h"
29
30#if defined(GR_TEST_UTILS)
32#endif
33
34#if !__has_feature(objc_arc)
35#error This file must be compiled with Arc. Use -fobjc-arc flag
36#endif
37
38GR_NORETAIN_BEGIN
39
40GrMtlCaps::GrMtlCaps(const GrContextOptions& contextOptions, const id<MTLDevice> device)
41 : INHERITED(contextOptions) {
42 fShaderCaps = std::make_unique<GrShaderCaps>();
43
44 this->initGPUFamily(device);
45 this->initGrCaps(device);
46 this->initShaderCaps();
47 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
48 this->applyDriverCorrectnessWorkarounds(contextOptions, device);
49 }
50
51 this->initFormatTable();
52 this->initStencilFormat(device);
53
54 // TODO: appears to be slow with Mac msaa8, disabled for now
55 fStoreAndMultisampleResolveSupport = (fGPUFamily == GPUFamily::kApple &&
56 fFamilyGroup >= 3);
57 // Also slow with non-Apple silicon
58 fPreferDiscardableMSAAAttachment = (fGPUFamily == GPUFamily::kApple);
59
60 this->finishInitialization(contextOptions);
61}
62
63// translates from older MTLFeatureSet interface to MTLGPUFamily interface
64bool GrMtlCaps::getGPUFamilyFromFeatureSet(id<MTLDevice> device,
65 GPUFamily* gpuFamily,
66 int* group) {
67// MTLFeatureSet is deprecated for newer versions of the SDK
68#if GR_METAL_SDK_VERSION < 300
69
70#if defined(SK_BUILD_FOR_MAC)
71 // Apple Silicon is only available in later OSes
72 *gpuFamily = GPUFamily::kMac;
73 // Mac OSX 14
74 if (@available(macOS 10.14, *)) {
75 if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1]) {
76 *group = 2;
77 return true;
78 }
79 if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v4]) {
80 *group = 1;
81 return true;
82 }
83 }
84 // Mac OSX 13
85 if (@available(macOS 10.13, *)) {
86 if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v3]) {
87 *group = 1;
88 return true;
89 }
90 }
91 // Mac OSX 12
92 if (@available(macOS 10.12, *)) {
93 if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v2]) {
94 *group = 1;
95 return true;
96 }
97 }
98 // Mac OSX 11
99 if (@available(macOS 10.11, *)) {
100 if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily1_v1]) {
101 *group = 1;
102 return true;
103 }
104 }
105#elif defined(SK_BUILD_FOR_IOS)
106 // TODO: support tvOS
107 *gpuFamily = GPUFamily::kApple;
108 // iOS 12
109 if (@available(iOS 12.0, tvOS 12.0, *)) {
110 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily5_v1]) {
111 *group = 5;
112 return true;
113 }
114 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v2]) {
115 *group = 4;
116 return true;
117 }
118 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v4]) {
119 *group = 3;
120 return true;
121 }
122 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v5]) {
123 *group = 2;
124 return true;
125 }
126 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v5]) {
127 *group = 1;
128 return true;
129 }
130 }
131 // iOS 11
132 if (@available(iOS 11.0, tvOS 11.0, *)) {
133 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]) {
134 *group = 4;
135 return true;
136 }
137 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v3]) {
138 *group = 3;
139 return true;
140 }
141 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v4]) {
142 *group = 2;
143 return true;
144 }
145 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v4]) {
146 *group = 1;
147 return true;
148 }
149 }
150 // iOS 10
151 if (@available(iOS 10.0, tvOS 10.0, *)) {
152 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2]) {
153 *group = 3;
154 return true;
155 }
156 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v3]) {
157 *group = 2;
158 return true;
159 }
160 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v3]) {
161 *group = 1;
162 return true;
163 }
164 }
165 // We don't support earlier OSes
166#endif
167
168#endif // GR_METAL_SDK_VERSION < 300
169
170 // No supported GPU families were found
171 return false;
172}
173
174bool GrMtlCaps::getGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group) {
175#if GR_METAL_SDK_VERSION >= 220
176 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
177 // Apple Silicon
178#if GR_METAL_SDK_VERSION >= 230
179 if ([device supportsFamily:MTLGPUFamilyApple7]) {
180 *gpuFamily = GPUFamily::kApple;
181 *group = 7;
182 return true;
183 }
184#endif
185#ifdef SK_BUILD_FOR_IOS
186 if ([device supportsFamily:MTLGPUFamilyApple6]) {
187 *gpuFamily = GPUFamily::kApple;
188 *group = 6;
189 return true;
190 }
191 if ([device supportsFamily:MTLGPUFamilyApple5]) {
192 *gpuFamily = GPUFamily::kApple;
193 *group = 5;
194 return true;
195 }
196 if ([device supportsFamily:MTLGPUFamilyApple4]) {
197 *gpuFamily = GPUFamily::kApple;
198 *group = 4;
199 return true;
200 }
201 if ([device supportsFamily:MTLGPUFamilyApple3]) {
202 *gpuFamily = GPUFamily::kApple;
203 *group = 3;
204 return true;
205 }
206 if ([device supportsFamily:MTLGPUFamilyApple2]) {
207 *gpuFamily = GPUFamily::kApple;
208 *group = 2;
209 return true;
210 }
211 if ([device supportsFamily:MTLGPUFamilyApple1]) {
212 *gpuFamily = GPUFamily::kApple;
213 *group = 1;
214 return true;
215 }
216#endif
217
218 // Older Macs
219#if GR_METAL_SDK_VERSION >= 300
220 // TODO: replace with Metal 3 definitions
221 SkASSERT([device supportsFamily:MTLGPUFamilyMac2]);
222 *gpuFamily = GPUFamily::kMac;
223 *group = 2;
224 return true;
225#else
226 // At the moment MacCatalyst families have the same features as Mac,
227 // so we treat them the same
228 if ([device supportsFamily:MTLGPUFamilyMac2] ||
229 [device supportsFamily:MTLGPUFamilyMacCatalyst2]) {
230 *gpuFamily = GPUFamily::kMac;
231 *group = 2;
232 return true;
233 }
234 if ([device supportsFamily:MTLGPUFamilyMac1] ||
235 [device supportsFamily:MTLGPUFamilyMacCatalyst1]) {
236 *gpuFamily = GPUFamily::kMac;
237 *group = 1;
238 return true;
239 }
240#endif
241 }
242#endif
243
244 // No supported GPU families were found
245 return false;
246}
247
248void GrMtlCaps::initGPUFamily(id<MTLDevice> device) {
249 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
250 if (this->getGPUFamily(device, &fGPUFamily, &fFamilyGroup)) {
251 return;
252 }
253 } else {
254 if (this->getGPUFamilyFromFeatureSet(device, &fGPUFamily, &fFamilyGroup)) {
255 return;
256 }
257 }
258 // We don't know what this is, fall back to minimum defaults
259#ifdef SK_BUILD_FOR_MAC
260 fGPUFamily = GPUFamily::kMac;
261 fFamilyGroup = 1;
262#else
263 fGPUFamily = GPUFamily::kApple;
264 fFamilyGroup = 1;
265#endif
266}
267
268bool GrMtlCaps::canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount,
269 MTLPixelFormat srcFormat, int srcSampleCount,
270 const SkIRect& srcRect, const SkIPoint& dstPoint,
271 bool areDstSrcSameObj) const {
272 if (!dstFormat || dstFormat != srcFormat) {
273 return false;
274 }
275 if ((dstSampleCount > 1 || srcSampleCount > 1) && (dstSampleCount != srcSampleCount)) {
276 return false;
277 }
278 if (areDstSrcSameObj) {
279 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
280 srcRect.width(), srcRect.height());
281 if (dstRect.intersect(srcRect)) {
282 return false;
283 }
284 }
285 return true;
286}
287
288bool GrMtlCaps::canCopyAsResolve(MTLPixelFormat dstFormat, int dstSampleCount,
289 MTLPixelFormat srcFormat, int srcSampleCount,
290 bool srcIsRenderTarget, const SkISize srcDimensions,
291 const SkIRect& srcRect,
292 const SkIPoint& dstPoint,
293 bool areDstSrcSameObj) const {
294 if (areDstSrcSameObj) {
295 return false;
296 }
297 if (dstFormat != srcFormat) {
298 return false;
299 }
300 if (dstSampleCount > 1 || srcSampleCount == 1 || !srcIsRenderTarget) {
301 return false;
302 }
303
304 // TODO: Support copying subrectangles
305 if (dstPoint != SkIPoint::Make(0, 0)) {
306 return false;
307 }
308 if (srcRect != SkIRect::MakeSize(srcDimensions)) {
309 return false;
310 }
311
312 return true;
313}
314
315bool GrMtlCaps::onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
316 const GrSurfaceProxy* src, const SkIRect& srcRect) const {
317 // Metal does not support scaling copies
318 if (srcRect.size() != dstRect.size()) {
319 return false;
320 }
321
322 int dstSampleCnt = 1;
323 int srcSampleCnt = 1;
324 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
325 dstSampleCnt = rtProxy->numSamples();
326 }
327 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
328 srcSampleCnt = rtProxy->numSamples();
329 }
330
331 // TODO: need some way to detect whether the proxy is framebufferOnly
332
333 const SkIPoint dstPoint = dstRect.topLeft();
334 if (this->canCopyAsBlit(GrBackendFormatAsMTLPixelFormat(dst->backendFormat()), dstSampleCnt,
335 GrBackendFormatAsMTLPixelFormat(src->backendFormat()), srcSampleCnt,
336 srcRect, dstPoint, dst == src)) {
337 return true;
338 }
339 bool srcIsRenderTarget = src->asRenderTargetProxy();
340 MTLPixelFormat dstFormat = GrBackendFormatAsMTLPixelFormat(dst->backendFormat());
341 MTLPixelFormat srcFormat = GrBackendFormatAsMTLPixelFormat(src->backendFormat());
342 return this->canCopyAsResolve(dstFormat, dstSampleCnt,
343 srcFormat, srcSampleCnt,
344 srcIsRenderTarget, src->backingStoreDimensions(), srcRect,
345 dstPoint,
346 dst == src);
347}
348
349void GrMtlCaps::initGrCaps(id<MTLDevice> device) {
350#if defined(GR_TEST_UTILS)
351 this->setDeviceName([[device name] UTF8String]);
352#endif
353
354 // Max vertex attribs is the same on all devices
356
357 // Metal does not support scissor + clear
359
360 // We always copy in/out of a transfer buffer so it's trivial to support row bytes.
364
365 // RenderTarget and Texture size
366 if (this->isMac() || fFamilyGroup >= 3) {
367 fMaxRenderTargetSize = 16384;
368 } else {
370 }
373
374 fMaxPushConstantsSize = 4*1024;
376
377 // This is documented to be 4 for all Macs. However, on Apple GPUs on Mac it appears there is
378 // no actual alignment requirement
379 // https://developer.apple.com/documentation/metal/mtlblitcommandencoder/1400767-copyfrombuffer
380 if (this->isMac()) {
382 // Buffer updates are sometimes implemented through transfers in GrMtlBuffer.
384 }
385
386 // Metal buffers are initialized to zero (if not created with initial data)
388
389 // Init sample counts. All devices support 1 (i.e. 0 in skia).
390 fSampleCounts.push_back(1);
391 if (@available(iOS 9.0, tvOS 9.0, *)) {
392 for (auto sampleCnt : {2, 4, 8}) {
393 if ([device supportsTextureSampleCount:sampleCnt]) {
394 fSampleCounts.push_back(sampleCnt);
395 }
396 }
397 }
398
399 // Clamp to border is supported on Mac 10.12 and higher. It is not supported on iOS.
400 fClampToBorderSupport = false;
401#ifdef SK_BUILD_FOR_MAC
402 if (@available(macOS 10.12, *)) {
404 }
405#endif
406
407 // Starting with the assumption that there isn't a reason to not map small buffers.
409
410 // Buffers are always fully mapped.
412
414
415 fNPOTTextureTileSupport = true; // always available in Metal
416 fMipmapSupport = true; // always available in Metal
417 fAnisoSupport = true; // always available in Metal
418
419 fReuseScratchTextures = true; // Assuming this okay
420
424
425 fTextureBarrierSupport = false; // Need to figure out if we can do this
426
428
429 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
430 if (this->isMac() || fFamilyGroup >= 3) {
433 }
434 }
435
436 fGpuTracingSupport = false;
437
438 bool supportsMTLEvent = false;
439 if (@available(macOS 10.14, iOS 12.0, tvOS 12.0, *)) {
440 supportsMTLEvent = true;
441 }
442 fSemaphoreSupport = supportsMTLEvent;
445
448
450}
451
452static bool format_is_srgb(MTLPixelFormat format) {
453 switch (format) {
454 case MTLPixelFormatRGBA8Unorm_sRGB:
455 case MTLPixelFormatBGRA8Unorm_sRGB:
456 return true;
457 default:
458 return false;
459 }
460}
461
464}
465
467 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
468 return this->isFormatTexturable(mtlFormat);
469}
470
471bool GrMtlCaps::isFormatTexturable(MTLPixelFormat format) const {
472 const FormatInfo& formatInfo = this->getFormatInfo(format);
473 return SkToBool(FormatInfo::kTexturable_Flag & formatInfo.fFlags);
474}
475
477 int sampleCount) const {
478 if (!this->isFormatRenderable(format, sampleCount)) {
479 return false;
480 }
481 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
482 SkASSERT(mtlFormat != MTLPixelFormatInvalid);
483 const auto& info = this->getFormatInfo(mtlFormat);
484 if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
485 return false;
486 }
487 return true;
488}
489
490bool GrMtlCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
491 return this->isFormatRenderable(GrBackendFormatAsMTLPixelFormat(format), sampleCount);
492}
493
494bool GrMtlCaps::isFormatRenderable(MTLPixelFormat format, int sampleCount) const {
495 return sampleCount <= this->maxRenderTargetSampleCount(format);
496}
497
500}
501
503 const FormatInfo& formatInfo = this->getFormatInfo(format);
504 if (formatInfo.fFlags & FormatInfo::kMSAA_Flag) {
505 return fSampleCounts[fSampleCounts.size() - 1];
506 } else if (formatInfo.fFlags & FormatInfo::kRenderable_Flag) {
507 return 1;
508 }
509 return 0;
510}
511
513 const GrBackendFormat& format) const {
514 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
515
516 return this->getRenderTargetSampleCount(requestedCount, mtlFormat);
517}
518
519int GrMtlCaps::getRenderTargetSampleCount(int requestedCount, MTLPixelFormat format) const {
520 requestedCount = std::max(requestedCount, 1);
521 const FormatInfo& formatInfo = this->getFormatInfo(format);
522 if (!(formatInfo.fFlags & FormatInfo::kRenderable_Flag)) {
523 return 0;
524 }
525 if (formatInfo.fFlags & FormatInfo::kMSAA_Flag) {
526 int count = fSampleCounts.size();
527 for (int i = 0; i < count; ++i) {
528 if (fSampleCounts[i] >= requestedCount) {
529 return fSampleCounts[i];
530 }
531 }
532 }
533 return 1 == requestedCount ? 1 : 0;
534}
535
536void GrMtlCaps::initShaderCaps() {
538
539 // Setting this true with the assumption that this cap will eventually mean we support varying
540 // precisions and not just via modifiers.
543 // We haven't yet tested that using flat attributes perform well.
545
548
549 if (@available(macOS 10.12, iOS 11.0, tvOS 11.0, *)) {
551 } else {
553 }
554
555 // TODO(skia:8270): Re-enable this once bug 8270 is fixed. Will also need to remove asserts in
556 // GrMtlPipelineStateBuilder which assert we aren't using this feature.
557#if 0
558 if (this->isIOS()) {
561 shaderCaps->fFBFetchColorName = ""; // Somehow add [[color(0)]] to arguments to frag shader
562 }
563#endif
565
572
573 // Metal uses IEEE float and half floats so assuming those values here.
575 shaderCaps->fHalfIs32Bits = false;
576
578}
579
580void GrMtlCaps::applyDriverCorrectnessWorkarounds(const GrContextOptions&, const id<MTLDevice>) {
581 // We don't have any active Metal workarounds.
582}
583
584// Define these so we can use them to initialize arrays and work around
585// the fact that these pixel formats are not always available.
586#define kMTLPixelFormatB5G6R5Unorm MTLPixelFormat(40)
587#define kMTLPixelFormatABGR4Unorm MTLPixelFormat(42)
588#define kMTLPixelFormatETC2_RGB8 MTLPixelFormat(180)
589
590// These are all the valid MTLPixelFormats that we support in Skia. They are roughly ordered from
591// most frequently used to least to improve look up times in arrays.
592static constexpr MTLPixelFormat kMtlFormats[] = {
593 MTLPixelFormatRGBA8Unorm,
594 MTLPixelFormatR8Unorm,
595 MTLPixelFormatA8Unorm,
596 MTLPixelFormatBGRA8Unorm,
598 MTLPixelFormatRGBA16Float,
599 MTLPixelFormatR16Float,
600 MTLPixelFormatRG8Unorm,
601 MTLPixelFormatRGB10A2Unorm,
602 MTLPixelFormatBGR10A2Unorm,
604 MTLPixelFormatRGBA8Unorm_sRGB,
605 MTLPixelFormatR16Unorm,
606 MTLPixelFormatRG16Unorm,
608#ifdef SK_BUILD_FOR_MAC
609 MTLPixelFormatBC1_RGBA,
610#endif
611 MTLPixelFormatRGBA16Unorm,
612 MTLPixelFormatRG16Float,
613
614 MTLPixelFormatInvalid,
615};
616
617void GrMtlCaps::setColorType(GrColorType colorType, std::initializer_list<MTLPixelFormat> formats) {
618#ifdef SK_DEBUG
619 for (size_t i = 0; i < kNumMtlFormats; ++i) {
620 const auto& formatInfo = fFormatTable[i];
621 for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
622 const auto& ctInfo = formatInfo.fColorTypeInfos[j];
623 if (ctInfo.fColorType == colorType) {
624 bool found = false;
625 for (auto it = formats.begin(); it != formats.end(); ++it) {
626 if (kMtlFormats[i] == *it) {
627 found = true;
628 }
629 }
630 SkASSERT(found);
631 }
632 }
633 }
634#endif
635 int idx = static_cast<int>(colorType);
636 for (auto it = formats.begin(); it != formats.end(); ++it) {
637 const auto& info = this->getFormatInfo(*it);
638 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
639 if (info.fColorTypeInfos[i].fColorType == colorType) {
640 fColorTypeToFormatTable[idx] = *it;
641 return;
642 }
643 }
644 }
645}
646
647size_t GrMtlCaps::GetFormatIndex(MTLPixelFormat pixelFormat) {
648 static_assert(std::size(kMtlFormats) == GrMtlCaps::kNumMtlFormats,
649 "Size of kMtlFormats array must match static value in header");
650 for (size_t i = 0; i < GrMtlCaps::kNumMtlFormats; ++i) {
651 if (kMtlFormats[i] == pixelFormat) {
652 return i;
653 }
654 }
655 SK_ABORT("Invalid MTLPixelFormat: %d", static_cast<int>(pixelFormat));
656}
657
658void GrMtlCaps::initFormatTable() {
659 FormatInfo* info;
660
661 if (@available(macos 11.0, *)) {
662 SkASSERT(kMTLPixelFormatB5G6R5Unorm == MTLPixelFormatB5G6R5Unorm);
663 SkASSERT(kMTLPixelFormatABGR4Unorm == MTLPixelFormatABGR4Unorm);
664 SkASSERT(kMTLPixelFormatETC2_RGB8 == MTLPixelFormatETC2_RGB8);
665 }
666
667 // Format: R8Unorm
668 {
669 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR8Unorm)];
670 info->fFlags = FormatInfo::kAllFlags;
671 info->fColorTypeInfoCount = 3;
672 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
673 int ctIdx = 0;
674 // Format: R8Unorm, Surface: kAlpha_8
675 {
676 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
677 ctInfo.fColorType = GrColorType::kR_8;
678 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
679 }
680 // Format: R8Unorm, Surface: kAlpha_8
681 {
682 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
683 ctInfo.fColorType = GrColorType::kAlpha_8;
684 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
685 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
686 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
687 }
688 // Format: R8Unorm, Surface: kGray_8
689 {
690 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
691 ctInfo.fColorType = GrColorType::kGray_8;
692 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
693 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
694 }
695 }
696
697 // Format: A8Unorm
698 {
699 info = &fFormatTable[GetFormatIndex(MTLPixelFormatA8Unorm)];
700 info->fFlags = FormatInfo::kTexturable_Flag;
701 info->fColorTypeInfoCount = 1;
702 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
703 int ctIdx = 0;
704 // Format: A8Unorm, Surface: kAlpha_8
705 {
706 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
707 ctInfo.fColorType = GrColorType::kAlpha_8;
708 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
709 }
710 }
711
712 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
713 if (this->isApple()) {
714 // Format: B5G6R5Unorm
715 {
716 info = &fFormatTable[GetFormatIndex(MTLPixelFormatB5G6R5Unorm)];
717 info->fFlags = FormatInfo::kAllFlags;
718 info->fColorTypeInfoCount = 1;
719 info->fColorTypeInfos =
720 std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
721 int ctIdx = 0;
722 // Format: B5G6R5Unorm, Surface: kBGR_565
723 {
724 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
725 ctInfo.fColorType = GrColorType::kBGR_565;
726 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
727 ColorTypeInfo::kRenderable_Flag;
728 }
729 }
730
731 // Format: ABGR4Unorm
732 {
733 info = &fFormatTable[GetFormatIndex(MTLPixelFormatABGR4Unorm)];
734 info->fFlags = FormatInfo::kAllFlags;
735 info->fColorTypeInfoCount = 1;
736 info->fColorTypeInfos =
737 std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
738 int ctIdx = 0;
739 // Format: ABGR4Unorm, Surface: kABGR_4444
740 {
741 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
742 ctInfo.fColorType = GrColorType::kABGR_4444;
743 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag |
744 ColorTypeInfo::kRenderable_Flag;
745 }
746 }
747 }
748 }
749
750 // Format: RGBA8Unorm
751 {
752 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm)];
753 info->fFlags = FormatInfo::kAllFlags;
754 info->fColorTypeInfoCount = 2;
755 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
756 int ctIdx = 0;
757 // Format: RGBA8Unorm, Surface: kRGBA_8888
758 {
759 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
760 ctInfo.fColorType = GrColorType::kRGBA_8888;
761 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
762 }
763 // Format: RGBA8Unorm, Surface: kRGB_888x
764 {
765 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
766 ctInfo.fColorType = GrColorType::kRGB_888x;
767 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
768 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
769 }
770 }
771
772 // Format: RG8Unorm
773 {
774 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG8Unorm)];
775 info->fFlags = FormatInfo::kAllFlags;
776 info->fColorTypeInfoCount = 1;
777 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
778 int ctIdx = 0;
779 // Format: RG8Unorm, Surface: kRG_88
780 {
781 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
782 ctInfo.fColorType = GrColorType::kRG_88;
783 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
784 }
785 }
786
787 // Format: BGRA8Unorm
788 {
789 info = &fFormatTable[GetFormatIndex(MTLPixelFormatBGRA8Unorm)];
790 info->fFlags = FormatInfo::kAllFlags;
791 info->fColorTypeInfoCount = 1;
792 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
793 int ctIdx = 0;
794 // Format: BGRA8Unorm, Surface: kBGRA_8888
795 {
796 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
797 ctInfo.fColorType = GrColorType::kBGRA_8888;
798 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
799 }
800 }
801
802 // Format: RGBA8Unorm_sRGB
803 {
804 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA8Unorm_sRGB)];
805 info->fFlags = FormatInfo::kAllFlags;
806 info->fColorTypeInfoCount = 1;
807 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
808 int ctIdx = 0;
809 // Format: RGBA8Unorm_sRGB, Surface: kRGBA_8888_SRGB
810 {
811 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
812 ctInfo.fColorType = GrColorType::kRGBA_8888_SRGB;
813 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
814 }
815 }
816
817 // Format: RGB10A2Unorm
818 {
819 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGB10A2Unorm)];
820 if (this->isMac() || fFamilyGroup >= 3) {
821 info->fFlags = FormatInfo::kAllFlags;
822 } else {
823 info->fFlags = FormatInfo::kTexturable_Flag;
824 }
825 info->fColorTypeInfoCount = 1;
826 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
827 int ctIdx = 0;
828 // Format: RGB10A2Unorm, Surface: kRGBA_1010102
829 {
830 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
831 ctInfo.fColorType = GrColorType::kRGBA_1010102;
832 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
833 }
834 }
835
836 // Format: BGR10A2Unorm
837 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
838 info = &fFormatTable[GetFormatIndex(MTLPixelFormatBGR10A2Unorm)];
839 if (this->isMac() && fFamilyGroup == 1) {
840 info->fFlags = FormatInfo::kTexturable_Flag;
841 } else {
842 info->fFlags = FormatInfo::kAllFlags;
843 }
844 info->fColorTypeInfoCount = 1;
845 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
846 int ctIdx = 0;
847 // Format: BGR10A2Unorm, Surface: kBGRA_1010102
848 {
849 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
850 ctInfo.fColorType = GrColorType::kBGRA_1010102;
851 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
852 }
853 }
854
855 // Format: R16Float
856 {
857 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Float)];
858 info->fFlags = FormatInfo::kAllFlags;
859 info->fColorTypeInfoCount = 1;
860 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
861 int ctIdx = 0;
862 // Format: R16Float, Surface: kAlpha_F16
863 {
864 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
865 ctInfo.fColorType = GrColorType::kAlpha_F16;
866 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
867 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
868 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
869 }
870 }
871
872 // Format: RGBA16Float
873 {
874 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Float)];
875 info->fFlags = FormatInfo::kAllFlags;
876 info->fColorTypeInfoCount = 2;
877 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
878 int ctIdx = 0;
879 // Format: RGBA16Float, Surface: kRGBA_F16
880 {
881 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
882 ctInfo.fColorType = GrColorType::kRGBA_F16;
883 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
884 }
885 // Format: RGBA16Float, Surface: kRGBA_F16_Clamped
886 {
887 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
888 ctInfo.fColorType = GrColorType::kRGBA_F16_Clamped;
889 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
890 }
891 }
892
893 // Format: R16Unorm
894 {
895 info = &fFormatTable[GetFormatIndex(MTLPixelFormatR16Unorm)];
896 if (this->isMac()) {
897 info->fFlags = FormatInfo::kAllFlags;
898 } else {
899 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
900 }
901 info->fColorTypeInfoCount = 1;
902 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
903 int ctIdx = 0;
904 // Format: R16Unorm, Surface: kAlpha_16
905 {
906 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
907 ctInfo.fColorType = GrColorType::kAlpha_16;
908 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
909 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
910 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
911 }
912 }
913
914 // Format: RG16Unorm
915 {
916 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Unorm)];
917 if (this->isMac()) {
918 info->fFlags = FormatInfo::kAllFlags;
919 } else {
920 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
921 }
922 info->fColorTypeInfoCount = 1;
923 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
924 int ctIdx = 0;
925 // Format: RG16Unorm, Surface: kRG_1616
926 {
927 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
928 ctInfo.fColorType = GrColorType::kRG_1616;
929 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
930 }
931 }
932
933 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
934 if (this->isApple()) {
935 // ETC2_RGB8
936 info = &fFormatTable[GetFormatIndex(MTLPixelFormatETC2_RGB8)];
937 info->fFlags = FormatInfo::kTexturable_Flag;
938 // NO supported colorTypes
939 }
940 }
941#ifdef SK_BUILD_FOR_MAC
942 if (this->isMac()) {
943 // BC1_RGBA
944 info = &fFormatTable[GetFormatIndex(MTLPixelFormatBC1_RGBA)];
945 info->fFlags = FormatInfo::kTexturable_Flag;
946 // NO supported colorTypes
947 }
948#endif
949
950 // Format: RGBA16Unorm
951 {
952 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRGBA16Unorm)];
953 if (this->isMac()) {
954 info->fFlags = FormatInfo::kAllFlags;
955 } else {
956 info->fFlags = FormatInfo::kTexturable_Flag | FormatInfo::kRenderable_Flag;
957 }
958 info->fColorTypeInfoCount = 1;
959 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
960 int ctIdx = 0;
961 // Format: RGBA16Unorm, Surface: kRGBA_16161616
962 {
963 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
964 ctInfo.fColorType = GrColorType::kRGBA_16161616;
965 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
966 }
967 }
968
969 // Format: RG16Float
970 {
971 info = &fFormatTable[GetFormatIndex(MTLPixelFormatRG16Float)];
972 info->fFlags = FormatInfo::kAllFlags;
973 info->fColorTypeInfoCount = 1;
974 info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
975 int ctIdx = 0;
976 // Format: RG16Float, Surface: kRG_F16
977 {
978 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
979 ctInfo.fColorType = GrColorType::kRG_F16;
980 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
981 }
982 }
983
984 ////////////////////////////////////////////////////////////////////////////
985 // Map GrColorTypes (used for creating GrSurfaces) to MTLPixelFormats. The order in which the
986 // formats are passed into the setColorType function indicates the priority in selecting which
987 // format we use for a given GrcolorType.
988
989 std::fill_n(fColorTypeToFormatTable, kGrColorTypeCnt, MTLPixelFormatInvalid);
990
991 this->setColorType(GrColorType::kAlpha_8, { MTLPixelFormatR8Unorm,
992 MTLPixelFormatA8Unorm });
993 if (@available(macOS 11.0, iOS 8.0, tvOS 9.0, *)) {
994 if (this->isApple()) {
995 this->setColorType(GrColorType::kBGR_565, { MTLPixelFormatB5G6R5Unorm });
996 this->setColorType(GrColorType::kABGR_4444, { MTLPixelFormatABGR4Unorm });
997 }
998 }
999 this->setColorType(GrColorType::kRGBA_8888, { MTLPixelFormatRGBA8Unorm });
1000 this->setColorType(GrColorType::kRGBA_8888_SRGB, { MTLPixelFormatRGBA8Unorm_sRGB });
1001 this->setColorType(GrColorType::kRGB_888x, { MTLPixelFormatRGBA8Unorm });
1002 this->setColorType(GrColorType::kRG_88, { MTLPixelFormatRG8Unorm });
1003 this->setColorType(GrColorType::kBGRA_8888, { MTLPixelFormatBGRA8Unorm });
1004 this->setColorType(GrColorType::kRGBA_1010102, { MTLPixelFormatRGB10A2Unorm });
1005 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
1006 this->setColorType(GrColorType::kBGRA_1010102, { MTLPixelFormatBGR10A2Unorm });
1007 }
1008 this->setColorType(GrColorType::kGray_8, { MTLPixelFormatR8Unorm });
1009 this->setColorType(GrColorType::kAlpha_F16, { MTLPixelFormatR16Float });
1010 this->setColorType(GrColorType::kRGBA_F16, { MTLPixelFormatRGBA16Float });
1011 this->setColorType(GrColorType::kRGBA_F16_Clamped, { MTLPixelFormatRGBA16Float });
1012 this->setColorType(GrColorType::kAlpha_16, { MTLPixelFormatR16Unorm });
1013 this->setColorType(GrColorType::kRG_1616, { MTLPixelFormatRG16Unorm });
1014 this->setColorType(GrColorType::kRGBA_16161616, { MTLPixelFormatRGBA16Unorm });
1015 this->setColorType(GrColorType::kRG_F16, { MTLPixelFormatRG16Float });
1016}
1017
1018void GrMtlCaps::initStencilFormat(id<MTLDevice> physDev) {
1019 fPreferredStencilFormat = MTLPixelFormatStencil8;
1020}
1021
1022bool GrMtlCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
1023 if (auto rt = surface->asRenderTarget()) {
1024 return rt->numSamples() <= 1 && SkToBool(surface->asTexture());
1025 }
1026 return true;
1027}
1028
1030 const GrSurface* surface) const {
1031 if (auto tex = static_cast<const GrMtlTexture*>(surface->asTexture())) {
1032 // We disallow reading back directly from compressed textures.
1033 if (skgpu::MtlFormatIsCompressed(tex->attachment()->mtlFormat())) {
1035 }
1036 }
1037
1038 if (auto mtlRT = static_cast<const GrMtlRenderTarget*>(surface->asRenderTarget())) {
1039 if (mtlRT->numSamples() > 1 && !mtlRT->resolveAttachment()) {
1041 }
1042 }
1044}
1045
1047 GrColorType ct) const {
1048 // If the src is a MSAA RT then the only supported copy action (not considering falling back
1049 // to a draw) is to resolve from the MSAA src to the non-MSAA dst. Currently we only support
1050 // resolving the entire texture to a resolve buffer of the same size.
1051 DstCopyRestrictions restrictions = {};
1052 if (auto rtProxy = src->asRenderTargetProxy()) {
1053 if (rtProxy->numSamples() > 1) {
1054 restrictions.fMustCopyWholeSrc = true;
1056 }
1057 }
1058 return restrictions;
1059}
1060
1061bool GrMtlCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
1062 const GrBackendFormat& format) const {
1063 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
1064
1065 const auto& info = this->getFormatInfo(mtlFormat);
1066 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1067 if (info.fColorTypeInfos[i].fColorType == ct) {
1068 return true;
1069 }
1070 }
1071 return false;
1072}
1073
1074GrBackendFormat GrMtlCaps::onGetDefaultBackendFormat(GrColorType ct) const {
1075 MTLPixelFormat format = this->getFormatFromColorType(ct);
1076 if (!format) {
1077 return {};
1078 }
1080}
1081
1083 SkTextureCompressionType compressionType) const {
1084 switch (compressionType) {
1086 return {};
1088 if (@available(macOS 11.0, *)) {
1089 if (this->isApple()) {
1090 return GrBackendFormats::MakeMtl(MTLPixelFormatETC2_RGB8);
1091 } else {
1092 return {};
1093 }
1094 } else {
1095 return {};
1096 }
1098 // Metal only supports the RGBA BC1 variant (see following)
1099 return {};
1101#ifdef SK_BUILD_FOR_MAC
1102 if (this->isMac()) {
1103 return GrBackendFormats::MakeMtl(MTLPixelFormatBC1_RGBA);
1104 } else {
1105 return {};
1106 }
1107#else
1108 return {};
1109#endif
1110
1111 }
1112 SK_ABORT("Invalid compression type");
1113}
1114
1115skgpu::Swizzle GrMtlCaps::onGetReadSwizzle(const GrBackendFormat& format,
1116 GrColorType colorType) const {
1117 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
1118 SkASSERT(mtlFormat != MTLPixelFormatInvalid);
1119 const auto& info = this->getFormatInfo(mtlFormat);
1120 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1121 const auto& ctInfo = info.fColorTypeInfos[i];
1122 if (ctInfo.fColorType == colorType) {
1123 return ctInfo.fReadSwizzle;
1124 }
1125 }
1126 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.", (int)colorType,
1127 static_cast<int>(mtlFormat));
1128 return {};
1129}
1130
1132 GrColorType colorType) const {
1133 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
1134 SkASSERT(mtlFormat != MTLPixelFormatInvalid);
1135 const auto& info = this->getFormatInfo(mtlFormat);
1136 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1137 const auto& ctInfo = info.fColorTypeInfos[i];
1138 if (ctInfo.fColorType == colorType) {
1139 return ctInfo.fWriteSwizzle;
1140 }
1141 }
1142 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.", (int)colorType,
1143 static_cast<int>(mtlFormat));
1144 return {};
1145}
1146
1148 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);
1149 SkASSERT(mtlFormat != MTLPixelFormatInvalid);
1150 // A MTLPixelFormat is an NSUInteger type which is documented to be 32 bits in 32 bit
1151 // applications and 64 bits in 64 bit applications. So it should fit in an uint64_t, but adding
1152 // the assert heere to make sure.
1153 static_assert(sizeof(MTLPixelFormat) <= sizeof(uint64_t));
1154 return (uint64_t)mtlFormat;
1155}
1156
1158 GrColorType surfaceColorType, const GrBackendFormat& surfaceFormat,
1159 GrColorType srcColorType) const {
1160 // Metal requires the destination offset for copyFromTexture to be a multiple of the textures
1161 // pixels size.
1162 size_t offsetAlignment = GrColorTypeBytesPerPixel(surfaceColorType);
1163
1164 const auto& info = this->getFormatInfo(GrBackendFormatAsMTLPixelFormat(surfaceFormat));
1165 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1166 const auto& ctInfo = info.fColorTypeInfos[i];
1167 if (ctInfo.fColorType == surfaceColorType) {
1168 return {surfaceColorType, offsetAlignment};
1169 }
1170 }
1171 return {GrColorType::kUnknown, 0};
1172}
1173
1174GrCaps::SupportedRead GrMtlCaps::onSupportedReadPixelsColorType(
1175 GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
1176 GrColorType dstColorType) const {
1177 SkTextureCompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
1178 if (compression != SkTextureCompressionType::kNone) {
1179#ifdef SK_BUILD_FOR_IOS
1180 // Reading back to kRGB_888x doesn't work on Metal/iOS (skbug.com/9839)
1181 return { GrColorType::kUnknown, 0 };
1182#else
1185#endif
1186 }
1187
1188 // Metal requires the destination offset for copyFromTexture to be a multiple of the textures
1189 // pixels size.
1190 size_t offsetAlignment = GrColorTypeBytesPerPixel(srcColorType);
1191 MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(srcBackendFormat);
1192
1193 const auto& info = this->getFormatInfo(mtlFormat);
1194 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1195 const auto& ctInfo = info.fColorTypeInfos[i];
1196 if (ctInfo.fColorType == srcColorType) {
1197 return {srcColorType, offsetAlignment};
1198 }
1199 }
1200 return {GrColorType::kUnknown, 0};
1201}
1202
1203/**
1204 * For Metal we want to cache the entire pipeline for reuse of draws. The Desc here holds all
1205 * the information needed to differentiate one pipeline from another.
1206 *
1207 * The GrProgramDesc contains all the information need to create the actual shaders for the
1208 * pipeline.
1209 *
1210 * For Metal we need to add to the GrProgramDesc to include the rest of the state on the
1211 * pipeline. This includes blending information and primitive type. The pipeline is immutable
1212 * so any remaining dynamic state is set via the MtlRenderCmdEncoder.
1213 */
1215 ProgramDescOverrideFlags overrideFlags) const {
1216 SkASSERT(overrideFlags == ProgramDescOverrideFlags::kNone);
1218 GrProgramDesc::Build(&desc, programInfo, *this);
1219
1220 skgpu::KeyBuilder b(desc.key());
1221
1222 // If ordering here is changed, update getStencilPixelFormat() below
1223 b.add32(GrBackendFormats::AsMtlFormat(programInfo.backendFormat()));
1224
1225 b.add32(programInfo.numSamples());
1226
1227 b.add32(programInfo.needsStencil() ? this->preferredStencilFormat() : MTLPixelFormatInvalid);
1228 b.add32((uint32_t)programInfo.isStencilEnabled());
1229 // Stencil samples don't seem to be tracked in the MTLRenderPipeline
1230
1231 programInfo.pipeline().genKey(&b, *this);
1232
1233 b.add32(programInfo.primitiveTypeKey());
1234
1235 b.flush();
1236 return desc;
1237}
1238
1240 // Set up read buffer to point to platform-dependent part of the key
1241 SkReadBuffer readBuffer(desc.asKey() + desc.initialKeyLength()/sizeof(uint32_t),
1242 desc.keyLength() - desc.initialKeyLength());
1243 // skip backend format
1244 readBuffer.readUInt();
1245 // skip raster samples
1246 readBuffer.readUInt();
1247
1248 return (MTLPixelFormat) readBuffer.readUInt();
1249}
1250
1252 return rt->resolveAttachment() &&
1254 (rt->numSamples() > 1 && this->preferDiscardableMSAAAttachment());
1255}
1256
1257#if defined(GR_TEST_UTILS)
1258std::vector<GrTest::TestFormatColorTypeCombination> GrMtlCaps::getTestingCombinations() const {
1259 std::vector<GrTest::TestFormatColorTypeCombination> combos = {
1260 { GrColorType::kAlpha_8, GrBackendFormats::MakeMtl(MTLPixelFormatA8Unorm) },
1261 { GrColorType::kAlpha_8, GrBackendFormats::MakeMtl(MTLPixelFormatR8Unorm) },
1264 { GrColorType::kRGBA_8888, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA8Unorm) },
1265 { GrColorType::kRGBA_8888_SRGB, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA8Unorm_sRGB) },
1266 { GrColorType::kRGB_888x, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA8Unorm) },
1268#ifdef SK_BUILD_FOR_MAC
1269 { GrColorType::kRGBA_8888, GrBackendFormats::MakeMtl(MTLPixelFormatBC1_RGBA) },
1270#endif
1271 { GrColorType::kRG_88, GrBackendFormats::MakeMtl(MTLPixelFormatRG8Unorm) },
1272 { GrColorType::kBGRA_8888, GrBackendFormats::MakeMtl(MTLPixelFormatBGRA8Unorm) },
1273 { GrColorType::kRGBA_1010102, GrBackendFormats::MakeMtl(MTLPixelFormatRGB10A2Unorm) },
1274 { GrColorType::kBGRA_1010102, GrBackendFormats::MakeMtl(MTLPixelFormatBGR10A2Unorm) },
1275 { GrColorType::kGray_8, GrBackendFormats::MakeMtl(MTLPixelFormatR8Unorm) },
1276 { GrColorType::kAlpha_F16, GrBackendFormats::MakeMtl(MTLPixelFormatR16Float) },
1277 { GrColorType::kRGBA_F16, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA16Float) },
1278 { GrColorType::kRGBA_F16_Clamped, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA16Float) },
1279 { GrColorType::kAlpha_16, GrBackendFormats::MakeMtl(MTLPixelFormatR16Unorm) },
1280 { GrColorType::kRG_1616, GrBackendFormats::MakeMtl(MTLPixelFormatRG16Unorm) },
1281 { GrColorType::kRGBA_16161616, GrBackendFormats::MakeMtl(MTLPixelFormatRGBA16Unorm) },
1282 { GrColorType::kRG_F16, GrBackendFormats::MakeMtl(MTLPixelFormatRG16Float) },
1283 };
1284
1285 return combos;
1286}
1287#endif
1288
1289#ifdef SK_ENABLE_DUMP_GPU
1290#include "src/utils/SkJSONWriter.h"
1291void GrMtlCaps::onDumpJSON(SkJSONWriter* writer) const {
1292
1293 // We are called by the base class, which has already called beginObject(). We choose to nest
1294 // all of our caps information in a named sub-object.
1295 writer->beginObject("Metal caps");
1296
1297 writer->beginObject("Preferred Stencil Format");
1298 writer->appendS32("stencil bits", GrMtlFormatStencilBits(fPreferredStencilFormat));
1299 writer->appendS32("total bytes", skgpu::MtlFormatBytesPerBlock(fPreferredStencilFormat));
1300 writer->endObject();
1301
1302 switch (fGPUFamily) {
1303 case GPUFamily::kMac:
1304 writer->appendNString("GPU Family", "Mac");
1305 break;
1306 case GPUFamily::kApple:
1307 writer->appendNString("GPU Family", "Apple");
1308 break;
1309 default:
1310 writer->appendNString("GPU Family", "unknown");
1311 break;
1312 }
1313 writer->appendS32("Family Group", fFamilyGroup);
1314
1315 writer->beginArray("Sample Counts");
1316 for (int v : fSampleCounts) {
1317 writer->appendS32(nullptr, v);
1318 }
1319 writer->endArray();
1320
1321 writer->endObject();
1322}
1323#else
1325#endif
1326
1327GR_NORETAIN_END
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
SkTextureCompressionType GrBackendFormatToCompressionType(const GrBackendFormat &format)
static constexpr MTLPixelFormat kMtlFormats[]
Definition: GrMtlCaps.mm:592
#define kMTLPixelFormatB5G6R5Unorm
Definition: GrMtlCaps.mm:586
#define kMTLPixelFormatETC2_RGB8
Definition: GrMtlCaps.mm:588
static bool format_is_srgb(MTLPixelFormat format)
Definition: GrMtlCaps.mm:452
#define kMTLPixelFormatABGR4Unorm
Definition: GrMtlCaps.mm:587
int GrMtlFormatStencilBits(MTLPixelFormat)
Definition: GrMtlUtil.mm:302
static MTLPixelFormat GrBackendFormatAsMTLPixelFormat(const GrBackendFormat &format)
Definition: GrMtlUtil.h:106
static constexpr size_t GrColorTypeBytesPerPixel(GrColorType ct)
Definition: GrTypesPriv.h:896
static const int kGrColorTypeCnt
Definition: GrTypesPriv.h:587
GrTextureType
Definition: GrTypesPriv.h:268
GrColorType
Definition: GrTypesPriv.h:540
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkDEBUGFAILF(fmt,...)
Definition: SkAssert.h:119
#define SkASSERT(cond)
Definition: SkAssert.h:116
static constexpr bool SkTextureCompressionTypeIsOpaque(SkTextureCompressionType compression)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
SkTextureCompressionType
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
SurfaceReadPixelsSupport
Definition: GrCaps.h:296
bool fDynamicStateArrayGeometryProcessorTextureSupport
Definition: GrCaps.h:646
int fMaxPreferredRenderTargetSize
Definition: GrCaps.h:658
int fMaxVertexAttributes
Definition: GrCaps.h:659
bool fFinishedProcAsyncCallbackSupport
Definition: GrCaps.h:640
int fMaxRenderTargetSize
Definition: GrCaps.h:657
bool fReadPixelsRowBytesSupport
Definition: GrCaps.h:621
const GrShaderCaps * shaderCaps() const
Definition: GrCaps.h:63
std::unique_ptr< GrShaderCaps > fShaderCaps
Definition: GrCaps.h:584
bool fReuseScratchTextures
Definition: GrCaps.h:589
bool fNativeDrawIndirectSupport
Definition: GrCaps.h:596
bool fAnisoSupport
Definition: GrCaps.h:588
uint32_t fMaxPushConstantsSize
Definition: GrCaps.h:663
bool fTransferFromBufferToBufferSupport
Definition: GrCaps.h:618
bool fTransferFromBufferToTextureSupport
Definition: GrCaps.h:616
bool fTextureBarrierSupport
Definition: GrCaps.h:593
bool fBuffersAreInitiallyZero
Definition: GrCaps.h:607
bool fTransferPixelsToRowBytesSupport
Definition: GrCaps.h:620
int fBufferMapThreshold
Definition: GrCaps.h:655
bool preferDiscardableMSAAAttachment() const
Definition: GrCaps.h:107
bool fBackendSemaphoreSupport
Definition: GrCaps.h:639
bool fHalfFloatVertexAttributeSupport
Definition: GrCaps.h:610
bool fClampToBorderSupport
Definition: GrCaps.h:611
bool fSampleLocationsSupport
Definition: GrCaps.h:594
bool fGpuTracingSupport
Definition: GrCaps.h:591
bool fOversizedStencilSupport
Definition: GrCaps.h:592
bool fSemaphoreSupport
Definition: GrCaps.h:638
bool fMipmapSupport
Definition: GrCaps.h:587
ProgramDescOverrideFlags
Definition: GrCaps.h:511
uint32_t fMapBufferFlags
Definition: GrCaps.h:654
bool fPerformPartialClearsAsDraws
Definition: GrCaps.h:612
bool fWritePixelsRowBytesSupport
Definition: GrCaps.h:619
size_t fTransferBufferRowBytesAlignment
Definition: GrCaps.h:664
bool fNPOTTextureTileSupport
Definition: GrCaps.h:586
bool fTransferFromSurfaceToBufferSupport
Definition: GrCaps.h:617
void finishInitialization(const GrContextOptions &options)
Definition: GrCaps.cpp:107
@ kCanMap_MapFlag
Definition: GrCaps.h:199
@ kAsyncRead_MapFlag
Definition: GrCaps.h:202
size_t fBufferUpdateDataPreserveAlignment
Definition: GrCaps.h:666
bool fPreferDiscardableMSAAAttachment
Definition: GrCaps.h:601
bool fDrawInstancedSupport
Definition: GrCaps.h:595
size_t fTransferFromBufferToBufferAlignment
Definition: GrCaps.h:665
int fMaxTextureSize
Definition: GrCaps.h:660
bool fCrossContextTextureSupport
Definition: GrCaps.h:643
bool framebufferOnly() const
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface *) const override
Definition: GrMtlCaps.mm:1029
bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat &format, int sampleCount=1) const override
Definition: GrMtlCaps.mm:476
int maxRenderTargetSampleCount(const GrBackendFormat &) const override
Definition: GrMtlCaps.mm:498
bool isApple() const
Definition: GrMtlCaps.h:90
DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy *src, GrColorType ct) const override
Definition: GrMtlCaps.mm:1046
bool isFormatSRGB(const GrBackendFormat &) const override
Definition: GrMtlCaps.mm:462
bool isMac() const
Definition: GrMtlCaps.h:89
MTLPixelFormat getFormatFromColorType(GrColorType colorType) const
Definition: GrMtlCaps.h:75
bool canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount, MTLPixelFormat srcFormat, int srcSampleCount, const SkIRect &srcRect, const SkIPoint &dstPoint, bool areDstSrcSameObj) const
Definition: GrMtlCaps.mm:268
bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const override
Definition: GrMtlCaps.mm:466
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const override
Definition: GrMtlCaps.mm:512
bool canCopyAsResolve(MTLPixelFormat dstFormat, int dstSampleCount, MTLPixelFormat srcFormat, int srcSampleCount, bool srcIsRenderTarget, const SkISize srcDimensions, const SkIRect &srcRect, const SkIPoint &dstPoint, bool areDstSrcSameObj) const
Definition: GrMtlCaps.mm:288
GrBackendFormat getBackendFormatFromCompressionType(SkTextureCompressionType) const override
Definition: GrMtlCaps.mm:1082
SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, const GrBackendFormat &surfaceFormat, GrColorType srcColorType) const override
Definition: GrMtlCaps.mm:1157
skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const override
Definition: GrMtlCaps.mm:1131
uint64_t computeFormatKey(const GrBackendFormat &) const override
Definition: GrMtlCaps.mm:1147
GrMtlCaps(const GrContextOptions &contextOptions, id< MTLDevice > device)
Definition: GrMtlCaps.mm:40
bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const override
Definition: GrMtlCaps.mm:490
void onDumpJSON(SkJSONWriter *) const override
Definition: GrMtlCaps.mm:1324
MTLPixelFormat getStencilPixelFormat(const GrProgramDesc &desc) const
Definition: GrMtlCaps.mm:1239
bool renderTargetSupportsDiscardableMSAA(const GrMtlRenderTarget *) const
Definition: GrMtlCaps.mm:1251
GrProgramDesc makeDesc(GrRenderTarget *, const GrProgramInfo &, ProgramDescOverrideFlags) const override
Definition: GrMtlCaps.mm:1214
GrMtlAttachment * resolveAttachment() const
void genKey(skgpu::KeyBuilder *, const GrCaps &) const
Definition: GrPipeline.cpp:79
static void Build(GrProgramDesc *, const GrProgramInfo &, const GrCaps &)
uint16_t primitiveTypeKey() const
Definition: GrProgramInfo.h:54
int numSamples() const
Definition: GrProgramInfo.h:29
const GrPipeline & pipeline() const
Definition: GrProgramInfo.h:39
bool isStencilEnabled() const
Definition: GrProgramInfo.h:31
int needsStencil() const
Definition: GrProgramInfo.h:30
const GrBackendFormat & backendFormat() const
Definition: GrProgramInfo.h:37
int numSamples() const
const GrBackendFormat & backendFormat() const
void appendS32(int32_t value)
Definition: SkJSONWriter.h:237
void appendNString(char const (&value)[N])
Definition: SkJSONWriter.h:220
void beginArray(const char *name=nullptr, bool multiline=true)
Definition: SkJSONWriter.h:146
void beginObject(const char *name=nullptr, bool multiline=true)
Definition: SkJSONWriter.h:114
void endObject()
Definition: SkJSONWriter.h:126
void endArray()
Definition: SkJSONWriter.h:158
uint32_t readUInt()
int size() const
Definition: SkTDArray.h:138
void push_back(const T &v)
Definition: SkTDArray.h:219
static constexpr Swizzle RGB1()
Definition: Swizzle.h:69
VkDevice device
Definition: main.cc:53
VkSurfaceKHR surface
Definition: main.cc:49
static bool b
uint32_t uint32_t * format
static float max(float r, float g, float b)
Definition: hsl.cpp:49
SK_API GrBackendFormat MakeMtl(GrMTLPixelFormat format)
SK_API GrMTLPixelFormat AsMtlFormat(const GrBackendFormat &)
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
dst
Definition: cp.py:12
bool MtlFormatIsCompressed(MTLPixelFormat mtlFormat)
Definition: MtlUtils.mm:60
size_t MtlFormatBytesPerBlock(MTLPixelFormat mtlFormat)
Definition: MtlUtils.mm:130
GrSurfaceProxy::RectsMustMatch fRectsMustMatch
Definition: GrCaps.h:458
bool fDisableDriverCorrectnessWorkarounds
bool fDstReadInShaderSupport
Definition: GrShaderCaps.h:34
bool fHalfIs32Bits
Definition: GrShaderCaps.h:42
int fMaxFragmentSamplers
Definition: GrShaderCaps.h:71
bool fPreferFlatInterpolation
Definition: GrShaderCaps.h:35
bool fVertexIDSupport
Definition: GrShaderCaps.h:36
bool fNonconstantArrayIndexSupport
Definition: GrShaderCaps.h:39
constexpr int32_t y() const
Definition: SkPoint_impl.h:52
static constexpr SkIPoint Make(int32_t x, int32_t y)
Definition: SkPoint_impl.h:38
constexpr int32_t x() const
Definition: SkPoint_impl.h:46
Definition: SkRect.h:32
bool intersect(const SkIRect &r)
Definition: SkRect.h:513
constexpr SkISize size() const
Definition: SkRect.h:172
constexpr int32_t height() const
Definition: SkRect.h:165
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
constexpr int32_t width() const
Definition: SkRect.h:158
constexpr SkIPoint topLeft() const
Definition: SkRect.h:151
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
Definition: SkSize.h:16
bool fFBFetchNeedsCustomOutput
Definition: SkSLUtil.h:94
bool fExplicitTextureLodSupport
Definition: SkSLUtil.h:87
bool fFBFetchSupport
Definition: SkSLUtil.h:93
bool fDualSourceBlendingSupport
Definition: SkSLUtil.h:84
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