blob: ec5d7efd48dad3fbfd5f980d6afcc290330f9354 [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 {
16 class GLSLCapsFactory;
17}
Brian Salomon94efbf52016-11-29 13:43:05 -050018struct GrContextOptions;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050019
Brian Salomon94efbf52016-11-29 13:43:05 -050020class GrShaderCaps : public SkRefCnt {
jvanverthcba99b82015-06-24 06:59:57 -070021public:
Brian Salomon94efbf52016-11-29 13:43:05 -050022 /** Info about shader variable precision within a given shader stage. That is, this info
23 is relevant to a float (or vecNf) variable declared with a GrSLPrecision
24 in a given GrShaderType. The info here is hoisted from the OpenGL spec. */
25 struct PrecisionInfo {
26 PrecisionInfo() {
27 fLogRangeLow = 0;
28 fLogRangeHigh = 0;
29 fBits = 0;
30 }
31
32 /** Is this precision level allowed in the shader stage? */
33 bool supported() const { return 0 != fBits; }
34
35 bool operator==(const PrecisionInfo& that) const {
36 return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh &&
37 fBits == that.fBits;
38 }
39 bool operator!=(const PrecisionInfo& that) const { return !(*this == that); }
40
41 /** floor(log2(|min_value|)) */
42 int fLogRangeLow;
43 /** floor(log2(|max_value|)) */
44 int fLogRangeHigh;
45 /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this
46 struct) :
47 """
48 If the smallest representable value greater than 1 is 1 + e, then fBits will
49 contain floor(log2(e)), and every value in the range [2^fLogRangeLow,
50 2^fLogRangeHigh] can be represented to at least one part in 2^fBits.
51 """
52 */
53 int fBits;
54 };
55
jvanverthcba99b82015-06-24 06:59:57 -070056 /**
57 * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
58 * special layout qualifiers in the fragment shader.
59 */
60 enum AdvBlendEqInteraction {
61 kNotSupported_AdvBlendEqInteraction, //<! No _blend_equation_advanced extension
62 kAutomatic_AdvBlendEqInteraction, //<! No interaction required
63 kGeneralEnable_AdvBlendEqInteraction, //<! layout(blend_support_all_equations) out
64 kSpecificEnables_AdvBlendEqInteraction, //<! Specific layout qualifiers per equation
65
66 kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
67 };
68
Brian Salomon94efbf52016-11-29 13:43:05 -050069 GrShaderCaps(const GrContextOptions&);
70
71 SkString dump() const;
72
73 bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
74 bool geometryShaderSupport() const { return fGeometryShaderSupport; }
75 bool pathRenderingSupport() const { return fPathRenderingSupport; }
76 bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
77 bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
78 bool integerSupport() const { return fIntegerSupport; }
79 bool texelBufferSupport() const { return fTexelBufferSupport; }
80 int imageLoadStoreSupport() const { return fImageLoadStoreSupport; }
81
jvanverthcba99b82015-06-24 06:59:57 -070082 /**
Brian Salomon94efbf52016-11-29 13:43:05 -050083 * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
84 * given shader type. If the shader type is not supported or the precision level is not
85 * supported in that shader type then the returned struct will report false when supported() is
86 * called.
87 */
88 const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
89 GrSLPrecision precision) const {
90 return fFloatPrecisions[shaderType][precision];
91 }
92
93 /**
94 * Is there any difference between the float shader variable precision types? If this is true
95 * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
96 * report the same info for all precisions in all shader types.
97 */
98 bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
99
100 /**
101 * PLS storage size in bytes (0 when not supported). The PLS spec defines a minimum size of 16
102 * bytes whenever PLS is supported.
jvanverthcba99b82015-06-24 06:59:57 -0700103 */
Brian Salomon94efbf52016-11-29 13:43:05 -0500104 int pixelLocalStorageSize() const { return fPixelLocalStorageSize; }
105
106 /**
107 * True if this context supports the necessary extensions and features to enable the PLS path
108 * renderer.
109 */
110 bool plsPathRenderingSupport() const {
111#if GR_ENABLE_PLS_PATH_RENDERING
112 return fPLSPathRenderingSupport;
113#else
114 return false;
115#endif
116 }
jvanverthcba99b82015-06-24 06:59:57 -0700117
118 /**
119 * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
120 *
121 * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
122 */
123 bool fbFetchSupport() const { return fFBFetchSupport; }
124
125 bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
126
127 bool bindlessTextureSupport() const { return fBindlessTextureSupport; }
128
egdaniel472d44e2015-10-22 08:20:00 -0700129 const char* versionDeclString() const { return fVersionDeclString; }
130
jvanverthcba99b82015-06-24 06:59:57 -0700131 const char* fbFetchColorName() const { return fFBFetchColorName; }
132
133 const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
134
135 bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
136
cdaltonc08f1962016-02-12 12:14:06 -0800137 bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
138
139 bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
140
cdalton4a98cdb2016-03-01 12:12:20 -0800141 bool multisampleInterpolationSupport() const { return fMultisampleInterpolationSupport; }
142
cdalton33ad7012016-02-22 07:55:44 -0800143 bool sampleVariablesSupport() const { return fSampleVariablesSupport; }
144
145 bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; }
146
cdalton9c3f1432016-03-11 10:07:37 -0800147 bool externalTextureSupport() const { return fExternalTextureSupport; }
148
cdaltonf8a6ce82016-04-11 13:02:05 -0700149 bool texelFetchSupport() const { return fTexelFetchSupport; }
cdaltonc04ce672016-03-11 14:07:38 -0800150
jvanverthcba99b82015-06-24 06:59:57 -0700151 AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
152
153 bool mustEnableAdvBlendEqs() const {
154 return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
155 }
156
157 bool mustEnableSpecificAdvBlendEqs() const {
158 return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
159 }
halcanary9d524f22016-03-29 09:03:52 -0700160
jvanverthcba99b82015-06-24 06:59:57 -0700161 bool mustDeclareFragmentShaderOutput() const {
162 return fGLSLGeneration > k110_GrGLSLGeneration;
163 }
164
egdanielf5294392015-10-21 07:14:17 -0700165 bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
166
egdaniel472d44e2015-10-22 08:20:00 -0700167 // Returns whether we can use the glsl funciton any() in our shader code.
168 bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
169
egdaniel8dcdedc2015-11-11 06:27:20 -0800170 bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
171
172 bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
173
egdaniel138c2632016-08-17 10:59:00 -0700174 bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
175
egdaniel574a4c12015-11-02 06:22:44 -0800176 // Returns the string of an extension that must be enabled in the shader to support
177 // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
178 // this function, the caller should check that shaderDerivativeSupport exists.
179 const char* shaderDerivativeExtensionString() const {
180 SkASSERT(this->shaderDerivativeSupport());
181 return fShaderDerivativeExtensionString;
182 }
cdalton33ad7012016-02-22 07:55:44 -0800183
egdaniel8dcdedc2015-11-11 06:27:20 -0800184 // Returns the string of an extension that will do all necessary coord transfomations needed
185 // when reading the fragment position. If such an extension does not exisits, this function
186 // returns a nullptr, and all transforms of the frag position must be done manually in the
187 // shader.
188 const char* fragCoordConventionsExtensionString() const {
189 return fFragCoordConventionsExtensionString;
190 }
191
192 // This returns the name of an extension that must be enabled in the shader, if such a thing is
193 // required in order to use a secondary output in the shader. This returns a nullptr if no such
194 // extension is required. However, the return value of this function does not say whether dual
195 // source blending is supported.
196 const char* secondaryOutputExtensionString() const {
197 return fSecondaryOutputExtensionString;
198 }
egdaniel574a4c12015-11-02 06:22:44 -0800199
bsalomon7ea33f52015-11-22 14:51:00 -0800200 const char* externalTextureExtensionString() const {
cdalton9c3f1432016-03-11 10:07:37 -0800201 SkASSERT(this->externalTextureSupport());
bsalomon7ea33f52015-11-22 14:51:00 -0800202 return fExternalTextureExtensionString;
203 }
204
cdaltonf8a6ce82016-04-11 13:02:05 -0700205 const char* texelBufferExtensionString() const {
206 SkASSERT(this->texelBufferSupport());
207 return fTexelBufferExtensionString;
cdaltonc04ce672016-03-11 14:07:38 -0800208 }
209
cdaltonc08f1962016-02-12 12:14:06 -0800210 const char* noperspectiveInterpolationExtensionString() const {
211 SkASSERT(this->noperspectiveInterpolationSupport());
212 return fNoPerspectiveInterpolationExtensionString;
213 }
214
cdalton4a98cdb2016-03-01 12:12:20 -0800215 const char* multisampleInterpolationExtensionString() const {
216 SkASSERT(this->multisampleInterpolationSupport());
217 return fMultisampleInterpolationExtensionString;
218 }
219
cdalton33ad7012016-02-22 07:55:44 -0800220 const char* sampleVariablesExtensionString() const {
221 SkASSERT(this->sampleVariablesSupport());
222 return fSampleVariablesExtensionString;
223 }
224
Brian Salomonf26f7a02016-11-15 14:05:01 -0500225 const char* imageLoadStoreExtensionString() const {
226 SkASSERT(this->imageLoadStoreSupport());
227 return fImageLoadStoreExtensionString;
228 }
229
cdalton9c3f1432016-03-11 10:07:37 -0800230 int maxVertexSamplers() const { return fMaxVertexSamplers; }
231
232 int maxGeometrySamplers() const { return fMaxGeometrySamplers; }
233
234 int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
235
236 int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
237
Brian Salomonf9f45122016-11-29 11:59:17 -0500238 int maxVertexImageStorages() const { return fMaxVertexImageStorages; }
Brian Salomonf26f7a02016-11-15 14:05:01 -0500239
Brian Salomonf9f45122016-11-29 11:59:17 -0500240 int maxGeometryImageStorages() const { return fMaxGeometryImageStorages; }
Brian Salomonf26f7a02016-11-15 14:05:01 -0500241
Brian Salomonf9f45122016-11-29 11:59:17 -0500242 int maxFragmentImageStorages() const { return fMaxFragmentImageStorages; }
Brian Salomonf26f7a02016-11-15 14:05:01 -0500243
Brian Salomonf9f45122016-11-29 11:59:17 -0500244 int maxCombinedImageStorages() const { return fMaxCombinedImageStorages; }
Brian Salomonf26f7a02016-11-15 14:05:01 -0500245
egdanielb7e7d572015-11-04 04:23:53 -0800246 /**
bsalomoncdee0092016-01-08 13:20:12 -0800247 * Given a texture's config, this determines what swizzle must be appended to accesses to the
248 * texture in generated shader code. Swizzling may be implemented in texture parameters or a
bsalomon7f9b2e42016-01-12 13:29:26 -0800249 * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
egdanielb7e7d572015-11-04 04:23:53 -0800250 */
bsalomoncdee0092016-01-08 13:20:12 -0800251 const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
252 return fConfigTextureSwizzle[config];
253 }
egdanielb7e7d572015-11-04 04:23:53 -0800254
bsalomon7f9b2e42016-01-12 13:29:26 -0800255 /** Swizzle that should occur on the fragment shader outputs for a given config. */
256 const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
257 return fConfigOutputSwizzle[config];
258 }
259
cdaltona6b92ad2016-04-11 12:03:08 -0700260 /** Precision qualifier that should be used with a sampler, given its config and visibility. */
261 GrSLPrecision samplerPrecision(GrPixelConfig config, GrShaderFlags visibility) const {
262 return static_cast<GrSLPrecision>(fSamplerPrecisions[visibility][config]);
263 }
264
jvanverthcba99b82015-06-24 06:59:57 -0700265 GrGLSLGeneration generation() const { return fGLSLGeneration; }
266
jvanverthcba99b82015-06-24 06:59:57 -0700267private:
cdaltona6b92ad2016-04-11 12:03:08 -0700268 /** GrCaps subclasses must call this after filling in the shader precision table. */
269 void initSamplerPrecisionTable();
270
Brian Salomon94efbf52016-11-29 13:43:05 -0500271 void applyOptionsOverrides(const GrContextOptions& options);
egdanielb7e7d572015-11-04 04:23:53 -0800272
jvanverthcba99b82015-06-24 06:59:57 -0700273 GrGLSLGeneration fGLSLGeneration;
halcanary9d524f22016-03-29 09:03:52 -0700274
Brian Salomon94efbf52016-11-29 13:43:05 -0500275 bool fShaderDerivativeSupport : 1;
276 bool fGeometryShaderSupport : 1;
277 bool fPathRenderingSupport : 1;
278 bool fDstReadInShaderSupport : 1;
279 bool fDualSourceBlendingSupport : 1;
280 bool fIntegerSupport : 1;
281 bool fTexelBufferSupport : 1;
282 bool fImageLoadStoreSupport : 1;
283 bool fPLSPathRenderingSupport : 1;
284 bool fShaderPrecisionVaries : 1;
jvanverthcba99b82015-06-24 06:59:57 -0700285 bool fDropsTileOnZeroDivide : 1;
286 bool fFBFetchSupport : 1;
287 bool fFBFetchNeedsCustomOutput : 1;
288 bool fBindlessTextureSupport : 1;
egdanielf5294392015-10-21 07:14:17 -0700289 bool fUsesPrecisionModifiers : 1;
egdaniel472d44e2015-10-22 08:20:00 -0700290 bool fCanUseAnyFunctionInShader : 1;
cdaltonc08f1962016-02-12 12:14:06 -0800291 bool fFlatInterpolationSupport : 1;
292 bool fNoPerspectiveInterpolationSupport : 1;
cdalton4a98cdb2016-03-01 12:12:20 -0800293 bool fMultisampleInterpolationSupport : 1;
cdalton33ad7012016-02-22 07:55:44 -0800294 bool fSampleVariablesSupport : 1;
295 bool fSampleMaskOverrideCoverageSupport : 1;
cdalton9c3f1432016-03-11 10:07:37 -0800296 bool fExternalTextureSupport : 1;
cdaltonf8a6ce82016-04-11 13:02:05 -0700297 bool fTexelFetchSupport : 1;
egdanielf5294392015-10-21 07:14:17 -0700298
egdaniel8dcdedc2015-11-11 06:27:20 -0800299 // Used for specific driver bug work arounds
300 bool fCanUseMinAndAbsTogether : 1;
301 bool fMustForceNegatedAtanParamToFloat : 1;
egdaniel138c2632016-08-17 10:59:00 -0700302 bool fRequiresLocalOutputColorForFBFetch : 1;
egdaniel8dcdedc2015-11-11 06:27:20 -0800303
Brian Salomon94efbf52016-11-29 13:43:05 -0500304 PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
305 int fPixelLocalStorageSize;
306
egdaniel472d44e2015-10-22 08:20:00 -0700307 const char* fVersionDeclString;
jvanverthcba99b82015-06-24 06:59:57 -0700308
egdaniel574a4c12015-11-02 06:22:44 -0800309 const char* fShaderDerivativeExtensionString;
egdaniel8dcdedc2015-11-11 06:27:20 -0800310 const char* fFragCoordConventionsExtensionString;
311 const char* fSecondaryOutputExtensionString;
bsalomon7ea33f52015-11-22 14:51:00 -0800312 const char* fExternalTextureExtensionString;
cdaltonf8a6ce82016-04-11 13:02:05 -0700313 const char* fTexelBufferExtensionString;
cdaltonc08f1962016-02-12 12:14:06 -0800314 const char* fNoPerspectiveInterpolationExtensionString;
cdalton4a98cdb2016-03-01 12:12:20 -0800315 const char* fMultisampleInterpolationExtensionString;
cdalton33ad7012016-02-22 07:55:44 -0800316 const char* fSampleVariablesExtensionString;
Brian Salomonf26f7a02016-11-15 14:05:01 -0500317 const char* fImageLoadStoreExtensionString;
egdaniel574a4c12015-11-02 06:22:44 -0800318
jvanverthcba99b82015-06-24 06:59:57 -0700319 const char* fFBFetchColorName;
320 const char* fFBFetchExtensionString;
321
jvanverthe78d4872016-09-27 03:33:05 -0700322 int fMaxVertexSamplers;
323 int fMaxGeometrySamplers;
324 int fMaxFragmentSamplers;
325 int fMaxCombinedSamplers;
cdalton9c3f1432016-03-11 10:07:37 -0800326
Brian Salomonf9f45122016-11-29 11:59:17 -0500327 int fMaxVertexImageStorages;
328 int fMaxGeometryImageStorages;
329 int fMaxFragmentImageStorages;
330 int fMaxCombinedImageStorages;
Brian Salomonf26f7a02016-11-15 14:05:01 -0500331
jvanverthcba99b82015-06-24 06:59:57 -0700332 AdvBlendEqInteraction fAdvBlendEqInteraction;
333
bsalomoncdee0092016-01-08 13:20:12 -0800334 GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
bsalomon7f9b2e42016-01-12 13:29:26 -0800335 GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
egdanielb7e7d572015-11-04 04:23:53 -0800336
cdaltona6b92ad2016-04-11 12:03:08 -0700337 uint8_t fSamplerPrecisions[(1 << kGrShaderTypeCount)][kGrPixelConfigCnt];
338
jvanverthcba99b82015-06-24 06:59:57 -0700339 friend class GrGLCaps; // For initialization.
egdanielfa896322016-01-13 12:19:30 -0800340 friend class GrVkCaps;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500341 friend class SkSL::GLSLCapsFactory;
jvanverthcba99b82015-06-24 06:59:57 -0700342};
343
jvanverthcba99b82015-06-24 06:59:57 -0700344#endif