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