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