1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef GrMtlCaps_DEFINED 9cb93a386Sopenharmony_ci#define GrMtlCaps_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 13cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlAttachment.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#import <Metal/Metal.h> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciclass GrShaderCaps; 18cb93a386Sopenharmony_ciclass GrMtlRenderTarget; 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci/** 21cb93a386Sopenharmony_ci * Stores some capabilities of a Mtl backend. 22cb93a386Sopenharmony_ci */ 23cb93a386Sopenharmony_ciclass GrMtlCaps : public GrCaps { 24cb93a386Sopenharmony_cipublic: 25cb93a386Sopenharmony_ci GrMtlCaps(const GrContextOptions& contextOptions, id<MTLDevice> device); 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci bool isFormatSRGB(const GrBackendFormat&) const override; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override; 30cb93a386Sopenharmony_ci bool isFormatTexturable(MTLPixelFormat) const; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci bool isFormatCopyable(const GrBackendFormat&) const override { return true; } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, 35cb93a386Sopenharmony_ci int sampleCount = 1) const override; 36cb93a386Sopenharmony_ci bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; 37cb93a386Sopenharmony_ci bool isFormatRenderable(MTLPixelFormat, int sampleCount) const; 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override; 40cb93a386Sopenharmony_ci int getRenderTargetSampleCount(int requestedCount, MTLPixelFormat) const; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci int maxRenderTargetSampleCount(const GrBackendFormat&) const override; 43cb93a386Sopenharmony_ci int maxRenderTargetSampleCount(MTLPixelFormat) const; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, 46cb93a386Sopenharmony_ci const GrBackendFormat& surfaceFormat, 47cb93a386Sopenharmony_ci GrColorType srcColorType) const override; 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override; 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src, 52cb93a386Sopenharmony_ci GrColorType ct) const override; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci /** 55cb93a386Sopenharmony_ci * Returns both a supported and most prefered stencil format to use in draws. 56cb93a386Sopenharmony_ci */ 57cb93a386Sopenharmony_ci MTLPixelFormat preferredStencilFormat() const { 58cb93a386Sopenharmony_ci return fPreferredStencilFormat; 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci bool canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount, 62cb93a386Sopenharmony_ci MTLPixelFormat srcFormat, int srcSampleCount, 63cb93a386Sopenharmony_ci const SkIRect& srcRect, const SkIPoint& dstPoint, 64cb93a386Sopenharmony_ci bool areDstSrcSameObj) const; 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci bool canCopyAsResolve(MTLPixelFormat dstFormat, int dstSampleCount, 67cb93a386Sopenharmony_ci MTLPixelFormat srcFormat, int srcSampleCount, 68cb93a386Sopenharmony_ci bool srcIsRenderTarget, const SkISize srcDimensions, 69cb93a386Sopenharmony_ci const SkIRect& srcRect, 70cb93a386Sopenharmony_ci const SkIPoint& dstPoint, 71cb93a386Sopenharmony_ci bool areDstSrcSameObj) const; 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci MTLPixelFormat getFormatFromColorType(GrColorType colorType) const { 76cb93a386Sopenharmony_ci int idx = static_cast<int>(colorType); 77cb93a386Sopenharmony_ci return fColorTypeToFormatTable[idx]; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci uint64_t computeFormatKey(const GrBackendFormat&) const override; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci GrProgramDesc makeDesc(GrRenderTarget*, 85cb93a386Sopenharmony_ci const GrProgramInfo&, 86cb93a386Sopenharmony_ci ProgramDescOverrideFlags) const override; 87cb93a386Sopenharmony_ci MTLPixelFormat getStencilPixelFormat(const GrProgramDesc& desc); 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci bool isMac() const { return fGPUFamily == GPUFamily::kMac; } 90cb93a386Sopenharmony_ci bool isApple() const { return fGPUFamily == GPUFamily::kApple; } 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci size_t getMinBufferAlignment() const { return this->isMac() ? 4 : 1; } 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci // if true, MTLStoreActionStoreAndMultiplesampleResolve is available 95cb93a386Sopenharmony_ci bool storeAndMultisampleResolveSupport() const { return fStoreAndMultisampleResolveSupport; } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci // If true when doing MSAA draws, we will prefer to discard the MSAA attachment on load 98cb93a386Sopenharmony_ci // and stores. The use of this feature for specific draws depends on the render target having a 99cb93a386Sopenharmony_ci // resolve attachment, and if we need to load previous data the resolve attachment must 100cb93a386Sopenharmony_ci // be readable in a shader. Otherwise we will just write out and store the MSAA attachment 101cb93a386Sopenharmony_ci // like normal. 102cb93a386Sopenharmony_ci bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; } 103cb93a386Sopenharmony_ci bool renderTargetSupportsDiscardableMSAA(const GrMtlRenderTarget*) const; 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci#if GR_TEST_UTILS 106cb93a386Sopenharmony_ci std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override; 107cb93a386Sopenharmony_ci#endif 108cb93a386Sopenharmony_ci void onDumpJSON(SkJSONWriter*) const override; 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ciprivate: 111cb93a386Sopenharmony_ci void initGPUFamily(id<MTLDevice> device); 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci void initStencilFormat(id<MTLDevice> device); 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci void initGrCaps(id<MTLDevice> device); 116cb93a386Sopenharmony_ci void initShaderCaps(); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci void applyDriverCorrectnessWorkarounds(const GrContextOptions&, const id<MTLDevice>); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci void initFormatTable(); 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 123cb93a386Sopenharmony_ci bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 124cb93a386Sopenharmony_ci const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 125cb93a386Sopenharmony_ci GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override; 126cb93a386Sopenharmony_ci bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; 127cb93a386Sopenharmony_ci 128cb93a386Sopenharmony_ci SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, 129cb93a386Sopenharmony_ci GrColorType) const override; 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override; 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci // ColorTypeInfo for a specific format 134cb93a386Sopenharmony_ci struct ColorTypeInfo { 135cb93a386Sopenharmony_ci GrColorType fColorType = GrColorType::kUnknown; 136cb93a386Sopenharmony_ci enum { 137cb93a386Sopenharmony_ci kUploadData_Flag = 0x1, 138cb93a386Sopenharmony_ci // Does Ganesh itself support rendering to this colorType & format pair. Renderability 139cb93a386Sopenharmony_ci // still additionally depends on if the format itself is renderable. 140cb93a386Sopenharmony_ci kRenderable_Flag = 0x2, 141cb93a386Sopenharmony_ci }; 142cb93a386Sopenharmony_ci uint32_t fFlags = 0; 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci GrSwizzle fReadSwizzle; 145cb93a386Sopenharmony_ci GrSwizzle fWriteSwizzle; 146cb93a386Sopenharmony_ci }; 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci struct FormatInfo { 149cb93a386Sopenharmony_ci uint32_t colorTypeFlags(GrColorType colorType) const { 150cb93a386Sopenharmony_ci for (int i = 0; i < fColorTypeInfoCount; ++i) { 151cb93a386Sopenharmony_ci if (fColorTypeInfos[i].fColorType == colorType) { 152cb93a386Sopenharmony_ci return fColorTypeInfos[i].fFlags; 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci return 0; 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci enum { 159cb93a386Sopenharmony_ci kTexturable_Flag = 0x1, 160cb93a386Sopenharmony_ci kRenderable_Flag = 0x2, // Color attachment and blendable 161cb93a386Sopenharmony_ci kMSAA_Flag = 0x4, 162cb93a386Sopenharmony_ci kResolve_Flag = 0x8, 163cb93a386Sopenharmony_ci }; 164cb93a386Sopenharmony_ci static const uint16_t kAllFlags = kTexturable_Flag | kRenderable_Flag | 165cb93a386Sopenharmony_ci kMSAA_Flag | kResolve_Flag; 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci uint16_t fFlags = 0; 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 170cb93a386Sopenharmony_ci int fColorTypeInfoCount = 0; 171cb93a386Sopenharmony_ci }; 172cb93a386Sopenharmony_ci#ifdef SK_BUILD_FOR_IOS 173cb93a386Sopenharmony_ci inline static constexpr size_t kNumMtlFormats = 17; 174cb93a386Sopenharmony_ci#else 175cb93a386Sopenharmony_ci inline static constexpr size_t kNumMtlFormats = 16; 176cb93a386Sopenharmony_ci#endif 177cb93a386Sopenharmony_ci static size_t GetFormatIndex(MTLPixelFormat); 178cb93a386Sopenharmony_ci FormatInfo fFormatTable[kNumMtlFormats]; 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci const FormatInfo& getFormatInfo(const MTLPixelFormat pixelFormat) const { 181cb93a386Sopenharmony_ci size_t index = GetFormatIndex(pixelFormat); 182cb93a386Sopenharmony_ci return fFormatTable[index]; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci MTLPixelFormat fColorTypeToFormatTable[kGrColorTypeCnt]; 186cb93a386Sopenharmony_ci void setColorType(GrColorType, std::initializer_list<MTLPixelFormat> formats); 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci enum class GPUFamily { 189cb93a386Sopenharmony_ci kMac, 190cb93a386Sopenharmony_ci kApple, 191cb93a386Sopenharmony_ci }; 192cb93a386Sopenharmony_ci bool getGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group); 193cb93a386Sopenharmony_ci bool getGPUFamilyFromFeatureSet(id<MTLDevice> device, GrMtlCaps::GPUFamily* gpuFamily, 194cb93a386Sopenharmony_ci int* group); 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci GPUFamily fGPUFamily; 197cb93a386Sopenharmony_ci int fFamilyGroup; 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci SkTDArray<int> fSampleCounts; 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ci MTLPixelFormat fPreferredStencilFormat; 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ci bool fStoreAndMultisampleResolveSupport : 1; 204cb93a386Sopenharmony_ci bool fPreferDiscardableMSAAAttachment : 1; 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci using INHERITED = GrCaps; 207cb93a386Sopenharmony_ci}; 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci#endif 210