blob: d8f4d95eb60bea632a4968906b3cd9b21e4cf930 [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
8
Brian Salomon94efbf52016-11-29 13:43:05 -05009#ifndef GrShaderCaps_DEFINED
10#define GrShaderCaps_DEFINED
jvanverthcba99b82015-06-24 06:59:57 -070011
Brian Salomon94efbf52016-11-29 13:43:05 -050012#include "../private/GrSwizzle.h"
13#include "../private/GrGLSL.h"
jvanverthcba99b82015-06-24 06:59:57 -070014
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050015namespace SkSL {
Brian Salomonf1dd6772016-11-29 15:27:52 -050016 class ShaderCapsFactory;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050017}
Brian Salomon94efbf52016-11-29 13:43:05 -050018struct GrContextOptions;
Brian Osman71a18892017-08-10 10:23:25 -040019class SkJSONWriter;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050020
Brian Salomon94efbf52016-11-29 13:43:05 -050021class GrShaderCaps : public SkRefCnt {
jvanverthcba99b82015-06-24 06:59:57 -070022public:
jvanverthcba99b82015-06-24 06:59:57 -070023 /**
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
Brian Salomon94efbf52016-11-29 13:43:05 -050036 GrShaderCaps(const GrContextOptions&);
37
Brian Osman71a18892017-08-10 10:23:25 -040038 void dumpJSON(SkJSONWriter*) const;
Brian Salomon94efbf52016-11-29 13:43:05 -050039
40 bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
41 bool geometryShaderSupport() const { return fGeometryShaderSupport; }
Chris Daltonf1b47bb2017-10-06 11:57:51 -060042 bool gsInvocationsSupport() const { return fGSInvocationsSupport; }
Brian Salomon94efbf52016-11-29 13:43:05 -050043 bool pathRenderingSupport() const { return fPathRenderingSupport; }
44 bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
45 bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
46 bool integerSupport() const { return fIntegerSupport; }
47 bool texelBufferSupport() const { return fTexelBufferSupport; }
48 int imageLoadStoreSupport() const { return fImageLoadStoreSupport; }
49
jvanverthcba99b82015-06-24 06:59:57 -070050 /**
jvanverthcba99b82015-06-24 06:59:57 -070051 * 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 */
55 bool fbFetchSupport() const { return fFBFetchSupport; }
56
57 bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
58
egdaniel472d44e2015-10-22 08:20:00 -070059 const char* versionDeclString() const { return fVersionDeclString; }
60
jvanverthcba99b82015-06-24 06:59:57 -070061 const char* fbFetchColorName() const { return fFBFetchColorName; }
62
63 const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
64
65 bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
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
cdalton9c3f1432016-03-11 10:07:37 -080073 bool externalTextureSupport() const { return fExternalTextureSupport; }
74
cdaltonf8a6ce82016-04-11 13:02:05 -070075 bool texelFetchSupport() const { return fTexelFetchSupport; }
cdaltonc04ce672016-03-11 14:07:38 -080076
Chris Dalton1d616352017-05-31 12:51:23 -060077 bool vertexIDSupport() const { return fVertexIDSupport; }
78
Chris Dalton7c7ff032018-03-28 20:09:58 -060079 // frexp, ldexp, etc.
80 bool fpManipulationSupport() const { return fFPManipulationSupport; }
81
Chris Dalton47c8ed32017-11-15 18:27:09 -070082 bool floatIs32Bits() const { return fFloatIs32Bits; }
83
84 bool halfIs32Bits() const { return fHalfIs32Bits; }
85
jvanverthcba99b82015-06-24 06:59:57 -070086 AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
87
88 bool mustEnableAdvBlendEqs() const {
89 return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
90 }
91
92 bool mustEnableSpecificAdvBlendEqs() const {
93 return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
94 }
halcanary9d524f22016-03-29 09:03:52 -070095
jvanverthcba99b82015-06-24 06:59:57 -070096 bool mustDeclareFragmentShaderOutput() const {
97 return fGLSLGeneration > k110_GrGLSLGeneration;
98 }
99
egdanielf5294392015-10-21 07:14:17 -0700100 bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
101
Greg Daniel80a08dd2017-01-20 10:45:49 -0500102 // Returns whether we can use the glsl function any() in our shader code.
egdaniel472d44e2015-10-22 08:20:00 -0700103 bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
104
egdaniel8dcdedc2015-11-11 06:27:20 -0800105 bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
106
Florin Malita8a0044f2017-08-07 14:38:22 -0400107 bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; }
108
egdaniel8dcdedc2015-11-11 06:27:20 -0800109 bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
110
Greg Daniel80a08dd2017-01-20 10:45:49 -0500111 // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
112 bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
113
Greg Daniel10ed2432017-12-01 16:19:43 -0500114 // If this returns true some operation (could be a no op) must be called between floor and abs
115 // to make sure the driver compiler doesn't inline them together which can cause a driver bug in
116 // the shader.
117 bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; }
118
Brian Osmancd3261a2018-01-16 13:52:29 +0000119 // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord
120 bool canUseFragCoord() const { return fCanUseFragCoord; }
121
Brian Salomondba65f92018-01-22 08:43:38 -0500122 // If true interpolated vertex shader outputs are inaccurate.
123 bool interpolantsAreInaccurate() const { return fInterpolantsAreInaccurate; }
124
Chris Daltonc2d0dd62018-03-07 07:46:10 -0700125 // If true, short ints can't represent every integer in the 16-bit two's complement range as
126 // required by the spec. SKSL will always emit full ints.
127 bool incompleteShortIntPrecision() const { return fIncompleteShortIntPrecision; }
128
egdaniel138c2632016-08-17 10:59:00 -0700129 bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
130
Brian Osmanac1e4962017-05-25 11:34:38 -0400131 bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
132
Brian Osmandff5d432017-08-01 14:46:18 -0400133 // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain
134 // constructs. See detailed comments in GrGLCaps.cpp.
135 bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
136 return fMustGuardDivisionEvenAfterExplicitZeroCheck;
137 }
138
egdaniel574a4c12015-11-02 06:22:44 -0800139 // Returns the string of an extension that must be enabled in the shader to support
140 // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
141 // this function, the caller should check that shaderDerivativeSupport exists.
142 const char* shaderDerivativeExtensionString() const {
143 SkASSERT(this->shaderDerivativeSupport());
144 return fShaderDerivativeExtensionString;
145 }
cdalton33ad7012016-02-22 07:55:44 -0800146
Chris Dalton8fd79552018-01-11 00:46:14 -0500147 // Returns the string of an extension that must be enabled in the shader to support geometry
148 // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this
149 // function, the caller must verify that geometryShaderSupport exists.
150 const char* geometryShaderExtensionString() const {
151 SkASSERT(this->geometryShaderSupport());
152 return fGeometryShaderExtensionString;
153 }
154
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600155 // Returns the string of an extension that must be enabled in the shader to support
156 // geometry shader invocations. If nullptr is returned then no extension needs to be enabled.
157 // Before calling this function, the caller must verify that gsInvocationsSupport exists.
158 const char* gsInvocationsExtensionString() const {
159 SkASSERT(this->gsInvocationsSupport());
160 return fGSInvocationsExtensionString;
161 }
162
egdaniel8dcdedc2015-11-11 06:27:20 -0800163 // Returns the string of an extension that will do all necessary coord transfomations needed
164 // when reading the fragment position. If such an extension does not exisits, this function
165 // returns a nullptr, and all transforms of the frag position must be done manually in the
166 // shader.
167 const char* fragCoordConventionsExtensionString() const {
168 return fFragCoordConventionsExtensionString;
169 }
170
171 // This returns the name of an extension that must be enabled in the shader, if such a thing is
172 // required in order to use a secondary output in the shader. This returns a nullptr if no such
173 // extension is required. However, the return value of this function does not say whether dual
174 // source blending is supported.
175 const char* secondaryOutputExtensionString() const {
176 return fSecondaryOutputExtensionString;
177 }
egdaniel574a4c12015-11-02 06:22:44 -0800178
Brian Osman061020e2018-04-17 14:22:15 -0400179 // This returns the name of an extension that must be enabled in the shader to support external
180 // textures. In some cases, two extensions must be enabled - the second extension is returned
181 // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one
182 // extension is required.
bsalomon7ea33f52015-11-22 14:51:00 -0800183 const char* externalTextureExtensionString() const {
cdalton9c3f1432016-03-11 10:07:37 -0800184 SkASSERT(this->externalTextureSupport());
bsalomon7ea33f52015-11-22 14:51:00 -0800185 return fExternalTextureExtensionString;
186 }
187
Brian Osman061020e2018-04-17 14:22:15 -0400188 const char* secondExternalTextureExtensionString() const {
189 SkASSERT(this->externalTextureSupport());
190 return fSecondExternalTextureExtensionString;
191 }
192
cdaltonf8a6ce82016-04-11 13:02:05 -0700193 const char* texelBufferExtensionString() const {
194 SkASSERT(this->texelBufferSupport());
195 return fTexelBufferExtensionString;
cdaltonc04ce672016-03-11 14:07:38 -0800196 }
197
cdaltonc08f1962016-02-12 12:14:06 -0800198 const char* noperspectiveInterpolationExtensionString() const {
199 SkASSERT(this->noperspectiveInterpolationSupport());
200 return fNoPerspectiveInterpolationExtensionString;
201 }
202
Brian Salomonf26f7a02016-11-15 14:05:01 -0500203 const char* imageLoadStoreExtensionString() const {
204 SkASSERT(this->imageLoadStoreSupport());
205 return fImageLoadStoreExtensionString;
206 }
207
cdalton9c3f1432016-03-11 10:07:37 -0800208 int maxVertexSamplers() const { return fMaxVertexSamplers; }
209
210 int maxGeometrySamplers() const { return fMaxGeometrySamplers; }
211
212 int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
213
214 int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
215
Brian Salomon762d5e72017-12-01 10:25:08 -0500216 /**
217 * In general using multiple texture units for image rendering seems to be a win at smaller
218 * sizes of dst rects and a loss at larger sizes. Dst rects above this pixel area threshold will
219 * not use multitexturing.
220 */
221 size_t disableImageMultitexturingDstRectAreaThreshold() const {
222 return fDisableImageMultitexturingDstRectAreaThreshold;
223 }
Brian Salomon0b4d8aa2017-10-11 15:34:27 -0400224
egdanielb7e7d572015-11-04 04:23:53 -0800225 /**
bsalomoncdee0092016-01-08 13:20:12 -0800226 * Given a texture's config, this determines what swizzle must be appended to accesses to the
227 * texture in generated shader code. Swizzling may be implemented in texture parameters or a
bsalomon7f9b2e42016-01-12 13:29:26 -0800228 * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
egdanielb7e7d572015-11-04 04:23:53 -0800229 */
bsalomoncdee0092016-01-08 13:20:12 -0800230 const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
231 return fConfigTextureSwizzle[config];
232 }
egdanielb7e7d572015-11-04 04:23:53 -0800233
bsalomon7f9b2e42016-01-12 13:29:26 -0800234 /** Swizzle that should occur on the fragment shader outputs for a given config. */
235 const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
236 return fConfigOutputSwizzle[config];
237 }
238
jvanverthcba99b82015-06-24 06:59:57 -0700239 GrGLSLGeneration generation() const { return fGLSLGeneration; }
240
jvanverthcba99b82015-06-24 06:59:57 -0700241private:
Brian Salomon94efbf52016-11-29 13:43:05 -0500242 void applyOptionsOverrides(const GrContextOptions& options);
egdanielb7e7d572015-11-04 04:23:53 -0800243
jvanverthcba99b82015-06-24 06:59:57 -0700244 GrGLSLGeneration fGLSLGeneration;
halcanary9d524f22016-03-29 09:03:52 -0700245
Brian Salomon94efbf52016-11-29 13:43:05 -0500246 bool fShaderDerivativeSupport : 1;
247 bool fGeometryShaderSupport : 1;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600248 bool fGSInvocationsSupport : 1;
Brian Salomon94efbf52016-11-29 13:43:05 -0500249 bool fPathRenderingSupport : 1;
250 bool fDstReadInShaderSupport : 1;
251 bool fDualSourceBlendingSupport : 1;
252 bool fIntegerSupport : 1;
253 bool fTexelBufferSupport : 1;
254 bool fImageLoadStoreSupport : 1;
jvanverthcba99b82015-06-24 06:59:57 -0700255 bool fDropsTileOnZeroDivide : 1;
256 bool fFBFetchSupport : 1;
257 bool fFBFetchNeedsCustomOutput : 1;
egdanielf5294392015-10-21 07:14:17 -0700258 bool fUsesPrecisionModifiers : 1;
cdaltonc08f1962016-02-12 12:14:06 -0800259 bool fFlatInterpolationSupport : 1;
Brian Salomon41274562017-09-15 09:40:03 -0700260 bool fPreferFlatInterpolation : 1;
cdaltonc08f1962016-02-12 12:14:06 -0800261 bool fNoPerspectiveInterpolationSupport : 1;
cdalton9c3f1432016-03-11 10:07:37 -0800262 bool fExternalTextureSupport : 1;
cdaltonf8a6ce82016-04-11 13:02:05 -0700263 bool fTexelFetchSupport : 1;
Chris Dalton1d616352017-05-31 12:51:23 -0600264 bool fVertexIDSupport : 1;
Chris Dalton7c7ff032018-03-28 20:09:58 -0600265 bool fFPManipulationSupport : 1;
Chris Dalton47c8ed32017-11-15 18:27:09 -0700266 bool fFloatIs32Bits : 1;
267 bool fHalfIs32Bits : 1;
egdanielf5294392015-10-21 07:14:17 -0700268
egdaniel8dcdedc2015-11-11 06:27:20 -0800269 // Used for specific driver bug work arounds
Brian Salomon01b476a2018-01-23 11:06:41 -0500270 bool fCanUseAnyFunctionInShader : 1;
egdaniel8dcdedc2015-11-11 06:27:20 -0800271 bool fCanUseMinAndAbsTogether : 1;
Florin Malita8a0044f2017-08-07 14:38:22 -0400272 bool fCanUseFractForNegativeValues : 1;
egdaniel8dcdedc2015-11-11 06:27:20 -0800273 bool fMustForceNegatedAtanParamToFloat : 1;
Greg Daniel80a08dd2017-01-20 10:45:49 -0500274 bool fAtan2ImplementedAsAtanYOverX : 1;
Greg Daniel10ed2432017-12-01 16:19:43 -0500275 bool fMustDoOpBetweenFloorAndAbs : 1;
egdaniel138c2632016-08-17 10:59:00 -0700276 bool fRequiresLocalOutputColorForFBFetch : 1;
Brian Osmanac1e4962017-05-25 11:34:38 -0400277 bool fMustObfuscateUniformColor : 1;
Brian Osmandff5d432017-08-01 14:46:18 -0400278 bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1;
Brian Osmancd3261a2018-01-16 13:52:29 +0000279 bool fCanUseFragCoord : 1;
Brian Salomondba65f92018-01-22 08:43:38 -0500280 bool fInterpolantsAreInaccurate : 1;
Chris Daltonc2d0dd62018-03-07 07:46:10 -0700281 bool fIncompleteShortIntPrecision : 1;
egdaniel8dcdedc2015-11-11 06:27:20 -0800282
egdaniel472d44e2015-10-22 08:20:00 -0700283 const char* fVersionDeclString;
jvanverthcba99b82015-06-24 06:59:57 -0700284
egdaniel574a4c12015-11-02 06:22:44 -0800285 const char* fShaderDerivativeExtensionString;
Chris Dalton8fd79552018-01-11 00:46:14 -0500286 const char* fGeometryShaderExtensionString;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600287 const char* fGSInvocationsExtensionString;
egdaniel8dcdedc2015-11-11 06:27:20 -0800288 const char* fFragCoordConventionsExtensionString;
289 const char* fSecondaryOutputExtensionString;
bsalomon7ea33f52015-11-22 14:51:00 -0800290 const char* fExternalTextureExtensionString;
Brian Osman061020e2018-04-17 14:22:15 -0400291 const char* fSecondExternalTextureExtensionString;
cdaltonf8a6ce82016-04-11 13:02:05 -0700292 const char* fTexelBufferExtensionString;
cdaltonc08f1962016-02-12 12:14:06 -0800293 const char* fNoPerspectiveInterpolationExtensionString;
Brian Salomonf26f7a02016-11-15 14:05:01 -0500294 const char* fImageLoadStoreExtensionString;
egdaniel574a4c12015-11-02 06:22:44 -0800295
jvanverthcba99b82015-06-24 06:59:57 -0700296 const char* fFBFetchColorName;
297 const char* fFBFetchExtensionString;
298
jvanverthe78d4872016-09-27 03:33:05 -0700299 int fMaxVertexSamplers;
300 int fMaxGeometrySamplers;
301 int fMaxFragmentSamplers;
302 int fMaxCombinedSamplers;
cdalton9c3f1432016-03-11 10:07:37 -0800303
Brian Salomon762d5e72017-12-01 10:25:08 -0500304 size_t fDisableImageMultitexturingDstRectAreaThreshold;
305
jvanverthcba99b82015-06-24 06:59:57 -0700306 AdvBlendEqInteraction fAdvBlendEqInteraction;
307
bsalomoncdee0092016-01-08 13:20:12 -0800308 GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
bsalomon7f9b2e42016-01-12 13:29:26 -0800309 GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
egdanielb7e7d572015-11-04 04:23:53 -0800310
Chris Dalton040238b2017-12-18 14:22:34 -0700311 friend class GrCaps; // For initialization.
312 friend class GrGLCaps;
Chris Daltonfddb6c02017-11-04 15:22:22 -0600313 friend class GrMockCaps;
Greg Danielcebcb842017-07-31 10:45:52 -0400314 friend class GrMtlCaps;
egdanielfa896322016-01-13 12:19:30 -0800315 friend class GrVkCaps;
Brian Salomonf1dd6772016-11-29 15:27:52 -0500316 friend class SkSL::ShaderCapsFactory;
jvanverthcba99b82015-06-24 06:59:57 -0700317};
318
jvanverthcba99b82015-06-24 06:59:57 -0700319#endif