Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(459)

Side by Side Diff: src/sksl/SkSLGLSLCodeGenerator.cpp

Issue 2185393003: added initial GLSL support to skslc (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fixes! Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 #include "SkSLGLSLCodeGenerator.h"
9
10 #include "string.h"
11
12 #include "GLSL.std.450.h"
13
14 #include "ir/SkSLExpressionStatement.h"
15 #include "ir/SkSLExtension.h"
16 #include "ir/SkSLIndexExpression.h"
17 #include "ir/SkSLVariableReference.h"
18
19 namespace SkSL {
20
21 void GLSLCodeGenerator::write(const char* s) {
22 if (s[0] == 0) {
23 return;
24 }
25 if (fAtLineStart) {
26 for (int i = 0; i < fIndentation; i++) {
27 *fOut << " ";
28 }
29 }
30 *fOut << s;
31 fAtLineStart = false;
32 }
33
34 void GLSLCodeGenerator::writeLine(const char* s) {
35 this->write(s);
36 *fOut << "\n";
37 fAtLineStart = true;
38 }
39
40 void GLSLCodeGenerator::write(const std::string& s) {
41 this->write(s.c_str());
42 }
43
44 void GLSLCodeGenerator::writeLine(const std::string& s) {
45 this->writeLine(s.c_str());
46 }
47
48 void GLSLCodeGenerator::writeLine() {
49 this->writeLine("");
50 }
51
52 void GLSLCodeGenerator::writeExtension(const Extension& ext) {
53 this->writeLine("#extension " + ext.fName + " : enable");
54 }
55
56 void GLSLCodeGenerator::writeType(const Type& type) {
57 if (type.kind() == Type::kStruct_Kind) {
58 this->writeLine("struct " + type.name() + " {");
59 fIndentation++;
60 for (const auto& f : type.fields()) {
61 this->writeModifiers(f.fModifiers);
62 this->writeType(f.fType);
dogben 2016/08/02 18:08:15 Example from the GLSL spec: struct S { float f; };
ethannicholas 2016/08/02 20:43:06 Good catch, fixed.
63 this->writeLine(" " + f.fName + ";");
64 }
65 fIndentation--;
66 this->writeLine("}");
67 } else {
68 this->write(type.name());
dogben 2016/08/02 18:08:15 Maybe add a comment that array sizes are part of t
ethannicholas 2016/08/02 20:43:06 Done.
69 }
70 }
71
72 void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren tPrecedence) {
73 switch (expr.fKind) {
74 case Expression::kBinary_Kind:
75 this->writeBinaryExpression((BinaryExpression&) expr, parentPreceden ce);
76 break;
77 case Expression::kBoolLiteral_Kind:
78 this->writeBoolLiteral((BoolLiteral&) expr);
79 break;
80 case Expression::kConstructor_Kind:
81 this->writeConstructor((Constructor&) expr);
82 break;
83 case Expression::kIntLiteral_Kind:
84 this->writeIntLiteral((IntLiteral&) expr);
85 break;
86 case Expression::kFieldAccess_Kind:
87 this->writeFieldAccess(((FieldAccess&) expr));
88 break;
89 case Expression::kFloatLiteral_Kind:
90 this->writeFloatLiteral(((FloatLiteral&) expr));
91 break;
92 case Expression::kFunctionCall_Kind:
93 this->writeFunctionCall((FunctionCall&) expr);
94 break;
95 case Expression::kPrefix_Kind:
96 this->writePrefixExpression((PrefixExpression&) expr, parentPreceden ce);
97 break;
98 case Expression::kPostfix_Kind:
99 this->writePostfixExpression((PostfixExpression&) expr, parentPreced ence);
100 break;
101 case Expression::kSwizzle_Kind:
102 this->writeSwizzle((Swizzle&) expr);
103 break;
104 case Expression::kVariableReference_Kind:
105 this->writeVariableReference((VariableReference&) expr);
106 break;
107 case Expression::kTernary_Kind:
108 this->writeTernaryExpression((TernaryExpression&) expr, parentPreced ence);
109 break;
110 case Expression::kIndex_Kind:
111 this->writeIndexExpression((IndexExpression&) expr);
112 break;
113 default:
114 ABORT("unsupported expression: %s", expr.description().c_str());
115 }
116 }
117
118 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
119 this->write(c.fFunction.fName + "(");
120 const char* separator = "";
121 for (const auto& arg : c.fArguments) {
122 this->write(separator);
123 separator = ", ";
124 this->writeExpression(*arg, kSequence_Precedence);
125 }
126 this->write(")");
127 }
128
129 void GLSLCodeGenerator::writeConstructor(const Constructor& c) {
130 this->write(c.fType.name() + "(");
131 const char* separator = "";
132 for (const auto& arg : c.fArguments) {
133 this->write(separator);
134 separator = ", ";
135 this->writeExpression(*arg, kSequence_Precedence);
136 }
137 this->write(")");
138 }
139
140 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
141 this->write(ref.fVariable.fName);
142 }
143
144 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
145 this->writeExpression(*expr.fBase, kPostfix_Precedence);
146 this->write("[");
147 this->writeExpression(*expr.fIndex, kTopLevel_Precedence);
148 this->write("]");
149 }
150
151 void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
152 if (f.fOwnerKind == FieldAccess::kDefault_OwnerKind) {
153 this->writeExpression(*f.fBase, kPostfix_Precedence);
154 this->write(".");
155 }
156 this->write(f.fBase->fType.fields()[f.fFieldIndex].fName);
157 }
158
159 void GLSLCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
160 this->writeExpression(*swizzle.fBase, kPostfix_Precedence);
161 this->write(".");
162 for (int c : swizzle.fComponents) {
163 this->write(&("x\0y\0z\0w\0"[c * 2]));
164 }
165 }
166
167 static GLSLCodeGenerator::Precedence get_binary_precedence(Token::Kind op) {
168 switch (op) {
169 case Token::STAR: // fall through
170 case Token::SLASH: // fall through
171 case Token::PERCENT: return GLSLCodeGenerator::kMultiplicative_Prec edence;
172 case Token::PLUS: // fall through
173 case Token::MINUS: return GLSLCodeGenerator::kAdditive_Precedence ;
174 case Token::SHL: // fall through
175 case Token::SHR: return GLSLCodeGenerator::kShift_Precedence;
176 case Token::LT: // fall through
177 case Token::GT: // fall through
178 case Token::LTEQ: // fall through
179 case Token::GTEQ: return GLSLCodeGenerator::kRelational_Preceden ce;
180 case Token::EQEQ: // fall through
181 case Token::NEQ: return GLSLCodeGenerator::kEquality_Precedence ;
182 case Token::BITWISEAND: return GLSLCodeGenerator::kBitwiseAnd_Preceden ce;
183 case Token::BITWISEXOR: return GLSLCodeGenerator::kBitwiseXor_Preceden ce;
184 case Token::BITWISEOR: return GLSLCodeGenerator::kBitwiseOr_Precedenc e;
185 case Token::LOGICALAND: return GLSLCodeGenerator::kLogicalAnd_Preceden ce;
186 case Token::LOGICALXOR: return GLSLCodeGenerator::kLogicalXor_Preceden ce;
187 case Token::LOGICALOR: return GLSLCodeGenerator::kLogicalOr_Precedenc e;
188 case Token::EQ: // fall through
189 case Token::PLUSEQ: // fall through
190 case Token::MINUSEQ: // fall through
191 case Token::STAREQ: // fall through
192 case Token::SLASHEQ: // fall through
193 case Token::PERCENTEQ: // fall through
194 case Token::SHLEQ: // fall through
195 case Token::SHREQ: // fall through
196 case Token::LOGICALANDEQ: // fall through
197 case Token::LOGICALXOREQ: // fall through
198 case Token::LOGICALOREQ: // fall through
199 case Token::BITWISEANDEQ: // fall through
200 case Token::BITWISEXOREQ: // fall through
201 case Token::BITWISEOREQ: return GLSLCodeGenerator::kAssignment_Preceden ce;
202 default: ABORT("unsupported binary operator");
203 }
204 }
205
206 void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
207 Precedence parentPrecedence) {
208 Precedence precedence = get_binary_precedence(b.fOperator);
209 if (precedence >= parentPrecedence) {
210 this->write("(");
211 }
212 this->writeExpression(*b.fLeft, precedence);
213 this->write(" " + Token::OperatorName(b.fOperator) + " ");
214 this->writeExpression(*b.fRight, precedence);
215 if (precedence >= parentPrecedence) {
216 this->write(")");
217 }
218 }
219
220 void GLSLCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
221 Precedence parentPrecedence) {
222 if (kTernary_Precedence >= parentPrecedence) {
223 this->write("(");
224 }
225 this->writeExpression(*t.fTest, kTernary_Precedence);
226 this->write(" ? ");
227 this->writeExpression(*t.fIfTrue, kTernary_Precedence);
228 this->write(" : ");
229 this->writeExpression(*t.fIfFalse, kTernary_Precedence);
230 if (kTernary_Precedence >= parentPrecedence) {
231 this->write(")");
232 }
233 }
234
235 void GLSLCodeGenerator::writePrefixExpression(const PrefixExpression& p,
236 Precedence parentPrecedence) {
237 if (kPrefix_Precedence >= parentPrecedence) {
238 this->write("(");
239 }
240 this->write(Token::OperatorName(p.fOperator));
241 this->writeExpression(*p.fOperand, kPrefix_Precedence);
242 if (kPrefix_Precedence >= parentPrecedence) {
243 this->write(")");
244 }
245 }
246
247 void GLSLCodeGenerator::writePostfixExpression(const PostfixExpression& p,
248 Precedence parentPrecedence) {
249 if (kPostfix_Precedence >= parentPrecedence) {
250 this->write("(");
251 }
252 this->writeExpression(*p.fOperand, kPostfix_Precedence);
253 this->write(Token::OperatorName(p.fOperator));
254 if (kPostfix_Precedence >= parentPrecedence) {
255 this->write(")");
256 }
257 }
258
259 void GLSLCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
260 this->write(b.fValue ? "true" : "false");
261 }
262
263 void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
264 this->write(to_string(i.fValue));
265 }
266
267 void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
268 this->write(to_string(f.fValue));
269 }
270
271 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
272 this->writeType(f.fDeclaration.fReturnType);
273 this->write(" " + f.fDeclaration.fName + "(");
274 const char* separator = "";
275 for (const auto& param : f.fDeclaration.fParameters) {
276 this->write(separator);
277 separator = ", ";
278 this->writeModifiers(param->fModifiers);
279 this->writeType(param->fType);
280 this->write(" " + param->fName);
281 }
282 this->write(") ");
283 this->writeBlock(*f.fBody);
284 this->writeLine();
285 }
286
287 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) {
288 this->write(modifiers.description());
289 }
290
291 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
292 if (intf.fVariable.fName == "gl_PerVertex") {
293 return;
294 }
295 this->writeModifiers(intf.fVariable.fModifiers);
296 this->writeLine(intf.fVariable.fType.name() + " {");
297 fIndentation++;
298 for (const auto& f : intf.fVariable.fType.fields()) {
299 this->writeModifiers(f.fModifiers);
300 this->writeType(f.fType);
301 this->writeLine(" " + f.fName + ";");
302 }
303 fIndentation--;
304 this->writeLine("};");
305 }
306
307 void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
308 ASSERT(decl.fVars.size() > 0);
309 this->writeModifiers(decl.fVars[0]->fModifiers);
310 this->writeType(decl.fBaseType);
311 std::string separator = " ";
312 for (size_t i = 0; i < decl.fVars.size(); i++) {
313 ASSERT(decl.fVars[i]->fModifiers == decl.fVars[0]->fModifiers);
314 this->write(separator);
315 separator = ", ";
316 this->write(decl.fVars[i]->fName);
317 for (const auto& size : decl.fSizes[i]) {
318 this->write("[");
319 this->writeExpression(*size, kTopLevel_Precedence);
320 this->write("]");
321 }
322 if (decl.fValues[i]) {
323 this->write(" = ");
324 this->writeExpression(*decl.fValues[i], kTopLevel_Precedence);
325 }
326 }
327 this->write(";");
328 }
329
330 void GLSLCodeGenerator::writeStatement(const Statement& s) {
331 switch (s.fKind) {
332 case Statement::kBlock_Kind:
333 this->writeBlock((Block&) s);
334 break;
335 case Statement::kExpression_Kind:
336 this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopL evel_Precedence);
337 this->write(";");
338 break;
339 case Statement::kReturn_Kind:
340 this->writeReturnStatement((ReturnStatement&) s);
341 break;
342 case Statement::kVarDeclaration_Kind:
343 this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclarati on);
344 break;
345 case Statement::kIf_Kind:
346 this->writeIfStatement((IfStatement&) s);
347 break;
348 case Statement::kFor_Kind:
349 this->writeForStatement((ForStatement&) s);
350 break;
351 case Statement::kWhile_Kind:
352 this->writeWhileStatement((WhileStatement&) s);
353 break;
354 case Statement::kDo_Kind:
355 this->writeDoStatement((DoStatement&) s);
356 break;
357 case Statement::kBreak_Kind:
358 this->write("break;");
359 break;
360 case Statement::kContinue_Kind:
361 this->write("continue;");
362 break;
363 case Statement::kDiscard_Kind:
364 this->write("discard;");
365 break;
366 default:
367 ABORT("unsupported statement: %s", s.description().c_str());
368 }
369 }
370
371 void GLSLCodeGenerator::writeBlock(const Block& b) {
372 this->writeLine("{");
373 fIndentation++;
374 for (const auto& s : b.fStatements) {
375 this->writeStatement(*s);
376 this->writeLine();
377 }
378 fIndentation--;
379 this->write("}");
380 }
381
382 void GLSLCodeGenerator::writeIfStatement(const IfStatement& stmt) {
383 this->write("if (");
384 this->writeExpression(*stmt.fTest, kTopLevel_Precedence);
385 this->write(") ");
386 this->writeStatement(*stmt.fIfTrue);
387 if (stmt.fIfFalse) {
388 this->write(" else ");
389 this->writeStatement(*stmt.fIfFalse);
390 }
391 }
392
393 void GLSLCodeGenerator::writeForStatement(const ForStatement& f) {
394 this->write("for (");
395 if (f.fInitializer) {
396 this->writeStatement(*f.fInitializer);
397 } else {
398 this->write("; ");
399 }
400 if (f.fTest) {
401 this->writeExpression(*f.fTest, kTopLevel_Precedence);
402 }
403 this->write("; ");
404 if (f.fNext) {
405 this->writeExpression(*f.fNext, kTopLevel_Precedence);
406 }
407 this->write(") ");
408 this->writeStatement(*f.fStatement);
409 }
410
411 void GLSLCodeGenerator::writeWhileStatement(const WhileStatement& w) {
412 this->write("while (");
413 this->writeExpression(*w.fTest, kTopLevel_Precedence);
414 this->write(") ");
415 this->writeStatement(*w.fStatement);
416 }
417
418 void GLSLCodeGenerator::writeDoStatement(const DoStatement& d) {
419 this->write("do ");
420 this->writeStatement(*d.fStatement);
421 this->write(" while (");
422 this->writeExpression(*d.fTest, kTopLevel_Precedence);
423 this->write(");");
424 }
425
426 void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
427 this->write("return");
428 if (r.fExpression) {
429 this->write(" ");
430 this->writeExpression(*r.fExpression, kTopLevel_Precedence);
431 }
432 this->write(";");
433 }
434
435 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
436 ASSERT(fOut == nullptr);
437 fOut = &out;
438 this->write("#version " + to_string(fCaps.fVersion));
439 if (fCaps.fStandard == GLCaps::kGLES_Standard) {
440 this->write(" es");
441 }
442 this->writeLine();
443 for (const auto& e : program.fElements) {
444 switch (e->fKind) {
445 case ProgramElement::kExtension_Kind:
446 this->writeExtension((Extension&) *e);
447 break;
448 case ProgramElement::kVar_Kind: {
449 VarDeclaration& decl = (VarDeclaration&) *e;
450 if (decl.fVars.size() > 0 && decl.fVars[0]->fModifiers.fLayout.f Builtin == -1) {
451 this->writeVarDeclaration(decl);
452 this->writeLine();
453 }
454 break;
455 }
456 case ProgramElement::kInterfaceBlock_Kind:
457 this->writeInterfaceBlock((InterfaceBlock&) *e);
458 break;
459 case ProgramElement::kFunction_Kind:
460 this->writeFunction((FunctionDefinition&) *e);
461 break;
462 default:
463 printf("%s\n", e->description().c_str());
464 ABORT("unsupported program element");
465 }
466 }
467 fOut = nullptr;
468 }
469
470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698