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_GLSLCODEGENERATOR |
9 | #define SKSL_GLSLCODEGENERATOR |
10 | |
11 | #include <stack> |
12 | #include <tuple> |
13 | #include <unordered_map> |
14 | |
15 | #include "src/sksl/SkSLCodeGenerator.h" |
16 | #include "src/sksl/SkSLStringStream.h" |
17 | #include "src/sksl/ir/SkSLBinaryExpression.h" |
18 | #include "src/sksl/ir/SkSLBoolLiteral.h" |
19 | #include "src/sksl/ir/SkSLConstructor.h" |
20 | #include "src/sksl/ir/SkSLDoStatement.h" |
21 | #include "src/sksl/ir/SkSLExtension.h" |
22 | #include "src/sksl/ir/SkSLFieldAccess.h" |
23 | #include "src/sksl/ir/SkSLFloatLiteral.h" |
24 | #include "src/sksl/ir/SkSLForStatement.h" |
25 | #include "src/sksl/ir/SkSLFunctionCall.h" |
26 | #include "src/sksl/ir/SkSLFunctionDeclaration.h" |
27 | #include "src/sksl/ir/SkSLFunctionDefinition.h" |
28 | #include "src/sksl/ir/SkSLIfStatement.h" |
29 | #include "src/sksl/ir/SkSLIndexExpression.h" |
30 | #include "src/sksl/ir/SkSLIntLiteral.h" |
31 | #include "src/sksl/ir/SkSLInterfaceBlock.h" |
32 | #include "src/sksl/ir/SkSLPostfixExpression.h" |
33 | #include "src/sksl/ir/SkSLPrefixExpression.h" |
34 | #include "src/sksl/ir/SkSLProgramElement.h" |
35 | #include "src/sksl/ir/SkSLReturnStatement.h" |
36 | #include "src/sksl/ir/SkSLSetting.h" |
37 | #include "src/sksl/ir/SkSLStatement.h" |
38 | #include "src/sksl/ir/SkSLSwitchStatement.h" |
39 | #include "src/sksl/ir/SkSLSwizzle.h" |
40 | #include "src/sksl/ir/SkSLTernaryExpression.h" |
41 | #include "src/sksl/ir/SkSLVarDeclarations.h" |
42 | #include "src/sksl/ir/SkSLVarDeclarationsStatement.h" |
43 | #include "src/sksl/ir/SkSLVariableReference.h" |
44 | #include "src/sksl/ir/SkSLWhileStatement.h" |
45 | |
46 | namespace SkSL { |
47 | |
48 | #define kLast_Capability SpvCapabilityMultiViewport |
49 | |
50 | /** |
51 | * Converts a Program into GLSL code. |
52 | */ |
53 | class GLSLCodeGenerator : public CodeGenerator { |
54 | public: |
55 | enum Precedence { |
56 | kParentheses_Precedence = 1, |
57 | kPostfix_Precedence = 2, |
58 | kPrefix_Precedence = 3, |
59 | kMultiplicative_Precedence = 4, |
60 | kAdditive_Precedence = 5, |
61 | kShift_Precedence = 6, |
62 | kRelational_Precedence = 7, |
63 | kEquality_Precedence = 8, |
64 | kBitwiseAnd_Precedence = 9, |
65 | kBitwiseXor_Precedence = 10, |
66 | kBitwiseOr_Precedence = 11, |
67 | kLogicalAnd_Precedence = 12, |
68 | kLogicalXor_Precedence = 13, |
69 | kLogicalOr_Precedence = 14, |
70 | kTernary_Precedence = 15, |
71 | kAssignment_Precedence = 16, |
72 | kSequence_Precedence = 17, |
73 | kTopLevel_Precedence = kSequence_Precedence |
74 | }; |
75 | |
76 | GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors, |
77 | OutputStream* out) |
78 | : INHERITED(program, errors, out) |
79 | , fLineEnding("\n" ) |
80 | , fContext(*context) |
81 | , fProgramKind(program->fKind) {} |
82 | |
83 | bool generateCode() override; |
84 | |
85 | protected: |
86 | enum class SwizzleOrder { |
87 | MASK_FIRST, |
88 | CONSTANTS_FIRST |
89 | }; |
90 | |
91 | void write(const char* s); |
92 | |
93 | void writeLine(); |
94 | |
95 | void writeLine(const char* s); |
96 | |
97 | void write(const String& s); |
98 | |
99 | void write(StringFragment s); |
100 | |
101 | void writeLine(const String& s); |
102 | |
103 | virtual void (); |
104 | |
105 | virtual bool usesPrecisionModifiers() const; |
106 | |
107 | virtual String getTypeName(const Type& type); |
108 | |
109 | void writeType(const Type& type); |
110 | |
111 | void writeExtension(const String& name); |
112 | |
113 | void writeExtension(const String& name, bool require); |
114 | |
115 | void writeInterfaceBlock(const InterfaceBlock& intf); |
116 | |
117 | void writeFunctionStart(const FunctionDeclaration& f); |
118 | |
119 | void writeFunctionDeclaration(const FunctionDeclaration& f); |
120 | |
121 | virtual void writeFunction(const FunctionDefinition& f); |
122 | |
123 | void writeLayout(const Layout& layout); |
124 | |
125 | void writeModifiers(const Modifiers& modifiers, bool globalContext); |
126 | |
127 | virtual void writeInputVars(); |
128 | |
129 | virtual void writeVarInitializer(const Variable& var, const Expression& value); |
130 | |
131 | const char* getTypePrecision(const Type& type); |
132 | |
133 | void writeTypePrecision(const Type& type); |
134 | |
135 | void writeVarDeclarations(const VarDeclarations& decl, bool global); |
136 | |
137 | void writeFragCoord(); |
138 | |
139 | virtual void writeVariableReference(const VariableReference& ref); |
140 | |
141 | void writeExpression(const Expression& expr, Precedence parentPrecedence); |
142 | |
143 | void writeIntrinsicCall(const FunctionCall& c); |
144 | |
145 | void writeMinAbsHack(Expression& absExpr, Expression& otherExpr); |
146 | |
147 | void writeDeterminantHack(const Expression& mat); |
148 | |
149 | void writeInverseHack(const Expression& mat); |
150 | |
151 | void writeTransposeHack(const Expression& mat); |
152 | |
153 | void writeInverseSqrtHack(const Expression& x); |
154 | |
155 | virtual void writeFunctionCall(const FunctionCall& c); |
156 | |
157 | void writeConstructor(const Constructor& c, Precedence parentPrecedence); |
158 | |
159 | virtual void writeFieldAccess(const FieldAccess& f); |
160 | |
161 | void writeConstantSwizzle(const Swizzle& swizzle, const String& constants); |
162 | |
163 | void writeSwizzleMask(const Swizzle& swizzle, const String& mask); |
164 | |
165 | void writeSwizzleConstructor(const Swizzle& swizzle, const String& constants, |
166 | const String& mask, SwizzleOrder order); |
167 | |
168 | void writeSwizzleConstructor(const Swizzle& swizzle, const String& constants, |
169 | const String& mask, const String& reswizzle); |
170 | virtual void writeSwizzle(const Swizzle& swizzle); |
171 | |
172 | static Precedence GetBinaryPrecedence(Token::Kind op); |
173 | |
174 | virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence); |
175 | void writeShortCircuitWorkaroundExpression(const BinaryExpression& b, |
176 | Precedence parentPrecedence); |
177 | |
178 | void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence); |
179 | |
180 | virtual void writeIndexExpression(const IndexExpression& expr); |
181 | |
182 | void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence); |
183 | |
184 | void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence); |
185 | |
186 | void writeBoolLiteral(const BoolLiteral& b); |
187 | |
188 | virtual void writeIntLiteral(const IntLiteral& i); |
189 | |
190 | void writeFloatLiteral(const FloatLiteral& f); |
191 | |
192 | virtual void writeSetting(const Setting& s); |
193 | |
194 | void writeStatement(const Statement& s); |
195 | |
196 | void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements); |
197 | |
198 | void writeBlock(const Block& b); |
199 | |
200 | virtual void writeIfStatement(const IfStatement& stmt); |
201 | |
202 | void writeForStatement(const ForStatement& f); |
203 | |
204 | void writeWhileStatement(const WhileStatement& w); |
205 | |
206 | void writeDoStatement(const DoStatement& d); |
207 | |
208 | virtual void writeSwitchStatement(const SwitchStatement& s); |
209 | |
210 | virtual void writeReturnStatement(const ReturnStatement& r); |
211 | |
212 | virtual void writeProgramElement(const ProgramElement& e); |
213 | |
214 | const char* fLineEnding; |
215 | const Context& fContext; |
216 | StringStream fExtensions; |
217 | StringStream fGlobals; |
218 | StringStream ; |
219 | String ; |
220 | Program::Kind fProgramKind; |
221 | int fVarCount = 0; |
222 | int fIndentation = 0; |
223 | bool fAtLineStart = false; |
224 | // Keeps track of which struct types we have written. Given that we are unlikely to ever write |
225 | // more than one or two structs per shader, a simple linear search will be faster than anything |
226 | // fancier. |
227 | std::vector<const Type*> fWrittenStructs; |
228 | std::set<String> fWrittenIntrinsics; |
229 | // true if we have run into usages of dFdx / dFdy |
230 | bool fFoundDerivatives = false; |
231 | bool fFoundExternalSamplerDecl = false; |
232 | bool fFoundRectSamplerDecl = false; |
233 | bool fFoundGSInvocations = false; |
234 | bool fSetupFragPositionGlobal = false; |
235 | bool fSetupFragPositionLocal = false; |
236 | bool fSetupFragCoordWorkaround = false; |
237 | // if non-empty, replace all texture / texture2D / textureProj / etc. calls with this name |
238 | String fTextureFunctionOverride; |
239 | |
240 | // We map function names to function class so we can quickly deal with function calls that need |
241 | // extra processing |
242 | enum class FunctionClass { |
243 | kAbs, |
244 | kAtan, |
245 | kDeterminant, |
246 | kDFdx, |
247 | kDFdy, |
248 | kFwidth, |
249 | kFMA, |
250 | kFract, |
251 | kInverse, |
252 | kInverseSqrt, |
253 | kMin, |
254 | kPow, |
255 | kSaturate, |
256 | kTexture, |
257 | kTranspose |
258 | }; |
259 | static std::unordered_map<StringFragment, FunctionClass>* fFunctionClasses; |
260 | |
261 | typedef CodeGenerator INHERITED; |
262 | }; |
263 | |
264 | } |
265 | |
266 | #endif |
267 | |