Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/gpu/GrShaderCaps.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2012 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 GrShaderCaps_DEFINED
9
#define GrShaderCaps_DEFINED
10
11
#include "include/core/SkRefCnt.h"
12
#include "include/private/GrTypesPriv.h"
13
#include "src/gpu/GrSwizzle.h"
14
#include "src/gpu/glsl/GrGLSL.h"
15
16
namespace SkSL {
17
class ShaderCapsFactory;
18
class SharedCompiler;
19
}  // namespace SkSL
20
21
struct GrContextOptions;
22
class SkJSONWriter;
23
24
class GrShaderCaps : public SkRefCnt {
25
public:
26
    /**
27
     * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
28
     * special layout qualifiers in the fragment shader.
29
     */
30
    enum AdvBlendEqInteraction {
31
        kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
32
        kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
33
        kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
34
35
        kLast_AdvBlendEqInteraction = kGeneralEnable_AdvBlendEqInteraction
36
    };
37
38
    GrShaderCaps(const GrContextOptions&);
39
40
    void dumpJSON(SkJSONWriter*) const;
41
42
785
    bool supportsDistanceFieldText() const { return fShaderDerivativeSupport; }
43
44
94.1k
    bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
45
0
    bool geometryShaderSupport() const { return fGeometryShaderSupport; }
46
0
    bool gsInvocationsSupport() const { return fGSInvocationsSupport; }
47
11.3k
    bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
48
93.7k
    bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
49
0
    bool nonsquareMatrixSupport() const { return fNonsquareMatrixSupport; }
50
51
    /** Indicates true 32-bit integer support, with unsigned types and bitwise operations */
52
1.87k
    bool integerSupport() const { return fIntegerSupport; }
53
54
    /** asinh(), acosh(), atanh() */
55
0
    bool inverseHyperbolicSupport() const { return fInverseHyperbolicSupport; }
56
57
    /**
58
     * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
59
     *
60
     * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
61
     */
62
382
    bool fbFetchSupport() const { return fFBFetchSupport; }
63
64
0
    bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
65
66
8.89k
    const char* versionDeclString() const { return fVersionDeclString; }
67
68
0
    const char* fbFetchColorName() const { return fFBFetchColorName; }
69
70
0
    const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
71
72
0
    bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
73
74
0
    bool preferFlatInterpolation() const { return fPreferFlatInterpolation; }
75
76
0
    bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
77
78
0
    bool sampleMaskSupport() const { return fSampleMaskSupport; }
79
80
10
    bool externalTextureSupport() const { return fExternalTextureSupport; }
81
82
0
    bool vertexIDSupport() const { return fVertexIDSupport; }
83
84
    // isinf() is defined, and floating point infinities are handled according to IEEE standards.
85
0
    bool infinitySupport() const { return fInfinitySupport; }
86
87
    // frexp(), ldexp(), findMSB(), findLSB().
88
0
    bool bitManipulationSupport() const { return fBitManipulationSupport; }
89
90
5.28k
    bool floatIs32Bits() const { return fFloatIs32Bits; }
91
92
0
    bool halfIs32Bits() const { return fHalfIs32Bits; }
93
94
0
    bool hasLowFragmentPrecision() const { return fHasLowFragmentPrecision; }
95
96
    // Use a reduced set of rendering algorithms or less optimal effects in order to
97
    // reduce the number of unique shaders generated.
98
88.1k
    bool reducedShaderMode() const { return fReducedShaderMode; }
99
100
    /**
101
     * SkSL ES3 requires support for derivatives, nonsquare matrices and bitwise integer operations.
102
     */
103
0
    bool supportsSkSLES3() const {
104
0
        return fShaderDerivativeSupport && fNonsquareMatrixSupport && fIntegerSupport &&
105
0
               fGLSLGeneration >= k330_GrGLSLGeneration;
106
0
    }
107
108
    // SkSL only.
109
0
    bool builtinFMASupport() const { return fBuiltinFMASupport; }
110
111
66.3k
    bool builtinDeterminantSupport() const { return fBuiltinDeterminantSupport; }
112
113
0
    AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
114
115
0
    bool mustEnableAdvBlendEqs() const {
116
0
        return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
117
0
    }
118
119
1.92k
    bool mustDeclareFragmentShaderOutput() const { return fGLSLGeneration > k110_GrGLSLGeneration; }
120
121
21.0k
    bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
122
123
    // Returns whether we can use the glsl function any() in our shader code.
124
11
    bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
125
126
627
    bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
127
128
0
    bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; }
