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_PROGRAMSETTINGS 9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_PROGRAMSETTINGS 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/sksl/SkSLVersion.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLDefines.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLModule.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLProgramKind.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker #include <optional> 17*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker enum class ModuleType : int8_t; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker /** 24*c8dee2aaSAndroid Build Coastguard Worker * Holds the compiler settings for a program. 25*c8dee2aaSAndroid Build Coastguard Worker */ 26*c8dee2aaSAndroid Build Coastguard Worker struct ProgramSettings { 27*c8dee2aaSAndroid Build Coastguard Worker // If true, the destination fragment color can be read from sk_FragColor. It must be declared 28*c8dee2aaSAndroid Build Coastguard Worker // inout. This is only supported in GLSL, when framebuffer-fetch is used. 29*c8dee2aaSAndroid Build Coastguard Worker bool fFragColorIsInOut = false; 30*c8dee2aaSAndroid Build Coastguard Worker // if true, all halfs are forced to be floats 31*c8dee2aaSAndroid Build Coastguard Worker bool fForceHighPrecision = false; 32*c8dee2aaSAndroid Build Coastguard Worker // if true, add -0.5 bias to LOD of all texture lookups 33*c8dee2aaSAndroid Build Coastguard Worker bool fSharpenTextures = false; 34*c8dee2aaSAndroid Build Coastguard Worker // If true, sk_FragCoord, the dFdy gradient, and sk_Clockwise won't be modified by the 35*c8dee2aaSAndroid Build Coastguard Worker // rtFlip. Additionally, the program interface's 'fRTFlipUniform' value will be left as None, 36*c8dee2aaSAndroid Build Coastguard Worker // so no rtFlip uniform will be emitted. 37*c8dee2aaSAndroid Build Coastguard Worker bool fForceNoRTFlip = false; 38*c8dee2aaSAndroid Build Coastguard Worker // if the program needs to create an RTFlip uniform, this is its offset in the uniform buffer 39*c8dee2aaSAndroid Build Coastguard Worker int fRTFlipOffset = -1; 40*c8dee2aaSAndroid Build Coastguard Worker // if the program needs to create an RTFlip uniform and is creating SPIR-V, this is the binding 41*c8dee2aaSAndroid Build Coastguard Worker // and set number of the uniform buffer. 42*c8dee2aaSAndroid Build Coastguard Worker int fRTFlipBinding = -1; 43*c8dee2aaSAndroid Build Coastguard Worker int fRTFlipSet = -1; 44*c8dee2aaSAndroid Build Coastguard Worker // If layout(set=S, binding=B) is not specified for a uniform, these values will be used. 45*c8dee2aaSAndroid Build Coastguard Worker // At present, zero is always used by our backends. 46*c8dee2aaSAndroid Build Coastguard Worker int fDefaultUniformSet = 0; 47*c8dee2aaSAndroid Build Coastguard Worker int fDefaultUniformBinding = 0; 48*c8dee2aaSAndroid Build Coastguard Worker // Enables the SkSL optimizer. Note that we never disable optimizations which are needed to 49*c8dee2aaSAndroid Build Coastguard Worker // fully evaluate constant-expressions, like constant folding or constant-intrinsic evaluation. 50*c8dee2aaSAndroid Build Coastguard Worker bool fOptimize = true; 51*c8dee2aaSAndroid Build Coastguard Worker // (Requires fOptimize = true) Removes any uncalled functions other than main(). Note that a 52*c8dee2aaSAndroid Build Coastguard Worker // function which starts out being used may end up being uncalled after optimization. 53*c8dee2aaSAndroid Build Coastguard Worker bool fRemoveDeadFunctions = true; 54*c8dee2aaSAndroid Build Coastguard Worker // (Requires fOptimize = true) Removes variables which are never used. 55*c8dee2aaSAndroid Build Coastguard Worker bool fRemoveDeadVariables = true; 56*c8dee2aaSAndroid Build Coastguard Worker // (Requires fOptimize = true) When greater than zero, enables the inliner. The threshold value 57*c8dee2aaSAndroid Build Coastguard Worker // sets an upper limit on the acceptable amount of code growth from inlining. 58*c8dee2aaSAndroid Build Coastguard Worker int fInlineThreshold = SkSL::kDefaultInlineThreshold; 59*c8dee2aaSAndroid Build Coastguard Worker // If true, every function in the generated program will be given the `noinline` modifier. 60*c8dee2aaSAndroid Build Coastguard Worker bool fForceNoInline = false; 61*c8dee2aaSAndroid Build Coastguard Worker // If true, implicit conversions to lower precision numeric types are allowed (e.g., float to 62*c8dee2aaSAndroid Build Coastguard Worker // half). These are always allowed when compiling Runtime Effects. 63*c8dee2aaSAndroid Build Coastguard Worker bool fAllowNarrowingConversions = false; 64*c8dee2aaSAndroid Build Coastguard Worker // If true, then Debug code will run SPIR-V output through the validator to ensure its 65*c8dee2aaSAndroid Build Coastguard Worker // correctness 66*c8dee2aaSAndroid Build Coastguard Worker bool fValidateSPIRV = true; 67*c8dee2aaSAndroid Build Coastguard Worker // If true, any synthetic uniforms must use push constant syntax 68*c8dee2aaSAndroid Build Coastguard Worker bool fUsePushConstants = false; 69*c8dee2aaSAndroid Build Coastguard Worker // TODO(skia:11209) - Replace this with a "promised" capabilities? 70*c8dee2aaSAndroid Build Coastguard Worker // Sets a maximum SkSL version. Compilation will fail if the program uses features that aren't 71*c8dee2aaSAndroid Build Coastguard Worker // allowed at the requested version. For instance, a valid program must have fully-unrollable 72*c8dee2aaSAndroid Build Coastguard Worker // `for` loops at version 100, but any loop structure is allowed at version 300. 73*c8dee2aaSAndroid Build Coastguard Worker SkSL::Version fMaxVersionAllowed = SkSL::Version::k100; 74*c8dee2aaSAndroid Build Coastguard Worker // If true, SkSL will use a memory pool for all IR nodes when compiling a program. This is 75*c8dee2aaSAndroid Build Coastguard Worker // usually a significant speed increase, but uses more memory, so it is a good idea for programs 76*c8dee2aaSAndroid Build Coastguard Worker // that will be freed shortly after compilation. It can also be useful to disable this flag when 77*c8dee2aaSAndroid Build Coastguard Worker // investigating memory corruption. (This controls behavior of the SkSL compiler, not the code 78*c8dee2aaSAndroid Build Coastguard Worker // we generate.) 79*c8dee2aaSAndroid Build Coastguard Worker bool fUseMemoryPool = true; 80*c8dee2aaSAndroid Build Coastguard Worker }; 81*c8dee2aaSAndroid Build Coastguard Worker 82*c8dee2aaSAndroid Build Coastguard Worker /** 83*c8dee2aaSAndroid Build Coastguard Worker * All the configuration data for a given program. 84*c8dee2aaSAndroid Build Coastguard Worker */ 85*c8dee2aaSAndroid Build Coastguard Worker struct ProgramConfig { 86*c8dee2aaSAndroid Build Coastguard Worker /** 87*c8dee2aaSAndroid Build Coastguard Worker * If we are compiling one of the SkSL built-in modules, this field indicates which one. 88*c8dee2aaSAndroid Build Coastguard Worker * Contains `ModuleType::program` when not compiling a module at all. 89*c8dee2aaSAndroid Build Coastguard Worker */ 90*c8dee2aaSAndroid Build Coastguard Worker ModuleType fModuleType; 91*c8dee2aaSAndroid Build Coastguard Worker ProgramKind fKind; 92*c8dee2aaSAndroid Build Coastguard Worker ProgramSettings fSettings; 93*c8dee2aaSAndroid Build Coastguard Worker isBuiltinCodeProgramConfig94*c8dee2aaSAndroid Build Coastguard Worker bool isBuiltinCode() { 95*c8dee2aaSAndroid Build Coastguard Worker return fModuleType != ModuleType::program; 96*c8dee2aaSAndroid Build Coastguard Worker } 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Worker // When enforcesSkSLVersion() is true, this determines the available feature set that will be 99*c8dee2aaSAndroid Build Coastguard Worker // enforced. This is set automatically when the `#version` directive is parsed. 100*c8dee2aaSAndroid Build Coastguard Worker SkSL::Version fRequiredSkSLVersion = SkSL::Version::k100; 101*c8dee2aaSAndroid Build Coastguard Worker enforcesSkSLVersionProgramConfig102*c8dee2aaSAndroid Build Coastguard Worker bool enforcesSkSLVersion() const { 103*c8dee2aaSAndroid Build Coastguard Worker return IsRuntimeEffect(fKind); 104*c8dee2aaSAndroid Build Coastguard Worker } 105*c8dee2aaSAndroid Build Coastguard Worker strictES2ModeProgramConfig106*c8dee2aaSAndroid Build Coastguard Worker bool strictES2Mode() const { 107*c8dee2aaSAndroid Build Coastguard Worker // TODO(skia:11209): Remove the first condition - so this is just based on #version. 108*c8dee2aaSAndroid Build Coastguard Worker // Make it more generic (eg, isVersionLT) checking. 109*c8dee2aaSAndroid Build Coastguard Worker return fSettings.fMaxVersionAllowed == Version::k100 && 110*c8dee2aaSAndroid Build Coastguard Worker fRequiredSkSLVersion == Version::k100 && 111*c8dee2aaSAndroid Build Coastguard Worker this->enforcesSkSLVersion(); 112*c8dee2aaSAndroid Build Coastguard Worker } 113*c8dee2aaSAndroid Build Coastguard Worker versionDescriptionProgramConfig114*c8dee2aaSAndroid Build Coastguard Worker const char* versionDescription() const { 115*c8dee2aaSAndroid Build Coastguard Worker if (this->enforcesSkSLVersion()) { 116*c8dee2aaSAndroid Build Coastguard Worker switch (fRequiredSkSLVersion) { 117*c8dee2aaSAndroid Build Coastguard Worker case Version::k100: return "#version 100\n"; 118*c8dee2aaSAndroid Build Coastguard Worker case Version::k300: return "#version 300\n"; 119*c8dee2aaSAndroid Build Coastguard Worker } 120*c8dee2aaSAndroid Build Coastguard Worker } 121*c8dee2aaSAndroid Build Coastguard Worker return ""; 122*c8dee2aaSAndroid Build Coastguard Worker } 123*c8dee2aaSAndroid Build Coastguard Worker IsFragmentProgramConfig124*c8dee2aaSAndroid Build Coastguard Worker static bool IsFragment(ProgramKind kind) { 125*c8dee2aaSAndroid Build Coastguard Worker return kind == ProgramKind::kFragment || 126*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kGraphiteFragment || 127*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kGraphiteFragmentES2; 128*c8dee2aaSAndroid Build Coastguard Worker } 129*c8dee2aaSAndroid Build Coastguard Worker IsVertexProgramConfig130*c8dee2aaSAndroid Build Coastguard Worker static bool IsVertex(ProgramKind kind) { 131*c8dee2aaSAndroid Build Coastguard Worker return kind == ProgramKind::kVertex || 132*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kGraphiteVertex || 133*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kGraphiteVertexES2; 134*c8dee2aaSAndroid Build Coastguard Worker } 135*c8dee2aaSAndroid Build Coastguard Worker IsComputeProgramConfig136*c8dee2aaSAndroid Build Coastguard Worker static bool IsCompute(ProgramKind kind) { 137*c8dee2aaSAndroid Build Coastguard Worker return kind == ProgramKind::kCompute; 138*c8dee2aaSAndroid Build Coastguard Worker } 139*c8dee2aaSAndroid Build Coastguard Worker IsRuntimeEffectProgramConfig140*c8dee2aaSAndroid Build Coastguard Worker static bool IsRuntimeEffect(ProgramKind kind) { 141*c8dee2aaSAndroid Build Coastguard Worker return (kind == ProgramKind::kRuntimeColorFilter || 142*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kRuntimeShader || 143*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kRuntimeBlender || 144*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeColorFilter || 145*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeShader || 146*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeBlender || 147*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kMeshVertex || 148*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kMeshFragment); 149*c8dee2aaSAndroid Build Coastguard Worker } 150*c8dee2aaSAndroid Build Coastguard Worker IsRuntimeShaderProgramConfig151*c8dee2aaSAndroid Build Coastguard Worker static bool IsRuntimeShader(ProgramKind kind) { 152*c8dee2aaSAndroid Build Coastguard Worker return (kind == ProgramKind::kRuntimeShader || 153*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeShader); 154*c8dee2aaSAndroid Build Coastguard Worker } 155*c8dee2aaSAndroid Build Coastguard Worker IsRuntimeColorFilterProgramConfig156*c8dee2aaSAndroid Build Coastguard Worker static bool IsRuntimeColorFilter(ProgramKind kind) { 157*c8dee2aaSAndroid Build Coastguard Worker return (kind == ProgramKind::kRuntimeColorFilter || 158*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeColorFilter); 159*c8dee2aaSAndroid Build Coastguard Worker } 160*c8dee2aaSAndroid Build Coastguard Worker IsRuntimeBlenderProgramConfig161*c8dee2aaSAndroid Build Coastguard Worker static bool IsRuntimeBlender(ProgramKind kind) { 162*c8dee2aaSAndroid Build Coastguard Worker return (kind == ProgramKind::kRuntimeBlender || 163*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kPrivateRuntimeBlender); 164*c8dee2aaSAndroid Build Coastguard Worker } 165*c8dee2aaSAndroid Build Coastguard Worker IsMeshProgramConfig166*c8dee2aaSAndroid Build Coastguard Worker static bool IsMesh(ProgramKind kind) { 167*c8dee2aaSAndroid Build Coastguard Worker return (kind == ProgramKind::kMeshVertex || 168*c8dee2aaSAndroid Build Coastguard Worker kind == ProgramKind::kMeshFragment); 169*c8dee2aaSAndroid Build Coastguard Worker } 170*c8dee2aaSAndroid Build Coastguard Worker AllowsPrivateIdentifiersProgramConfig171*c8dee2aaSAndroid Build Coastguard Worker static bool AllowsPrivateIdentifiers(ProgramKind kind) { 172*c8dee2aaSAndroid Build Coastguard Worker return (kind != ProgramKind::kRuntimeColorFilter && 173*c8dee2aaSAndroid Build Coastguard Worker kind != ProgramKind::kRuntimeShader && 174*c8dee2aaSAndroid Build Coastguard Worker kind != ProgramKind::kRuntimeBlender && 175*c8dee2aaSAndroid Build Coastguard Worker kind != ProgramKind::kMeshVertex && 176*c8dee2aaSAndroid Build Coastguard Worker kind != ProgramKind::kMeshFragment); 177*c8dee2aaSAndroid Build Coastguard Worker } 178*c8dee2aaSAndroid Build Coastguard Worker }; 179*c8dee2aaSAndroid Build Coastguard Worker 180*c8dee2aaSAndroid Build Coastguard Worker } // namespace SkSL 181*c8dee2aaSAndroid Build Coastguard Worker 182*c8dee2aaSAndroid Build Coastguard Worker #endif 183