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