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