blob: fb68ec354eef3b43cecd31d3145227e7f67b45c4 [file] [log] [blame]
jvanverthcba99b82015-06-24 06:59:57 -07001/*
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
Brian Salomon94efbf52016-11-29 13:43:05 -05008#ifndef GrShaderCaps_DEFINED
9#define GrShaderCaps_DEFINED
jvanverthcba99b82015-06-24 06:59:57 -070010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkRefCnt.h"
12#include "include/private/GrTypesPriv.h"
Brian Salomon3ec1f542019-06-17 17:54:57 +000013#include "src/gpu/GrSwizzle.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/glsl/GrGLSL.h"
jvanverthcba99b82015-06-24 06:59:57 -070015
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050016namespace SkSL {
Brian Salomonc7fe0f72018-05-11 10:14:21 -040017class ShaderCapsFactory;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050018}
Brian Salomonc7fe0f72018-05-11 10:14:21 -040019
Brian Salomon94efbf52016-11-29 13:43:05 -050020struct GrContextOptions;
Brian Osman71a18892017-08-10 10:23:25 -040021class SkJSONWriter;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050022
Brian Salomon94efbf52016-11-29 13:43:05 -050023class GrShaderCaps : public SkRefCnt {
jvanverthcba99b82015-06-24 06:59:57 -070024public:
jvanverthcba99b82015-06-24 06:59:57 -070025 /**
Brian Salomonc7fe0f72018-05-11 10:14:21 -040026 * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
27 * special layout qualifiers in the fragment shader.
28 */
jvanverthcba99b82015-06-24 06:59:57 -070029 enum AdvBlendEqInteraction {
30 kNotSupported_AdvBlendEqInteraction, //<! No _blend_equation_advanced extension
31 kAutomatic_AdvBlendEqInteraction, //<! No interaction required
32 kGeneralEnable_AdvBlendEqInteraction, //<! layout(blend_support_all_equations) out
33 kSpecificEnables_AdvBlendEqInteraction, //<! Specific layout qualifiers per equation
34
35 kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
36 };
37
Brian Salomon94efbf52016-11-29 13:43:05 -050038 GrShaderCaps(const GrContextOptions&);
39
Brian Osman71a18892017-08-10 10:23:25 -040040 void dumpJSON(SkJSONWriter*) const;
Brian Salomon94efbf52016-11-29 13:43:05 -050041
Khushal3e7548c2018-05-23 15:45:01 -070042 bool supportsDistanceFieldText() const { return fShaderDerivativeSupport; }
43
Brian Salomon94efbf52016-11-29 13:43:05 -050044 bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
45 bool geometryShaderSupport() const { return fGeometryShaderSupport; }
Chris Daltonf1b47bb2017-10-06 11:57:51 -060046 bool gsInvocationsSupport() const { return fGSInvocationsSupport; }
Brian Salomon94efbf52016-11-29 13:43:05 -050047 bool pathRenderingSupport() const { return fPathRenderingSupport; }
48 bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
49 bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
50 bool integerSupport() const { return fIntegerSupport; }
Brian Salomon94efbf52016-11-29 13:43:05 -050051
jvanverthcba99b82015-06-24 06:59:57 -070052 /**
jvanverthcba99b82015-06-24 06:59:57 -070053 * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
54 *
55 * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
56 */
57 bool fbFetchSupport() const { return fFBFetchSupport; }
58
59 bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
60
egdaniel472d44e2015-10-22 08:20:00 -070061 const char* versionDeclString() const { return fVersionDeclString; }
62
jvanverthcba99b82015-06-24 06:59:57 -070063 const char* fbFetchColorName() const { return fFBFetchColorName; }
64
65 const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
66
cdaltonc08f1962016-02-12 12:14:06 -080067 bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
68
Brian Salomon41274562017-09-15 09:40:03 -070069 bool preferFlatInterpolation() const { return fPreferFlatInterpolation; }
70
cdaltonc08f1962016-02-12 12:14:06 -080071 bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
72
Chris Dalton69258ff2019-05-13 17:59:54 -060073 // Can we use sample variables everywhere?
Chris Daltond31b5e72019-02-26 18:02:16 -070074 bool sampleVariablesSupport() const { return fSampleVariablesSupport; }
75
Chris Dalton69258ff2019-05-13 17:59:54 -060076 // Can we use sample variables when rendering to stencil? (This is a workaround for platforms
77 // where sample variables are broken in general, but seem to work when rendering to stencil.)
78 bool sampleVariablesStencilSupport() const { return fSampleVariablesStencilSupport; }
79
cdalton9c3f1432016-03-11 10:07:37 -080080 bool externalTextureSupport() const { return fExternalTextureSupport; }
81
Chris Dalton1d616352017-05-31 12:51:23 -060082 bool vertexIDSupport() const { return fVertexIDSupport; }
83
Chris Dalton7c7ff032018-03-28 20:09:58 -060084 // frexp, ldexp, etc.
85 bool fpManipulationSupport() const { return fFPManipulationSupport; }
86
Chris Dalton47c8ed32017-11-15 18:27:09 -070087 bool floatIs32Bits() const { return fFloatIs32Bits; }
88
89 bool halfIs32Bits() const { return fHalfIs32Bits; }
90
Jim Van Verth20ae25c2019-03-29 08:50:41 -040091 bool hasLowFragmentPrecision() const { return fHasLowFragmentPrecision; }
92
Chris Daltona7086182018-11-16 09:33:43 -050093 // SkSL only.
94 bool builtinFMASupport() const { return fBuiltinFMASupport; }
95
jvanverthcba99b82015-06-24 06:59:57 -070096 AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
97
98 bool mustEnableAdvBlendEqs() const {
99 return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
100 }
101
102 bool mustEnableSpecificAdvBlendEqs() const {
103 return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
104 }
halcanary9d524f22016-03-29 09:03:52 -0700105
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400106 bool mustDeclareFragmentShaderOutput() const { return fGLSLGeneration > k110_GrGLSLGeneration; }
jvanverthcba99b82015-06-24 06:59:57 -0700107
egdanielf5294392015-10-21 07:14:17 -0700108 bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
109
Greg Daniel80a08dd2017-01-20 10:45:49 -0500110 // Returns whether we can use the glsl function any() in our shader code.
egdaniel472d44e2015-10-22 08:20:00 -0700111 bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
112
egdaniel8dcdedc2015-11-11 06:27:20 -0800113 bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
114
Florin Malita8a0044f2017-08-07 14:38:22 -0400115 bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; }
116
egdaniel8dcdedc2015-11-11 06:27:20 -0800117 bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
118
Greg Daniel80a08dd2017-01-20 10:45:49 -0500119 // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
120 bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
121
Greg Daniel10ed2432017-12-01 16:19:43 -0500122 // If this returns true some operation (could be a no op) must be called between floor and abs
123 // to make sure the driver compiler doesn't inline them together which can cause a driver bug in
124 // the shader.
125 bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; }
126
Brian Osmancd3261a2018-01-16 13:52:29 +0000127 // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord
128 bool canUseFragCoord() const { return fCanUseFragCoord; }
129
Chris Daltonc2d0dd62018-03-07 07:46:10 -0700130 // If true, short ints can't represent every integer in the 16-bit two's complement range as
131 // required by the spec. SKSL will always emit full ints.
132 bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; }
133
Adrienne Walkerc02165f2018-08-21 11:08:11 -0700134 // If true, then conditions in for loops need "&& true" to work around driver bugs.
Adrienne Walkeree8295c2018-08-21 10:56:30 -0700135 bool addAndTrueToLoopCondition() const { return fAddAndTrueToLoopCondition; }
136
Adrienne Walkerc02165f2018-08-21 11:08:11 -0700137 // If true, then expressions such as "x && y" or "x || y" are rewritten as
138 // ternary to work around driver bugs.
139 bool unfoldShortCircuitAsTernary() const { return fUnfoldShortCircuitAsTernary; }
140
Adrienne Walker92b161f2018-08-22 10:41:52 -0700141 bool emulateAbsIntFunction() const { return fEmulateAbsIntFunction; }
142
Adrienne Walker8b23ca62018-08-22 10:45:41 -0700143 bool rewriteDoWhileLoops() const { return fRewriteDoWhileLoops; }
144
Adrienne Walker2f4c09b2018-08-22 16:04:57 -0700145 bool removePowWithConstantExponent() const { return fRemovePowWithConstantExponent; }
146
egdaniel138c2632016-08-17 10:59:00 -0700147 bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
148
Brian Osmanac1e4962017-05-25 11:34:38 -0400149 bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
150
Brian Osmandff5d432017-08-01 14:46:18 -0400151 // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain
152 // constructs. See detailed comments in GrGLCaps.cpp.
153 bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
154 return fMustGuardDivisionEvenAfterExplicitZeroCheck;
155 }
156
Chris Dalton8e30ad42019-04-08 10:51:14 -0600157 // On Nexus 6, the GL context can get lost if a shader does not write a value to gl_FragColor.
158 // https://bugs.chromium.org/p/chromium/issues/detail?id=445377
159 bool mustWriteToFragColor() const { return fMustWriteToFragColor; }
160
Brian Salomon5a5f3e82019-08-16 15:05:40 -0400161 // The Android emulator claims samplerExternalOES is an unknown type if a default precision
162 // statement is made for the type.
163 bool noDefaultPrecisionForExternalSamplers() const {
164 return fNoDefaultPrecisionForExternalSamplers;
165 }
166
egdaniel574a4c12015-11-02 06:22:44 -0800167 // Returns the string of an extension that must be enabled in the shader to support
168 // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
169 // this function, the caller should check that shaderDerivativeSupport exists.
170 const char* shaderDerivativeExtensionString() const {
171 SkASSERT(this->shaderDerivativeSupport());
172 return fShaderDerivativeExtensionString;
173 }
cdalton33ad7012016-02-22 07:55:44 -0800174
Chris Dalton8fd79552018-01-11 00:46:14 -0500175 // Returns the string of an extension that must be enabled in the shader to support geometry
176 // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this
177 // function, the caller must verify that geometryShaderSupport exists.
178 const char* geometryShaderExtensionString() const {
179 SkASSERT(this->geometryShaderSupport());
180 return fGeometryShaderExtensionString;
181 }
182
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600183 // Returns the string of an extension that must be enabled in the shader to support
184 // geometry shader invocations. If nullptr is returned then no extension needs to be enabled.
185 // Before calling this function, the caller must verify that gsInvocationsSupport exists.
186 const char* gsInvocationsExtensionString() const {
187 SkASSERT(this->gsInvocationsSupport());
188 return fGSInvocationsExtensionString;
189 }
190
egdaniel8dcdedc2015-11-11 06:27:20 -0800191 // Returns the string of an extension that will do all necessary coord transfomations needed
192 // when reading the fragment position. If such an extension does not exisits, this function
193 // returns a nullptr, and all transforms of the frag position must be done manually in the
194 // shader.
195 const char* fragCoordConventionsExtensionString() const {
196 return fFragCoordConventionsExtensionString;
197 }
198
199 // This returns the name of an extension that must be enabled in the shader, if such a thing is
200 // required in order to use a secondary output in the shader. This returns a nullptr if no such
201 // extension is required. However, the return value of this function does not say whether dual
202 // source blending is supported.
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400203 const char* secondaryOutputExtensionString() const { return fSecondaryOutputExtensionString; }
egdaniel574a4c12015-11-02 06:22:44 -0800204
Brian Osman061020e2018-04-17 14:22:15 -0400205 // This returns the name of an extension that must be enabled in the shader to support external
206 // textures. In some cases, two extensions must be enabled - the second extension is returned
207 // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one
208 // extension is required.
bsalomon7ea33f52015-11-22 14:51:00 -0800209 const char* externalTextureExtensionString() const {
cdalton9c3f1432016-03-11 10:07:37 -0800210 SkASSERT(this->externalTextureSupport());
bsalomon7ea33f52015-11-22 14:51:00 -0800211 return fExternalTextureExtensionString;
212 }
213
Brian Osman061020e2018-04-17 14:22:15 -0400214 const char* secondExternalTextureExtensionString() const {
215 SkASSERT(this->externalTextureSupport());
216 return fSecondExternalTextureExtensionString;
217 }
218
cdaltonc08f1962016-02-12 12:14:06 -0800219 const char* noperspectiveInterpolationExtensionString() const {
220 SkASSERT(this->noperspectiveInterpolationSupport());
221 return fNoPerspectiveInterpolationExtensionString;
222 }
223
Chris Daltond31b5e72019-02-26 18:02:16 -0700224 const char* sampleVariablesExtensionString() const {
Chris Daltona7ad1202019-07-19 15:31:59 -0600225 SkASSERT(this->sampleVariablesSupport() || this->sampleVariablesStencilSupport());
Chris Daltond31b5e72019-02-26 18:02:16 -0700226 return fSampleVariablesExtensionString;
227 }
228
cdalton9c3f1432016-03-11 10:07:37 -0800229 int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
230
Brian Salomon68ba1172019-06-05 11:15:08 -0400231 bool textureSwizzleAppliedInShader() const { return fTextureSwizzleAppliedInShader; }
232
jvanverthcba99b82015-06-24 06:59:57 -0700233 GrGLSLGeneration generation() const { return fGLSLGeneration; }
234
jvanverthcba99b82015-06-24 06:59:57 -0700235private:
Brian Salomon94efbf52016-11-29 13:43:05 -0500236 void applyOptionsOverrides(const GrContextOptions& options);
egdanielb7e7d572015-11-04 04:23:53 -0800237
jvanverthcba99b82015-06-24 06:59:57 -0700238 GrGLSLGeneration fGLSLGeneration;
halcanary9d524f22016-03-29 09:03:52 -0700239
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400240 bool fShaderDerivativeSupport : 1;
241 bool fGeometryShaderSupport : 1;
242 bool fGSInvocationsSupport : 1;
243 bool fPathRenderingSupport : 1;
244 bool fDstReadInShaderSupport : 1;
245 bool fDualSourceBlendingSupport : 1;
246 bool fIntegerSupport : 1;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400247 bool fFBFetchSupport : 1;
248 bool fFBFetchNeedsCustomOutput : 1;
249 bool fUsesPrecisionModifiers : 1;
250 bool fFlatInterpolationSupport : 1;
251 bool fPreferFlatInterpolation : 1;
cdaltonc08f1962016-02-12 12:14:06 -0800252 bool fNoPerspectiveInterpolationSupport : 1;
Chris Daltond31b5e72019-02-26 18:02:16 -0700253 bool fSampleVariablesSupport : 1;
Chris Dalton69258ff2019-05-13 17:59:54 -0600254 bool fSampleVariablesStencilSupport : 1;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400255 bool fExternalTextureSupport : 1;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400256 bool fVertexIDSupport : 1;
257 bool fFPManipulationSupport : 1;
258 bool fFloatIs32Bits : 1;
259 bool fHalfIs32Bits : 1;
Jim Van Verth20ae25c2019-03-29 08:50:41 -0400260 bool fHasLowFragmentPrecision : 1;
Brian Salomon68ba1172019-06-05 11:15:08 -0400261 bool fTextureSwizzleAppliedInShader : 1;
egdanielf5294392015-10-21 07:14:17 -0700262
Chris Daltona7086182018-11-16 09:33:43 -0500263 // Used by SkSL to know when to generate polyfills.
264 bool fBuiltinFMASupport : 1;
265
egdaniel8dcdedc2015-11-11 06:27:20 -0800266 // Used for specific driver bug work arounds
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400267 bool fCanUseAnyFunctionInShader : 1;
268 bool fCanUseMinAndAbsTogether : 1;
269 bool fCanUseFractForNegativeValues : 1;
270 bool fMustForceNegatedAtanParamToFloat : 1;
271 bool fAtan2ImplementedAsAtanYOverX : 1;
272 bool fMustDoOpBetweenFloorAndAbs : 1;
273 bool fRequiresLocalOutputColorForFBFetch : 1;
274 bool fMustObfuscateUniformColor : 1;
Brian Osmandff5d432017-08-01 14:46:18 -0400275 bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400276 bool fCanUseFragCoord : 1;
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400277 bool fIncompleteShortIntPrecision : 1;
Adrienne Walkeree8295c2018-08-21 10:56:30 -0700278 bool fAddAndTrueToLoopCondition : 1;
Adrienne Walkerc02165f2018-08-21 11:08:11 -0700279 bool fUnfoldShortCircuitAsTernary : 1;
Adrienne Walker92b161f2018-08-22 10:41:52 -0700280 bool fEmulateAbsIntFunction : 1;
Adrienne Walker8b23ca62018-08-22 10:45:41 -0700281 bool fRewriteDoWhileLoops : 1;
Adrienne Walker2f4c09b2018-08-22 16:04:57 -0700282 bool fRemovePowWithConstantExponent : 1;
Chris Dalton8e30ad42019-04-08 10:51:14 -0600283 bool fMustWriteToFragColor : 1;
Brian Salomon5a5f3e82019-08-16 15:05:40 -0400284 bool fNoDefaultPrecisionForExternalSamplers : 1;
egdaniel8dcdedc2015-11-11 06:27:20 -0800285
egdaniel472d44e2015-10-22 08:20:00 -0700286 const char* fVersionDeclString;
jvanverthcba99b82015-06-24 06:59:57 -0700287
egdaniel574a4c12015-11-02 06:22:44 -0800288 const char* fShaderDerivativeExtensionString;
Chris Dalton8fd79552018-01-11 00:46:14 -0500289 const char* fGeometryShaderExtensionString;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600290 const char* fGSInvocationsExtensionString;
egdaniel8dcdedc2015-11-11 06:27:20 -0800291 const char* fFragCoordConventionsExtensionString;
292 const char* fSecondaryOutputExtensionString;
bsalomon7ea33f52015-11-22 14:51:00 -0800293 const char* fExternalTextureExtensionString;
Brian Osman061020e2018-04-17 14:22:15 -0400294 const char* fSecondExternalTextureExtensionString;
cdaltonc08f1962016-02-12 12:14:06 -0800295 const char* fNoPerspectiveInterpolationExtensionString;
Chris Daltond31b5e72019-02-26 18:02:16 -0700296 const char* fSampleVariablesExtensionString;
egdaniel574a4c12015-11-02 06:22:44 -0800297
jvanverthcba99b82015-06-24 06:59:57 -0700298 const char* fFBFetchColorName;
299 const char* fFBFetchExtensionString;
300
jvanverthe78d4872016-09-27 03:33:05 -0700301 int fMaxFragmentSamplers;
cdalton9c3f1432016-03-11 10:07:37 -0800302
jvanverthcba99b82015-06-24 06:59:57 -0700303 AdvBlendEqInteraction fAdvBlendEqInteraction;
304
Chris Dalton040238b2017-12-18 14:22:34 -0700305 friend class GrCaps; // For initialization.
Stephen White79b81c92019-07-31 15:56:26 -0400306 friend class GrDawnCaps;
Chris Dalton040238b2017-12-18 14:22:34 -0700307 friend class GrGLCaps;
Chris Daltonfddb6c02017-11-04 15:22:22 -0600308 friend class GrMockCaps;
Greg Danielcebcb842017-07-31 10:45:52 -0400309 friend class GrMtlCaps;
egdanielfa896322016-01-13 12:19:30 -0800310 friend class GrVkCaps;
Brian Salomonf1dd6772016-11-29 15:27:52 -0500311 friend class SkSL::ShaderCapsFactory;
jvanverthcba99b82015-06-24 06:59:57 -0700312};
313
jvanverthcba99b82015-06-24 06:59:57 -0700314#endif