OLD | NEW |
---|---|
(Empty) | |
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 | |
8 #ifndef SKSL_SPIRVCODEGENERATOR | |
9 #define SKSL_SPIRVCODEGENERATOR | |
10 | |
11 #include <sstream> | |
12 #include <stack> | |
13 #include <tuple> | |
14 #include <unordered_map> | |
15 | |
16 #include "SkSLCodeGenerator.h" | |
17 #include "ir/SkSLBinaryExpression.h" | |
18 #include "ir/SkSLBoolLiteral.h" | |
19 #include "ir/SkSLConstructor.h" | |
20 #include "ir/SkSLFloatLiteral.h" | |
21 #include "ir/SkSLIfStatement.h" | |
22 #include "ir/SkSLIndexExpression.h" | |
23 #include "ir/SkSLInterfaceBlock.h" | |
24 #include "ir/SkSLIntLiteral.h" | |
25 #include "ir/SkSLFieldAccess.h" | |
26 #include "ir/SkSLForStatement.h" | |
27 #include "ir/SkSLFunctionCall.h" | |
28 #include "ir/SkSLFunctionDeclaration.h" | |
29 #include "ir/SkSLFunctionDefinition.h" | |
30 #include "ir/SkSLPrefixExpression.h" | |
31 #include "ir/SkSLPostfixExpression.h" | |
32 #include "ir/SkSLProgramElement.h" | |
33 #include "ir/SkSLReturnStatement.h" | |
34 #include "ir/SkSLStatement.h" | |
35 #include "ir/SkSLSwizzle.h" | |
36 #include "ir/SkSLTernaryExpression.h" | |
37 #include "ir/SkSLVarDeclaration.h" | |
38 #include "ir/SkSLVarDeclarationStatement.h" | |
39 #include "ir/SkSLVariableReference.h" | |
40 #include "spirv.h" | |
41 | |
42 namespace SkSL { | |
43 | |
44 #define kLast_Capability SpvCapabilityMultiViewport | |
45 | |
46 /** | |
47 * Converts a Program into a SPIR-V binary. | |
48 */ | |
49 class SPIRVCodeGenerator : public CodeGenerator { | |
50 public: | |
51 SPIRVCodeGenerator() | |
52 : fCapabilities(1 << SpvCapabilityShader) | |
53 , fIdCount(1) | |
54 , fBoolTrue(0) | |
55 , fBoolFalse(0) | |
56 , fCurrentBlock(0) { | |
57 this->setupIntrinsics(); | |
58 } | |
59 | |
60 void generateCode(Program& program, std::ostream& out) override; | |
61 | |
62 private: | |
63 enum IntrinsicKind { | |
64 kGLSL_STD_450_IntrinsicKind, | |
65 kSPIRV_IntrinsicKind, | |
66 kSpecial_IntrinsicKind | |
67 }; | |
68 | |
69 enum SpecialIntrinsic { | |
70 kAtan_SpecialIntrinsic, | |
71 kTexture_SpecialIntrinsic, | |
72 kTexture2D_SpecialIntrinsic, | |
73 kTextureProj_SpecialIntrinsic | |
74 }; | |
75 | |
76 void setupIntrinsics(); | |
77 | |
78 SpvId nextId(); | |
79 | |
80 SpvId getType(std::shared_ptr<Type> type); | |
81 | |
82 SpvId getFunctionType(std::shared_ptr<FunctionDeclaration> function); | |
83 | |
84 SpvId getPointerType(std::shared_ptr<Type> type, SpvStorageClass_ storageCla ss); | |
85 | |
86 std::vector<SpvId> getAccessChain(Expression& expr, std::ostream& out); | |
87 | |
88 void writeLayout(const Layout& layout, SpvId target); | |
89 | |
90 void writeLayout(const Layout& layout, SpvId target, int member); | |
91 | |
92 void writeStruct(std::shared_ptr<Type> type, SpvId resultId); | |
93 | |
94 void writeProgramElement(ProgramElement& pe, std::ostream& out); | |
95 | |
96 SpvId writeInterfaceBlock(InterfaceBlock& intf); | |
97 | |
98 SpvId writeFunctionStart(std::shared_ptr<FunctionDeclaration> f, std::ostrea m& out); | |
99 | |
100 SpvId writeFunctionDeclaration(std::shared_ptr<FunctionDeclaration> f, std:: ostream& out); | |
101 | |
102 SpvId writeFunction(FunctionDefinition& f, std::ostream& out); | |
103 | |
104 void writeGlobalVars(VarDeclaration& v, std::ostream& out); | |
105 | |
106 void writeVarDeclaration(VarDeclaration& decl, std::ostream& out); | |
107 | |
108 SpvId writeVariableReference(VariableReference& ref, std::ostream& out); | |
109 | |
110 SpvId getLValue(Expression& value, std::ostream& out); | |
111 | |
112 void storeToLValue(Expression& lvalue, SpvId value, std::ostream& out); | |
113 | |
114 SpvId writeExpression(Expression& expr, std::ostream& out); | |
115 | |
116 SpvId writeIntrinsicCall(FunctionCall& c, std::ostream& out); | |
117 | |
118 SpvId writeFunctionCall(FunctionCall& c, std::ostream& out); | |
119 | |
120 SpvId writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind, std::ost ream& out); | |
121 | |
122 SpvId writeConstructor(Constructor& c, std::ostream& out); | |
123 | |
124 SpvId writeFieldAccess(FieldAccess& f, std::ostream& out); | |
125 | |
126 SpvId writeSwizzle(Swizzle& swizzle, std::ostream& out); | |
127 | |
128 SpvId writeBinaryOperation(std::shared_ptr<Type> resultType, std::shared_ptr <Type> operandType, | |
129 SpvId lhs, SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifIn t, SpvOp_ ifUInt, | |
130 SpvOp_ ifBool, std::ostream& out); | |
131 | |
132 SpvId writeBinaryOperation(BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ if Int, SpvOp_ ifUInt, | |
133 std::ostream& out); | |
134 | |
135 SpvId writeBinaryExpression(BinaryExpression& b, std::ostream& out); | |
136 | |
137 SpvId writeTernaryExpression(TernaryExpression& t, std::ostream& out); | |
138 | |
139 SpvId writeIndexExpression(IndexExpression& expr, std::ostream& out); | |
140 | |
141 SpvId writeLogicalAnd(BinaryExpression& b, std::ostream& out); | |
142 | |
143 SpvId writeLogicalOr(BinaryExpression& o, std::ostream& out); | |
144 | |
145 SpvId writePrefixExpression(PrefixExpression& p, std::ostream& out); | |
146 | |
147 SpvId writePostfixExpression(PostfixExpression& p, std::ostream& out); | |
148 | |
149 SpvId writeBoolLiteral(BoolLiteral& b); | |
150 | |
151 SpvId writeIntLiteral(IntLiteral& i); | |
152 | |
153 SpvId writeFloatLiteral(FloatLiteral& f); | |
154 | |
155 void writeStatement(Statement& s, std::ostream& out); | |
156 | |
157 void writeBlock(Block& b, std::ostream& out); | |
158 | |
159 void writeIfStatement(IfStatement& stmt, std::ostream& out); | |
160 | |
161 void writeForStatement(ForStatement& f, std::ostream& out); | |
162 | |
163 void writeReturnStatement(ReturnStatement& r, std::ostream& out); | |
164 | |
165 void writeCapabilities(std::ostream& out); | |
166 | |
167 void writeInstructions(Program& program, std::ostream& out); | |
168 | |
169 void writeOpCode(SpvOp_ opCode, int length, std::ostream& out); | |
170 | |
171 void writeWord(int32_t word, std::ostream& out); | |
172 | |
173 void writeString(const char* string, std::ostream& out); | |
174 | |
175 void writeLabel(SpvId id, std::ostream& out); | |
176 | |
177 void writeInstruction(SpvOp_ opCode, std::ostream& out); | |
178 | |
179 void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out); | |
180 | |
181 void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out); | |
182 | |
183 void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std: :ostream& out); | |
184 | |
185 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const cha r* string, | |
186 std::ostream& out); | |
187 | |
188 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostr eam& out); | |
189 | |
190 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, | |
191 std::ostream& out); | |
192 | |
193 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, int32_t word4, | |
194 std::ostream& out); | |
195 | |
196 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, int32_t word4, | |
197 int32_t word5, std::ostream& out); | |
198 | |
199 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, int32_t word4, | |
200 int32_t word5, int32_t word6, std::ostream& out); | |
201 | |
202 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, int32_t word4, | |
203 int32_t word5, int32_t word6, int32_t word7, std::ostr eam& out); | |
204 | |
205 void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t w ord3, int32_t word4, | |
206 int32_t word5, int32_t word6, int32_t word7, int32_t w ord8, | |
207 std::ostream& out); | |
208 | |
209 uint64_t fCapabilities; | |
210 SpvId fIdCount; | |
211 SpvId fGLSLExtendedInstructions; | |
212 typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrin sic; | |
dogben
2016/06/24 17:05:29
nit: define a struct?
| |
213 std::unordered_map<std::string, Intrinsic> fIntrinsicMap; | |
214 std::unordered_map<std::shared_ptr<FunctionDeclaration>, SpvId> fFunctionMap ; | |
dogben
2016/06/24 17:05:29
nit: Seems like fFunctionMap, fVariableMap, and fI
| |
215 std::unordered_map<std::shared_ptr<Variable>, SpvId> fVariableMap; | |
216 std::unordered_map<std::shared_ptr<Variable>, int32_t> fInterfaceBlockMap; | |
217 std::unordered_map<std::string, SpvId> fTypeMap; | |
dogben
2016/06/24 17:05:29
nit: Seems like it would be better to have fTypeMa
| |
218 std::stringstream fCapabilitiesBuffer; | |
219 std::stringstream fGlobalInitializersBuffer; | |
220 std::stringstream fConstantBuffer; | |
221 std::stringstream fExternalFunctionsBuffer; | |
222 std::stringstream fVariableBuffer; | |
223 std::stringstream fNameBuffer; | |
224 std::stringstream fDecorationBuffer; | |
225 | |
226 SpvId fBoolTrue; | |
227 SpvId fBoolFalse; | |
228 std::unordered_map<int64_t, SpvId> fIntConstants; | |
229 std::unordered_map<uint64_t, SpvId> fUIntConstants; | |
230 std::unordered_map<float, SpvId> fFloatConstants; | |
231 std::unordered_map<double, SpvId> fDoubleConstants; | |
232 // label of the current block, or 0 if we are not in a block | |
233 SpvId fCurrentBlock; | |
234 std::stack<SpvId> fBreakTarget; | |
235 std::stack<SpvId> fContinueTarget; | |
236 }; | |
237 | |
238 } | |
239 | |
240 #endif | |
OLD | NEW |