Home | History | Annotate | Download | only in sksl
      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:
     54     GrGLSLGeneration generation() const {
     55         return k400_GrGLSLGeneration;
     56     }
     57 
     58     bool canUseMinAndAbsTogether() const {
     59         return true;
     60     }
     61 
     62     bool mustForceNegatedAtanParamToFloat() const {
     63         return false;
     64     }
     65 
     66     bool shaderDerivativeSupport() const {
     67         return true;
     68     }
     69 
     70     bool usesPrecisionModifiers() const {
     71         return true;
     72     }
     73 
     74     bool mustDeclareFragmentShaderOutput() const {
     75         return true;
     76     }
     77 
     78     bool fbFetchSupport() const {
     79         return true;
     80     }
     81 
     82     bool fbFetchNeedsCustomOutput() const {
     83         return false;
     84     }
     85 
     86     bool bindlessTextureSupport() const {
     87         return false;
     88     }
     89 
     90     bool dropsTileOnZeroDivide() const {
     91         return false;
     92     }
     93 
     94     bool flatInterpolationSupport() const {
     95         return true;
     96     }
     97 
     98     bool noperspectiveInterpolationSupport() const {
     99         return true;
    100     }
    101 
    102     bool multisampleInterpolationSupport() const {
    103         return true;
    104     }
    105 
    106     bool sampleVariablesSupport() const {
    107         return true;
    108     }
    109 
    110     bool sampleMaskOverrideCoverageSupport() const {
    111         return true;
    112     }
    113 
    114     bool externalTextureSupport() const {
    115         return true;
    116     }
    117 
    118     bool texelFetchSupport() const {
    119         return true;
    120     }
    121 
    122     bool imageLoadStoreSupport() const {
    123         return true;
    124     }
    125 
    126     bool mustEnableAdvBlendEqs() const {
    127         return false;
    128     }
    129 
    130     bool mustEnableSpecificAdvBlendEqs() const {
    131         return false;
    132     }
    133 
    134     bool canUseAnyFunctionInShader() const {
    135         return false;
    136     }
    137 
    138     bool floatIs32Bits() const {
    139         return true;
    140     }
    141 
    142     bool integerSupport() const {
    143         return false;
    144     }
    145 
    146     const char* shaderDerivativeExtensionString() const {
    147         return nullptr;
    148     }
    149 
    150     const char* fragCoordConventionsExtensionString() const {
    151         return nullptr;
    152     }
    153 
    154     const char* imageLoadStoreExtensionString() const {
    155         return nullptr;
    156     }
    157 
    158     const char* geometryShaderExtensionString() const {
    159         return nullptr;
    160     }
    161 
    162     const char* gsInvocationsExtensionString() const {
    163         return nullptr;
    164     }
    165 
    166     const char* versionDeclString() const {
    167         return "";
    168     }
    169 
    170     bool gsInvocationsSupport() const {
    171         return true;
    172     }
    173 
    174     bool canUseFractForNegativeValues() const {
    175         return true;
    176     }
    177 
    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