129
130
1
    bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
131
132
    // http://skbug.com/12076
133
0
    bool mustForceNegatedLdexpParamToMultiply() const {
134
0
        return fMustForceNegatedLdexpParamToMultiply;
135
0
    }
136
137
    // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
138
1.48k
    bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
139
140
    // If this returns true some operation (could be a no op) must be called between floor and abs
141
    // to make sure the driver compiler doesn't inline them together which can cause a driver bug in
142
    // the shader.
143
0
    bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; }
144
145
    // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord
146
9.90k
    bool canUseFragCoord() const { return fCanUseFragCoord; }
147
148
    // If true, short ints can't represent every integer in the 16-bit two's complement range as
149
    // required by the spec. SKSL will always emit full ints.
150
0
    bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; }
151
152
0
    bool colorSpaceMathNeedsFloat() const { return fColorSpaceMathNeedsFloat; }
153
154
    // If true, then conditions in for loops need "&& true" to work around driver bugs.
155
170
    bool addAndTrueToLoopCondition() const { return fAddAndTrueToLoopCondition; }
156
157
    // If true, then expressions such as "x && y" or "x || y" are rewritten as
158
    // ternary to work around driver bugs.
159
9.20k
    bool unfoldShortCircuitAsTernary() const { return fUnfoldShortCircuitAsTernary; }
160
161
627
    bool emulateAbsIntFunction() const { return fEmulateAbsIntFunction; }
162
163
34
    bool rewriteDoWhileLoops() const { return fRewriteDoWhileLoops; }
164
165
0
    bool removePowWithConstantExponent() const { return fRemovePowWithConstantExponent; }
166
167
0
    bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
168
169
0
    bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
170
171
    // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain
172
    // constructs. See detailed comments in GrGLCaps.cpp.
173
66.3k
    bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
174
66.3k
        return fMustGuardDivisionEvenAfterExplicitZeroCheck;
175
66.3k
    }
176
177
    // On Pixel 3, 3a, and 4 devices we've noticed that the simple function:
178
    // half4 blend(half4 a, half4 b) { return a.a * b; }
179
    // may return (0, 0, 0, 1) when b is (0, 0, 0, 0).
180
33.1k
    bool inBlendModesFailRandomlyForAllZeroVec() const {
181
33.1k
        return fInBlendModesFailRandomlyForAllZeroVec;
182
33.1k
    }
183
184
    // On Nexus 6, the GL context can get lost if a shader does not write a value to gl_FragColor.
185
    // https://bugs.chromium.org/p/chromium/issues/detail?id=445377
186
0
    bool mustWriteToFragColor() const { return fMustWriteToFragColor; }
187
188
    // The Android emulator claims samplerExternalOES is an unknown type if a default precision
189
    // statement is made for the type.
190
0
    bool noDefaultPrecisionForExternalSamplers() const {
191
0
        return fNoDefaultPrecisionForExternalSamplers;
192
0
    }
193
194
    // ARM GPUs calculate `matrix * vector` in SPIR-V at full precision, even when the inputs are
195
    // RelaxedPrecision. Rewriting the multiply as a sum of vector*scalar fixes this. (skia:11769)
196
824
    bool rewriteMatrixVectorMultiply() const {
197
824
        return fRewriteMatrixVectorMultiply;
198
824
    }
199
200
    // Rewrites matrix equality comparisons to avoid an Adreno driver bug. (skia:11308)
201
9.20k
    bool rewriteMatrixComparisons() const { return fRewriteMatrixComparisons; }
202
203
    // ANGLE disallows do loops altogether, and we're seeing crashes on Tegra3 with do loops in at
204
    // least some cases.
205
0
    bool canUseDoLoops() const { return fCanUseDoLoops; }
206
207
    // Some GPUs produce poor results when enabling Metal's fastmath option
208
0
    bool canUseFastMath() const { return fCanUseFastMath; }
209
210
    // By default, SkSL pools IR nodes per-program. To debug memory corruption, it is sometimes
211
    // helpful to disable that feature.
212
67.6k
    bool useNodePools() const { return fUseNodePools; }
213
214
    // When we have the option of using either dFdx or dfDy in a shader, this returns whether we
215
    // should avoid using dFdx. We have found some drivers have bugs or lower precision when using
216
    // dFdx.
217
0
    bool avoidDfDxForGradientsWhenPossible() const { return fAvoidDfDxForGradientsWhenPossible; }
