1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_UTIL 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_UTIL 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/sksl/SkSLVersion.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLGLSL.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker enum class SkSLType : char; 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker class Context; 22*c8dee2aaSAndroid Build Coastguard Worker class OutputStream; 23*c8dee2aaSAndroid Build Coastguard Worker class StringStream; 24*c8dee2aaSAndroid Build Coastguard Worker class Type; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker struct ShaderCaps { 27*c8dee2aaSAndroid Build Coastguard Worker /** 28*c8dee2aaSAndroid Build Coastguard Worker * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires 29*c8dee2aaSAndroid Build Coastguard Worker * special layout qualifiers in the fragment shader. 30*c8dee2aaSAndroid Build Coastguard Worker */ 31*c8dee2aaSAndroid Build Coastguard Worker enum AdvBlendEqInteraction { 32*c8dee2aaSAndroid Build Coastguard Worker kNotSupported_AdvBlendEqInteraction, //<! No _blend_equation_advanced extension 33*c8dee2aaSAndroid Build Coastguard Worker kAutomatic_AdvBlendEqInteraction, //<! No interaction required 34*c8dee2aaSAndroid Build Coastguard Worker kGeneralEnable_AdvBlendEqInteraction, //<! layout(blend_support_all_equations) out 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker kLast_AdvBlendEqInteraction = kGeneralEnable_AdvBlendEqInteraction 37*c8dee2aaSAndroid Build Coastguard Worker }; 38*c8dee2aaSAndroid Build Coastguard Worker mustEnableAdvBlendEqsShaderCaps39*c8dee2aaSAndroid Build Coastguard Worker bool mustEnableAdvBlendEqs() const { 40*c8dee2aaSAndroid Build Coastguard Worker return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction; 41*c8dee2aaSAndroid Build Coastguard Worker } 42*c8dee2aaSAndroid Build Coastguard Worker mustDeclareFragmentShaderOutputShaderCaps43*c8dee2aaSAndroid Build Coastguard Worker bool mustDeclareFragmentShaderOutput() const { 44*c8dee2aaSAndroid Build Coastguard Worker return fGLSLGeneration > SkSL::GLSLGeneration::k110; 45*c8dee2aaSAndroid Build Coastguard Worker } 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker // Returns the string of an extension that must be enabled in the shader to support 48*c8dee2aaSAndroid Build Coastguard Worker // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling 49*c8dee2aaSAndroid Build Coastguard Worker // this function, the caller should check that shaderDerivativeSupport exists. shaderDerivativeExtensionStringShaderCaps50*c8dee2aaSAndroid Build Coastguard Worker const char* shaderDerivativeExtensionString() const { 51*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->fShaderDerivativeSupport); 52*c8dee2aaSAndroid Build Coastguard Worker return fShaderDerivativeExtensionString; 53*c8dee2aaSAndroid Build Coastguard Worker } 54*c8dee2aaSAndroid Build Coastguard Worker 55*c8dee2aaSAndroid Build Coastguard Worker // This returns the name of an extension that must be enabled in the shader to support external 56*c8dee2aaSAndroid Build Coastguard Worker // textures. In some cases, two extensions must be enabled - the second extension is returned 57*c8dee2aaSAndroid Build Coastguard Worker // by secondExternalTextureExtensionString(). If that function returns nullptr, then only one 58*c8dee2aaSAndroid Build Coastguard Worker // extension is required. externalTextureExtensionStringShaderCaps59*c8dee2aaSAndroid Build Coastguard Worker const char* externalTextureExtensionString() const { 60*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->fExternalTextureSupport); 61*c8dee2aaSAndroid Build Coastguard Worker return fExternalTextureExtensionString; 62*c8dee2aaSAndroid Build Coastguard Worker } 63*c8dee2aaSAndroid Build Coastguard Worker secondExternalTextureExtensionStringShaderCaps64*c8dee2aaSAndroid Build Coastguard Worker const char* secondExternalTextureExtensionString() const { 65*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(this->fExternalTextureSupport); 66*c8dee2aaSAndroid Build Coastguard Worker return fSecondExternalTextureExtensionString; 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker 69*c8dee2aaSAndroid Build Coastguard Worker /** 70*c8dee2aaSAndroid Build Coastguard Worker * SkSL 300 requires support for derivatives, nonsquare matrices and bitwise integer operations. 71*c8dee2aaSAndroid Build Coastguard Worker */ supportedSkSLVerionShaderCaps72*c8dee2aaSAndroid Build Coastguard Worker SkSL::Version supportedSkSLVerion() const { 73*c8dee2aaSAndroid Build Coastguard Worker if (fShaderDerivativeSupport && fNonsquareMatrixSupport && fIntegerSupport && 74*c8dee2aaSAndroid Build Coastguard Worker fGLSLGeneration >= SkSL::GLSLGeneration::k330) { 75*c8dee2aaSAndroid Build Coastguard Worker return SkSL::Version::k300; 76*c8dee2aaSAndroid Build Coastguard Worker } 77*c8dee2aaSAndroid Build Coastguard Worker return SkSL::Version::k100; 78*c8dee2aaSAndroid Build Coastguard Worker } 79*c8dee2aaSAndroid Build Coastguard Worker supportsDistanceFieldTextShaderCaps80*c8dee2aaSAndroid Build Coastguard Worker bool supportsDistanceFieldText() const { return fShaderDerivativeSupport; } 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker SkSL::GLSLGeneration fGLSLGeneration = SkSL::GLSLGeneration::k330; 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker bool fDualSourceBlendingSupport = false; 85*c8dee2aaSAndroid Build Coastguard Worker bool fShaderDerivativeSupport = false; 86*c8dee2aaSAndroid Build Coastguard Worker /** Enables sampleGrad and sampleLod functions that don't rely on implicit derivatives */ 87*c8dee2aaSAndroid Build Coastguard Worker bool fExplicitTextureLodSupport = false; 88*c8dee2aaSAndroid Build Coastguard Worker /** Indicates true 32-bit integer support, with unsigned types and bitwise operations */ 89*c8dee2aaSAndroid Build Coastguard Worker bool fIntegerSupport = false; 90*c8dee2aaSAndroid Build Coastguard Worker bool fNonsquareMatrixSupport = false; 91*c8dee2aaSAndroid Build Coastguard Worker /** asinh(), acosh(), atanh() */ 92*c8dee2aaSAndroid Build Coastguard Worker bool fInverseHyperbolicSupport = false; 93*c8dee2aaSAndroid Build Coastguard Worker bool fFBFetchSupport = false; 94*c8dee2aaSAndroid Build Coastguard Worker bool fFBFetchNeedsCustomOutput = false; 95*c8dee2aaSAndroid Build Coastguard Worker bool fUsesPrecisionModifiers = false; 96*c8dee2aaSAndroid Build Coastguard Worker bool fFlatInterpolationSupport = false; 97*c8dee2aaSAndroid Build Coastguard Worker bool fNoPerspectiveInterpolationSupport = false; 98*c8dee2aaSAndroid Build Coastguard Worker bool fSampleMaskSupport = false; 99*c8dee2aaSAndroid Build Coastguard Worker bool fExternalTextureSupport = false; 100*c8dee2aaSAndroid Build Coastguard Worker bool fFloatIs32Bits = true; 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker // isinf() is defined, and floating point infinities are handled according to IEEE standards. 103*c8dee2aaSAndroid Build Coastguard Worker bool fInfinitySupport = false; 104*c8dee2aaSAndroid Build Coastguard Worker 105*c8dee2aaSAndroid Build Coastguard Worker // Used by SkSL to know when to generate polyfills. 106*c8dee2aaSAndroid Build Coastguard Worker bool fBuiltinFMASupport = true; 107*c8dee2aaSAndroid Build Coastguard Worker bool fBuiltinDeterminantSupport = true; 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker // Used for specific driver bug work arounds 110*c8dee2aaSAndroid Build Coastguard Worker bool fCanUseVoidInSequenceExpressions = true; 111*c8dee2aaSAndroid Build Coastguard Worker bool fCanUseMinAndAbsTogether = true; 112*c8dee2aaSAndroid Build Coastguard Worker bool fCanUseFractForNegativeValues = true; 113*c8dee2aaSAndroid Build Coastguard Worker bool fMustForceNegatedAtanParamToFloat = false; 114*c8dee2aaSAndroid Build Coastguard Worker bool fMustForceNegatedLdexpParamToMultiply = false; // http://skbug.com/12076 115*c8dee2aaSAndroid Build Coastguard Worker // Returns whether a device incorrectly implements atan(y,x) as atan(y/x) 116*c8dee2aaSAndroid Build Coastguard Worker bool fAtan2ImplementedAsAtanYOverX = false; 117*c8dee2aaSAndroid Build Coastguard Worker // If this returns true some operation (could be a no op) must be called between floor and abs 118*c8dee2aaSAndroid Build Coastguard Worker // to make sure the driver compiler doesn't inline them together which can cause a driver bug in 119*c8dee2aaSAndroid Build Coastguard Worker // the shader. 120*c8dee2aaSAndroid Build Coastguard Worker bool fMustDoOpBetweenFloorAndAbs = false; 121*c8dee2aaSAndroid Build Coastguard Worker // The D3D shader compiler, when targeting PS 3.0 (ie within ANGLE) fails to compile certain 122*c8dee2aaSAndroid Build Coastguard Worker // constructs. See detailed comments in GrGLCaps.cpp. 123*c8dee2aaSAndroid Build Coastguard Worker bool fMustGuardDivisionEvenAfterExplicitZeroCheck = false; 124*c8dee2aaSAndroid Build Coastguard Worker // If false, SkSL uses a workaround so that sk_FragCoord doesn't actually query gl_FragCoord 125*c8dee2aaSAndroid Build Coastguard Worker bool fCanUseFragCoord = true; 126*c8dee2aaSAndroid Build Coastguard Worker // If true, then conditions in for loops need "&& true" to work around driver bugs. 127*c8dee2aaSAndroid Build Coastguard Worker bool fAddAndTrueToLoopCondition = false; 128*c8dee2aaSAndroid Build Coastguard Worker // If true, then expressions such as "x && y" or "x || y" are rewritten as ternary to work 129*c8dee2aaSAndroid Build Coastguard Worker // around driver bugs. 130*c8dee2aaSAndroid Build Coastguard Worker bool fUnfoldShortCircuitAsTernary = false; 131*c8dee2aaSAndroid Build Coastguard Worker bool fEmulateAbsIntFunction = false; 132*c8dee2aaSAndroid Build Coastguard Worker bool fRewriteDoWhileLoops = false; 133*c8dee2aaSAndroid Build Coastguard Worker bool fRewriteSwitchStatements = false; 134*c8dee2aaSAndroid Build Coastguard Worker bool fRemovePowWithConstantExponent = false; 135*c8dee2aaSAndroid Build Coastguard Worker // The Android emulator claims samplerExternalOES is an unknown type if a default precision 136*c8dee2aaSAndroid Build Coastguard Worker // statement is made for the type. 137*c8dee2aaSAndroid Build Coastguard Worker bool fNoDefaultPrecisionForExternalSamplers = false; 138*c8dee2aaSAndroid Build Coastguard Worker // ARM GPUs calculate `matrix * vector` in SPIR-V at full precision, even when the inputs are 139*c8dee2aaSAndroid Build Coastguard Worker // RelaxedPrecision. Rewriting the multiply as a sum of vector*scalar fixes this. (skia:11769) 140*c8dee2aaSAndroid Build Coastguard Worker bool fRewriteMatrixVectorMultiply = false; 141*c8dee2aaSAndroid Build Coastguard Worker // Rewrites matrix equality comparisons to avoid an Adreno driver bug. (skia:11308) 142*c8dee2aaSAndroid Build Coastguard Worker bool fRewriteMatrixComparisons = false; 143*c8dee2aaSAndroid Build Coastguard Worker // Strips const from function parameters in the GLSL code generator. (skia:13858) 144*c8dee2aaSAndroid Build Coastguard Worker bool fRemoveConstFromFunctionParameters = false; 145*c8dee2aaSAndroid Build Coastguard Worker // On some Android devices colors aren't accurate enough for the double lookup in the 146*c8dee2aaSAndroid Build Coastguard Worker // Perlin noise shader. This workaround aggressively snaps colors to multiples of 1/255. 147*c8dee2aaSAndroid Build Coastguard Worker bool fPerlinNoiseRoundingFix = false; 148*c8dee2aaSAndroid Build Coastguard Worker // Vulkan requires certain builtin variables be present, even if they're unused. At one time, 149*c8dee2aaSAndroid Build Coastguard Worker // validation errors would result if sk_Clockwise was missing. Now, it's just (Adreno) driver 150*c8dee2aaSAndroid Build Coastguard Worker // bugs that drop or corrupt draws if they're missing. 151*c8dee2aaSAndroid Build Coastguard Worker bool fMustDeclareFragmentFrontFacing = false; 152*c8dee2aaSAndroid Build Coastguard Worker // SPIR-V currently doesn't handle different array strides being passed in to a fixed sized 153*c8dee2aaSAndroid Build Coastguard Worker // array function parameter, so fForceStd430ArrayLayout will make all array strides conform 154*c8dee2aaSAndroid Build Coastguard Worker // to std430 stride alignment rules. 155*c8dee2aaSAndroid Build Coastguard Worker bool fForceStd430ArrayLayout = false; 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker const char* fVersionDeclString = ""; 158*c8dee2aaSAndroid Build Coastguard Worker 159*c8dee2aaSAndroid Build Coastguard Worker const char* fShaderDerivativeExtensionString = nullptr; 160*c8dee2aaSAndroid Build Coastguard Worker const char* fExternalTextureExtensionString = nullptr; 161*c8dee2aaSAndroid Build Coastguard Worker const char* fSecondExternalTextureExtensionString = nullptr; 162*c8dee2aaSAndroid Build Coastguard Worker const char* fFBFetchColorName = nullptr; 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker AdvBlendEqInteraction fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; 165*c8dee2aaSAndroid Build Coastguard Worker }; 166*c8dee2aaSAndroid Build Coastguard Worker 167*c8dee2aaSAndroid Build Coastguard Worker // Various sets of caps for use in tests 168*c8dee2aaSAndroid Build Coastguard Worker class ShaderCapsFactory { 169*c8dee2aaSAndroid Build Coastguard Worker public: Default()170*c8dee2aaSAndroid Build Coastguard Worker static const ShaderCaps* Default() { 171*c8dee2aaSAndroid Build Coastguard Worker static const SkSL::ShaderCaps* sCaps = [] { 172*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<ShaderCaps> caps = MakeShaderCaps(); 173*c8dee2aaSAndroid Build Coastguard Worker caps->fVersionDeclString = "#version 400"; 174*c8dee2aaSAndroid Build Coastguard Worker caps->fShaderDerivativeSupport = true; 175*c8dee2aaSAndroid Build Coastguard Worker return caps.release(); 176*c8dee2aaSAndroid Build Coastguard Worker }(); 177*c8dee2aaSAndroid Build Coastguard Worker return sCaps; 178*c8dee2aaSAndroid Build Coastguard Worker } 179*c8dee2aaSAndroid Build Coastguard Worker Standalone()180*c8dee2aaSAndroid Build Coastguard Worker static const ShaderCaps* Standalone() { 181*c8dee2aaSAndroid Build Coastguard Worker static const SkSL::ShaderCaps* sCaps = MakeShaderCaps().release(); 182*c8dee2aaSAndroid Build Coastguard Worker return sCaps; 183*c8dee2aaSAndroid Build Coastguard Worker } 184*c8dee2aaSAndroid Build Coastguard Worker 185*c8dee2aaSAndroid Build Coastguard Worker protected: 186*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<ShaderCaps> MakeShaderCaps(); 187*c8dee2aaSAndroid Build Coastguard Worker }; 188*c8dee2aaSAndroid Build Coastguard Worker 189*c8dee2aaSAndroid Build Coastguard Worker bool type_to_sksltype(const Context& context, const Type& type, SkSLType* outType); 190*c8dee2aaSAndroid Build Coastguard Worker 191*c8dee2aaSAndroid Build Coastguard Worker void write_stringstream(const StringStream& d, OutputStream& out); 192*c8dee2aaSAndroid Build Coastguard Worker 193*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 194*c8dee2aaSAndroid Build Coastguard Worker 195*c8dee2aaSAndroid Build Coastguard Worker #endif // SKSL_UTIL 196