• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #ifndef GrShaderCaps_DEFINED
10 #define GrShaderCaps_DEFINED
11 
12 #include "../private/GrSwizzle.h"
13 #include "../private/GrGLSL.h"
14 
15 namespace SkSL {
16     class ShaderCapsFactory;
17 }
18 struct GrContextOptions;
19 class SkJSONWriter;
20 
21 class GrShaderCaps : public SkRefCnt {
22 public:
23     /**
24     * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
25     * special layout qualifiers in the fragment shader.
26     */
27     enum AdvBlendEqInteraction {
28         kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
29         kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
30         kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
31         kSpecificEnables_AdvBlendEqInteraction,  //<! Specific layout qualifiers per equation
32 
33         kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
34     };
35 
36     GrShaderCaps(const GrContextOptions&);
37 
38     void dumpJSON(SkJSONWriter*) const;
39 
shaderDerivativeSupport()40     bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
geometryShaderSupport()41     bool geometryShaderSupport() const { return fGeometryShaderSupport; }
gsInvocationsSupport()42     bool gsInvocationsSupport() const { return fGSInvocationsSupport; }
pathRenderingSupport()43     bool pathRenderingSupport() const { return fPathRenderingSupport; }
dstReadInShaderSupport()44     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
dualSourceBlendingSupport()45     bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
integerSupport()46     bool integerSupport() const { return fIntegerSupport; }
texelBufferSupport()47     bool texelBufferSupport() const { return fTexelBufferSupport; }
imageLoadStoreSupport()48     int imageLoadStoreSupport() const { return fImageLoadStoreSupport; }
49 
50     /**
51      * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
52      *
53      * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
54      */
fbFetchSupport()55     bool fbFetchSupport() const { return fFBFetchSupport; }
56 
fbFetchNeedsCustomOutput()57     bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
58 
versionDeclString()59     const char* versionDeclString() const { return fVersionDeclString; }
60 
fbFetchColorName()61     const char* fbFetchColorName() const { return fFBFetchColorName; }
62 
fbFetchExtensionString()63     const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
64 
dropsTileOnZeroDivide()65     bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
66 
flatInterpolationSupport()67     bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
68 
preferFlatInterpolation()69     bool preferFlatInterpolation() const { return fPreferFlatInterpolation; }
70 
noperspectiveInterpolationSupport()71     bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
72 
externalTextureSupport()73     bool externalTextureSupport() const { return fExternalTextureSupport; }
74 
texelFetchSupport()75     bool texelFetchSupport() const { return fTexelFetchSupport; }
76 
vertexIDSupport()77     bool vertexIDSupport() const { return fVertexIDSupport; }
78 
floatIs32Bits()79     bool floatIs32Bits() const { return fFloatIs32Bits; }
80 
halfIs32Bits()81     bool halfIs32Bits() const { return fHalfIs32Bits; }
82 
advBlendEqInteraction()83     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
84 
mustEnableAdvBlendEqs()85     bool mustEnableAdvBlendEqs() const {
86         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
87     }
88 
mustEnableSpecificAdvBlendEqs()89     bool mustEnableSpecificAdvBlendEqs() const {
90         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
91     }
92 
mustDeclareFragmentShaderOutput()93     bool mustDeclareFragmentShaderOutput() const {
94         return fGLSLGeneration > k110_GrGLSLGeneration;
95     }
96 
usesPrecisionModifiers()97     bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
98 
99     // Returns whether we can use the glsl function any() in our shader code.
canUseAnyFunctionInShader()100     bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
101 
canUseMinAndAbsTogether()102     bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
103 
canUseFractForNegativeValues()104     bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; }
105 
mustForceNegatedAtanParamToFloat()106     bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
107 
108     // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
atan2ImplementedAsAtanYOverX()109     bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
110 
111     // If this returns true some operation (could be a no op) must be called between floor and abs
112     // to make sure the driver compiler doesn't inline them together which can cause a driver bug in
113     // the shader.
mustDoOpBetweenFloorAndAbs()114     bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; }
115 
116     // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord
canUseFragCoord()117     bool canUseFragCoord() const { return fCanUseFragCoord; }
118 
119     // If true interpolated vertex shader outputs are inaccurate.
interpolantsAreInaccurate()120     bool interpolantsAreInaccurate() const { return fInterpolantsAreInaccurate; }
121 
requiresLocalOutputColorForFBFetch()122     bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
123 
mustObfuscateUniformColor()124     bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
125 
126     // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain
127     // constructs. See detailed comments in GrGLCaps.cpp.
mustGuardDivisionEvenAfterExplicitZeroCheck()128     bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
129         return fMustGuardDivisionEvenAfterExplicitZeroCheck;
130     }
131 
132     // Returns the string of an extension that must be enabled in the shader to support
133     // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
134     // this function, the caller should check that shaderDerivativeSupport exists.
shaderDerivativeExtensionString()135     const char* shaderDerivativeExtensionString() const {
136         SkASSERT(this->shaderDerivativeSupport());
137         return fShaderDerivativeExtensionString;
138     }
139 
140     // Returns the string of an extension that must be enabled in the shader to support geometry
141     // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this
142     // function, the caller must verify that geometryShaderSupport exists.
geometryShaderExtensionString()143     const char* geometryShaderExtensionString() const {
144         SkASSERT(this->geometryShaderSupport());
145         return fGeometryShaderExtensionString;
146     }
147 
148     // Returns the string of an extension that must be enabled in the shader to support
149     // geometry shader invocations. If nullptr is returned then no extension needs to be enabled.
150     // Before calling this function, the caller must verify that gsInvocationsSupport exists.
gsInvocationsExtensionString()151     const char* gsInvocationsExtensionString() const {
152         SkASSERT(this->gsInvocationsSupport());
153         return fGSInvocationsExtensionString;
154     }
155 
156     // Returns the string of an extension that will do all necessary coord transfomations needed
157     // when reading the fragment position. If such an extension does not exisits, this function
158     // returns a nullptr, and all transforms of the frag position must be done manually in the
159     // shader.
fragCoordConventionsExtensionString()160     const char* fragCoordConventionsExtensionString() const {
161         return fFragCoordConventionsExtensionString;
162     }
163 
164     // This returns the name of an extension that must be enabled in the shader, if such a thing is
165     // required in order to use a secondary output in the shader. This returns a nullptr if no such
166     // extension is required. However, the return value of this function does not say whether dual
167     // source blending is supported.
secondaryOutputExtensionString()168     const char* secondaryOutputExtensionString() const {
169         return fSecondaryOutputExtensionString;
170     }
171 
externalTextureExtensionString()172     const char* externalTextureExtensionString() const {
173         SkASSERT(this->externalTextureSupport());
174         return fExternalTextureExtensionString;
175     }
176 
texelBufferExtensionString()177     const char* texelBufferExtensionString() const {
178         SkASSERT(this->texelBufferSupport());
179         return fTexelBufferExtensionString;
180     }
181 
noperspectiveInterpolationExtensionString()182     const char* noperspectiveInterpolationExtensionString() const {
183         SkASSERT(this->noperspectiveInterpolationSupport());
184         return fNoPerspectiveInterpolationExtensionString;
185     }
186 
imageLoadStoreExtensionString()187     const char* imageLoadStoreExtensionString() const {
188         SkASSERT(this->imageLoadStoreSupport());
189         return fImageLoadStoreExtensionString;
190     }
191 
maxVertexSamplers()192     int maxVertexSamplers() const { return fMaxVertexSamplers; }
193 
maxGeometrySamplers()194     int maxGeometrySamplers() const { return fMaxGeometrySamplers; }
195 
maxFragmentSamplers()196     int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
197 
maxCombinedSamplers()198     int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
199 
200     /**
201      * In general using multiple texture units for image rendering seems to be a win at smaller
202      * sizes of dst rects and a loss at larger sizes. Dst rects above this pixel area threshold will
203      * not use multitexturing.
204      */
disableImageMultitexturingDstRectAreaThreshold()205     size_t disableImageMultitexturingDstRectAreaThreshold() const {
206         return fDisableImageMultitexturingDstRectAreaThreshold;
207     }
208 
209     /**
210      * Given a texture's config, this determines what swizzle must be appended to accesses to the
211      * texture in generated shader code. Swizzling may be implemented in texture parameters or a
212      * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
213      */
configTextureSwizzle(GrPixelConfig config)214     const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
215         return fConfigTextureSwizzle[config];
216     }
217 
218     /** Swizzle that should occur on the fragment shader outputs for a given config. */
configOutputSwizzle(GrPixelConfig config)219     const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
220         return fConfigOutputSwizzle[config];
221     }
222 
generation()223     GrGLSLGeneration generation() const { return fGLSLGeneration; }
224 
225 private:
226     void applyOptionsOverrides(const GrContextOptions& options);
227 
228     GrGLSLGeneration fGLSLGeneration;
229 
230     bool fShaderDerivativeSupport   : 1;
231     bool fGeometryShaderSupport     : 1;
232     bool fGSInvocationsSupport      : 1;
233     bool fPathRenderingSupport      : 1;
234     bool fDstReadInShaderSupport    : 1;
235     bool fDualSourceBlendingSupport : 1;
236     bool fIntegerSupport            : 1;
237     bool fTexelBufferSupport        : 1;
238     bool fImageLoadStoreSupport     : 1;
239     bool fDropsTileOnZeroDivide : 1;
240     bool fFBFetchSupport : 1;
241     bool fFBFetchNeedsCustomOutput : 1;
242     bool fUsesPrecisionModifiers : 1;
243     bool fFlatInterpolationSupport : 1;
244     bool fPreferFlatInterpolation : 1;
245     bool fNoPerspectiveInterpolationSupport : 1;
246     bool fExternalTextureSupport : 1;
247     bool fTexelFetchSupport : 1;
248     bool fVertexIDSupport : 1;
249     bool fFloatIs32Bits : 1;
250     bool fHalfIs32Bits : 1;
251 
252     // Used for specific driver bug work arounds
253     bool fCanUseAnyFunctionInShader : 1;
254     bool fCanUseMinAndAbsTogether : 1;
255     bool fCanUseFractForNegativeValues : 1;
256     bool fMustForceNegatedAtanParamToFloat : 1;
257     bool fAtan2ImplementedAsAtanYOverX : 1;
258     bool fMustDoOpBetweenFloorAndAbs : 1;
259     bool fRequiresLocalOutputColorForFBFetch : 1;
260     bool fMustObfuscateUniformColor : 1;
261     bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
262     bool fCanUseFragCoord : 1;
263     bool fInterpolantsAreInaccurate : 1;
264 
265     const char* fVersionDeclString;
266 
267     const char* fShaderDerivativeExtensionString;
268     const char* fGeometryShaderExtensionString;
269     const char* fGSInvocationsExtensionString;
270     const char* fFragCoordConventionsExtensionString;
271     const char* fSecondaryOutputExtensionString;
272     const char* fExternalTextureExtensionString;
273     const char* fTexelBufferExtensionString;
274     const char* fNoPerspectiveInterpolationExtensionString;
275     const char* fImageLoadStoreExtensionString;
276 
277     const char* fFBFetchColorName;
278     const char* fFBFetchExtensionString;
279 
280     int fMaxVertexSamplers;
281     int fMaxGeometrySamplers;
282     int fMaxFragmentSamplers;
283     int fMaxCombinedSamplers;
284 
285     size_t fDisableImageMultitexturingDstRectAreaThreshold;
286 
287     AdvBlendEqInteraction fAdvBlendEqInteraction;
288 
289     GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
290     GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
291 
292     friend class GrCaps;  // For initialization.
293     friend class GrGLCaps;
294     friend class GrMockCaps;
295     friend class GrMtlCaps;
296     friend class GrVkCaps;
297     friend class SkSL::ShaderCapsFactory;
298 };
299 
300 #endif
301