218
219
    // Returns the string of an extension that must be enabled in the shader to support
220
    // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
221
    // this function, the caller should check that shaderDerivativeSupport exists.
222
24
    const char* shaderDerivativeExtensionString() const {
223
24
        SkASSERT(this->shaderDerivativeSupport());
224
24
        return fShaderDerivativeExtensionString;
225
24
    }
226
227
    // Returns the string of an extension that must be enabled in the shader to support geometry
228
    // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this
229
    // function, the caller must verify that geometryShaderSupport exists.
230
0
    const char* geometryShaderExtensionString() const {
231
0
        SkASSERT(this->geometryShaderSupport());
232
0
        return fGeometryShaderExtensionString;
233
0
    }
Unexecuted instantiation: GrShaderCaps::geometryShaderExtensionString() const
Unexecuted instantiation: GrShaderCaps::geometryShaderExtensionString() const
234
235
    // Returns the string of an extension that must be enabled in the shader to support
236
    // geometry shader invocations. If nullptr is returned then no extension needs to be enabled.
237
    // Before calling this function, the caller must verify that gsInvocationsSupport exists.
238
0
    const char* gsInvocationsExtensionString() const {
239
0
        SkASSERT(this->gsInvocationsSupport());
240
0
        return fGSInvocationsExtensionString;
241
0
    }
Unexecuted instantiation: GrShaderCaps::gsInvocationsExtensionString() const
Unexecuted instantiation: GrShaderCaps::gsInvocationsExtensionString() const
242
243
    // This returns the name of an extension that must be enabled in the shader, if such a thing is
244
    // required in order to use a secondary output in the shader. This returns a nullptr if no such
245
    // extension is required. However, the return value of this function does not say whether dual
246
    // source blending is supported.
247
0
    const char* secondaryOutputExtensionString() const { return fSecondaryOutputExtensionString; }
248
249
    // This returns the name of an extension that must be enabled in the shader to support external
250
    // textures. In some cases, two extensions must be enabled - the second extension is returned
251
    // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one
252
    // extension is required.
253
0
    const char* externalTextureExtensionString() const {
254
0
        SkASSERT(this->externalTextureSupport());
255
0
        return fExternalTextureExtensionString;
256
0
    }
Unexecuted instantiation: GrShaderCaps::externalTextureExtensionString() const
Unexecuted instantiation: GrShaderCaps::externalTextureExtensionString() const
257
258
0
    const char* secondExternalTextureExtensionString() const {
259
0
        SkASSERT(this->externalTextureSupport());
260
0
        return fSecondExternalTextureExtensionString;
261
0
    }
Unexecuted instantiation: GrShaderCaps::secondExternalTextureExtensionString() const
Unexecuted instantiation: GrShaderCaps::secondExternalTextureExtensionString() const
262
263
0
    const char* noperspectiveInterpolationExtensionString() const {
264
0
        SkASSERT(this->noperspectiveInterpolationSupport());
265
0
        return fNoPerspectiveInterpolationExtensionString;
266
0
    }
Unexecuted instantiation: GrShaderCaps::noperspectiveInterpolationExtensionString() const
Unexecuted instantiation: GrShaderCaps::noperspectiveInterpolationExtensionString() const
267
268
0
    const char* sampleVariablesExtensionString() const {
269
0
        SkASSERT(this->sampleMaskSupport());
270
0
        return fSampleVariablesExtensionString;
271
0
    }
272
273
0
    const char* tessellationExtensionString() const {
274
0
        SkASSERT(this->tessellationSupport());
275
0
        return fTessellationExtensionString;
276
0
    }
Unexecuted instantiation: GrShaderCaps::tessellationExtensionString() const
Unexecuted instantiation: GrShaderCaps::tessellationExtensionString() const
277
278
0
    int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
279
280
    // Maximum number of segments a tessellation edge can be divided into.
281
0
    int maxTessellationSegments() const { return fMaxTessellationSegments; }
282
283
0
    bool tessellationSupport() const { return SkToBool(fMaxTessellationSegments);}
284
285
10.3k
    GrGLSLGeneration generation() const { return fGLSLGeneration; }
286
287
private:
288
    void applyOptionsOverrides(const GrContextOptions& options);
289
290
    GrGLSLGeneration fGLSLGeneration;
291
292
    bool fShaderDerivativeSupport           : 1;
293
    bool fGeometryShaderSupport             : 1;
294
    bool fGSInvocationsSupport              : 1;
