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