1 /*
2  * Copyright 2017 Google Inc.
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 GrMtlCaps_DEFINED
9 #define GrMtlCaps_DEFINED
10 
11 #include "include/private/SkTDArray.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/mtl/GrMtlAttachment.h"
14 
15 #import <Metal/Metal.h>
16 
17 class GrShaderCaps;
18 
19 /**
20  * Stores some capabilities of a Mtl backend.
21  */
22 class GrMtlCaps : public GrCaps {
23 public:
24     GrMtlCaps(const GrContextOptions& contextOptions, id<MTLDevice> device,
25               MTLFeatureSet featureSet);
26 
27     bool isFormatSRGB(const GrBackendFormat&) const override;
28 
29     bool isFormatTexturable(const GrBackendFormat&) const override;
30     bool isFormatTexturable(MTLPixelFormat) const;
31 
isFormatCopyable(const GrBackendFormat &)32     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
33 
34     bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
35                                        int sampleCount = 1) const override;
36     bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
37     bool isFormatRenderable(MTLPixelFormat, int sampleCount) const;
38 
39     int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
40     int getRenderTargetSampleCount(int requestedCount, MTLPixelFormat) const;
41 
42     int maxRenderTargetSampleCount(const GrBackendFormat&) const override;
43     int maxRenderTargetSampleCount(MTLPixelFormat) const;
44 
45     SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
46                                                  const GrBackendFormat& surfaceFormat,
47                                                  GrColorType srcColorType) const override;
48 
49     SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
50 
51     DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src,
52                                                GrColorType ct) const override;
53 
54     /**
55      * Returns both a supported and most prefered stencil format to use in draws.
56      */
preferredStencilFormat()57     MTLPixelFormat preferredStencilFormat() const {
58         return fPreferredStencilFormat;
59     }
60 
61     bool canCopyAsBlit(GrSurface* dst,
62                        GrSurface* src,
63                        const SkIRect& srcRect,
64                        const SkIPoint& dstPoint) const;
65 
66     bool canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount,
67                        MTLPixelFormat srcFormat, int srcSampleCount,
68                        const SkIRect& srcRect, const SkIPoint& dstPoint,
69                        bool areDstSrcSameObj) const;
70 
71     bool canCopyAsResolve(GrSurface* dst,
72                           GrSurface* src,
73                           const SkIRect& srcRect,
74                           const SkIPoint& dstPoint) const;
75 
76     bool canCopyAsResolve(MTLPixelFormat dstFormat, int dstSampleCount,
77                           MTLPixelFormat srcFormat, int srcSampleCount,
78                           bool srcIsRenderTarget, const SkISize srcDimensions,
79                           const SkIRect& srcRect,
80                           const SkIPoint& dstPoint,
81                           bool areDstSrcSameObj) const;
82 
83     GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
84 
getFormatFromColorType(GrColorType colorType)85     MTLPixelFormat getFormatFromColorType(GrColorType colorType) const {
86         int idx = static_cast<int>(colorType);
87         return fColorTypeToFormatTable[idx];
88     }
89 
90     GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override;
91 
92     uint64_t computeFormatKey(const GrBackendFormat&) const override;
93 
94     GrProgramDesc makeDesc(GrRenderTarget*, const GrProgramInfo&) const override;
95 
96 #if GR_TEST_UTILS
97     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
98 #endif
99     void onDumpJSON(SkJSONWriter*) const override;
100 
101 private:
102     void initFeatureSet(MTLFeatureSet featureSet);
103 
104     void initStencilFormat(const id<MTLDevice> device);
105 
106     void initGrCaps(const id<MTLDevice> device);
107     void initShaderCaps();
108 
109     void initFormatTable();
110 
111     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
112     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
113                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
114     GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override;
115     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
116 
117     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
118                                                  GrColorType) const override;
119 
120     GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
121 
122     // ColorTypeInfo for a specific format
123     struct ColorTypeInfo {
124         GrColorType fColorType = GrColorType::kUnknown;
125         enum {
126             kUploadData_Flag = 0x1,
127             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
128             // still additionally depends on if the format itself is renderable.
129             kRenderable_Flag = 0x2,
130         };
131         uint32_t fFlags = 0;
132 
133         GrSwizzle fReadSwizzle;
134         GrSwizzle fWriteSwizzle;
135     };
136 
137     struct FormatInfo {
colorTypeFlagsFormatInfo138         uint32_t colorTypeFlags(GrColorType colorType) const {
139             for (int i = 0; i < fColorTypeInfoCount; ++i) {
140                 if (fColorTypeInfos[i].fColorType == colorType) {
141                     return fColorTypeInfos[i].fFlags;
142                 }
143             }
144             return 0;
145         }
146 
147         enum {
148             kTexturable_Flag  = 0x1,
149             kRenderable_Flag  = 0x2, // Color attachment and blendable
150             kMSAA_Flag        = 0x4,
151             kResolve_Flag     = 0x8,
152         };
153         static const uint16_t kAllFlags = kTexturable_Flag | kRenderable_Flag |
154                                           kMSAA_Flag | kResolve_Flag;
155 
156         uint16_t fFlags = 0;
157 
158         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
159         int fColorTypeInfoCount = 0;
160     };
161 #ifdef SK_BUILD_FOR_IOS
162     static constexpr size_t kNumMtlFormats = 17;
163 #else
164     static constexpr size_t kNumMtlFormats = 16;
165 #endif
166     static size_t GetFormatIndex(MTLPixelFormat);
167     FormatInfo fFormatTable[kNumMtlFormats];
168 
getFormatInfo(const MTLPixelFormat pixelFormat)169     const FormatInfo& getFormatInfo(const MTLPixelFormat pixelFormat) const {
170         size_t index = GetFormatIndex(pixelFormat);
171         return fFormatTable[index];
172     }
173 
174     MTLPixelFormat fColorTypeToFormatTable[kGrColorTypeCnt];
175     void setColorType(GrColorType, std::initializer_list<MTLPixelFormat> formats);
176 
177     enum class Platform {
178         kMac,
179         kIOS
180     };
isMac()181     bool isMac() { return Platform::kMac == fPlatform; }
isIOS()182     bool isIOS() { return Platform::kIOS == fPlatform; }
183 
184     Platform fPlatform;
185     int fFamilyGroup;
186     int fVersion;
187 
188     SkTDArray<int> fSampleCounts;
189 
190     MTLPixelFormat fPreferredStencilFormat;
191 
192     using INHERITED = GrCaps;
193 };
194 
195 #endif
196