1 /* 2 * Copyright 2016 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 #ifndef SKSL_UTIL 9 #define SKSL_UTIL 10 11 #include <cstdarg> 12 #include <memory> 13 #include "stdlib.h" 14 #include "string.h" 15 #include "SkSLLexer.h" 16 #include "SkSLDefines.h" 17 #include "SkSLString.h" 18 #include "SkSLStringStream.h" 19 20 #ifndef SKSL_STANDALONE 21 #include "SkTypes.h" 22 #if SK_SUPPORT_GPU 23 #include "GrContextOptions.h" 24 #include "GrShaderCaps.h" 25 #endif // SK_SUPPORT_GPU 26 #endif // SKSL_STANDALONE 27 28 class GrShaderCaps; 29 30 namespace SkSL { 31 32 class OutputStream; 33 class StringStream; 34 35 #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU 36 37 // we're being compiled standalone, so we don't have access to caps... 38 enum GrGLSLGeneration { 39 k110_GrGLSLGeneration, 40 k130_GrGLSLGeneration, 41 k140_GrGLSLGeneration, 42 k150_GrGLSLGeneration, 43 k330_GrGLSLGeneration, 44 k400_GrGLSLGeneration, 45 k420_GrGLSLGeneration, 46 k310es_GrGLSLGeneration, 47 k320es_GrGLSLGeneration, 48 }; 49 50 #define SKSL_CAPS_CLASS StandaloneShaderCaps 51 class StandaloneShaderCaps { 52 public: generation()53 GrGLSLGeneration generation() const { 54 return k400_GrGLSLGeneration; 55 } 56 atan2ImplementedAsAtanYOverX()57 bool atan2ImplementedAsAtanYOverX() const { 58 return false; 59 } 60 canUseMinAndAbsTogether()61 bool canUseMinAndAbsTogether() const { 62 return true; 63 } 64 mustForceNegatedAtanParamToFloat()65 bool mustForceNegatedAtanParamToFloat() const { 66 return false; 67 } 68 shaderDerivativeSupport()69 bool shaderDerivativeSupport() const { 70 return true; 71 } 72 usesPrecisionModifiers()73 bool usesPrecisionModifiers() const { 74 return true; 75 } 76 mustDeclareFragmentShaderOutput()77 bool mustDeclareFragmentShaderOutput() const { 78 return true; 79 } 80 fbFetchSupport()81 bool fbFetchSupport() const { 82 return true; 83 } 84 fbFetchNeedsCustomOutput()85 bool fbFetchNeedsCustomOutput() const { 86 return false; 87 } 88 dropsTileOnZeroDivide()89 bool dropsTileOnZeroDivide() const { 90 return false; 91 } 92 flatInterpolationSupport()93 bool flatInterpolationSupport() const { 94 return true; 95 } 96 noperspectiveInterpolationSupport()97 bool noperspectiveInterpolationSupport() const { 98 return true; 99 } 100 multisampleInterpolationSupport()101 bool multisampleInterpolationSupport() const { 102 return true; 103 } 104 sampleVariablesSupport()105 bool sampleVariablesSupport() const { 106 return true; 107 } 108 externalTextureSupport()109 bool externalTextureSupport() const { 110 return true; 111 } 112 imageLoadStoreSupport()113 bool imageLoadStoreSupport() const { 114 return true; 115 } 116 mustDoOpBetweenFloorAndAbs()117 bool mustDoOpBetweenFloorAndAbs() const { 118 return false; 119 } 120 mustEnableAdvBlendEqs()121 bool mustEnableAdvBlendEqs() const { 122 return false; 123 } 124 mustEnableSpecificAdvBlendEqs()125 bool mustEnableSpecificAdvBlendEqs() const { 126 return false; 127 } 128 canUseAnyFunctionInShader()129 bool canUseAnyFunctionInShader() const { 130 return false; 131 } 132 floatIs32Bits()133 bool floatIs32Bits() const { 134 return true; 135 } 136 integerSupport()137 bool integerSupport() const { 138 return false; 139 } 140 builtinFMASupport()141 bool builtinFMASupport() const { 142 return true; 143 } 144 shaderDerivativeExtensionString()145 const char* shaderDerivativeExtensionString() const { 146 return nullptr; 147 } 148 fragCoordConventionsExtensionString()149 const char* fragCoordConventionsExtensionString() const { 150 return nullptr; 151 } 152 imageLoadStoreExtensionString()153 const char* imageLoadStoreExtensionString() const { 154 return nullptr; 155 } 156 geometryShaderExtensionString()157 const char* geometryShaderExtensionString() const { 158 return nullptr; 159 } 160 gsInvocationsExtensionString()161 const char* gsInvocationsExtensionString() const { 162 return nullptr; 163 } 164 externalTextureExtensionString()165 const char* externalTextureExtensionString() const { 166 return nullptr; 167 } 168 secondExternalTextureExtensionString()169 const char* secondExternalTextureExtensionString() const { 170 return nullptr; 171 } 172 versionDeclString()173 const char* versionDeclString() const { 174 return ""; 175 } 176 gsInvocationsSupport()177 bool gsInvocationsSupport() const { 178 return true; 179 } 180 canUseFractForNegativeValues()181 bool canUseFractForNegativeValues() const { 182 return true; 183 } 184 canUseFragCoord()185 bool canUseFragCoord() const { 186 return true; 187 } 188 incompleteShortIntPrecision()189 bool incompleteShortIntPrecision() const { 190 return false; 191 } 192 addAndTrueToLoopCondition()193 bool addAndTrueToLoopCondition() const { 194 return false; 195 } 196 unfoldShortCircuitAsTernary()197 bool unfoldShortCircuitAsTernary() const { 198 return false; 199 } 200 emulateAbsIntFunction()201 bool emulateAbsIntFunction() const { 202 return false; 203 } 204 rewriteDoWhileLoops()205 bool rewriteDoWhileLoops() const { 206 return false; 207 } 208 removePowWithConstantExponent()209 bool removePowWithConstantExponent() const { 210 return false; 211 } 212 fbFetchColorName()213 const char* fbFetchColorName() const { 214 return nullptr; 215 } 216 }; 217 218 extern StandaloneShaderCaps standaloneCaps; 219 220 #else 221 222 #define SKSL_CAPS_CLASS GrShaderCaps 223 // Various sets of caps for use in tests 224 class ShaderCapsFactory { 225 public: Default()226 static sk_sp<GrShaderCaps> Default() { 227 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 228 result->fVersionDeclString = "#version 400"; 229 result->fShaderDerivativeSupport = true; 230 return result; 231 } 232 Version450Core()233 static sk_sp<GrShaderCaps> Version450Core() { 234 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 235 result->fVersionDeclString = "#version 450 core"; 236 return result; 237 } 238 Version110()239 static sk_sp<GrShaderCaps> Version110() { 240 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 241 result->fVersionDeclString = "#version 110"; 242 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; 243 return result; 244 } 245 UsesPrecisionModifiers()246 static sk_sp<GrShaderCaps> UsesPrecisionModifiers() { 247 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 248 result->fVersionDeclString = "#version 400"; 249 result->fUsesPrecisionModifiers = true; 250 return result; 251 } 252 CannotUseMinAndAbsTogether()253 static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() { 254 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 255 result->fVersionDeclString = "#version 400"; 256 result->fCanUseMinAndAbsTogether = false; 257 return result; 258 } 259 CannotUseFractForNegativeValues()260 static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() { 261 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 262 result->fVersionDeclString = "#version 400"; 263 result->fCanUseFractForNegativeValues = false; 264 return result; 265 } 266 MustForceNegatedAtanParamToFloat()267 static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() { 268 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 269 result->fVersionDeclString = "#version 400"; 270 result->fMustForceNegatedAtanParamToFloat = true; 271 return result; 272 } 273 ShaderDerivativeExtensionString()274 static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() { 275 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 276 result->fVersionDeclString = "#version 400"; 277 result->fShaderDerivativeSupport = true; 278 result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives"; 279 result->fUsesPrecisionModifiers = true; 280 return result; 281 } 282 FragCoordsOld()283 static sk_sp<GrShaderCaps> FragCoordsOld() { 284 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 285 result->fVersionDeclString = "#version 110"; 286 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; 287 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions"; 288 return result; 289 } 290 FragCoordsNew()291 static sk_sp<GrShaderCaps> FragCoordsNew() { 292 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 293 result->fVersionDeclString = "#version 400"; 294 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions"; 295 return result; 296 } 297 GeometryShaderSupport()298 static sk_sp<GrShaderCaps> GeometryShaderSupport() { 299 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 300 result->fVersionDeclString = "#version 400"; 301 result->fGeometryShaderSupport = true; 302 result->fGSInvocationsSupport = true; 303 return result; 304 } 305 NoGSInvocationsSupport()306 static sk_sp<GrShaderCaps> NoGSInvocationsSupport() { 307 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 308 result->fVersionDeclString = "#version 400"; 309 result->fGeometryShaderSupport = true; 310 result->fGSInvocationsSupport = false; 311 return result; 312 } 313 GeometryShaderExtensionString()314 static sk_sp<GrShaderCaps> GeometryShaderExtensionString() { 315 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 316 result->fVersionDeclString = "#version 310es"; 317 result->fGeometryShaderSupport = true; 318 result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader"; 319 result->fGSInvocationsSupport = true; 320 return result; 321 } 322 GSInvocationsExtensionString()323 static sk_sp<GrShaderCaps> GSInvocationsExtensionString() { 324 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 325 result->fVersionDeclString = "#version 400"; 326 result->fGeometryShaderSupport = true; 327 result->fGSInvocationsSupport = true; 328 result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5"; 329 return result; 330 } 331 VariousCaps()332 static sk_sp<GrShaderCaps> VariousCaps() { 333 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 334 result->fVersionDeclString = "#version 400"; 335 result->fExternalTextureSupport = true; 336 result->fFBFetchSupport = false; 337 result->fDropsTileOnZeroDivide = true; 338 result->fCanUseAnyFunctionInShader = false; 339 return result; 340 } 341 CannotUseFragCoord()342 static sk_sp<GrShaderCaps> CannotUseFragCoord() { 343 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 344 result->fVersionDeclString = "#version 400"; 345 result->fCanUseFragCoord = false; 346 return result; 347 } 348 IncompleteShortIntPrecision()349 static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() { 350 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 351 result->fVersionDeclString = "#version 310es"; 352 result->fUsesPrecisionModifiers = true; 353 result->fIncompleteShortIntPrecision = true; 354 return result; 355 } 356 AddAndTrueToLoopCondition()357 static sk_sp<GrShaderCaps> AddAndTrueToLoopCondition() { 358 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 359 result->fVersionDeclString = "#version 400"; 360 result->fAddAndTrueToLoopCondition = true; 361 return result; 362 } 363 UnfoldShortCircuitAsTernary()364 static sk_sp<GrShaderCaps> UnfoldShortCircuitAsTernary() { 365 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 366 result->fVersionDeclString = "#version 400"; 367 result->fUnfoldShortCircuitAsTernary = true; 368 return result; 369 } 370 EmulateAbsIntFunction()371 static sk_sp<GrShaderCaps> EmulateAbsIntFunction() { 372 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 373 result->fVersionDeclString = "#version 400"; 374 result->fEmulateAbsIntFunction = true; 375 return result; 376 } 377 RewriteDoWhileLoops()378 static sk_sp<GrShaderCaps> RewriteDoWhileLoops() { 379 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 380 result->fVersionDeclString = "#version 400"; 381 result->fRewriteDoWhileLoops = true; 382 return result; 383 } 384 RemovePowWithConstantExponent()385 static sk_sp<GrShaderCaps> RemovePowWithConstantExponent() { 386 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 387 result->fVersionDeclString = "#version 400"; 388 result->fRemovePowWithConstantExponent = true; 389 return result; 390 } 391 }; 392 #endif 393 394 void write_stringstream(const StringStream& d, OutputStream& out); 395 396 // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.) 397 bool is_assignment(Token::Kind op); 398 399 // Given a compound assignment operator, returns the non-assignment version of the operator (e.g. 400 // '+=' becomes '+') 401 Token::Kind remove_assignment(Token::Kind op); 402 403 NORETURN void sksl_abort(); 404 405 } // namespace 406 407 #endif 408