1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_MtlCaps_DEFINED 9 #define skgpu_graphite_MtlCaps_DEFINED 10 11 #include <vector> 12 13 #import <Metal/Metal.h> 14 15 #include "src/gpu/graphite/Caps.h" 16 17 namespace skgpu::graphite { 18 struct ContextOptions; 19 20 class MtlCaps final : public Caps { 21 public: 22 MtlCaps(const id<MTLDevice>, const ContextOptions&); ~MtlCaps()23 ~MtlCaps() override {} 24 25 TextureInfo getDefaultSampledTextureInfo(SkColorType, 26 Mipmapped mipmapped, 27 Protected, 28 Renderable) const override; 29 30 TextureInfo getTextureInfoForSampledCopy(const TextureInfo& textureInfo, 31 Mipmapped mipmapped) const override; 32 33 TextureInfo getDefaultCompressedTextureInfo(SkTextureCompressionType, 34 Mipmapped mipmapped, 35 Protected) const override; 36 37 TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo, 38 Discardable discardable) const override; 39 40 TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>, 41 uint32_t sampleCount, 42 Protected, 43 Discardable discardable) const override; 44 45 TextureInfo getDefaultStorageTextureInfo(SkColorType) const override; 46 47 UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&, 48 const RenderPassDesc&) const override; 49 UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override; 50 51 bool extractGraphicsDescs(const UniqueKey&, 52 GraphicsPipelineDesc*, 53 RenderPassDesc*, 54 const RendererProvider*) const override; 55 56 bool serializeTextureInfo(const TextureInfo&, SkWStream*) const override; 57 bool deserializeTextureInfo(SkStream*, TextureInfo* out) const override; 58 59 // Get a sufficiently unique bit representation for the RenderPassDesc to be embedded in other 60 // UniqueKeys (e.g. makeGraphicsPipelineKey). 61 uint64_t getRenderPassDescKey(const RenderPassDesc&) const; 62 isMac()63 bool isMac() const { return fGPUFamily == GPUFamily::kMac; } isApple()64 bool isApple() const { return fGPUFamily == GPUFamily::kApple; } 65 66 bool isRenderable(const TextureInfo&) const override; 67 bool isStorage(const TextureInfo&) const override; 68 69 void buildKeyForTexture(SkISize dimensions, 70 const TextureInfo&, 71 ResourceType, 72 GraphiteResourceKey*) const override; 73 74 private: 75 void initGPUFamily(const id<MTLDevice>); 76 77 void initCaps(const id<MTLDevice>); 78 void initShaderCaps(); 79 void initFormatTable(const id<MTLDevice>); 80 81 enum class GPUFamily { 82 kMac, 83 kApple, 84 }; 85 static bool GetGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group); 86 getFormatFromColorType(SkColorType colorType)87 MTLPixelFormat getFormatFromColorType(SkColorType colorType) const { 88 int idx = static_cast<int>(colorType); 89 return fColorTypeToFormatTable[idx]; 90 } 91 MTLPixelFormat getFormatFromDepthStencilFlags(SkEnumBitMask<DepthStencilFlags>) const; 92 93 const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override; 94 95 bool onIsTexturable(const TextureInfo&) const override; 96 bool isTexturable(MTLPixelFormat) const; 97 bool isRenderable(MTLPixelFormat, uint32_t numSamples) const; 98 uint32_t maxRenderTargetSampleCount(MTLPixelFormat) const; 99 100 bool supportsWritePixels(const TextureInfo&) const override; 101 bool supportsReadPixels(const TextureInfo&) const override; 102 103 std::pair<SkColorType, bool /*isRGBFormat*/> supportedWritePixelsColorType( 104 SkColorType dstColorType, 105 const TextureInfo& dstTextureInfo, 106 SkColorType srcColorType) const override; 107 std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType( 108 SkColorType srcColorType, 109 const TextureInfo& srcTextureInfo, 110 SkColorType dstColorType) const override; 111 112 MTLStorageMode getDefaultMSAAStorageMode(Discardable discardable) const; 113 114 struct FormatInfo { colorTypeFlagsFormatInfo115 uint32_t colorTypeFlags(SkColorType colorType) const { 116 for (int i = 0; i < fColorTypeInfoCount; ++i) { 117 if (fColorTypeInfos[i].fColorType == colorType) { 118 return fColorTypeInfos[i].fFlags; 119 } 120 } 121 return 0; 122 } 123 124 enum { 125 kTexturable_Flag = 0x01, 126 kRenderable_Flag = 0x02, // Color attachment and blendable 127 kMSAA_Flag = 0x04, 128 kResolve_Flag = 0x08, 129 kStorage_Flag = 0x10, 130 }; 131 static const uint16_t kAllFlags = 132 kTexturable_Flag | kRenderable_Flag | kMSAA_Flag | kResolve_Flag | kStorage_Flag; 133 134 uint16_t fFlags = 0; 135 136 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 137 int fColorTypeInfoCount = 0; 138 }; 139 #ifdef SK_BUILD_FOR_MAC 140 inline static constexpr size_t kNumMtlFormats = 23; 141 #else 142 inline static constexpr size_t kNumMtlFormats = 21; 143 #endif 144 145 static size_t GetFormatIndex(MTLPixelFormat); 146 FormatInfo fFormatTable[kNumMtlFormats]; 147 getFormatInfo(const MTLPixelFormat pixelFormat)148 const FormatInfo& getFormatInfo(const MTLPixelFormat pixelFormat) const { 149 size_t index = GetFormatIndex(pixelFormat); 150 return fFormatTable[index]; 151 } 152 153 MTLPixelFormat fColorTypeToFormatTable[kSkColorTypeCnt]; 154 void setColorType(SkColorType, std::initializer_list<MTLPixelFormat> formats); 155 156 // A vector of the viable sample counts (e.g., { 1, 2, 4, 8 }). 157 std::vector<uint32_t> fColorSampleCounts; 158 159 GPUFamily fGPUFamily; 160 int fFamilyGroup; 161 }; 162 163 } // namespace skgpu::graphite 164 165 #endif // skgpu_graphite_MtlCaps_DEFINED 166