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

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

Powered by Google App Engine
This is Rietveld 408576698