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) const override; 43 44 TextureInfo getDefaultStorageTextureInfo(SkColorType) const override; 45 46 UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&, 47 const RenderPassDesc&) const override; 48 UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override; 49 50 bool extractGraphicsDescs(const UniqueKey&, 51 GraphicsPipelineDesc*, 52 RenderPassDesc*, 53 const RendererProvider*) const override; 54 55 // Get a sufficiently unique bit representation for the RenderPassDesc to be embedded in other 56 // UniqueKeys (e.g. makeGraphicsPipelineKey). 57 uint64_t getRenderPassDescKey(const RenderPassDesc&) const; 58 isMac()59 bool isMac() const { return fGPUFamily == GPUFamily::kMac; } isApple()60 bool isApple() const { return fGPUFamily == GPUFamily::kApple; } 61 62 uint32_t channelMask(const TextureInfo&) const override; 63 64 bool isRenderable(const TextureInfo&) const override; 65 bool isStorage(const TextureInfo&) const override; 66 67 void buildKeyForTexture(SkISize dimensions, 68 const TextureInfo&, 69 ResourceType, 70 Shareable, 71 GraphiteResourceKey*) const override; 72 73 private: 74 void initGPUFamily(const id<MTLDevice>); 75 76 void initCaps(const id<MTLDevice>); 77 void initShaderCaps(); 78 void initFormatTable(const id<MTLDevice>); 79 80 enum class GPUFamily { 81 kMac, 82 kApple, 83 }; 84 static bool GetGPUFamily(id<MTLDevice> device, GPUFamily* gpuFamily, int* group); 85 getFormatFromColorType(SkColorType colorType)86 MTLPixelFormat getFormatFromColorType(SkColorType colorType) const { 87 int idx = static_cast<int>(colorType); 88 return fColorTypeToFormatTable[idx]; 89 } 90 MTLPixelFormat getFormatFromDepthStencilFlags(SkEnumBitMask<DepthStencilFlags>) const; 91 92 const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override; 93 94 bool onIsTexturable(const TextureInfo&) const override; 95 bool isTexturable(MTLPixelFormat) const; 96 bool isRenderable(MTLPixelFormat, uint32_t numSamples) const; 97 uint32_t maxRenderTargetSampleCount(MTLPixelFormat) const; 98 99 bool supportsWritePixels(const TextureInfo&) const override; 100 bool supportsReadPixels(const TextureInfo&) const override; 101 102 std::pair<SkColorType, bool /*isRGBFormat*/> supportedWritePixelsColorType( 103 SkColorType dstColorType, 104 const TextureInfo& dstTextureInfo, 105 SkColorType srcColorType) const override; 106 std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType( 107 SkColorType srcColorType, 108 const TextureInfo& srcTextureInfo, 109 SkColorType dstColorType) const override; 110 111 MTLStorageMode getDefaultMSAAStorageMode(Discardable discardable) const; 112 113 struct FormatInfo { colorTypeFlagsFormatInfo114 uint32_t colorTypeFlags(SkColorType colorType) const { 115 for (int i = 0; i < fColorTypeInfoCount; ++i) { 116 if (fColorTypeInfos[i].fColorType == colorType) { 117 return fColorTypeInfos[i].fFlags; 118 } 119 } 120 return 0; 121 } 122 123 enum { 124 kTexturable_Flag = 0x01, 125 kRenderable_Flag = 0x02, // Color attachment and blendable 126 kMSAA_Flag = 0x04, 127 kResolve_Flag = 0x08, 128 kStorage_Flag = 0x10, 129 }; 130 static const uint16_t kAllFlags = 131 kTexturable_Flag | kRenderable_Flag | kMSAA_Flag | kResolve_Flag | kStorage_Flag; 132 133 uint16_t fFlags = 0; 134 135 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 136 int fColorTypeInfoCount = 0; 137 }; 138 #ifdef SK_BUILD_FOR_MAC 139 inline static constexpr size_t kNumMtlFormats = 23; 140 #else 141 inline static constexpr size_t kNumMtlFormats = 21; 142 #endif 143 144 static size_t GetFormatIndex(MTLPixelFormat); 145 FormatInfo fFormatTable[kNumMtlFormats]; 146 getFormatInfo(const MTLPixelFormat pixelFormat)147 const FormatInfo& getFormatInfo(const MTLPixelFormat pixelFormat) const { 148 size_t index = GetFormatIndex(pixelFormat); 149 return fFormatTable[index]; 150 } 151 152 MTLPixelFormat fColorTypeToFormatTable[kSkColorTypeCnt]; 153 void setColorType(SkColorType, std::initializer_list<MTLPixelFormat> formats); 154 155 // A vector of the viable sample counts (e.g., { 1, 2, 4, 8 }). 156 std::vector<uint32_t> fColorSampleCounts; 157 158 GPUFamily fGPUFamily; 159 int fFamilyGroup; 160 }; 161 162 } // namespace skgpu::graphite 163 164 #endif // skgpu_graphite_MtlCaps_DEFINED 165