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/GrMtlStencilAttachment.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     typedef GrMtlStencilAttachment::Format StencilFormat;
25 
26     GrMtlCaps(const GrContextOptions& contextOptions, id<MTLDevice> device,
27               MTLFeatureSet featureSet);
28 
29     bool isFormatSRGB(const GrBackendFormat&) const override;
30     bool isFormatCompressed(const GrBackendFormat&,
31                             SkImage::CompressionType* compressionType = nullptr) const override;
32 
33     bool isFormatTexturableAndUploadable(GrColorType, const GrBackendFormat&) const override;
34     bool isFormatTexturable(const GrBackendFormat&) const override;
35     bool isFormatTexturable(MTLPixelFormat) const;
36 
isFormatCopyable(const GrBackendFormat &)37     bool isFormatCopyable(const GrBackendFormat&) const override { return true; }
38 
39     bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
40                                        int sampleCount = 1) const override;
41     bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override;
42     bool isFormatRenderable(MTLPixelFormat, int sampleCount) const;
43 
44     int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override;
45     int getRenderTargetSampleCount(int requestedCount, MTLPixelFormat) const;
46 
47     int maxRenderTargetSampleCount(const GrBackendFormat&) const override;
48     int maxRenderTargetSampleCount(MTLPixelFormat) const;
49 
50     size_t bytesPerPixel(const GrBackendFormat&) const override;
51     size_t bytesPerPixel(MTLPixelFormat) const;
52 
53     SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType,
54                                                  const GrBackendFormat& surfaceFormat,
55                                                  GrColorType srcColorType) const override;
56 
surfaceSupportsReadPixels(const GrSurface *)57     SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override {
58         return SurfaceReadPixelsSupport::kSupported;
59     }
60 
61     /**
62      * Returns both a supported and most prefered stencil format to use in draws.
63      */
preferredStencilFormat()64     const StencilFormat& preferredStencilFormat() const {
65         return fPreferredStencilFormat;
66     }
67 
68     bool canCopyAsBlit(MTLPixelFormat dstFormat, int dstSampleCount, MTLPixelFormat srcFormat,
69                        int srcSampleCount, const SkIRect& srcRect, const SkIPoint& dstPoint,
70                        bool areDstSrcSameObj) const;
71 
72     bool canCopyAsResolve(GrSurface* dst, int dstSampleCount, GrSurface* src, int srcSampleCount,
73                           const SkIRect& srcRect, const SkIPoint& dstPoint) const;
74 
75     GrColorType getYUVAColorTypeFromBackendFormat(const GrBackendFormat&,
76                                                   bool isAlphaChannel) const override;
77 
78     GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
79 
getFormatFromColorType(GrColorType colorType)80     MTLPixelFormat getFormatFromColorType(GrColorType colorType) const {
81         int idx = static_cast<int>(colorType);
82         return fColorTypeToFormatTable[idx];
83     }
84 
85     GrSwizzle getTextureSwizzle(const GrBackendFormat&, GrColorType) const override;
86     GrSwizzle getOutputSwizzle(const GrBackendFormat&, GrColorType) const override;
87 
88 #if GR_TEST_UTILS
89     std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override;
90 #endif
91 
92 private:
93     void initFeatureSet(MTLFeatureSet featureSet);
94 
95     void initStencilFormat(const id<MTLDevice> device);
96 
97     void initGrCaps(const id<MTLDevice> device);
98     void initShaderCaps();
99 
100     void initFormatTable();
101 
102     bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
103     bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
104                           const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
105     GrBackendFormat onGetDefaultBackendFormat(GrColorType, GrRenderable) const override;
106     GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
107     bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
108 
109     SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
110                                                  GrColorType) const override;
111 
112     // ColorTypeInfo for a specific format
113     struct ColorTypeInfo {
114         GrColorType fColorType = GrColorType::kUnknown;
115         enum {
116             kUploadData_Flag = 0x1,
117             // Does Ganesh itself support rendering to this colorType & format pair. Renderability
118             // still additionally depends on if the format itself is renderable.
119             kRenderable_Flag = 0x2,
120         };
121         uint32_t fFlags = 0;
122 
123         GrSwizzle fTextureSwizzle;
124         GrSwizzle fOutputSwizzle;
125     };
126 
127     struct FormatInfo {
colorTypeFlagsFormatInfo128         uint32_t colorTypeFlags(GrColorType colorType) const {
129             for (int i = 0; i < fColorTypeInfoCount; ++i) {
130                 if (fColorTypeInfos[i].fColorType == colorType) {
131                     return fColorTypeInfos[i].fFlags;
132                 }
133             }
134             return 0;
135         }
136 
137         enum {
138             kTexturable_Flag  = 0x1,
139             kRenderable_Flag  = 0x2, // Color attachment and blendable
140             kMSAA_Flag        = 0x4,
141             kResolve_Flag     = 0x8,
142         };
143         static const uint16_t kAllFlags = kTexturable_Flag | kRenderable_Flag |
144                                           kMSAA_Flag | kResolve_Flag;
145 
146         uint16_t fFlags = 0;
147 
148         // This value is only valid for regular formats. Compressed formats will be 0.
149         size_t fBytesPerPixel = 0;
150 
151         std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
152         int fColorTypeInfoCount = 0;
153     };
154 #ifdef SK_BUILD_FOR_IOS
155     static constexpr size_t kNumMtlFormats = 17;
156 #else
157     static constexpr size_t kNumMtlFormats = 14;
158 #endif
159     static size_t GetFormatIndex(MTLPixelFormat);
160     FormatInfo fFormatTable[kNumMtlFormats];
161 
getFormatInfo(const MTLPixelFormat pixelFormat)162     const FormatInfo& getFormatInfo(const MTLPixelFormat pixelFormat) const {
163         size_t index = GetFormatIndex(pixelFormat);
164         return fFormatTable[index];
165     }
166 
167     MTLPixelFormat fColorTypeToFormatTable[kGrColorTypeCnt];
168     void setColorType(GrColorType, std::initializer_list<MTLPixelFormat> formats);
169 
170     enum class Platform {
171         kMac,
172         kIOS
173     };
isMac()174     bool isMac() { return Platform::kMac == fPlatform; }
isIOS()175     bool isIOS() { return Platform::kIOS == fPlatform; }
176 
177     Platform fPlatform;
178     int fFamilyGroup;
179     int fVersion;
180 
181     SkTDArray<int> fSampleCounts;
182 
183     StencilFormat fPreferredStencilFormat;
184 
185     typedef GrCaps INHERITED;
186 };
187 
188 #endif
189