295
    bool fDstReadInShaderSupport            : 1;
296
    bool fDualSourceBlendingSupport         : 1;
297
    bool fIntegerSupport                    : 1;
298
    bool fNonsquareMatrixSupport            : 1;
299
    bool fInverseHyperbolicSupport          : 1;
300
    bool fFBFetchSupport                    : 1;
301
    bool fFBFetchNeedsCustomOutput          : 1;
302
    bool fUsesPrecisionModifiers            : 1;
303
    bool fFlatInterpolationSupport          : 1;
304
    bool fPreferFlatInterpolation           : 1;
305
    bool fNoPerspectiveInterpolationSupport : 1;
306
    bool fSampleMaskSupport                 : 1;
307
    bool fExternalTextureSupport            : 1;
308
    bool fVertexIDSupport                   : 1;
309
    bool fInfinitySupport                   : 1;
310
    bool fBitManipulationSupport            : 1;
311
    bool fFloatIs32Bits                     : 1;
312
    bool fHalfIs32Bits                      : 1;
313
    bool fHasLowFragmentPrecision           : 1;
314
    bool fReducedShaderMode                 : 1;
315
316
    // Used by SkSL to know when to generate polyfills.
317
    bool fBuiltinFMASupport : 1;
318
    bool fBuiltinDeterminantSupport : 1;
319
320
    // Used for specific driver bug work arounds
321
    bool fCanUseAnyFunctionInShader                   : 1;
322
    bool fCanUseMinAndAbsTogether                     : 1;
323
    bool fCanUseFractForNegativeValues                : 1;
324
    bool fMustForceNegatedAtanParamToFloat            : 1;
325
    bool fMustForceNegatedLdexpParamToMultiply        : 1;
326
    bool fAtan2ImplementedAsAtanYOverX                : 1;
327
    bool fMustDoOpBetweenFloorAndAbs                  : 1;
328
    bool fRequiresLocalOutputColorForFBFetch          : 1;
329
    bool fMustObfuscateUniformColor                   : 1;
330
    bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
331
    bool fInBlendModesFailRandomlyForAllZeroVec       : 1;
332
    bool fCanUseFragCoord                             : 1;
333
    bool fIncompleteShortIntPrecision                 : 1;
334
    bool fAddAndTrueToLoopCondition                   : 1;
335
    bool fUnfoldShortCircuitAsTernary                 : 1;
336
    bool fEmulateAbsIntFunction                       : 1;
337
    bool fRewriteDoWhileLoops                         : 1;
338
    bool fRemovePowWithConstantExponent               : 1;
339
    bool fMustWriteToFragColor                        : 1;
340
    bool fNoDefaultPrecisionForExternalSamplers       : 1;
341
    bool fRewriteMatrixVectorMultiply                 : 1;
342
    bool fRewriteMatrixComparisons                    : 1;
343
    bool fColorSpaceMathNeedsFloat                    : 1;
344
    bool fCanUseDoLoops                               : 1;
345
    bool fCanUseFastMath                              : 1;
346
    bool fAvoidDfDxForGradientsWhenPossible           : 1;
347
348
    // This controls behavior of the SkSL compiler, not the code we generate
349
    bool fUseNodePools : 1;
350
351
    const char* fVersionDeclString;
352
353
    const char* fShaderDerivativeExtensionString;
354
    const char* fGeometryShaderExtensionString;
355
    const char* fGSInvocationsExtensionString;
356
    const char* fSecondaryOutputExtensionString;
357
    const char* fExternalTextureExtensionString;
358
    const char* fSecondExternalTextureExtensionString;
359
    const char* fNoPerspectiveInterpolationExtensionString;
360
    const char* fSampleVariablesExtensionString;
361
    const char* fTessellationExtensionString;
362
363
    const char* fFBFetchColorName;
364
    const char* fFBFetchExtensionString;
365
366
    int fMaxFragmentSamplers;
367
    int fMaxTessellationSegments;
368
369
    AdvBlendEqInteraction fAdvBlendEqInteraction;
370
371
    friend class GrCaps;  // For initialization.
372
    friend class GrDawnCaps;
373
    friend class GrD3DCaps;
374
    friend class GrGLCaps;
375
    friend class GrMockCaps;
376
    friend class GrMtlCaps;
377
    friend class GrVkCaps;
378
    friend class SkSL::ShaderCapsFactory;
379
    friend class SkSL::SharedCompiler;
380
};
381
382
#endif