#include "src/sksl/codegen/SkSLWGSLCodeGenerator.h"
#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkEnumBitMask.h"
#include "src/base/SkStringView.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTraceEvent.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLDefines.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLIntrinsicList.h"
#include "src/sksl/SkSLMemoryLayout.h"
#include "src/sksl/SkSLOperator.h"
#include "src/sksl/SkSLOutputStream.h"
#include "src/sksl/SkSLPosition.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLString.h"
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/analysis/SkSLProgramUsage.h"
#include "src/sksl/analysis/SkSLProgramVisitor.h"
#include "src/sksl/codegen/SkSLCodeGenTypes.h"
#include "src/sksl/codegen/SkSLCodeGenerator.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLBlock.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorCompound.h"
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
#include "src/sksl/ir/SkSLFieldSymbol.h"
#include "src/sksl/ir/SkSLForStatement.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLIRHelpers.h"
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLIndexExpression.h"
#include "src/sksl/ir/SkSLInterfaceBlock.h"
#include "src/sksl/ir/SkSLLayout.h"
#include "src/sksl/ir/SkSLLiteral.h"
#include "src/sksl/ir/SkSLModifierFlags.h"
#include "src/sksl/ir/SkSLModifiersDeclaration.h"
#include "src/sksl/ir/SkSLPostfixExpression.h"
#include "src/sksl/ir/SkSLPrefixExpression.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLReturnStatement.h"
#include "src/sksl/ir/SkSLSetting.h"
#include "src/sksl/ir/SkSLStatement.h"
#include "src/sksl/ir/SkSLStructDefinition.h"
#include "src/sksl/ir/SkSLSwitchCase.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/ir/SkSLSwizzle.h"
#include "src/sksl/ir/SkSLTernaryExpression.h"
#include "src/sksl/ir/SkSLType.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/ir/SkSLVariable.h"
#include "src/sksl/ir/SkSLVariableReference.h"
#include "src/sksl/spirv.h"
#include "src/sksl/transform/SkSLTransform.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
usingnamespaceskia_private;
namespace …
namespace SkSL {
class WGSLCodeGenerator : public CodeGenerator { … };
enum class ProgramKind : int8_t;
namespace {
static constexpr char kSamplerSuffix[] = …;
static constexpr char kTextureSuffix[] = …;
enum class PtrAddressSpace { … };
const char* operator_name(Operator op) { … }
bool is_reserved_word(std::string_view word) { … }
std::string_view pipeline_struct_prefix(ProgramKind kind) { … }
std::string_view address_space_to_str(PtrAddressSpace addressSpace) { … }
std::string_view to_scalar_type(const Type& type) { … }
std::string to_wgsl_type(const Context& context, const Type& raw, const Layout* layout = nullptr) { … }
std::string to_ptr_type(const Context& context,
const Type& type,
const Layout* layout,
PtrAddressSpace addressSpace = PtrAddressSpace::kFunction) { … }
std::string_view wgsl_builtin_name(WGSLCodeGenerator::Builtin builtin) { … }
std::string_view wgsl_builtin_type(WGSLCodeGenerator::Builtin builtin) { … }
std::optional<std::string_view> needs_builtin_type_conversion(const Variable& v) { … }
std::optional<WGSLCodeGenerator::Builtin> builtin_from_sksl_name(int builtin) { … }
const char* delimiter_to_str(WGSLCodeGenerator::Delimiter delimiter) { … }
class FunctionDependencyResolver : public ProgramVisitor { … };
WGSLCodeGenerator::ProgramRequirements resolve_program_requirements(const Program* program) { … }
void collect_pipeline_io_vars(const Program* program,
TArray<const Variable*>* ioVars,
ModifierFlag ioType) { … }
bool is_in_global_uniforms(const Variable& var) { … }
}
class WGSLCodeGenerator::LValue { … };
class WGSLCodeGenerator::PointerLValue : public WGSLCodeGenerator::LValue { … };
class WGSLCodeGenerator::VectorComponentLValue : public WGSLCodeGenerator::LValue { … };
class WGSLCodeGenerator::SwizzleLValue : public WGSLCodeGenerator::LValue { … };
bool WGSLCodeGenerator::generateCode() { … }
void WGSLCodeGenerator::writeUniformPolyfills() { … }
void WGSLCodeGenerator::preprocessProgram() { … }
void WGSLCodeGenerator::write(std::string_view s) { … }
void WGSLCodeGenerator::writeLine(std::string_view s) { … }
void WGSLCodeGenerator::finishLine() { … }
std::string WGSLCodeGenerator::assembleName(std::string_view name) { … }
void WGSLCodeGenerator::writeVariableDecl(const Layout& layout,
const Type& type,
std::string_view name,
Delimiter delimiter) { … }
void WGSLCodeGenerator::writePipelineIODeclaration(const Layout& layout,
const Type& type,
ModifierFlags modifiers,
std::string_view name,
Delimiter delimiter) { … }
void WGSLCodeGenerator::writeUserDefinedIODecl(const Layout& layout,
const Type& type,
ModifierFlags flags,
std::string_view name,
Delimiter delimiter) { … }
void WGSLCodeGenerator::writeBuiltinIODecl(const Type& type,
std::string_view name,
Builtin builtin,
Delimiter delimiter) { … }
void WGSLCodeGenerator::writeFunction(const FunctionDefinition& f) { … }
void WGSLCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& decl,
SkSpan<const bool> paramNeedsDedicatedStorage) { … }
void WGSLCodeGenerator::writeEntryPoint(const FunctionDefinition& main) { … }
void WGSLCodeGenerator::writeStatement(const Statement& s) { … }
void WGSLCodeGenerator::writeStatements(const StatementArray& statements) { … }
void WGSLCodeGenerator::writeBlock(const Block& b) { … }
void WGSLCodeGenerator::writeExpressionStatement(const Expression& expr) { … }
void WGSLCodeGenerator::writeDoStatement(const DoStatement& s) { … }
void WGSLCodeGenerator::writeForStatement(const ForStatement& s) { … }
void WGSLCodeGenerator::writeIfStatement(const IfStatement& s) { … }
void WGSLCodeGenerator::writeReturnStatement(const ReturnStatement& s) { … }
void WGSLCodeGenerator::writeSwitchCaseList(SkSpan<const SwitchCase* const> cases) { … }
void WGSLCodeGenerator::writeSwitchCases(SkSpan<const SwitchCase* const> cases) { … }
void WGSLCodeGenerator::writeEmulatedSwitchFallthroughCases(SkSpan<const SwitchCase* const> cases,
std::string_view switchValue) { … }
void WGSLCodeGenerator::writeSwitchStatement(const SwitchStatement& s) { … }
void WGSLCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl) { … }
std::unique_ptr<WGSLCodeGenerator::LValue> WGSLCodeGenerator::makeLValue(const Expression& e) { … }
std::string WGSLCodeGenerator::assembleExpression(const Expression& e,
Precedence parentPrecedence) { … }
static bool is_nontrivial_expression(const Expression& expr) { … }
static bool binary_op_is_ambiguous_in_wgsl(Operator op) { … }
bool WGSLCodeGenerator::binaryOpNeedsComponentwiseMatrixPolyfill(const Type& left,
const Type& right,
Operator op) { … }
std::string WGSLCodeGenerator::assembleBinaryExpression(const BinaryExpression& b,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleBinaryExpression(const Expression& left,
Operator op,
const Expression& right,
const Type& resultType,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleFieldAccess(const FieldAccess& f) { … }
static bool all_arguments_constant(const ExpressionArray& arguments) { … }
std::string WGSLCodeGenerator::assembleSimpleIntrinsic(std::string_view intrinsicName,
const FunctionCall& call) { … }
std::string WGSLCodeGenerator::assembleVectorizedIntrinsic(std::string_view intrinsicName,
const FunctionCall& call) { … }
std::string WGSLCodeGenerator::assembleUnaryOpIntrinsic(Operator op,
const FunctionCall& call,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleBinaryOpIntrinsic(Operator op,
const FunctionCall& call,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleOutAssignedIntrinsic(std::string_view intrinsicName,
std::string_view returnField,
std::string_view outField,
const FunctionCall& call) { … }
std::string WGSLCodeGenerator::assemblePartialSampleCall(std::string_view functionName,
const Expression& sampler,
const Expression& coords) { … }
std::string WGSLCodeGenerator::assembleComponentwiseMatrixBinary(const Type& leftType,
const Type& rightType,
const std::string& left,
const std::string& right,
Operator op) { … }
std::string WGSLCodeGenerator::assembleIntrinsicCall(const FunctionCall& call,
IntrinsicKind kind,
Precedence parentPrecedence) { … }
static constexpr char kInverse2x2[] = …;
static constexpr char kInverse3x3[] = …;
static constexpr char kInverse4x4[] = …;
std::string WGSLCodeGenerator::assembleInversePolyfill(const FunctionCall& call) { … }
std::string WGSLCodeGenerator::assembleFunctionCall(const FunctionCall& call,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleIndexExpression(const IndexExpression& i) { … }
std::string WGSLCodeGenerator::assembleLiteral(const Literal& l) { … }
std::string WGSLCodeGenerator::assembleIncrementExpr(const Type& type) { … }
std::string WGSLCodeGenerator::assemblePrefixExpression(const PrefixExpression& p,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assemblePostfixExpression(const PostfixExpression& p,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleSwizzle(const Swizzle& swizzle) { … }
std::string WGSLCodeGenerator::writeScratchVar(const Type& type, const std::string& value) { … }
std::string WGSLCodeGenerator::writeScratchLet(const std::string& expr,
bool isCompileTimeConstant) { … }
std::string WGSLCodeGenerator::writeScratchLet(const Expression& expr,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::writeNontrivialScratchLet(const Expression& expr,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleTernaryExpression(const TernaryExpression& t,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::variablePrefix(const Variable& v) { … }
std::string WGSLCodeGenerator::variableReferenceNameForLValue(const VariableReference& r) { … }
std::string WGSLCodeGenerator::assembleVariableReference(const VariableReference& r) { … }
std::string WGSLCodeGenerator::assembleAnyConstructor(const AnyConstructor& c) { … }
std::string WGSLCodeGenerator::assembleConstructorCompound(const ConstructorCompound& c) { … }
std::string WGSLCodeGenerator::assembleConstructorCompoundVector(const ConstructorCompound& c) { … }
std::string WGSLCodeGenerator::assembleConstructorCompoundMatrix(const ConstructorCompound& ctor) { … }
std::string WGSLCodeGenerator::assembleConstructorDiagonalMatrix(
const ConstructorDiagonalMatrix& c) { … }
std::string WGSLCodeGenerator::assembleConstructorMatrixResize(
const ConstructorMatrixResize& ctor) { … }
std::string WGSLCodeGenerator::assembleEqualityExpression(const Type& left,
const std::string& leftName,
const Type& right,
const std::string& rightName,
Operator op,
Precedence parentPrecedence) { … }
std::string WGSLCodeGenerator::assembleEqualityExpression(const Expression& left,
const Expression& right,
Operator op,
Precedence parentPrecedence) { … }
void WGSLCodeGenerator::writeProgramElement(const ProgramElement& e) { … }
void WGSLCodeGenerator::writeTextureOrSampler(const Variable& var,
int bindingLocation,
std::string_view suffix,
std::string_view wgslType) { … }
void WGSLCodeGenerator::writeGlobalVarDeclaration(const GlobalVarDeclaration& d) { … }
void WGSLCodeGenerator::writeStructDefinition(const StructDefinition& s) { … }
void WGSLCodeGenerator::writeModifiersDeclaration(const ModifiersDeclaration& modifiers) { … }
void WGSLCodeGenerator::writeFields(SkSpan<const Field> fields, const MemoryLayout* memoryLayout) { … }
void WGSLCodeGenerator::writeEnables() { … }
bool WGSLCodeGenerator::needsStageInputStruct() const { … }
void WGSLCodeGenerator::writeStageInputStruct() { … }
bool WGSLCodeGenerator::needsStageOutputStruct() const { … }
void WGSLCodeGenerator::writeStageOutputStruct() { … }
void WGSLCodeGenerator::prepareUniformPolyfillsForInterfaceBlock(
const InterfaceBlock* interfaceBlock,
std::string_view instanceName,
MemoryLayout::Standard nativeLayout) { … }
void WGSLCodeGenerator::writeUniformsAndBuffers() { … }
void WGSLCodeGenerator::writeNonBlockUniformsForTests() { … }
std::string WGSLCodeGenerator::functionDependencyArgs(const FunctionDeclaration& f) { … }
bool WGSLCodeGenerator::writeFunctionDependencyParams(const FunctionDeclaration& f) { … }
bool ToWGSL(Program& program,
const ShaderCaps* caps,
OutputStream& out,
PrettyPrint pp,
IncludeSyntheticCode isc,
ValidateWGSLProc validateWGSL) { … }
bool ToWGSL(Program& program, const ShaderCaps* caps, OutputStream& out) { … }
bool ToWGSL(Program& program, const ShaderCaps* caps, std::string* out) { … }
}