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 
sampleVariablesSupport()61     bool sampleVariablesSupport() const { return fSampleVariablesSupport; }
62 
sampleMaskOverrideCoverageSupport()63     bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; }
64 
advBlendEqInteraction()65     AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
66 
mustEnableAdvBlendEqs()67     bool mustEnableAdvBlendEqs() const {
68         return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
69     }
70 
mustEnableSpecificAdvBlendEqs()71     bool mustEnableSpecificAdvBlendEqs() const {
72         return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
73     }
74 
mustDeclareFragmentShaderOutput()75     bool mustDeclareFragmentShaderOutput() const {
76         return fGLSLGeneration > k110_GrGLSLGeneration;
77     }
78 
usesPrecisionModifiers()79     bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
80 
81     // Returns whether we can use the glsl funciton any() in our shader code.
canUseAnyFunctionInShader()82     bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
83 
canUseMinAndAbsTogether()84     bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
85 
mustForceNegatedAtanParamToFloat()86     bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
87 
88     // Returns the string of an extension that must be enabled in the shader to support
89     // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
90     // this function, the caller should check that shaderDerivativeSupport exists.
shaderDerivativeExtensionString()91     const char* shaderDerivativeExtensionString() const {
92         SkASSERT(this->shaderDerivativeSupport());
93         return fShaderDerivativeExtensionString;
94     }
95 
96     // Returns the string of an extension that will do all necessary coord transfomations needed
97     // when reading the fragment position. If such an extension does not exisits, this function
98     // returns a nullptr, and all transforms of the frag position must be done manually in the
99     // shader.
fragCoordConventionsExtensionString()100     const char* fragCoordConventionsExtensionString() const {
101         return fFragCoordConventionsExtensionString;
102     }
103 
104     // This returns the name of an extension that must be enabled in the shader, if such a thing is
105     // required in order to use a secondary output in the shader. This returns a nullptr if no such
106     // extension is required. However, the return value of this function does not say whether dual
107     // source blending is supported.
secondaryOutputExtensionString()108     const char* secondaryOutputExtensionString() const {
109         return fSecondaryOutputExtensionString;
110     }
111 
externalTextureExtensionString()112     const char* externalTextureExtensionString() const {
113         return fExternalTextureExtensionString;
114     }
115 
noperspectiveInterpolationExtensionString()116     const char* noperspectiveInterpolationExtensionString() const {
117         SkASSERT(this->noperspectiveInterpolationSupport());
118         return fNoPerspectiveInterpolationExtensionString;
119     }
120 
sampleVariablesExtensionString()121     const char* sampleVariablesExtensionString() const {
122         SkASSERT(this->sampleVariablesSupport());
123         return fSampleVariablesExtensionString;
124     }
125 
126     /**
127      * Given a texture's config, this determines what swizzle must be appended to accesses to the
128      * texture in generated shader code. Swizzling may be implemented in texture parameters or a
129      * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
130      */
configTextureSwizzle(GrPixelConfig config)131     const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
132         return fConfigTextureSwizzle[config];
133     }
134 
135     /** Swizzle that should occur on the fragment shader outputs for a given config. */
configOutputSwizzle(GrPixelConfig config)136     const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
137         return fConfigOutputSwizzle[config];
138     }
139 
generation()140     GrGLSLGeneration generation() const { return fGLSLGeneration; }
141 
142     /**
143     * Returns a string containing the caps info.
144     */
145     SkString dump() const override;
146 
147 private:
148     void onApplyOptionsOverrides(const GrContextOptions& options) override;
149 
150     GrGLSLGeneration fGLSLGeneration;
151 
152     bool fDropsTileOnZeroDivide : 1;
153     bool fFBFetchSupport : 1;
154     bool fFBFetchNeedsCustomOutput : 1;
155     bool fBindlessTextureSupport : 1;
156     bool fUsesPrecisionModifiers : 1;
157     bool fCanUseAnyFunctionInShader : 1;
158     bool fFlatInterpolationSupport : 1;
159     bool fNoPerspectiveInterpolationSupport : 1;
160     bool fSampleVariablesSupport : 1;
161     bool fSampleMaskOverrideCoverageSupport : 1;
162 
163     // Used for specific driver bug work arounds
164     bool fCanUseMinAndAbsTogether : 1;
165     bool fMustForceNegatedAtanParamToFloat : 1;
166 
167     const char* fVersionDeclString;
168 
169     const char* fShaderDerivativeExtensionString;
170     const char* fFragCoordConventionsExtensionString;
171     const char* fSecondaryOutputExtensionString;
172     const char* fExternalTextureExtensionString;
173     const char* fNoPerspectiveInterpolationExtensionString;
174     const char* fSampleVariablesExtensionString;
175 
176     const char* fFBFetchColorName;
177     const char* fFBFetchExtensionString;
178 
179     AdvBlendEqInteraction fAdvBlendEqInteraction;
180 
181     GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
182     GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
183 
184     friend class GrGLCaps;  // For initialization.
185     friend class GrVkCaps;
186 
187     typedef GrShaderCaps INHERITED;
188 };
189 
190 #endif
191