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