#include "src/sksl/codegen/SkSLSPIRVCodeGenerator.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/core/SkChecksum.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTraceEvent.h"
#include "src/sksl/GLSL.std.450.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/SkSLPool.h"
#include "src/sksl/SkSLPosition.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/analysis/SkSLSpecialization.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/SkSLConstructorCompoundCast.h"
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
#include "src/sksl/ir/SkSLConstructorSplat.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLExtension.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/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/SkSLPoison.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/SkSLSwitchCase.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/ir/SkSLSwizzle.h"
#include "src/sksl/ir/SkSLSymbol.h"
#include "src/sksl/ir/SkSLSymbolTable.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 "src/utils/SkBitSet.h"
#include <algorithm>
#include <cstdint>
#include <cstring>
#include <ctype.h>
#include <functional>
#include <memory>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
usingnamespaceskia_private;
#define kLast_Capability …
constexpr int DEVICE_FRAGCOORDS_BUILTIN = …;
constexpr int DEVICE_CLOCKWISE_BUILTIN = …;
static constexpr SkSL::Layout kDefaultTypeLayout;
namespace SkSL {
enum class ProgramKind : int8_t;
enum class StorageClass { … };
static SpvStorageClass get_storage_class_spv_id(StorageClass storageClass) { … }
class SPIRVCodeGenerator : public CodeGenerator { … };
bool SPIRVCodeGenerator::Instruction::operator==(const SPIRVCodeGenerator::Instruction& that) const { … }
struct SPIRVCodeGenerator::Instruction::Hash { … };
struct SPIRVCodeGenerator::Word { … };
static const int32_t SKSL_MAGIC = …;
SPIRVCodeGenerator::Intrinsic SPIRVCodeGenerator::getIntrinsic(IntrinsicKind ik) const { … }
void SPIRVCodeGenerator::writeWord(int32_t word, OutputStream& out) { … }
static bool is_float(const Type& type) { … }
static bool is_signed(const Type& type) { … }
static bool is_unsigned(const Type& type) { … }
static bool is_bool(const Type& type) { … }
template <typename T>
static T pick_by_type(const Type& type, T ifFloat, T ifInt, T ifUInt, T ifBool) { … }
static bool is_out(ModifierFlags f) { … }
static bool is_in(ModifierFlags f) { … }
static bool is_control_flow_op(SpvOp_ op) { … }
static bool is_globally_reachable_op(SpvOp_ op) { … }
void SPIRVCodeGenerator::writeOpCode(SpvOp_ opCode, int length, OutputStream& out) { … }
void SPIRVCodeGenerator::writeLabel(SpvId label, StraightLineLabelType, OutputStream& out) { … }
void SPIRVCodeGenerator::writeLabel(SpvId label, BranchingLabelType type,
ConditionalOpCounts ops, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, OutputStream& out) { … }
void SPIRVCodeGenerator::writeString(std::string_view s, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, std::string_view string,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, std::string_view string,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
std::string_view string, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, int32_t word4, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, int32_t word4, int32_t word5,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, int32_t word4, int32_t word5,
int32_t word6, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, int32_t word4, int32_t word5,
int32_t word6, int32_t word7, OutputStream& out) { … }
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
int32_t word3, int32_t word4, int32_t word5,
int32_t word6, int32_t word7, int32_t word8,
OutputStream& out) { … }
SPIRVCodeGenerator::Instruction SPIRVCodeGenerator::BuildInstructionKey(SpvOp_ opCode,
const TArray<Word>& words) { … }
SpvId SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode,
const TArray<Word>& words,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeOpLoad(SpvId type,
Precision precision,
SpvId pointer,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeOpStore(StorageClass storageClass,
SpvId pointer,
SpvId value,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeOpConstantTrue(const Type& type) { … }
SpvId SPIRVCodeGenerator::writeOpConstantFalse(const Type& type) { … }
SpvId SPIRVCodeGenerator::writeOpConstant(const Type& type, int32_t valueBits) { … }
SpvId SPIRVCodeGenerator::writeOpConstantComposite(const Type& type,
const TArray<SpvId>& values) { … }
bool SPIRVCodeGenerator::toConstants(SpvId value, TArray<SpvId>* constants) { … }
bool SPIRVCodeGenerator::toConstants(SkSpan<const SpvId> values, TArray<SpvId>* constants) { … }
SpvId SPIRVCodeGenerator::writeOpCompositeConstruct(const Type& type,
const TArray<SpvId>& values,
OutputStream& out) { … }
SPIRVCodeGenerator::Instruction* SPIRVCodeGenerator::resultTypeForInstruction(
const Instruction& instr) { … }
int SPIRVCodeGenerator::numComponentsForVecInstruction(const Instruction& instr) { … }
SpvId SPIRVCodeGenerator::toComponent(SpvId id, int component) { … }
SpvId SPIRVCodeGenerator::writeOpCompositeExtract(const Type& type,
SpvId base,
int component,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeOpCompositeExtract(const Type& type,
SpvId base,
int componentA,
int componentB,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeCapabilities(OutputStream& out) { … }
SpvId SPIRVCodeGenerator::nextId(const Type* type) { … }
SpvId SPIRVCodeGenerator::nextId(Precision precision) { … }
SpvId SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memoryLayout) { … }
SpvId SPIRVCodeGenerator::getType(const Type& type) { … }
static SpvImageFormat layout_flags_to_image_format(LayoutFlags flags) { … }
SpvId SPIRVCodeGenerator::getType(const Type& rawType,
const Layout& typeLayout,
const MemoryLayout& memoryLayout) { … }
SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { … }
SpvId SPIRVCodeGenerator::getFunctionParameterType(const Type& parameterType,
const Layout& parameterLayout) { … }
SpvId SPIRVCodeGenerator::getPointerType(const Type& type, StorageClass storageClass) { … }
SpvId SPIRVCodeGenerator::getPointerType(const Type& type,
const Layout& typeLayout,
const MemoryLayout& memoryLayout,
StorageClass storageClass) { … }
SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::vectorize(const Expression& arg, int vectorSize, OutputStream& out) { … }
TArray<SpvId> SPIRVCodeGenerator::vectorize(const ExpressionArray& args, OutputStream& out) { … }
void SPIRVCodeGenerator::writeGLSLExtendedInstruction(const Type& type, SpvId id, SpvId floatInst,
SpvId signedInst, SpvId unsignedInst,
const TArray<SpvId>& args,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeAtomicIntrinsic(const FunctionCall& c,
SpecialIntrinsic kind,
SpvId resultId,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeFunctionCallArgument(TArray<SpvId>& argumentList,
const FunctionCall& call,
int argIndex,
std::vector<TempVar>* tempVars,
const SkBitSet* specializedParams,
OutputStream& out) { … }
void SPIRVCodeGenerator::copyBackTempVars(const std::vector<TempVar>& tempVars, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::castScalarToType(SpvId inputExprId,
const Type& inputType,
const Type& outputType,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::castScalarToFloat(SpvId inputId, const Type& inputType,
const Type& outputType, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::castScalarToSignedInt(SpvId inputId, const Type& inputType,
const Type& outputType, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::castScalarToUnsignedInt(SpvId inputId, const Type& inputType,
const Type& outputType, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::castScalarToBoolean(SpvId inputId, const Type& inputType,
const Type& outputType, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeMatrixCopy(SpvId src, const Type& srcType, const Type& dstType,
OutputStream& out) { … }
void SPIRVCodeGenerator::addColumnEntry(const Type& columnType,
TArray<SpvId>* currentColumn,
TArray<SpvId>* columnIds,
int rows,
SpvId entry,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeMatrixConstructor(const ConstructorCompound& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorCompound(const ConstructorCompound& c,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeVectorConstructor(const ConstructorCompound& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorSplat(const ConstructorSplat& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeCompositeConstructor(const AnyConstructor& c, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorScalarCast(const ConstructorScalarCast& c,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorCompoundCast(const ConstructorCompoundCast& c,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeConstructorMatrixResize(const ConstructorMatrixResize& c,
OutputStream& out) { … }
static StorageClass get_storage_class_for_global_variable(
const Variable& var, StorageClass fallbackStorageClass) { … }
StorageClass SPIRVCodeGenerator::getStorageClass(const Expression& expr) { … }
TArray<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, OutputStream& out) { … }
class PointerLValue : public SPIRVCodeGenerator::LValue { … };
class SwizzleLValue : public SPIRVCodeGenerator::LValue { … };
int SPIRVCodeGenerator::findUniformFieldIndex(const Variable& var) const { … }
std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
OutputStream& out) { … }
std::unique_ptr<Expression> SPIRVCodeGenerator::identifier(std::string_view name) { … }
SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeFieldAccess(const FieldAccess& f, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeSwizzle(const Expression& baseExpr,
const ComponentArray& components,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, const Type& operandType,
SpvId lhs, SpvId rhs,
bool writeComponentwiseIfMatrix,
SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
SpvOp_ ifBool, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeBinaryOperationComponentwiseIfMatrix(const Type& resultType,
const Type& operandType,
SpvId lhs, SpvId rhs,
SpvOp_ ifFloat, SpvOp_ ifInt,
SpvOp_ ifUInt, SpvOp_ ifBool,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, const Type& operandType,
SpvId lhs, SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt,
SpvOp_ ifUInt, SpvOp_ ifBool, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::foldToBool(SpvId id, const Type& operandType, SpvOp op,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeMatrixComparison(const Type& operandType, SpvId lhs, SpvId rhs,
SpvOp_ floatOperator, SpvOp_ intOperator,
SpvOp_ vectorMergeOperator, SpvOp_ mergeOperator,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeComponentwiseMatrixUnary(const Type& operandType,
SpvId operand,
SpvOp_ op,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeComponentwiseMatrixBinary(const Type& operandType, SpvId lhs,
SpvId rhs, SpvOp_ op, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeReciprocal(const Type& type, SpvId value, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::splat(const Type& type, SpvId id, OutputStream& out) { … }
static bool types_match(const Type& a, const Type& b) { … }
SpvId SPIRVCodeGenerator::writeDecomposedMatrixVectorMultiply(const Type& leftType,
SpvId lhs,
const Type& rightType,
SpvId rhs,
const Type& resultType,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, Operator op,
const Type& rightType, SpvId rhs,
const Type& resultType, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeArrayComparison(const Type& arrayType, SpvId lhs, Operator op,
SpvId rhs, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeStructComparison(const Type& structType, SpvId lhs, Operator op,
SpvId rhs, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::mergeComparisons(SpvId comparison, SpvId allComparisons, Operator op,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeLogicalAnd(const Expression& left, const Expression& right,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeLogicalOr(const Expression& left, const Expression& right,
OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, OutputStream& out) { … }
SpvId SPIRVCodeGenerator::writeLiteral(const Literal& l) { … }
SpvId SPIRVCodeGenerator::writeLiteral(double value, const Type& type) { … }
void SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, OutputStream& out) { … }
void SPIRVCodeGenerator::writeFunction(const FunctionDefinition& f, OutputStream& out) { … }
void SPIRVCodeGenerator::writeFunctionInstantiation(
const FunctionDefinition& f,
Analysis::SpecializationIndex specializationIndex,
const Analysis::SpecializedParameters* specializedParams,
OutputStream& out) { … }
void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, Position pos) { … }
void SPIRVCodeGenerator::writeFieldLayout(const Layout& layout, SpvId target, int member) { … }
MemoryLayout SPIRVCodeGenerator::memoryLayoutForStorageClass(StorageClass storageClass) { … }
MemoryLayout SPIRVCodeGenerator::memoryLayoutForVariable(const Variable& v) const { … }
SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool appendRTFlip) { … }
static bool is_vardecl_compile_time_constant(const VarDeclaration& varDecl) { … }
bool SPIRVCodeGenerator::writeGlobalVarDeclaration(ProgramKind kind,
const VarDeclaration& varDecl) { … }
SpvId SPIRVCodeGenerator::writeGlobalVar(ProgramKind kind,
StorageClass storageClass,
const Variable& var) { … }
void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl, OutputStream& out) { … }
void SPIRVCodeGenerator::writeStatement(const Statement& s, OutputStream& out) { … }
void SPIRVCodeGenerator::writeBlock(const Block& b, OutputStream& out) { … }
SPIRVCodeGenerator::ConditionalOpCounts SPIRVCodeGenerator::getConditionalOpCounts() { … }
void SPIRVCodeGenerator::pruneConditionalOps(ConditionalOpCounts ops) { … }
void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, OutputStream& out) { … }
void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, OutputStream& out) { … }
void SPIRVCodeGenerator::writeDoStatement(const DoStatement& d, OutputStream& out) { … }
void SPIRVCodeGenerator::writeSwitchStatement(const SwitchStatement& s, OutputStream& out) { … }
void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, OutputStream& out) { … }
static SymbolTable* get_top_level_symbol_table(const FunctionDeclaration& anyFunc) { … }
SPIRVCodeGenerator::EntrypointAdapter SPIRVCodeGenerator::writeEntrypointAdapter(
const FunctionDeclaration& main) { … }
void SPIRVCodeGenerator::writeUniformBuffer(SymbolTable* topLevelSymbolTable) { … }
void SPIRVCodeGenerator::addRTFlipUniform(Position pos) { … }
std::tuple<const Variable*, const Variable*> SPIRVCodeGenerator::synthesizeTextureAndSampler(
const Variable& combinedSampler) { … }
void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream& out) { … }
bool SPIRVCodeGenerator::generateCode() { … }
bool ToSPIRV(Program& program,
const ShaderCaps* caps,
OutputStream& out,
ValidateSPIRVProc validateSPIRV) { … }
bool ToSPIRV(Program& program,
const ShaderCaps* caps,
std::string* out,
ValidateSPIRVProc validateSPIRV) { … }
}