| /* | |
| * Copyright 2016 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef SKSL_PROGRAMSETTINGS | |
| #define SKSL_PROGRAMSETTINGS | |
| #include "include/sksl/SkSLVersion.h" | |
| #include "src/sksl/SkSLDefines.h" | |
| #include "src/sksl/SkSLProgramKind.h" | |
| #include <vector> | |
| namespace SkSL { | |
| /** | |
| * Holds the compiler settings for a program. | |
| */ | |
| struct ProgramSettings { | |
| // If true, the destination fragment color can be read from sk_FragColor. It must be declared | |
| // inout. This is only supported in GLSL, when framebuffer-fetch is used. | |
| bool fFragColorIsInOut = false; | |
| // if true, all halfs are forced to be floats | |
| bool fForceHighPrecision = false; | |
| // if true, add -0.5 bias to LOD of all texture lookups | |
| bool fSharpenTextures = false; | |
| // If true, sk_FragCoord, the dFdy gradient, and sk_Clockwise won't be modified by the | |
| // rtFlip. Additionally, the program interface's 'fRTFlipUniform' value will be left as None, | |
| // so no rtFlip uniform will be emitted. | |
| bool fForceNoRTFlip = false; | |
| // if the program needs to create an RTFlip uniform, this is its offset in the uniform buffer | |
| int fRTFlipOffset = -1; | |
| // if the program needs to create an RTFlip uniform and is creating SPIR-V, this is the binding | |
| // and set number of the uniform buffer. | |
| int fRTFlipBinding = -1; | |
| int fRTFlipSet = -1; | |
| // If layout(set=S, binding=B) is not specified for a uniform, these values will be used. | |
| // At present, zero is always used by our backends. | |
| int fDefaultUniformSet = 0; | |
| int fDefaultUniformBinding = 0; | |
| // Enables the SkSL optimizer. Note that we never disable optimizations which are needed to | |
| // fully evaluate constant-expressions, like constant folding or constant-intrinsic evaluation. | |
| bool fOptimize = true; | |
| // (Requires fOptimize = true) Removes any uncalled functions other than main(). Note that a | |
| // function which starts out being used may end up being uncalled after optimization. | |
| bool fRemoveDeadFunctions = true; | |
| // (Requires fOptimize = true) Removes variables which are never used. | |
| bool fRemoveDeadVariables = true; | |
| // (Requires fOptimize = true) When greater than zero, enables the inliner. The threshold value | |
| // sets an upper limit on the acceptable amount of code growth from inlining. | |
| int fInlineThreshold = SkSL::kDefaultInlineThreshold; | |
| // If true, every function in the generated program will be given the `noinline` modifier. | |
| bool fForceNoInline = false; | |
| // If true, implicit conversions to lower precision numeric types are allowed (e.g., float to | |
| // half). These are always allowed when compiling Runtime Effects. | |
| bool fAllowNarrowingConversions = false; | |
| // If true, then Debug code will run SPIR-V output through the validator to ensure its | |
| // correctness | |
| bool fValidateSPIRV = true; | |
| // If true, any synthetic uniforms must use push constant syntax | |
| bool fUsePushConstants = false; | |
| // TODO(skia:11209) - Replace this with a "promised" capabilities? | |
| // Sets a maximum SkSL version. Compilation will fail if the program uses features that aren't | |
| // allowed at the requested version. For instance, a valid program must have fully-unrollable | |
| // `for` loops at version 100, but any loop structure is allowed at version 300. | |
| SkSL::Version fMaxVersionAllowed = SkSL::Version::k100; | |
| // If true, SkSL will use a memory pool for all IR nodes when compiling a program. This is | |
| // usually a significant speed increase, but uses more memory, so it is a good idea for programs | |
| // that will be freed shortly after compilation. It can also be useful to disable this flag when | |
| // investigating memory corruption. (This controls behavior of the SkSL compiler, not the code | |
| // we generate.) | |
| bool fUseMemoryPool = true; | |
| }; | |
| /** | |
| * All the configuration data for a given program. | |
| */ | |
| struct ProgramConfig { | |
| /** True if we are currently processing one of the built-in SkSL include modules. */ | |
| bool fIsBuiltinCode; | |
| ProgramKind fKind; | |
| ProgramSettings fSettings; | |
| // When enforcesSkSLVersion() is true, this determines the available feature set that will be | |
| // enforced. This is set automatically when the `#version` directive is parsed. | |
| SkSL::Version fRequiredSkSLVersion = SkSL::Version::k100; | |
| bool enforcesSkSLVersion() const { | |
| return IsRuntimeEffect(fKind); | |
| } | |
| bool strictES2Mode() const { | |
| // TODO(skia:11209): Remove the first condition - so this is just based on #version. | |
| // Make it more generic (eg, isVersionLT) checking. | |
| return fSettings.fMaxVersionAllowed == Version::k100 && | |
| fRequiredSkSLVersion == Version::k100 && | |
| this->enforcesSkSLVersion(); | |
| } | |
| const char* versionDescription() const { | |
| if (this->enforcesSkSLVersion()) { | |
| switch (fRequiredSkSLVersion) { | |
| case Version::k100: return "#version 100\n"; | |
| case Version::k300: return "#version 300\n"; | |
| } | |
| } | |
| return ""; | |
| } | |
| static bool IsFragment(ProgramKind kind) { | |
| return kind == ProgramKind::kFragment || | |
| kind == ProgramKind::kGraphiteFragment || | |
| kind == ProgramKind::kGraphiteFragmentES2; | |
| } | |
| static bool IsVertex(ProgramKind kind) { | |
| return kind == ProgramKind::kVertex || | |
| kind == ProgramKind::kGraphiteVertex || | |
| kind == ProgramKind::kGraphiteVertexES2; | |
| } | |
| static bool IsCompute(ProgramKind kind) { | |
| return kind == ProgramKind::kCompute; | |
| } | |
| static bool IsRuntimeEffect(ProgramKind kind) { | |
| return (kind == ProgramKind::kRuntimeColorFilter || | |
| kind == ProgramKind::kRuntimeShader || | |
| kind == ProgramKind::kRuntimeBlender || | |
| kind == ProgramKind::kPrivateRuntimeColorFilter || | |
| kind == ProgramKind::kPrivateRuntimeShader || | |
| kind == ProgramKind::kPrivateRuntimeBlender || | |
| kind == ProgramKind::kMeshVertex || | |
| kind == ProgramKind::kMeshFragment); | |
| } | |
| static bool IsRuntimeShader(ProgramKind kind) { | |
| return (kind == ProgramKind::kRuntimeShader || | |
| kind == ProgramKind::kPrivateRuntimeShader); | |
| } | |
| static bool IsRuntimeColorFilter(ProgramKind kind) { | |
| return (kind == ProgramKind::kRuntimeColorFilter || | |
| kind == ProgramKind::kPrivateRuntimeColorFilter); | |
| } | |
| static bool IsRuntimeBlender(ProgramKind kind) { | |
| return (kind == ProgramKind::kRuntimeBlender || | |
| kind == ProgramKind::kPrivateRuntimeBlender); | |
| } | |
| static bool AllowsPrivateIdentifiers(ProgramKind kind) { | |
| return (kind != ProgramKind::kRuntimeColorFilter && | |
| kind != ProgramKind::kRuntimeShader && | |
| kind != ProgramKind::kRuntimeBlender && | |
| kind != ProgramKind::kMeshVertex && | |
| kind != ProgramKind::kMeshFragment); | |
| } | |
| }; | |
| } // namespace SkSL | |
| #endif |