• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_Caps_DEFINED
9 #define skgpu_graphite_Caps_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/private/base/SkAlign.h"
14 #include "src/core/SkEnumBitMask.h"
15 #include "src/gpu/ResourceKey.h"
16 #include "src/gpu/Swizzle.h"
17 #include "src/gpu/graphite/ResourceTypes.h"
18 #include "src/text/gpu/SDFTControl.h"
19 
20 class SkCapabilities;
21 
22 namespace SkSL { struct ShaderCaps; }
23 
24 namespace skgpu { class ShaderErrorHandler; }
25 
26 namespace skgpu::graphite {
27 
28 enum class BufferType : int;
29 struct ContextOptions;
30 class ComputePipelineDesc;
31 class GraphicsPipelineDesc;
32 class GraphiteResourceKey;
33 struct RenderPassDesc;
34 class TextureInfo;
35 class TextureProxy;
36 
37 struct ResourceBindingRequirements {
38     // The required data layout rules for the contents of a uniform buffer.
39     Layout fUniformBufferLayout = Layout::kInvalid;
40 
41     // The required data layout rules for the contents of a storage buffer.
42     Layout fStorageBufferLayout = Layout::kInvalid;
43 
44     // Whether combined texture-sampler types are supported. Backends that do not support
45     // combined image samplers (i.e. sampler2D) require a texture and sampler object to be bound
46     // separately and their binding indices explicitly specified in the shader text.
47     bool fSeparateTextureAndSamplerBinding = false;
48 
49     // Whether buffer, texture, and sampler resource bindings use distinct index ranges.
50     bool fDistinctIndexRanges = false;
51 };
52 
53 class Caps {
54 public:
55     virtual ~Caps();
56 
shaderCaps()57     const SkSL::ShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
58 
59     sk_sp<SkCapabilities> capabilities() const;
60 
61     virtual TextureInfo getDefaultSampledTextureInfo(SkColorType,
62                                                      Mipmapped mipmapped,
63                                                      Protected,
64                                                      Renderable) const = 0;
65 
66     virtual TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
67                                                   Discardable discardable) const = 0;
68 
69     virtual TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>,
70                                                           uint32_t sampleCount,
71                                                           Protected) const = 0;
72 
73     virtual UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&,
74                                               const RenderPassDesc&) const = 0;
75     virtual UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const = 0;
76 
77     bool areColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo&) const;
78 
79     bool isTexturable(const TextureInfo&) const;
80     virtual bool isRenderable(const TextureInfo&) const = 0;
81 
maxTextureSize()82     int maxTextureSize() const { return fMaxTextureSize; }
83 
84     virtual void buildKeyForTexture(SkISize dimensions,
85                                     const TextureInfo&,
86                                     ResourceType,
87                                     Shareable,
88                                     GraphiteResourceKey*) const = 0;
89 
resourceBindingRequirements()90     const ResourceBindingRequirements& resourceBindingRequirements() const {
91         return fResourceBindingReqs;
92     }
93 
94     // Returns the required alignment in bytes for the offset into a uniform buffer when binding it
95     // to a draw.
requiredUniformBufferAlignment()96     size_t requiredUniformBufferAlignment() const { return fRequiredUniformBufferAlignment; }
97 
98     // Returns the required alignment in bytes for the offset into a storage buffer when binding it
99     // to a draw.
requiredStorageBufferAlignment()100     size_t requiredStorageBufferAlignment() const { return fRequiredStorageBufferAlignment; }
101 
102     // Returns the required alignment in bytes for the offset and size of copies involving a buffer.
requiredTransferBufferAlignment()103     size_t requiredTransferBufferAlignment() const { return fRequiredTransferBufferAlignment; }
104 
105     // Returns the aligned rowBytes when transfering to or from a Texture
getAlignedTextureDataRowBytes(size_t rowBytes)106     size_t getAlignedTextureDataRowBytes(size_t rowBytes) const {
107         return SkAlignTo(rowBytes, fTextureDataRowBytesAlignment);
108     }
109 
110     /**
111      * Backends may have restrictions on what types of textures support Device::writePixels().
112      * If this returns false then the caller should implement a fallback where a temporary texture
113      * is created, pixels are written to it, and then that is copied or drawn into the the surface.
114      */
115     virtual bool supportsWritePixels(const TextureInfo& textureInfo) const = 0;
116 
117     /**
118      * Backends may have restrictions on what types of textures support Device::readPixels().
119      * If this returns false then the caller should implement a fallback where a temporary texture
120      * is created, the original texture is copied or drawn into it, and then pixels read from
121      * the temporary texture.
122      */
123     virtual bool supportsReadPixels(const TextureInfo& textureInfo) const = 0;
124 
125     /**
126      * Given a dst pixel config and a src color type what color type must the caller coax the
127      * the data into in order to use writePixels.
128      */
129     virtual SkColorType supportedWritePixelsColorType(SkColorType dstColorType,
130                                                       const TextureInfo& dstTextureInfo,
131                                                       SkColorType srcColorType) const = 0;
132 
133     /**
134      * Given a src surface's color type and its texture info as well as a color type the caller
135      * would like read into, this provides a legal color type that the caller can use for
136      * readPixels. The returned color type may differ from the passed dstColorType, in
137      * which case the caller must convert the read pixel data (see GrConvertPixels). When converting
138      * to dstColorType the swizzle in the returned struct should be applied. The caller must check
139      * the returned color type for kUnknown.
140      */
141     virtual SkColorType supportedReadPixelsColorType(SkColorType srcColorType,
142                                                      const TextureInfo& srcTextureInfo,
143                                                      SkColorType dstColorType) const = 0;
144 
clampToBorderSupport()145     bool clampToBorderSupport() const { return fClampToBorderSupport; }
146 
protectedSupport()147     bool protectedSupport() const { return fProtectedSupport; }
148 
149     // Returns whether storage buffers are supported.
storageBufferSupport()150     bool storageBufferSupport() const { return fStorageBufferSupport; }
151 
152     // Returns whether storage buffers are preferred over uniform buffers, when both will yield
153     // correct results.
storageBufferPreferred()154     bool storageBufferPreferred() const { return fStorageBufferPreferred; }
155 
156     // Returns whether a draw buffer can be mapped.
drawBufferCanBeMapped()157     bool drawBufferCanBeMapped() const { return fDrawBufferCanBeMapped; }
158 
159     // Returns the skgpu::Swizzle to use when sampling or reading back from a texture with the
160     // passed in SkColorType and TextureInfo.
161     skgpu::Swizzle getReadSwizzle(SkColorType, const TextureInfo&) const;
162 
163     // Returns the skgpu::Swizzle to use when writing colors to a surface with the passed in
164     // SkColorType and TextureInfo.
165     skgpu::Swizzle getWriteSwizzle(SkColorType, const TextureInfo&) const;
166 
shaderErrorHandler()167     skgpu::ShaderErrorHandler* shaderErrorHandler() const { return fShaderErrorHandler; }
168 
minDistanceFieldFontSize()169     float minDistanceFieldFontSize() const { return fMinDistanceFieldFontSize; }
glyphsAsPathsFontSize()170     float glyphsAsPathsFontSize() const { return fGlyphsAsPathsFontSize; }
171 
glyphCacheTextureMaximumBytes()172     size_t glyphCacheTextureMaximumBytes() const { return fGlyphCacheTextureMaximumBytes; }
173 
allowMultipleGlyphCacheTextures()174     bool allowMultipleGlyphCacheTextures() const { return fAllowMultipleGlyphCacheTextures; }
supportBilerpFromGlyphAtlas()175     bool supportBilerpFromGlyphAtlas() const { return fSupportBilerpFromGlyphAtlas; }
176 
177     sktext::gpu::SDFTControl getSDFTControl(bool useSDFTForSmallText) const;
178 
179 protected:
180     Caps();
181 
182     // Subclasses must call this at the end of their init method in order to do final processing on
183     // the caps.
184     void finishInitialization(const ContextOptions&);
185 
186     // TODO: This value should be set by some context option. For now just making it 4.
defaultMSAASamples()187     uint32_t defaultMSAASamples() const { return 4; }
188 
189     // There are only a few possible valid sample counts (1, 2, 4, 8, 16). So we can key on those 5
190     // options instead of the actual sample value.
SamplesToKey(uint32_t numSamples)191     static inline uint32_t SamplesToKey(uint32_t numSamples) {
192         switch (numSamples) {
193             case 1:
194                 return 0;
195             case 2:
196                 return 1;
197             case 4:
198                 return 2;
199             case 8:
200                 return 3;
201             case 16:
202                 return 4;
203             default:
204                 SkUNREACHABLE;
205         }
206     }
207 
208     // ColorTypeInfo for a specific format.
209     // Used in format tables.
210     struct ColorTypeInfo {
211         SkColorType fColorType = kUnknown_SkColorType;
212         SkColorType fTransferColorType = kUnknown_SkColorType;
213         enum {
214             kUploadData_Flag = 0x1,
215             // Does Graphite itself support rendering to this colorType & format pair. Renderability
216             // still additionally depends on if the format itself is renderable.
217             kRenderable_Flag = 0x2,
218         };
219         uint32_t fFlags = 0;
220 
221         skgpu::Swizzle fReadSwizzle;
222         skgpu::Swizzle fWriteSwizzle;
223     };
224 
225     int fMaxTextureSize = 0;
226     size_t fRequiredUniformBufferAlignment = 0;
227     size_t fRequiredStorageBufferAlignment = 0;
228     size_t fRequiredTransferBufferAlignment = 0;
229     size_t fTextureDataRowBytesAlignment = 1;
230 
231     std::unique_ptr<SkSL::ShaderCaps> fShaderCaps;
232 
233     bool fClampToBorderSupport = true;
234     bool fProtectedSupport = false;
235     bool fStorageBufferSupport = false;
236     bool fStorageBufferPreferred = false;
237     bool fDrawBufferCanBeMapped = true;
238 
239     ResourceBindingRequirements fResourceBindingReqs;
240 
241     //////////////////////////////////////////////////////////////////////////////////////////
242     // Client-provided Caps
243 
244     /**
245      * If present, use this object to report shader compilation failures. If not, report failures
246      * via SkDebugf and assert.
247      */
248     ShaderErrorHandler* fShaderErrorHandler = nullptr;
249 
250 #if GRAPHITE_TEST_UTILS
251     int  fMaxTextureAtlasSize = 2048;
252 #endif
253     size_t fGlyphCacheTextureMaximumBytes = 2048 * 1024 * 4;
254 
255     float fMinDistanceFieldFontSize = 18;
256     float fGlyphsAsPathsFontSize = 324;
257 
258     bool fAllowMultipleGlyphCacheTextures = true;
259     bool fSupportBilerpFromGlyphAtlas = false;
260 
261 private:
262     virtual bool onIsTexturable(const TextureInfo&) const = 0;
263     virtual const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const = 0;
264 
265     sk_sp<SkCapabilities> fCapabilities;
266 };
267 
268 } // namespace skgpu::graphite
269 
270 #endif // skgpu_graphite_Caps_DEFINED
271