123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /*
- * 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_METALCODEGENERATOR
- #define SKSL_METALCODEGENERATOR
- #include <stack>
- #include <tuple>
- #include <unordered_map>
- #include "src/sksl/SkSLCodeGenerator.h"
- #include "src/sksl/SkSLMemoryLayout.h"
- #include "src/sksl/SkSLStringStream.h"
- #include "src/sksl/ir/SkSLBinaryExpression.h"
- #include "src/sksl/ir/SkSLBoolLiteral.h"
- #include "src/sksl/ir/SkSLConstructor.h"
- #include "src/sksl/ir/SkSLDoStatement.h"
- #include "src/sksl/ir/SkSLExtension.h"
- #include "src/sksl/ir/SkSLFieldAccess.h"
- #include "src/sksl/ir/SkSLFloatLiteral.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/SkSLIfStatement.h"
- #include "src/sksl/ir/SkSLIndexExpression.h"
- #include "src/sksl/ir/SkSLIntLiteral.h"
- #include "src/sksl/ir/SkSLInterfaceBlock.h"
- #include "src/sksl/ir/SkSLPostfixExpression.h"
- #include "src/sksl/ir/SkSLPrefixExpression.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/SkSLSwitchStatement.h"
- #include "src/sksl/ir/SkSLSwizzle.h"
- #include "src/sksl/ir/SkSLTernaryExpression.h"
- #include "src/sksl/ir/SkSLVarDeclarations.h"
- #include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
- #include "src/sksl/ir/SkSLVariableReference.h"
- #include "src/sksl/ir/SkSLWhileStatement.h"
- namespace SkSL {
- #define kLast_Capability SpvCapabilityMultiViewport
- /**
- * Converts a Program into Metal code.
- */
- class MetalCodeGenerator : public CodeGenerator {
- public:
- static constexpr const char* SAMPLER_SUFFIX = "Smplr";
- static constexpr const char* PACKED_PREFIX = "packed_";
- enum Precedence {
- kParentheses_Precedence = 1,
- kPostfix_Precedence = 2,
- kPrefix_Precedence = 3,
- kMultiplicative_Precedence = 4,
- kAdditive_Precedence = 5,
- kShift_Precedence = 6,
- kRelational_Precedence = 7,
- kEquality_Precedence = 8,
- kBitwiseAnd_Precedence = 9,
- kBitwiseXor_Precedence = 10,
- kBitwiseOr_Precedence = 11,
- kLogicalAnd_Precedence = 12,
- kLogicalXor_Precedence = 13,
- kLogicalOr_Precedence = 14,
- kTernary_Precedence = 15,
- kAssignment_Precedence = 16,
- kSequence_Precedence = 17,
- kTopLevel_Precedence = kSequence_Precedence
- };
- MetalCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
- OutputStream* out)
- : INHERITED(program, errors, out)
- , fReservedWords({"atan2", "rsqrt", "dfdx", "dfdy", "vertex", "fragment"})
- , fLineEnding("\n")
- , fContext(*context) {
- this->setupIntrinsics();
- }
- bool generateCode() override;
- protected:
- typedef int Requirements;
- static constexpr Requirements kNo_Requirements = 0;
- static constexpr Requirements kInputs_Requirement = 1 << 0;
- static constexpr Requirements kOutputs_Requirement = 1 << 1;
- static constexpr Requirements kUniforms_Requirement = 1 << 2;
- static constexpr Requirements kGlobals_Requirement = 1 << 3;
- enum IntrinsicKind {
- kSpecial_IntrinsicKind,
- kMetal_IntrinsicKind,
- };
- enum SpecialIntrinsic {
- kTexture_SpecialIntrinsic,
- kMod_SpecialIntrinsic,
- };
- enum MetalIntrinsic {
- kEqual_MetalIntrinsic,
- kNotEqual_MetalIntrinsic,
- kLessThan_MetalIntrinsic,
- kLessThanEqual_MetalIntrinsic,
- kGreaterThan_MetalIntrinsic,
- kGreaterThanEqual_MetalIntrinsic,
- };
- void setupIntrinsics();
- void write(const char* s);
- void writeLine();
- void writeLine(const char* s);
- void write(const String& s);
- void writeLine(const String& s);
- void writeHeader();
- void writeUniformStruct();
- void writeInputStruct();
- void writeOutputStruct();
- void writeInterfaceBlocks();
- void writeFields(const std::vector<Type::Field>& fields, int parentOffset,
- const InterfaceBlock* parentIntf = nullptr);
- int size(const Type* type, bool isPacked) const;
- int alignment(const Type* type, bool isPacked) const;
- void writeGlobalStruct();
- void writePrecisionModifier();
- void writeType(const Type& type);
- void writeExtension(const Extension& ext);
- void writeInterfaceBlock(const InterfaceBlock& intf);
- void writeFunctionStart(const FunctionDeclaration& f);
- void writeFunctionDeclaration(const FunctionDeclaration& f);
- void writeFunction(const FunctionDefinition& f);
- void writeLayout(const Layout& layout);
- void writeModifiers(const Modifiers& modifiers, bool globalContext);
- void writeGlobalVars(const VarDeclaration& vs);
- void writeVarInitializer(const Variable& var, const Expression& value);
- void writeName(const String& name);
- void writeVarDeclarations(const VarDeclarations& decl, bool global);
- void writeFragCoord();
- void writeVariableReference(const VariableReference& ref);
- void writeExpression(const Expression& expr, Precedence parentPrecedence);
- void writeIntrinsicCall(const FunctionCall& c);
- void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
- void writeFunctionCall(const FunctionCall& c);
- void writeInverseHack(const Expression& mat);
- String getMatrixConstructHelper(const Type& matrix, const Type& arg);
- void writeMatrixTimesEqualHelper(const Type& left, const Type& right, const Type& result);
- void writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind);
- bool canCoerce(const Type& t1, const Type& t2);
- void writeConstructor(const Constructor& c, Precedence parentPrecedence);
- void writeFieldAccess(const FieldAccess& f);
- void writeSwizzle(const Swizzle& swizzle);
- static Precedence GetBinaryPrecedence(Token::Kind op);
- void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
- void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
- void writeIndexExpression(const IndexExpression& expr);
- void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
- void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
- void writeBoolLiteral(const BoolLiteral& b);
- void writeIntLiteral(const IntLiteral& i);
- void writeFloatLiteral(const FloatLiteral& f);
- void writeSetting(const Setting& s);
- void writeStatement(const Statement& s);
- void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
- void writeBlock(const Block& b);
- void writeIfStatement(const IfStatement& stmt);
- void writeForStatement(const ForStatement& f);
- void writeWhileStatement(const WhileStatement& w);
- void writeDoStatement(const DoStatement& d);
- void writeSwitchStatement(const SwitchStatement& s);
- void writeReturnStatement(const ReturnStatement& r);
- void writeProgramElement(const ProgramElement& e);
- Requirements requirements(const FunctionDeclaration& f);
- Requirements requirements(const Expression& e);
- Requirements requirements(const Statement& e);
- typedef std::pair<IntrinsicKind, int32_t> Intrinsic;
- std::unordered_map<String, Intrinsic> fIntrinsicMap;
- std::unordered_set<String> fReservedWords;
- std::vector<const VarDeclaration*> fInitNonConstGlobalVars;
- std::vector<const Variable*> fTextures;
- std::unordered_map<const Type::Field*, const InterfaceBlock*> fInterfaceBlockMap;
- std::unordered_map<const InterfaceBlock*, String> fInterfaceBlockNameMap;
- int fAnonInterfaceCount = 0;
- int fPaddingCount = 0;
- bool fNeedsGlobalStructInit = false;
- const char* fLineEnding;
- const Context& fContext;
- StringStream fHeader;
- String fFunctionHeader;
- StringStream fExtraFunctions;
- Program::Kind fProgramKind;
- int fVarCount = 0;
- int fIndentation = 0;
- bool fAtLineStart = false;
- // Keeps track of which struct types we have written. Given that we are unlikely to ever write
- // more than one or two structs per shader, a simple linear search will be faster than anything
- // fancier.
- std::vector<const Type*> fWrittenStructs;
- std::set<String> fWrittenIntrinsics;
- // true if we have run into usages of dFdx / dFdy
- bool fFoundDerivatives = false;
- std::unordered_map<const FunctionDeclaration*, Requirements> fRequirements;
- bool fSetupFragPositionGlobal = false;
- bool fSetupFragPositionLocal = false;
- std::unordered_map<String, String> fHelpers;
- int fUniformBuffer = -1;
- typedef CodeGenerator INHERITED;
- };
- }
- #endif
|