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 GrGLSLCaps_DEFINED
10 #define GrGLSLCaps_DEFINED
11 
12 #include "GrCaps.h"
13 #include "GrGLSL.h"
14 #include "GrSwizzle.h"
15 
16 class GrGLSLCaps : public GrShaderCaps {
17 public:
18 
19 
20     /**
21     * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
22     * special layout qualifiers in the fragment shader.
23     */
24     enum AdvBlendEqInteraction {
25         kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
26         kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
27         kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
28         kSpecificEnables_AdvBlendEqInteraction,  //<! Specific layout qualifiers per equation
29 
30         kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
31     };
32 
33     /**
34      * Initializes the GrGLSLCaps to a default set of features
35      */
36     GrGLSLCaps(const GrContextOptions&);
37 
38     /**
39      * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
40      *
41      * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
42      */
fbFetchSupport()43     bool fbFetchSupport() const { return fFBFetchSupport; }
44 
fbFetchNeedsCustomOutput()45     bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
46 
bindlessTextureSupport()47     bool bindlessTextureSupport() const { return fBindlessTextureSupport; }
48 
versionDeclString()49     const char* versionDeclString() const { return fVersionDeclString; }
50 
fbFetchColorName()51     const char* fbFetchColorName() const { return fFBFetchColorName; }
52 
fbFetchExtensionString()53     const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
54 
dropsTileOnZeroDivide()55     bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
56 
flatInterpolationSupport()57     bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
58 
noperspectiveInterpolationSupport()59     bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
60 
multisampleInterpolationSupport()61     bool multisampleInterpolationSupport() const { return fMultisampleInterpolationSupport; }
62 
sampleVariablesSupport()63     bool sampleVariablesSupport() const { return fSampleVariablesSupport; }
64 
sampleMaskOverrideCoverageSupport()65     bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; }
66 
externalTextureSupport()67     bool externalTextureSupport() const { return fExternalTextureSupport; }
68 
texelFetchSupport()69     bool texelFetchSupport() const { return fTexelFetchSupport; }
70 
advBlendEqInteraction()71     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
72 
mustEnableAdvBlendEqs()73     bool mustEnableAdvBlendEqs() const {
74         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
75     }
76 
mustEnableSpecificAdvBlendEqs()77     bool mustEnableSpecificAdvBlendEqs() const {
78         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
79     }
80 
mustDeclareFragmentShaderOutput()81     bool mustDeclareFragmentShaderOutput() const {
82         return fGLSLGeneration > k110_GrGLSLGeneration;
83     }
84 
usesPrecisionModifiers()85     bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
86 
87     // Returns whether we can use the glsl funciton any() in our shader code.
canUseAnyFunctionInShader()88     bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
89 
canUseMinAndAbsTogether()90     bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
91 
mustForceNegatedAtanParamToFloat()92     bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
93 
requiresLocalOutputColorForFBFetch()94     bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
95 
96     // Returns the string of an extension that must be enabled in the shader to support
97     // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
98     // this function, the caller should check that shaderDerivativeSupport exists.
shaderDerivativeExtensionString()99     const char* shaderDerivativeExtensionString() const {
100         SkASSERT(this->shaderDerivativeSupport());
101         return fShaderDerivativeExtensionString;
102     }
103 
104     // Returns the string of an extension that will do all necessary coord transfomations needed
105     // when reading the fragment position. If such an extension does not exisits, this function
106     // returns a nullptr, and all transforms of the frag position must be done manually in the
107     // shader.
fragCoordConventionsExtensionString()108     const char* fragCoordConventionsExtensionString() const {
109         return fFragCoordConventionsExtensionString;
110     }
111 
112     // This returns the name of an extension that must be enabled in the shader, if such a thing is
113     // required in order to use a secondary output in the shader. This returns a nullptr if no such
114     // extension is required. However, the return value of this function does not say whether dual
115     // source blending is supported.
secondaryOutputExtensionString()116     const char* secondaryOutputExtensionString() const {
117         return fSecondaryOutputExtensionString;
118     }
119 
externalTextureExtensionString()120     const char* externalTextureExtensionString() const {
121         SkASSERT(this->externalTextureSupport());
122         return fExternalTextureExtensionString;
123     }
124 
texelBufferExtensionString()125     const char* texelBufferExtensionString() const {
126         SkASSERT(this->texelBufferSupport());
127         return fTexelBufferExtensionString;
128     }
129 
noperspectiveInterpolationExtensionString()130     const char* noperspectiveInterpolationExtensionString() const {
131         SkASSERT(this->noperspectiveInterpolationSupport());
132         return fNoPerspectiveInterpolationExtensionString;
133     }
134 
multisampleInterpolationExtensionString()135     const char* multisampleInterpolationExtensionString() const {
136         SkASSERT(this->multisampleInterpolationSupport());
137         return fMultisampleInterpolationExtensionString;
138     }
139 
sampleVariablesExtensionString()140     const char* sampleVariablesExtensionString() const {
141         SkASSERT(this->sampleVariablesSupport());
142         return fSampleVariablesExtensionString;
143     }
144 
maxVertexSamplers()145     int maxVertexSamplers() const { return fMaxVertexSamplers; }
146 
maxGeometrySamplers()147     int maxGeometrySamplers() const { return fMaxGeometrySamplers; }
148 
maxFragmentSamplers()149     int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
150 
maxCombinedSamplers()151     int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
152 
153     /**
154      * Given a texture's config, this determines what swizzle must be appended to accesses to the
155      * texture in generated shader code. Swizzling may be implemented in texture parameters or a
156      * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
157      */
configTextureSwizzle(GrPixelConfig config)158     const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
159         return fConfigTextureSwizzle[config];
160     }
161 
162     /** Swizzle that should occur on the fragment shader outputs for a given config. */
configOutputSwizzle(GrPixelConfig config)163     const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
164         return fConfigOutputSwizzle[config];
165     }
166 
167     /** Precision qualifier that should be used with a sampler, given its config and visibility. */
samplerPrecision(GrPixelConfig config,GrShaderFlags visibility)168     GrSLPrecision samplerPrecision(GrPixelConfig config, GrShaderFlags visibility) const {
169         return static_cast<GrSLPrecision>(fSamplerPrecisions[visibility][config]);
170     }
171 
generation()172     GrGLSLGeneration generation() const { return fGLSLGeneration; }
173 
174     /**
175     * Returns a string containing the caps info.
176     */
177     SkString dump() const override;
178 
179 private:
180     /** GrCaps subclasses must call this after filling in the shader precision table. */
181     void initSamplerPrecisionTable();
182 
183     void onApplyOptionsOverrides(const GrContextOptions& options) override;
184 
185     GrGLSLGeneration fGLSLGeneration;
186 
187     bool fDropsTileOnZeroDivide : 1;
188     bool fFBFetchSupport : 1;
189     bool fFBFetchNeedsCustomOutput : 1;
190     bool fBindlessTextureSupport : 1;
191     bool fUsesPrecisionModifiers : 1;
192     bool fCanUseAnyFunctionInShader : 1;
193     bool fFlatInterpolationSupport : 1;
194     bool fNoPerspectiveInterpolationSupport : 1;
195     bool fMultisampleInterpolationSupport : 1;
196     bool fSampleVariablesSupport : 1;
197     bool fSampleMaskOverrideCoverageSupport : 1;
198     bool fExternalTextureSupport : 1;
199     bool fTexelFetchSupport : 1;
200 
201     // Used for specific driver bug work arounds
202     bool fCanUseMinAndAbsTogether : 1;
203     bool fMustForceNegatedAtanParamToFloat : 1;
204     bool fRequiresLocalOutputColorForFBFetch : 1;
205 
206     const char* fVersionDeclString;
207 
208     const char* fShaderDerivativeExtensionString;
209     const char* fFragCoordConventionsExtensionString;
210     const char* fSecondaryOutputExtensionString;
211     const char* fExternalTextureExtensionString;
212     const char* fTexelBufferExtensionString;
213     const char* fNoPerspectiveInterpolationExtensionString;
214     const char* fMultisampleInterpolationExtensionString;
215     const char* fSampleVariablesExtensionString;
216 
217     const char* fFBFetchColorName;
218     const char* fFBFetchExtensionString;
219 
220     int fMaxVertexSamplers;
221     int fMaxGeometrySamplers;
222     int fMaxFragmentSamplers;
223     int fMaxCombinedSamplers;
224 
225     AdvBlendEqInteraction fAdvBlendEqInteraction;
226 
227     GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
228     GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
229 
230     uint8_t fSamplerPrecisions[(1 << kGrShaderTypeCount)][kGrPixelConfigCnt];
231 
232     friend class GrGLCaps;  // For initialization.
233     friend class GrVkCaps;
234 
235     typedef GrShaderCaps INHERITED;
236 };
237 
238 #endif
239