SkSLMetalCodeGenerator.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. #ifndef SKSL_METALCODEGENERATOR
  8. #define SKSL_METALCODEGENERATOR
  9. #include <stack>
  10. #include <tuple>
  11. #include <unordered_map>
  12. #include "src/sksl/SkSLCodeGenerator.h"
  13. #include "src/sksl/SkSLMemoryLayout.h"
  14. #include "src/sksl/SkSLStringStream.h"
  15. #include "src/sksl/ir/SkSLBinaryExpression.h"
  16. #include "src/sksl/ir/SkSLBoolLiteral.h"
  17. #include "src/sksl/ir/SkSLConstructor.h"
  18. #include "src/sksl/ir/SkSLDoStatement.h"
  19. #include "src/sksl/ir/SkSLExtension.h"
  20. #include "src/sksl/ir/SkSLFieldAccess.h"
  21. #include "src/sksl/ir/SkSLFloatLiteral.h"
  22. #include "src/sksl/ir/SkSLForStatement.h"
  23. #include "src/sksl/ir/SkSLFunctionCall.h"
  24. #include "src/sksl/ir/SkSLFunctionDeclaration.h"
  25. #include "src/sksl/ir/SkSLFunctionDefinition.h"
  26. #include "src/sksl/ir/SkSLIfStatement.h"
  27. #include "src/sksl/ir/SkSLIndexExpression.h"
  28. #include "src/sksl/ir/SkSLIntLiteral.h"
  29. #include "src/sksl/ir/SkSLInterfaceBlock.h"
  30. #include "src/sksl/ir/SkSLPostfixExpression.h"
  31. #include "src/sksl/ir/SkSLPrefixExpression.h"
  32. #include "src/sksl/ir/SkSLProgramElement.h"
  33. #include "src/sksl/ir/SkSLReturnStatement.h"
  34. #include "src/sksl/ir/SkSLSetting.h"
  35. #include "src/sksl/ir/SkSLStatement.h"
  36. #include "src/sksl/ir/SkSLSwitchStatement.h"
  37. #include "src/sksl/ir/SkSLSwizzle.h"
  38. #include "src/sksl/ir/SkSLTernaryExpression.h"
  39. #include "src/sksl/ir/SkSLVarDeclarations.h"
  40. #include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
  41. #include "src/sksl/ir/SkSLVariableReference.h"
  42. #include "src/sksl/ir/SkSLWhileStatement.h"
  43. namespace SkSL {
  44. #define kLast_Capability SpvCapabilityMultiViewport
  45. /**
  46. * Converts a Program into Metal code.
  47. */
  48. class MetalCodeGenerator : public CodeGenerator {
  49. public:
  50. static constexpr const char* SAMPLER_SUFFIX = "Smplr";
  51. static constexpr const char* PACKED_PREFIX = "packed_";
  52. enum Precedence {
  53. kParentheses_Precedence = 1,
  54. kPostfix_Precedence = 2,
  55. kPrefix_Precedence = 3,
  56. kMultiplicative_Precedence = 4,
  57. kAdditive_Precedence = 5,
  58. kShift_Precedence = 6,
  59. kRelational_Precedence = 7,
  60. kEquality_Precedence = 8,
  61. kBitwiseAnd_Precedence = 9,
  62. kBitwiseXor_Precedence = 10,
  63. kBitwiseOr_Precedence = 11,
  64. kLogicalAnd_Precedence = 12,
  65. kLogicalXor_Precedence = 13,
  66. kLogicalOr_Precedence = 14,
  67. kTernary_Precedence = 15,
  68. kAssignment_Precedence = 16,
  69. kSequence_Precedence = 17,
  70. kTopLevel_Precedence = kSequence_Precedence
  71. };
  72. MetalCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
  73. OutputStream* out)
  74. : INHERITED(program, errors, out)
  75. , fReservedWords({"atan2", "rsqrt", "dfdx", "dfdy", "vertex", "fragment"})
  76. , fLineEnding("\n")
  77. , fContext(*context) {
  78. this->setupIntrinsics();
  79. }
  80. bool generateCode() override;
  81. protected:
  82. typedef int Requirements;
  83. static constexpr Requirements kNo_Requirements = 0;
  84. static constexpr Requirements kInputs_Requirement = 1 << 0;
  85. static constexpr Requirements kOutputs_Requirement = 1 << 1;
  86. static constexpr Requirements kUniforms_Requirement = 1 << 2;
  87. static constexpr Requirements kGlobals_Requirement = 1 << 3;
  88. enum IntrinsicKind {
  89. kSpecial_IntrinsicKind,
  90. kMetal_IntrinsicKind,
  91. };
  92. enum SpecialIntrinsic {
  93. kTexture_SpecialIntrinsic,
  94. kMod_SpecialIntrinsic,
  95. };
  96. enum MetalIntrinsic {
  97. kEqual_MetalIntrinsic,
  98. kNotEqual_MetalIntrinsic,
  99. kLessThan_MetalIntrinsic,
  100. kLessThanEqual_MetalIntrinsic,
  101. kGreaterThan_MetalIntrinsic,
  102. kGreaterThanEqual_MetalIntrinsic,
  103. };
  104. void setupIntrinsics();
  105. void write(const char* s);
  106. void writeLine();
  107. void writeLine(const char* s);
  108. void write(const String& s);
  109. void writeLine(const String& s);
  110. void writeHeader();
  111. void writeUniformStruct();
  112. void writeInputStruct();
  113. void writeOutputStruct();
  114. void writeInterfaceBlocks();
  115. void writeFields(const std::vector<Type::Field>& fields, int parentOffset,
  116. const InterfaceBlock* parentIntf = nullptr);
  117. int size(const Type* type, bool isPacked) const;
  118. int alignment(const Type* type, bool isPacked) const;
  119. void writeGlobalStruct();
  120. void writePrecisionModifier();
  121. void writeType(const Type& type);
  122. void writeExtension(const Extension& ext);
  123. void writeInterfaceBlock(const InterfaceBlock& intf);
  124. void writeFunctionStart(const FunctionDeclaration& f);
  125. void writeFunctionDeclaration(const FunctionDeclaration& f);
  126. void writeFunction(const FunctionDefinition& f);
  127. void writeLayout(const Layout& layout);
  128. void writeModifiers(const Modifiers& modifiers, bool globalContext);
  129. void writeGlobalVars(const VarDeclaration& vs);
  130. void writeVarInitializer(const Variable& var, const Expression& value);
  131. void writeName(const String& name);
  132. void writeVarDeclarations(const VarDeclarations& decl, bool global);
  133. void writeFragCoord();
  134. void writeVariableReference(const VariableReference& ref);
  135. void writeExpression(const Expression& expr, Precedence parentPrecedence);
  136. void writeIntrinsicCall(const FunctionCall& c);
  137. void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
  138. void writeFunctionCall(const FunctionCall& c);
  139. void writeInverseHack(const Expression& mat);
  140. String getMatrixConstructHelper(const Type& matrix, const Type& arg);
  141. void writeMatrixTimesEqualHelper(const Type& left, const Type& right, const Type& result);
  142. void writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind);
  143. bool canCoerce(const Type& t1, const Type& t2);
  144. void writeConstructor(const Constructor& c, Precedence parentPrecedence);
  145. void writeFieldAccess(const FieldAccess& f);
  146. void writeSwizzle(const Swizzle& swizzle);
  147. static Precedence GetBinaryPrecedence(Token::Kind op);
  148. void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
  149. void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
  150. void writeIndexExpression(const IndexExpression& expr);
  151. void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
  152. void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
  153. void writeBoolLiteral(const BoolLiteral& b);
  154. void writeIntLiteral(const IntLiteral& i);
  155. void writeFloatLiteral(const FloatLiteral& f);
  156. void writeSetting(const Setting& s);
  157. void writeStatement(const Statement& s);
  158. void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
  159. void writeBlock(const Block& b);
  160. void writeIfStatement(const IfStatement& stmt);
  161. void writeForStatement(const ForStatement& f);
  162. void writeWhileStatement(const WhileStatement& w);
  163. void writeDoStatement(const DoStatement& d);
  164. void writeSwitchStatement(const SwitchStatement& s);
  165. void writeReturnStatement(const ReturnStatement& r);
  166. void writeProgramElement(const ProgramElement& e);
  167. Requirements requirements(const FunctionDeclaration& f);
  168. Requirements requirements(const Expression& e);
  169. Requirements requirements(const Statement& e);
  170. typedef std::pair<IntrinsicKind, int32_t> Intrinsic;
  171. std::unordered_map<String, Intrinsic> fIntrinsicMap;
  172. std::unordered_set<String> fReservedWords;
  173. std::vector<const VarDeclaration*> fInitNonConstGlobalVars;
  174. std::vector<const Variable*> fTextures;
  175. std::unordered_map<const Type::Field*, const InterfaceBlock*> fInterfaceBlockMap;
  176. std::unordered_map<const InterfaceBlock*, String> fInterfaceBlockNameMap;
  177. int fAnonInterfaceCount = 0;
  178. int fPaddingCount = 0;
  179. bool fNeedsGlobalStructInit = false;
  180. const char* fLineEnding;
  181. const Context& fContext;
  182. StringStream fHeader;
  183. String fFunctionHeader;
  184. StringStream fExtraFunctions;
  185. Program::Kind fProgramKind;
  186. int fVarCount = 0;
  187. int fIndentation = 0;
  188. bool fAtLineStart = false;
  189. // Keeps track of which struct types we have written. Given that we are unlikely to ever write
  190. // more than one or two structs per shader, a simple linear search will be faster than anything
  191. // fancier.
  192. std::vector<const Type*> fWrittenStructs;
  193. std::set<String> fWrittenIntrinsics;
  194. // true if we have run into usages of dFdx / dFdy
  195. bool fFoundDerivatives = false;
  196. std::unordered_map<const FunctionDeclaration*, Requirements> fRequirements;
  197. bool fSetupFragPositionGlobal = false;
  198. bool fSetupFragPositionLocal = false;
  199. std::unordered_map<String, String> fHelpers;
  200. int fUniformBuffer = -1;
  201. typedef CodeGenerator INHERITED;
  202. };
  203. }
  204. #endif