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

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

Issue 2288033003: Turned on SkSL->GLSL compiler (Closed)
Patch Set: changed <iostream> to <ostream> Created 4 years, 2 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.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkSLGLSLCodeGenerator.h" 8 #include "SkSLGLSLCodeGenerator.h"
9 9
10 #include "string.h" 10 #include "string.h"
11 11
12 #include "GLSL.std.450.h" 12 #include "GLSL.std.450.h"
13 13
14 #include "ir/SkSLExpressionStatement.h" 14 #include "ir/SkSLExpressionStatement.h"
15 #include "ir/SkSLExtension.h" 15 #include "ir/SkSLExtension.h"
16 #include "ir/SkSLIndexExpression.h" 16 #include "ir/SkSLIndexExpression.h"
17 #include "ir/SkSLModifiersDeclaration.h"
17 #include "ir/SkSLVariableReference.h" 18 #include "ir/SkSLVariableReference.h"
18 19
20 #define SK_FRAGCOLOR_BUILTIN 10001
21
19 namespace SkSL { 22 namespace SkSL {
20 23
21 void GLSLCodeGenerator::write(const char* s) { 24 void GLSLCodeGenerator::write(const char* s) {
22 if (s[0] == 0) { 25 if (s[0] == 0) {
23 return; 26 return;
24 } 27 }
25 if (fAtLineStart) { 28 if (fAtLineStart) {
26 for (int i = 0; i < fIndentation; i++) { 29 for (int i = 0; i < fIndentation; i++) {
27 *fOut << " "; 30 *fOut << " ";
28 } 31 }
(...skipping 30 matching lines...) Expand all
59 if (*search == type) { 62 if (*search == type) {
60 // already written 63 // already written
61 this->write(type.name()); 64 this->write(type.name());
62 return; 65 return;
63 } 66 }
64 } 67 }
65 fWrittenStructs.push_back(&type); 68 fWrittenStructs.push_back(&type);
66 this->writeLine("struct " + type.name() + " {"); 69 this->writeLine("struct " + type.name() + " {");
67 fIndentation++; 70 fIndentation++;
68 for (const auto& f : type.fields()) { 71 for (const auto& f : type.fields()) {
69 this->writeModifiers(f.fModifiers); 72 this->writeModifiers(f.fModifiers, false);
70 // sizes (which must be static in structs) are part of the type name here 73 // sizes (which must be static in structs) are part of the type name here
71 this->writeType(*f.fType); 74 this->writeType(*f.fType);
72 this->writeLine(" " + f.fName + ";"); 75 this->writeLine(" " + f.fName + ";");
73 } 76 }
74 fIndentation--; 77 fIndentation--;
75 this->writeLine("}"); 78 this->writeLine("}");
76 } else { 79 } else {
77 this->write(type.name()); 80 this->write(type.name());
78 } 81 }
79 } 82 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 this->writeTernaryExpression((TernaryExpression&) expr, parentPreced ence); 120 this->writeTernaryExpression((TernaryExpression&) expr, parentPreced ence);
118 break; 121 break;
119 case Expression::kIndex_Kind: 122 case Expression::kIndex_Kind:
120 this->writeIndexExpression((IndexExpression&) expr); 123 this->writeIndexExpression((IndexExpression&) expr);
121 break; 124 break;
122 default: 125 default:
123 ABORT("unsupported expression: %s", expr.description().c_str()); 126 ABORT("unsupported expression: %s", expr.description().c_str());
124 } 127 }
125 } 128 }
126 129
130 static bool is_abs(Expression& expr) {
131 if (expr.fKind != Expression::kFunctionCall_Kind) {
132 return false;
133 }
134 return ((FunctionCall&) expr).fFunction.fName == "abs";
135 }
136
137 // turns min(abs(x), y) into ((tmpVar1 = abs(x)) < (tmpVar2 = y) ? tmpVar1 : tmp Var2) to avoid a
138 // Tegra3 compiler bug.
139 void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherEx pr) {
140 ASSERT(!fCaps.fCanUseMinAndAbsTogether);
141 std::string tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
142 std::string tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
143 this->fFunctionHeader += " " + absExpr.fType.name() + " " + tmpVar1 + ";\ n";
144 this->fFunctionHeader += " " + otherExpr.fType.name() + " " + tmpVar2 + " ;\n";
145 this->write("((" + tmpVar1 + " = ");
146 this->writeExpression(absExpr, kTopLevel_Precedence);
147 this->write(") < (" + tmpVar2 + " = ");
148 this->writeExpression(otherExpr, kAssignment_Precedence);
149 this->write(") ? " + tmpVar1 + " : " + tmpVar2 + ")");
150 }
151
127 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { 152 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
153 if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min") {
154 ASSERT(c.fArguments.size() == 2);
155 if (is_abs(*c.fArguments[0])) {
156 this->writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]);
157 return;
158 }
159 if (is_abs(*c.fArguments[1])) {
160 // note that this violates the GLSL left-to-right evaluation semanti cs. I doubt it will
161 // ever end up mattering, but it's worth calling out.
162 this->writeMinAbsHack(*c.fArguments[1], *c.fArguments[0]);
163 return;
164 }
165 }
128 this->write(c.fFunction.fName + "("); 166 this->write(c.fFunction.fName + "(");
129 const char* separator = ""; 167 const char* separator = "";
130 for (const auto& arg : c.fArguments) { 168 for (const auto& arg : c.fArguments) {
131 this->write(separator); 169 this->write(separator);
132 separator = ", "; 170 separator = ", ";
133 this->writeExpression(*arg, kSequence_Precedence); 171 this->writeExpression(*arg, kSequence_Precedence);
134 } 172 }
135 this->write(")"); 173 this->write(")");
136 } 174 }
137 175
138 void GLSLCodeGenerator::writeConstructor(const Constructor& c) { 176 void GLSLCodeGenerator::writeConstructor(const Constructor& c) {
139 this->write(c.fType.name() + "("); 177 this->write(c.fType.name() + "(");
140 const char* separator = ""; 178 const char* separator = "";
141 for (const auto& arg : c.fArguments) { 179 for (const auto& arg : c.fArguments) {
142 this->write(separator); 180 this->write(separator);
143 separator = ", "; 181 separator = ", ";
144 this->writeExpression(*arg, kSequence_Precedence); 182 this->writeExpression(*arg, kSequence_Precedence);
145 } 183 }
146 this->write(")"); 184 this->write(")");
147 } 185 }
148 186
149 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) { 187 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
150 this->write(ref.fVariable.fName); 188 if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN) {
189 if (fCaps.fMustDeclareFragmentShaderOutput) {
190 this->write("sk_FragColor");
191 } else {
192 this->write("gl_FragColor");
193 }
194 } else {
195 this->write(ref.fVariable.fName);
196 }
151 } 197 }
152 198
153 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) { 199 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
154 this->writeExpression(*expr.fBase, kPostfix_Precedence); 200 this->writeExpression(*expr.fBase, kPostfix_Precedence);
155 this->write("["); 201 this->write("[");
156 this->writeExpression(*expr.fIndex, kTopLevel_Precedence); 202 this->writeExpression(*expr.fIndex, kTopLevel_Precedence);
157 this->write("]"); 203 this->write("]");
158 } 204 }
159 205
160 void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) { 206 void GLSLCodeGenerator::writeFieldAccess(const FieldAccess& f) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 if (kPostfix_Precedence >= parentPrecedence) { 309 if (kPostfix_Precedence >= parentPrecedence) {
264 this->write(")"); 310 this->write(")");
265 } 311 }
266 } 312 }
267 313
268 void GLSLCodeGenerator::writeBoolLiteral(const BoolLiteral& b) { 314 void GLSLCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
269 this->write(b.fValue ? "true" : "false"); 315 this->write(b.fValue ? "true" : "false");
270 } 316 }
271 317
272 void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) { 318 void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
273 this->write(to_string(i.fValue)); 319 if (i.fType == *fContext.fUInt_Type) {
320 this->write(to_string(i.fValue & 0xffffffff) + "u");
321 } else {
322 this->write(to_string((int32_t) i.fValue));
323 }
274 } 324 }
275 325
276 void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { 326 void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
277 this->write(to_string(f.fValue)); 327 this->write(to_string(f.fValue));
278 } 328 }
279 329
280 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) { 330 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
281 this->writeType(f.fDeclaration.fReturnType); 331 this->writeType(f.fDeclaration.fReturnType);
282 this->write(" " + f.fDeclaration.fName + "("); 332 this->write(" " + f.fDeclaration.fName + "(");
283 const char* separator = ""; 333 const char* separator = "";
284 for (const auto& param : f.fDeclaration.fParameters) { 334 for (const auto& param : f.fDeclaration.fParameters) {
285 this->write(separator); 335 this->write(separator);
286 separator = ", "; 336 separator = ", ";
287 this->writeModifiers(param->fModifiers); 337 this->writeModifiers(param->fModifiers, false);
288 this->writeType(param->fType); 338 std::vector<int> sizes;
339 const Type* type = &param->fType;
340 while (type->kind() == Type::kArray_Kind) {
341 sizes.push_back(type->columns());
342 type = &type->componentType();
343 }
344 this->writeType(*type);
289 this->write(" " + param->fName); 345 this->write(" " + param->fName);
346 for (int s : sizes) {
347 if (s <= 0) {
348 this->write("[]");
349 } else {
350 this->write("[" + to_string(s) + "]");
351 }
352 }
290 } 353 }
291 this->write(") "); 354 this->writeLine(") {");
292 this->writeBlock(*f.fBody); 355
293 this->writeLine(); 356 fFunctionHeader = "";
357 std::ostream* oldOut = fOut;
358 std::stringstream buffer;
359 fOut = &buffer;
360 fIndentation++;
361 for (const auto& s : f.fBody->fStatements) {
362 this->writeStatement(*s);
363 this->writeLine();
364 }
365 fIndentation--;
366 this->writeLine("}");
367
368 fOut = oldOut;
369 this->write(fFunctionHeader);
370 this->write(buffer.str());
294 } 371 }
295 372
296 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) { 373 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
297 this->write(modifiers.description()); 374 bool globalContext) {
375 if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
376 this->write("noperspective ");
377 }
378 if (modifiers.fFlags & Modifiers::kFlat_Flag) {
379 this->write("flat ");
380 }
381 std::string layout = modifiers.fLayout.description();
382 if (layout.length()) {
383 this->write(layout + " ");
384 }
385 if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
386 (modifiers.fFlags & Modifiers::kOut_Flag)) {
387 this->write("inout ");
388 } else if (modifiers.fFlags & Modifiers::kIn_Flag) {
389 if (globalContext && fCaps.fVersion < 130) {
390 this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
391 : "varying ");
392 } else {
393 this->write("in ");
394 }
395 } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
396 if (globalContext && fCaps.fVersion < 130) {
397 this->write("varying ");
398 } else {
399 this->write("out ");
400 }
401 }
402 if (modifiers.fFlags & Modifiers::kUniform_Flag) {
403 this->write("uniform ");
404 }
405 if (modifiers.fFlags & Modifiers::kConst_Flag) {
406 this->write("const ");
407 }
408 if (fCaps.fUsesPrecisionModifiers) {
409 if (modifiers.fFlags & Modifiers::kLowp_Flag) {
410 this->write("lowp ");
411 }
412 if (modifiers.fFlags & Modifiers::kMediump_Flag) {
413 this->write("mediump ");
414 }
415 if (modifiers.fFlags & Modifiers::kHighp_Flag) {
416 this->write("highp ");
417 }
418 }
298 } 419 }
299 420
300 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { 421 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
301 if (intf.fVariable.fName == "gl_PerVertex") { 422 if (intf.fVariable.fName == "gl_PerVertex") {
302 return; 423 return;
303 } 424 }
304 this->writeModifiers(intf.fVariable.fModifiers); 425 this->writeModifiers(intf.fVariable.fModifiers, true);
305 this->writeLine(intf.fVariable.fType.name() + " {"); 426 this->writeLine(intf.fVariable.fType.name() + " {");
306 fIndentation++; 427 fIndentation++;
307 for (const auto& f : intf.fVariable.fType.fields()) { 428 for (const auto& f : intf.fVariable.fType.fields()) {
308 this->writeModifiers(f.fModifiers); 429 this->writeModifiers(f.fModifiers, false);
309 this->writeType(*f.fType); 430 this->writeType(*f.fType);
310 this->writeLine(" " + f.fName + ";"); 431 this->writeLine(" " + f.fName + ";");
311 } 432 }
312 fIndentation--; 433 fIndentation--;
313 this->writeLine("};"); 434 this->writeLine("};");
314 } 435 }
315 436
316 void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) { 437 void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g lobal) {
317 ASSERT(decl.fVars.size() > 0); 438 ASSERT(decl.fVars.size() > 0);
318 this->writeModifiers(decl.fVars[0].fVar->fModifiers); 439 this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
319 this->writeType(decl.fBaseType); 440 this->writeType(decl.fBaseType);
320 std::string separator = " "; 441 std::string separator = " ";
321 for (const auto& var : decl.fVars) { 442 for (const auto& var : decl.fVars) {
322 ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers); 443 ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
323 this->write(separator); 444 this->write(separator);
324 separator = ", "; 445 separator = ", ";
325 this->write(var.fVar->fName); 446 this->write(var.fVar->fName);
326 for (const auto& size : var.fSizes) { 447 for (const auto& size : var.fSizes) {
327 this->write("["); 448 this->write("[");
328 this->writeExpression(*size, kTopLevel_Precedence); 449 if (size) {
450 this->writeExpression(*size, kTopLevel_Precedence);
451 }
329 this->write("]"); 452 this->write("]");
330 } 453 }
331 if (var.fValue) { 454 if (var.fValue) {
332 this->write(" = "); 455 this->write(" = ");
333 this->writeExpression(*var.fValue, kTopLevel_Precedence); 456 this->writeExpression(*var.fValue, kTopLevel_Precedence);
334 } 457 }
335 } 458 }
336 this->write(";"); 459 this->write(";");
337 } 460 }
338 461
339 void GLSLCodeGenerator::writeStatement(const Statement& s) { 462 void GLSLCodeGenerator::writeStatement(const Statement& s) {
340 switch (s.fKind) { 463 switch (s.fKind) {
341 case Statement::kBlock_Kind: 464 case Statement::kBlock_Kind:
342 this->writeBlock((Block&) s); 465 this->writeBlock((Block&) s);
343 break; 466 break;
344 case Statement::kExpression_Kind: 467 case Statement::kExpression_Kind:
345 this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopL evel_Precedence); 468 this->writeExpression(*((ExpressionStatement&) s).fExpression, kTopL evel_Precedence);
346 this->write(";"); 469 this->write(";");
347 break; 470 break;
348 case Statement::kReturn_Kind: 471 case Statement::kReturn_Kind:
349 this->writeReturnStatement((ReturnStatement&) s); 472 this->writeReturnStatement((ReturnStatement&) s);
350 break; 473 break;
351 case Statement::kVarDeclarations_Kind: 474 case Statement::kVarDeclarations_Kind:
352 this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclara tion); 475 this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclara tion, false);
353 break; 476 break;
354 case Statement::kIf_Kind: 477 case Statement::kIf_Kind:
355 this->writeIfStatement((IfStatement&) s); 478 this->writeIfStatement((IfStatement&) s);
356 break; 479 break;
357 case Statement::kFor_Kind: 480 case Statement::kFor_Kind:
358 this->writeForStatement((ForStatement&) s); 481 this->writeForStatement((ForStatement&) s);
359 break; 482 break;
360 case Statement::kWhile_Kind: 483 case Statement::kWhile_Kind:
361 this->writeWhileStatement((WhileStatement&) s); 484 this->writeWhileStatement((WhileStatement&) s);
362 break; 485 break;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 if (r.fExpression) { 560 if (r.fExpression) {
438 this->write(" "); 561 this->write(" ");
439 this->writeExpression(*r.fExpression, kTopLevel_Precedence); 562 this->writeExpression(*r.fExpression, kTopLevel_Precedence);
440 } 563 }
441 this->write(";"); 564 this->write(";");
442 } 565 }
443 566
444 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) { 567 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
445 ASSERT(fOut == nullptr); 568 ASSERT(fOut == nullptr);
446 fOut = &out; 569 fOut = &out;
570 fProgramKind = program.fKind;
447 this->write("#version " + to_string(fCaps.fVersion)); 571 this->write("#version " + to_string(fCaps.fVersion));
448 if (fCaps.fStandard == GLCaps::kGLES_Standard) { 572 if (fCaps.fStandard == GLCaps::kGLES_Standard && fCaps.fVersion >= 300) {
449 this->write(" es"); 573 this->write(" es");
574 } else if (fCaps.fIsCoreProfile) {
575 this->write(" core");
450 } 576 }
451 this->writeLine(); 577 this->writeLine();
452 for (const auto& e : program.fElements) { 578 for (const auto& e : program.fElements) {
579 if (e->fKind == ProgramElement::kExtension_Kind) {
580 this->writeExtension((Extension&) *e);
581 }
582 }
583 if (fCaps.fStandard == GLCaps::kGLES_Standard) {
584 this->write("precision ");
585 switch (program.fDefaultPrecision) {
586 case Modifiers::kLowp_Flag:
587 this->write("lowp");
588 break;
589 case Modifiers::kMediump_Flag:
590 this->write("mediump");
591 break;
592 case Modifiers::kHighp_Flag:
593 this->write("highp");
594 break;
595 default:
596 ASSERT(false);
597 this->write("<error>");
598 }
599 this->writeLine(" float;");
600 }
601 for (const auto& e : program.fElements) {
453 switch (e->fKind) { 602 switch (e->fKind) {
454 case ProgramElement::kExtension_Kind: 603 case ProgramElement::kExtension_Kind:
455 this->writeExtension((Extension&) *e);
456 break; 604 break;
457 case ProgramElement::kVar_Kind: { 605 case ProgramElement::kVar_Kind: {
458 VarDeclarations& decl = (VarDeclarations&) *e; 606 VarDeclarations& decl = (VarDeclarations&) *e;
459 if (decl.fVars.size() > 0 && 607 if (decl.fVars.size() > 0) {
460 decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) { 608 int builtin = decl.fVars[0].fVar->fModifiers.fLayout.fBuilti n;
461 this->writeVarDeclarations(decl); 609 if (builtin == -1) {
462 this->writeLine(); 610 // normal var
611 this->writeVarDeclarations(decl, true);
612 this->writeLine();
613 } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
614 fCaps.fMustDeclareFragmentShaderOutput) {
615 this->write("out ");
616 if (fCaps.fUsesPrecisionModifiers) {
617 this->write("mediump ");
618 }
619 this->writeLine("vec4 sk_FragColor;");
620 }
463 } 621 }
464 break; 622 break;
465 } 623 }
466 case ProgramElement::kInterfaceBlock_Kind: 624 case ProgramElement::kInterfaceBlock_Kind:
467 this->writeInterfaceBlock((InterfaceBlock&) *e); 625 this->writeInterfaceBlock((InterfaceBlock&) *e);
468 break; 626 break;
469 case ProgramElement::kFunction_Kind: 627 case ProgramElement::kFunction_Kind:
470 this->writeFunction((FunctionDefinition&) *e); 628 this->writeFunction((FunctionDefinition&) *e);
471 break; 629 break;
630 case ProgramElement::kModifiers_Kind:
631 this->writeModifiers(((ModifiersDeclaration&) *e).fModifiers, tr ue);
632 this->writeLine(";");
633 break;
472 default: 634 default:
473 printf("%s\n", e->description().c_str()); 635 printf("%s\n", e->description().c_str());
474 ABORT("unsupported program element"); 636 ABORT("unsupported program element");
475 } 637 }
476 } 638 }
477 fOut = nullptr; 639 fOut = nullptr;
478 } 640 }
479 641
480 } 642 }
OLDNEW
« no previous file with comments | « src/sksl/SkSLGLSLCodeGenerator.h ('k') | src/sksl/SkSLIRGenerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698