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 dropsTileOnZeroDivide()86 bool dropsTileOnZeroDivide() const { 87 return false; 88 } 89 flatInterpolationSupport()90 bool flatInterpolationSupport() const { 91 return true; 92 } 93 noperspectiveInterpolationSupport()94 bool noperspectiveInterpolationSupport() const { 95 return true; 96 } 97 multisampleInterpolationSupport()98 bool multisampleInterpolationSupport() const { 99 return true; 100 } 101 externalTextureSupport()102 bool externalTextureSupport() const { 103 return true; 104 } 105 texelFetchSupport()106 bool texelFetchSupport() const { 107 return true; 108 } 109 imageLoadStoreSupport()110 bool imageLoadStoreSupport() const { 111 return true; 112 } 113 mustEnableAdvBlendEqs()114 bool mustEnableAdvBlendEqs() const { 115 return false; 116 } 117 mustEnableSpecificAdvBlendEqs()118 bool mustEnableSpecificAdvBlendEqs() const { 119 return false; 120 } 121 canUseAnyFunctionInShader()122 bool canUseAnyFunctionInShader() const { 123 return false; 124 } 125 floatIs32Bits()126 bool floatIs32Bits() const { 127 return true; 128 } 129 integerSupport()130 bool integerSupport() const { 131 return false; 132 } 133 shaderDerivativeExtensionString()134 const char* shaderDerivativeExtensionString() const { 135 return nullptr; 136 } 137 fragCoordConventionsExtensionString()138 const char* fragCoordConventionsExtensionString() const { 139 return nullptr; 140 } 141 imageLoadStoreExtensionString()142 const char* imageLoadStoreExtensionString() const { 143 return nullptr; 144 } 145 geometryShaderExtensionString()146 const char* geometryShaderExtensionString() const { 147 return nullptr; 148 } 149 gsInvocationsExtensionString()150 const char* gsInvocationsExtensionString() const { 151 return nullptr; 152 } 153 versionDeclString()154 const char* versionDeclString() const { 155 return ""; 156 } 157 gsInvocationsSupport()158 bool gsInvocationsSupport() const { 159 return true; 160 } 161 canUseFractForNegativeValues()162 bool canUseFractForNegativeValues() const { 163 return true; 164 } 165 canUseFragCoord()166 bool canUseFragCoord() const { 167 return true; 168 } 169 }; 170 171 extern StandaloneShaderCaps standaloneCaps; 172 173 #else 174 175 #define SKSL_CAPS_CLASS GrShaderCaps 176 // Various sets of caps for use in tests 177 class ShaderCapsFactory { 178 public: 179 static sk_sp<GrShaderCaps> Default() { 180 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 181 result->fVersionDeclString = "#version 400"; 182 result->fShaderDerivativeSupport = true; 183 return result; 184 } 185 186 static sk_sp<GrShaderCaps> Version450Core() { 187 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 188 result->fVersionDeclString = "#version 450 core"; 189 return result; 190 } 191 192 static sk_sp<GrShaderCaps> Version110() { 193 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 194 result->fVersionDeclString = "#version 110"; 195 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; 196 return result; 197 } 198 199 static sk_sp<GrShaderCaps> UsesPrecisionModifiers() { 200 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 201 result->fVersionDeclString = "#version 400"; 202 result->fUsesPrecisionModifiers = true; 203 return result; 204 } 205 206 static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() { 207 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 208 result->fVersionDeclString = "#version 400"; 209 result->fCanUseMinAndAbsTogether = false; 210 return result; 211 } 212 213 static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() { 214 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 215 result->fVersionDeclString = "#version 400"; 216 result->fCanUseFractForNegativeValues = false; 217 return result; 218 } 219 220 static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() { 221 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 222 result->fVersionDeclString = "#version 400"; 223 result->fMustForceNegatedAtanParamToFloat = true; 224 return result; 225 } 226 227 static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() { 228 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 229 result->fVersionDeclString = "#version 400"; 230 result->fShaderDerivativeSupport = true; 231 result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives"; 232 result->fUsesPrecisionModifiers = true; 233 return result; 234 } 235 236 static sk_sp<GrShaderCaps> FragCoordsOld() { 237 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 238 result->fVersionDeclString = "#version 110"; 239 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; 240 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions"; 241 return result; 242 } 243 244 static sk_sp<GrShaderCaps> FragCoordsNew() { 245 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 246 result->fVersionDeclString = "#version 400"; 247 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions"; 248 return result; 249 } 250 251 static sk_sp<GrShaderCaps> GeometryShaderSupport() { 252 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 253 result->fVersionDeclString = "#version 400"; 254 result->fGeometryShaderSupport = true; 255 result->fGSInvocationsSupport = true; 256 return result; 257 } 258 259 static sk_sp<GrShaderCaps> NoGSInvocationsSupport() { 260 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 261 result->fVersionDeclString = "#version 400"; 262 result->fGeometryShaderSupport = true; 263 result->fGSInvocationsSupport = false; 264 return result; 265 } 266 267 static sk_sp<GrShaderCaps> GeometryShaderExtensionString() { 268 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 269 result->fVersionDeclString = "#version 310es"; 270 result->fGeometryShaderSupport = true; 271 result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader"; 272 result->fGSInvocationsSupport = true; 273 return result; 274 } 275 276 static sk_sp<GrShaderCaps> GSInvocationsExtensionString() { 277 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 278 result->fVersionDeclString = "#version 400"; 279 result->fGeometryShaderSupport = true; 280 result->fGSInvocationsSupport = true; 281 result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5"; 282 return result; 283 } 284 285 static sk_sp<GrShaderCaps> VariousCaps() { 286 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 287 result->fVersionDeclString = "#version 400"; 288 result->fExternalTextureSupport = true; 289 result->fFBFetchSupport = false; 290 result->fDropsTileOnZeroDivide = true; 291 result->fTexelFetchSupport = true; 292 result->fCanUseAnyFunctionInShader = false; 293 return result; 294 } 295 296 static sk_sp<GrShaderCaps> CannotUseFragCoord() { 297 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); 298 result->fVersionDeclString = "#version 400"; 299 result->fCanUseFragCoord = false; 300 return result; 301 } 302 }; 303 #endif 304 305 void write_stringstream(const StringStream& d, OutputStream& out); 306 307 #if _MSC_VER 308 #define NORETURN __declspec(noreturn) 309 #else 310 #define NORETURN __attribute__((__noreturn__)) 311 #endif 312 313 NORETURN void sksl_abort(); 314 315 } // namespace 316 317 #ifdef SKSL_STANDALONE 318 #define ASSERT(x) (void)((x) || (ABORT("failed assert(%s): %s:%d\n", #x, __FILE__, __LINE__), 0)) 319 #define ASSERT_RESULT(x) ASSERT(x) 320 #define SKSL_DEBUGCODE(x) x 321 #else 322 #define ASSERT SkASSERT 323 #define ASSERT_RESULT(x) SkAssertResult(x) 324 #define SKSL_DEBUGCODE(x) SkDEBUGCODE(x) 325 #endif 326 327 #define SKSL_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 328 329 #if defined(__clang__) || defined(__GNUC__) 330 #define SKSL_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B)))) 331 #else 332 #define SKSL_PRINTF_LIKE(A, B) 333 #endif 334 335 #define ABORT(...) (printf(__VA_ARGS__), sksl_abort()) 336 337 #endif 338