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 GrShaderCaps_DEFINED 10 #define GrShaderCaps_DEFINED 11 12 #include "../private/GrSwizzle.h" 13 #include "../private/GrGLSL.h" 14 15 namespace SkSL { 16 class ShaderCapsFactory; 17 } 18 struct GrContextOptions; 19 class SkJSONWriter; 20 21 class GrShaderCaps : public SkRefCnt { 22 public: 23 /** 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 36 GrShaderCaps(const GrContextOptions&); 37 38 void dumpJSON(SkJSONWriter*) const; 39 40 bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; } 41 bool geometryShaderSupport() const { return fGeometryShaderSupport; } 42 bool gsInvocationsSupport() const { return fGSInvocationsSupport; } 43 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 50 /** 51 * 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 59 bool bindlessTextureSupport() const { return fBindlessTextureSupport; } 60 61 const char* versionDeclString() const { return fVersionDeclString; } 62 63 const char* fbFetchColorName() const { return fFBFetchColorName; } 64 65 const char* fbFetchExtensionString() const { return fFBFetchExtensionString; } 66 67 bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; } 68 69 bool flatInterpolationSupport() const { return fFlatInterpolationSupport; } 70 71 bool preferFlatInterpolation() const { return fPreferFlatInterpolation; } 72 73 bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; } 74 75 bool multisampleInterpolationSupport() const { return fMultisampleInterpolationSupport; } 76 77 bool sampleVariablesSupport() const { return fSampleVariablesSupport; } 78 79 bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; } 80 81 bool externalTextureSupport() const { return fExternalTextureSupport; } 82 83 bool texelFetchSupport() const { return fTexelFetchSupport; } 84 85 bool vertexIDSupport() const { return fVertexIDSupport; } 86 87 bool floatIs32Bits() const { return fFloatIs32Bits; } 88 89 bool halfIs32Bits() const { return fHalfIs32Bits; } 90 91 AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; } 92 93 bool mustEnableAdvBlendEqs() const { 94 return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction; 95 } 96 97 bool mustEnableSpecificAdvBlendEqs() const { 98 return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction; 99 } 100 101 bool mustDeclareFragmentShaderOutput() const { 102 return fGLSLGeneration > k110_GrGLSLGeneration; 103 } 104 105 bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; } 106 107 // Returns whether we can use the glsl function any() in our shader code. 108 bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; } 109 110 bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; } 111 112 bool canUseFractForNegativeValues() const { return fCanUseFractForNegativeValues; } 113 114 bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; } 115 116 // Returns whether a device incorrectly implements atan(y,x) as atan(y/x) 117 bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; } 118 119 // If this returns true some operation (could be a no op) must be called between floor and abs 120 // to make sure the driver compiler doesn't inline them together which can cause a driver bug in 121 // the shader. 122 bool mustDoOpBetweenFloorAndAbs() const { return fMustDoOpBetweenFloorAndAbs; } 123 124 // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord 125 bool canUseFragCoord() const { return fCanUseFragCoord; } 126 127 // If true interpolated vertex shader outputs are inaccurate. 128 bool interpolantsAreInaccurate() const { return fInterpolantsAreInaccurate; } 129 130 bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; } 131 132 bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; } 133 134 // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain 135 // constructs. See detailed comments in GrGLCaps.cpp. 136 bool mustGuardDivisionEvenAfterExplicitZeroCheck() const { 137 return fMustGuardDivisionEvenAfterExplicitZeroCheck; 138 } 139 140 // Returns the string of an extension that must be enabled in the shader to support 141 // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling 142 // this function, the caller should check that shaderDerivativeSupport exists. 143 const char* shaderDerivativeExtensionString() const { 144 SkASSERT(this->shaderDerivativeSupport()); 145 return fShaderDerivativeExtensionString; 146 } 147 148 // Returns the string of an extension that must be enabled in the shader to support geometry 149 // shaders. If nullptr is returned then no extension needs to be enabled. Before calling this 150 // function, the caller must verify that geometryShaderSupport exists. 151 const char* geometryShaderExtensionString() const { 152 SkASSERT(this->geometryShaderSupport()); 153 return fGeometryShaderExtensionString; 154 } 155 156 // Returns the string of an extension that must be enabled in the shader to support 157 // geometry shader invocations. If nullptr is returned then no extension needs to be enabled. 158 // Before calling this function, the caller must verify that gsInvocationsSupport exists. 159 const char* gsInvocationsExtensionString() const { 160 SkASSERT(this->gsInvocationsSupport()); 161 return fGSInvocationsExtensionString; 162 } 163 164 // Returns the string of an extension that will do all necessary coord transfomations needed 165 // when reading the fragment position. If such an extension does not exisits, this function 166 // returns a nullptr, and all transforms of the frag position must be done manually in the 167 // shader. 168 const char* fragCoordConventionsExtensionString() const { 169 return fFragCoordConventionsExtensionString; 170 } 171 172 // This returns the name of an extension that must be enabled in the shader, if such a thing is 173 // required in order to use a secondary output in the shader. This returns a nullptr if no such 174 // extension is required. However, the return value of this function does not say whether dual 175 // source blending is supported. 176 const char* secondaryOutputExtensionString() const { 177 return fSecondaryOutputExtensionString; 178 } 179 180 const char* externalTextureExtensionString() const { 181 SkASSERT(this->externalTextureSupport()); 182 return fExternalTextureExtensionString; 183 } 184 185 const char* texelBufferExtensionString() const { 186 SkASSERT(this->texelBufferSupport()); 187 return fTexelBufferExtensionString; 188 } 189 190 const char* noperspectiveInterpolationExtensionString() const { 191 SkASSERT(this->noperspectiveInterpolationSupport()); 192 return fNoPerspectiveInterpolationExtensionString; 193 } 194 195 const char* multisampleInterpolationExtensionString() const { 196 SkASSERT(this->multisampleInterpolationSupport()); 197 return fMultisampleInterpolationExtensionString; 198 } 199 200 const char* sampleVariablesExtensionString() const { 201 SkASSERT(this->sampleVariablesSupport()); 202 return fSampleVariablesExtensionString; 203 } 204 205 const char* imageLoadStoreExtensionString() const { 206 SkASSERT(this->imageLoadStoreSupport()); 207 return fImageLoadStoreExtensionString; 208 } 209 210 int maxVertexSamplers() const { return fMaxVertexSamplers; } 211 212 int maxGeometrySamplers() const { return fMaxGeometrySamplers; } 213 214 int maxFragmentSamplers() const { return fMaxFragmentSamplers; } 215 216 int maxCombinedSamplers() const { return fMaxCombinedSamplers; } 217 218 /** 219 * In general using multiple texture units for image rendering seems to be a win at smaller 220 * sizes of dst rects and a loss at larger sizes. Dst rects above this pixel area threshold will 221 * not use multitexturing. 222 */ 223 size_t disableImageMultitexturingDstRectAreaThreshold() const { 224 return fDisableImageMultitexturingDstRectAreaThreshold; 225 } 226 227 /** 228 * Given a texture's config, this determines what swizzle must be appended to accesses to the 229 * texture in generated shader code. Swizzling may be implemented in texture parameters or a 230 * sampler rather than in the shader. In this case the returned swizzle will always be "rgba". 231 */ 232 const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const { 233 return fConfigTextureSwizzle[config]; 234 } 235 236 /** Swizzle that should occur on the fragment shader outputs for a given config. */ 237 const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const { 238 return fConfigOutputSwizzle[config]; 239 } 240 241 GrGLSLGeneration generation() const { return fGLSLGeneration; } 242 243 private: 244 void applyOptionsOverrides(const GrContextOptions& options); 245 246 GrGLSLGeneration fGLSLGeneration; 247 248 bool fShaderDerivativeSupport : 1; 249 bool fGeometryShaderSupport : 1; 250 bool fGSInvocationsSupport : 1; 251 bool fPathRenderingSupport : 1; 252 bool fDstReadInShaderSupport : 1; 253 bool fDualSourceBlendingSupport : 1; 254 bool fIntegerSupport : 1; 255 bool fTexelBufferSupport : 1; 256 bool fImageLoadStoreSupport : 1; 257 bool fDropsTileOnZeroDivide : 1; 258 bool fFBFetchSupport : 1; 259 bool fFBFetchNeedsCustomOutput : 1; 260 bool fBindlessTextureSupport : 1; 261 bool fUsesPrecisionModifiers : 1; 262 bool fFlatInterpolationSupport : 1; 263 bool fPreferFlatInterpolation : 1; 264 bool fNoPerspectiveInterpolationSupport : 1; 265 bool fMultisampleInterpolationSupport : 1; 266 bool fSampleVariablesSupport : 1; 267 bool fSampleMaskOverrideCoverageSupport : 1; 268 bool fExternalTextureSupport : 1; 269 bool fTexelFetchSupport : 1; 270 bool fVertexIDSupport : 1; 271 bool fFloatIs32Bits : 1; 272 bool fHalfIs32Bits : 1; 273 274 // Used for specific driver bug work arounds 275 bool fCanUseAnyFunctionInShader : 1; 276 bool fCanUseMinAndAbsTogether : 1; 277 bool fCanUseFractForNegativeValues : 1; 278 bool fMustForceNegatedAtanParamToFloat : 1; 279 bool fAtan2ImplementedAsAtanYOverX : 1; 280 bool fMustDoOpBetweenFloorAndAbs : 1; 281 bool fRequiresLocalOutputColorForFBFetch : 1; 282 bool fMustObfuscateUniformColor : 1; 283 bool fMustGuardDivisionEvenAfterExplicitZeroCheck : 1; 284 bool fCanUseFragCoord : 1; 285 bool fInterpolantsAreInaccurate : 1; 286 287 const char* fVersionDeclString; 288 289 const char* fShaderDerivativeExtensionString; 290 const char* fGeometryShaderExtensionString; 291 const char* fGSInvocationsExtensionString; 292 const char* fFragCoordConventionsExtensionString; 293 const char* fSecondaryOutputExtensionString; 294 const char* fExternalTextureExtensionString; 295 const char* fTexelBufferExtensionString; 296 const char* fNoPerspectiveInterpolationExtensionString; 297 const char* fMultisampleInterpolationExtensionString; 298 const char* fSampleVariablesExtensionString; 299 const char* fImageLoadStoreExtensionString; 300 301 const char* fFBFetchColorName; 302 const char* fFBFetchExtensionString; 303 304 int fMaxVertexSamplers; 305 int fMaxGeometrySamplers; 306 int fMaxFragmentSamplers; 307 int fMaxCombinedSamplers; 308 309 size_t fDisableImageMultitexturingDstRectAreaThreshold; 310 311 AdvBlendEqInteraction fAdvBlendEqInteraction; 312 313 GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt]; 314 GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt]; 315 316 friend class GrCaps; // For initialization. 317 friend class GrGLCaps; 318 friend class GrMockCaps; 319 friend class GrMtlCaps; 320 friend class GrVkCaps; 321 friend class SkSL::ShaderCapsFactory; 322 }; 323 324 #endif 325