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