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 "SkSLCompiler.h" 9 10 #include "ast/SkSLASTPrecision.h" 11 #include "SkSLCFGGenerator.h" 12 #include "SkSLGLSLCodeGenerator.h" 13 #include "SkSLIRGenerator.h" 14 #include "SkSLParser.h" 15 #include "SkSLSPIRVCodeGenerator.h" 16 #include "ir/SkSLExpression.h" 17 #include "ir/SkSLIntLiteral.h" 18 #include "ir/SkSLModifiersDeclaration.h" 19 #include "ir/SkSLSymbolTable.h" 20 #include "ir/SkSLUnresolvedFunction.h" 21 #include "ir/SkSLVarDeclarations.h" 22 #include "SkMutex.h" 23 24 #ifdef SK_ENABLE_SPIRV_VALIDATION 25 #include "spirv-tools/libspirv.hpp" 26 #endif 27 28 #define STRINGIFY(x) #x 29 30 // include the built-in shader symbols as static strings 31 32 static const char* SKSL_INCLUDE = 33 #include "sksl.include" 34 ; 35 36 static const char* SKSL_VERT_INCLUDE = 37 #include "sksl_vert.include" 38 ; 39 40 static const char* SKSL_FRAG_INCLUDE = 41 #include "sksl_frag.include" 42 ; 43 44 static const char* SKSL_GEOM_INCLUDE = 45 #include "sksl_geom.include" 46 ; 47 48 namespace SkSL { 49 50 Compiler::Compiler() 51 : fErrorCount(0) { 52 auto types = std::shared_ptr<SymbolTable>(new SymbolTable(*this)); 53 auto symbols = std::shared_ptr<SymbolTable>(new SymbolTable(types, *this)); 54 fIRGenerator = new IRGenerator(&fContext, symbols, *this); 55 fTypes = types; 56 #define ADD_TYPE(t) types->addWithoutOwnership(fContext.f ## t ## _Type->fName, \ 57 fContext.f ## t ## _Type.get()) 58 ADD_TYPE(Void); 59 ADD_TYPE(Float); 60 ADD_TYPE(Vec2); 61 ADD_TYPE(Vec3); 62 ADD_TYPE(Vec4); 63 ADD_TYPE(Double); 64 ADD_TYPE(DVec2); 65 ADD_TYPE(DVec3); 66 ADD_TYPE(DVec4); 67 ADD_TYPE(Int); 68 ADD_TYPE(IVec2); 69 ADD_TYPE(IVec3); 70 ADD_TYPE(IVec4); 71 ADD_TYPE(UInt); 72 ADD_TYPE(UVec2); 73 ADD_TYPE(UVec3); 74 ADD_TYPE(UVec4); 75 ADD_TYPE(Bool); 76 ADD_TYPE(BVec2); 77 ADD_TYPE(BVec3); 78 ADD_TYPE(BVec4); 79 ADD_TYPE(Mat2x2); 80 types->addWithoutOwnership(SkString("mat2x2"), fContext.fMat2x2_Type.get()); 81 ADD_TYPE(Mat2x3); 82 ADD_TYPE(Mat2x4); 83 ADD_TYPE(Mat3x2); 84 ADD_TYPE(Mat3x3); 85 types->addWithoutOwnership(SkString("mat3x3"), fContext.fMat3x3_Type.get()); 86 ADD_TYPE(Mat3x4); 87 ADD_TYPE(Mat4x2); 88 ADD_TYPE(Mat4x3); 89 ADD_TYPE(Mat4x4); 90 types->addWithoutOwnership(SkString("mat4x4"), fContext.fMat4x4_Type.get()); 91 ADD_TYPE(GenType); 92 ADD_TYPE(GenDType); 93 ADD_TYPE(GenIType); 94 ADD_TYPE(GenUType); 95 ADD_TYPE(GenBType); 96 ADD_TYPE(Mat); 97 ADD_TYPE(Vec); 98 ADD_TYPE(GVec); 99 ADD_TYPE(GVec2); 100 ADD_TYPE(GVec3); 101 ADD_TYPE(GVec4); 102 ADD_TYPE(DVec); 103 ADD_TYPE(IVec); 104 ADD_TYPE(UVec); 105 ADD_TYPE(BVec); 106 107 ADD_TYPE(Sampler1D); 108 ADD_TYPE(Sampler2D); 109 ADD_TYPE(Sampler3D); 110 ADD_TYPE(SamplerExternalOES); 111 ADD_TYPE(SamplerCube); 112 ADD_TYPE(Sampler2DRect); 113 ADD_TYPE(Sampler1DArray); 114 ADD_TYPE(Sampler2DArray); 115 ADD_TYPE(SamplerCubeArray); 116 ADD_TYPE(SamplerBuffer); 117 ADD_TYPE(Sampler2DMS); 118 ADD_TYPE(Sampler2DMSArray); 119 120 ADD_TYPE(ISampler2D); 121 122 ADD_TYPE(Image2D); 123 ADD_TYPE(IImage2D); 124 125 ADD_TYPE(SubpassInput); 126 ADD_TYPE(SubpassInputMS); 127 128 ADD_TYPE(GSampler1D); 129 ADD_TYPE(GSampler2D); 130 ADD_TYPE(GSampler3D); 131 ADD_TYPE(GSamplerCube); 132 ADD_TYPE(GSampler2DRect); 133 ADD_TYPE(GSampler1DArray); 134 ADD_TYPE(GSampler2DArray); 135 ADD_TYPE(GSamplerCubeArray); 136 ADD_TYPE(GSamplerBuffer); 137 ADD_TYPE(GSampler2DMS); 138 ADD_TYPE(GSampler2DMSArray); 139 140 ADD_TYPE(Sampler1DShadow); 141 ADD_TYPE(Sampler2DShadow); 142 ADD_TYPE(SamplerCubeShadow); 143 ADD_TYPE(Sampler2DRectShadow); 144 ADD_TYPE(Sampler1DArrayShadow); 145 ADD_TYPE(Sampler2DArrayShadow); 146 ADD_TYPE(SamplerCubeArrayShadow); 147 ADD_TYPE(GSampler2DArrayShadow); 148 ADD_TYPE(GSamplerCubeArrayShadow); 149 150 SkString skCapsName("sk_Caps"); 151 Variable* skCaps = new Variable(Position(), Modifiers(), skCapsName, 152 *fContext.fSkCaps_Type, Variable::kGlobal_Storage); 153 fIRGenerator->fSymbolTable->add(skCapsName, std::unique_ptr<Symbol>(skCaps)); 154 155 Modifiers::Flag ignored1; 156 std::vector<std::unique_ptr<ProgramElement>> ignored2; 157 this->internalConvertProgram(SkString(SKSL_INCLUDE), &ignored1, &ignored2); 158 fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); 159 ASSERT(!fErrorCount); 160 } 161 162 Compiler::~Compiler() { 163 delete fIRGenerator; 164 } 165 166 // add the definition created by assigning to the lvalue to the definition set 167 void Compiler::addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, 168 DefinitionMap* definitions) { 169 switch (lvalue->fKind) { 170 case Expression::kVariableReference_Kind: { 171 const Variable& var = ((VariableReference*) lvalue)->fVariable; 172 if (var.fStorage == Variable::kLocal_Storage) { 173 (*definitions)[&var] = expr; 174 } 175 break; 176 } 177 case Expression::kSwizzle_Kind: 178 // We consider the variable written to as long as at least some of its components have 179 // been written to. This will lead to some false negatives (we won't catch it if you 180 // write to foo.x and then read foo.y), but being stricter could lead to false positives 181 // (we write to foo.x, and then pass foo to a function which happens to only read foo.x, 182 // but since we pass foo as a whole it is flagged as an error) unless we perform a much 183 // more complicated whole-program analysis. This is probably good enough. 184 this->addDefinition(((Swizzle*) lvalue)->fBase.get(), 185 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 186 definitions); 187 break; 188 case Expression::kIndex_Kind: 189 // see comments in Swizzle 190 this->addDefinition(((IndexExpression*) lvalue)->fBase.get(), 191 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 192 definitions); 193 break; 194 case Expression::kFieldAccess_Kind: 195 // see comments in Swizzle 196 this->addDefinition(((FieldAccess*) lvalue)->fBase.get(), 197 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 198 definitions); 199 break; 200 default: 201 // not an lvalue, can't happen 202 ASSERT(false); 203 } 204 } 205 206 // add local variables defined by this node to the set 207 void Compiler::addDefinitions(const BasicBlock::Node& node, 208 DefinitionMap* definitions) { 209 switch (node.fKind) { 210 case BasicBlock::Node::kExpression_Kind: { 211 ASSERT(node.fExpression); 212 const Expression* expr = (Expression*) node.fExpression->get(); 213 switch (expr->fKind) { 214 case Expression::kBinary_Kind: { 215 BinaryExpression* b = (BinaryExpression*) expr; 216 if (b->fOperator == Token::EQ) { 217 this->addDefinition(b->fLeft.get(), &b->fRight, definitions); 218 } else if (Token::IsAssignment(b->fOperator)) { 219 this->addDefinition( 220 b->fLeft.get(), 221 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 222 definitions); 223 224 } 225 break; 226 } 227 case Expression::kPrefix_Kind: { 228 const PrefixExpression* p = (PrefixExpression*) expr; 229 if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { 230 this->addDefinition( 231 p->fOperand.get(), 232 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 233 definitions); 234 } 235 break; 236 } 237 case Expression::kPostfix_Kind: { 238 const PostfixExpression* p = (PostfixExpression*) expr; 239 if (p->fOperator == Token::MINUSMINUS || p->fOperator == Token::PLUSPLUS) { 240 this->addDefinition( 241 p->fOperand.get(), 242 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression, 243 definitions); 244 245 } 246 break; 247 } 248 default: 249 break; 250 } 251 break; 252 } 253 case BasicBlock::Node::kStatement_Kind: { 254 const Statement* stmt = (Statement*) node.fStatement; 255 if (stmt->fKind == Statement::kVarDeclarations_Kind) { 256 VarDeclarationsStatement* vd = (VarDeclarationsStatement*) stmt; 257 for (VarDeclaration& decl : vd->fDeclaration->fVars) { 258 if (decl.fValue) { 259 (*definitions)[decl.fVar] = &decl.fValue; 260 } 261 } 262 } 263 break; 264 } 265 } 266 } 267 268 void Compiler::scanCFG(CFG* cfg, BlockId blockId, std::set<BlockId>* workList) { 269 BasicBlock& block = cfg->fBlocks[blockId]; 270 271 // compute definitions after this block 272 DefinitionMap after = block.fBefore; 273 for (const BasicBlock::Node& n : block.fNodes) { 274 this->addDefinitions(n, &after); 275 } 276 277 // propagate definitions to exits 278 for (BlockId exitId : block.fExits) { 279 BasicBlock& exit = cfg->fBlocks[exitId]; 280 for (const auto& pair : after) { 281 std::unique_ptr<Expression>* e1 = pair.second; 282 auto found = exit.fBefore.find(pair.first); 283 if (found == exit.fBefore.end()) { 284 // exit has no definition for it, just copy it 285 workList->insert(exitId); 286 exit.fBefore[pair.first] = e1; 287 } else { 288 // exit has a (possibly different) value already defined 289 std::unique_ptr<Expression>* e2 = exit.fBefore[pair.first]; 290 if (e1 != e2) { 291 // definition has changed, merge and add exit block to worklist 292 workList->insert(exitId); 293 if (e1 && e2) { 294 exit.fBefore[pair.first] = 295 (std::unique_ptr<Expression>*) &fContext.fDefined_Expression; 296 } else { 297 exit.fBefore[pair.first] = nullptr; 298 } 299 } 300 } 301 } 302 } 303 } 304 305 // returns a map which maps all local variables in the function to null, indicating that their value 306 // is initially unknown 307 static DefinitionMap compute_start_state(const CFG& cfg) { 308 DefinitionMap result; 309 for (const auto& block : cfg.fBlocks) { 310 for (const auto& node : block.fNodes) { 311 if (node.fKind == BasicBlock::Node::kStatement_Kind) { 312 ASSERT(node.fStatement); 313 const Statement* s = node.fStatement; 314 if (s->fKind == Statement::kVarDeclarations_Kind) { 315 const VarDeclarationsStatement* vd = (const VarDeclarationsStatement*) s; 316 for (const VarDeclaration& decl : vd->fDeclaration->fVars) { 317 result[decl.fVar] = nullptr; 318 } 319 } 320 } 321 } 322 } 323 return result; 324 } 325 326 void Compiler::scanCFG(const FunctionDefinition& f) { 327 CFG cfg = CFGGenerator().getCFG(f); 328 329 // compute the data flow 330 cfg.fBlocks[cfg.fStart].fBefore = compute_start_state(cfg); 331 std::set<BlockId> workList; 332 for (BlockId i = 0; i < cfg.fBlocks.size(); i++) { 333 workList.insert(i); 334 } 335 while (workList.size()) { 336 BlockId next = *workList.begin(); 337 workList.erase(workList.begin()); 338 this->scanCFG(&cfg, next, &workList); 339 } 340 341 // check for unreachable code 342 for (size_t i = 0; i < cfg.fBlocks.size(); i++) { 343 if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() && 344 cfg.fBlocks[i].fNodes.size()) { 345 Position p; 346 switch (cfg.fBlocks[i].fNodes[0].fKind) { 347 case BasicBlock::Node::kStatement_Kind: 348 p = cfg.fBlocks[i].fNodes[0].fStatement->fPosition; 349 break; 350 case BasicBlock::Node::kExpression_Kind: 351 p = (*cfg.fBlocks[i].fNodes[0].fExpression)->fPosition; 352 break; 353 } 354 this->error(p, SkString("unreachable")); 355 } 356 } 357 if (fErrorCount) { 358 return; 359 } 360 361 // check for undefined variables, perform constant propagation 362 for (BasicBlock& b : cfg.fBlocks) { 363 DefinitionMap definitions = b.fBefore; 364 for (BasicBlock::Node& n : b.fNodes) { 365 if (n.fKind == BasicBlock::Node::kExpression_Kind) { 366 ASSERT(n.fExpression); 367 Expression* expr = n.fExpression->get(); 368 if (n.fConstantPropagation) { 369 std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, 370 definitions); 371 if (optimized) { 372 n.fExpression->reset(optimized.release()); 373 expr = n.fExpression->get(); 374 } 375 } 376 if (expr->fKind == Expression::kVariableReference_Kind) { 377 const Variable& var = ((VariableReference*) expr)->fVariable; 378 if (var.fStorage == Variable::kLocal_Storage && 379 !definitions[&var]) { 380 this->error(expr->fPosition, 381 "'" + var.fName + "' has not been assigned"); 382 } 383 } 384 } 385 this->addDefinitions(n, &definitions); 386 } 387 } 388 389 // check for missing return 390 if (f.fDeclaration.fReturnType != *fContext.fVoid_Type) { 391 if (cfg.fBlocks[cfg.fExit].fEntrances.size()) { 392 this->error(f.fPosition, SkString("function can exit without returning a value")); 393 } 394 } 395 } 396 397 void Compiler::internalConvertProgram(SkString text, 398 Modifiers::Flag* defaultPrecision, 399 std::vector<std::unique_ptr<ProgramElement>>* result) { 400 Parser parser(text, *fTypes, *this); 401 std::vector<std::unique_ptr<ASTDeclaration>> parsed = parser.file(); 402 if (fErrorCount) { 403 return; 404 } 405 *defaultPrecision = Modifiers::kHighp_Flag; 406 for (size_t i = 0; i < parsed.size(); i++) { 407 ASTDeclaration& decl = *parsed[i]; 408 switch (decl.fKind) { 409 case ASTDeclaration::kVar_Kind: { 410 std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations( 411 (ASTVarDeclarations&) decl, 412 Variable::kGlobal_Storage); 413 if (s) { 414 result->push_back(std::move(s)); 415 } 416 break; 417 } 418 case ASTDeclaration::kFunction_Kind: { 419 std::unique_ptr<FunctionDefinition> f = fIRGenerator->convertFunction( 420 (ASTFunction&) decl); 421 if (!fErrorCount && f) { 422 this->scanCFG(*f); 423 result->push_back(std::move(f)); 424 } 425 break; 426 } 427 case ASTDeclaration::kModifiers_Kind: { 428 std::unique_ptr<ModifiersDeclaration> f = fIRGenerator->convertModifiersDeclaration( 429 (ASTModifiersDeclaration&) decl); 430 if (f) { 431 result->push_back(std::move(f)); 432 } 433 break; 434 } 435 case ASTDeclaration::kInterfaceBlock_Kind: { 436 std::unique_ptr<InterfaceBlock> i = fIRGenerator->convertInterfaceBlock( 437 (ASTInterfaceBlock&) decl); 438 if (i) { 439 result->push_back(std::move(i)); 440 } 441 break; 442 } 443 case ASTDeclaration::kExtension_Kind: { 444 std::unique_ptr<Extension> e = fIRGenerator->convertExtension((ASTExtension&) decl); 445 if (e) { 446 result->push_back(std::move(e)); 447 } 448 break; 449 } 450 case ASTDeclaration::kPrecision_Kind: { 451 *defaultPrecision = ((ASTPrecision&) decl).fPrecision; 452 break; 453 } 454 default: 455 ABORT("unsupported declaration: %s\n", decl.description().c_str()); 456 } 457 } 458 } 459 460 std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, SkString text, 461 const Program::Settings& settings) { 462 fErrorText = ""; 463 fErrorCount = 0; 464 fIRGenerator->start(&settings); 465 std::vector<std::unique_ptr<ProgramElement>> elements; 466 Modifiers::Flag ignored; 467 switch (kind) { 468 case Program::kVertex_Kind: 469 this->internalConvertProgram(SkString(SKSL_VERT_INCLUDE), &ignored, &elements); 470 break; 471 case Program::kFragment_Kind: 472 this->internalConvertProgram(SkString(SKSL_FRAG_INCLUDE), &ignored, &elements); 473 break; 474 case Program::kGeometry_Kind: 475 this->internalConvertProgram(SkString(SKSL_GEOM_INCLUDE), &ignored, &elements); 476 break; 477 } 478 fIRGenerator->fSymbolTable->markAllFunctionsBuiltin(); 479 Modifiers::Flag defaultPrecision; 480 this->internalConvertProgram(text, &defaultPrecision, &elements); 481 auto result = std::unique_ptr<Program>(new Program(kind, settings, defaultPrecision, &fContext, 482 std::move(elements), 483 fIRGenerator->fSymbolTable, 484 fIRGenerator->fInputs)); 485 fIRGenerator->finish(); 486 this->writeErrorCount(); 487 if (fErrorCount) { 488 return nullptr; 489 } 490 return result; 491 } 492 493 bool Compiler::toSPIRV(const Program& program, SkWStream& out) { 494 #ifdef SK_ENABLE_SPIRV_VALIDATION 495 SkDynamicMemoryWStream buffer; 496 SPIRVCodeGenerator cg(&fContext, &program, this, &buffer); 497 bool result = cg.generateCode(); 498 if (result) { 499 sk_sp<SkData> data(buffer.detachAsData()); 500 spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); 501 SkASSERT(0 == data->size() % 4); 502 auto dumpmsg = [](spv_message_level_t, const char*, const spv_position_t&, const char* m) { 503 SkDebugf("SPIR-V validation error: %s\n", m); 504 }; 505 tools.SetMessageConsumer(dumpmsg); 506 // Verify that the SPIR-V we produced is valid. If this assert fails, check the logs prior 507 // to the failure to see the validation errors. 508 SkAssertResult(tools.Validate((const uint32_t*) data->data(), data->size() / 4)); 509 out.write(data->data(), data->size()); 510 } 511 #else 512 SPIRVCodeGenerator cg(&fContext, &program, this, &out); 513 bool result = cg.generateCode(); 514 #endif 515 this->writeErrorCount(); 516 return result; 517 } 518 519 bool Compiler::toSPIRV(const Program& program, SkString* out) { 520 SkDynamicMemoryWStream buffer; 521 bool result = this->toSPIRV(program, buffer); 522 if (result) { 523 sk_sp<SkData> data(buffer.detachAsData()); 524 *out = SkString((const char*) data->data(), data->size()); 525 } 526 return result; 527 } 528 529 bool Compiler::toGLSL(const Program& program, SkWStream& out) { 530 GLSLCodeGenerator cg(&fContext, &program, this, &out); 531 bool result = cg.generateCode(); 532 this->writeErrorCount(); 533 return result; 534 } 535 536 bool Compiler::toGLSL(const Program& program, SkString* out) { 537 SkDynamicMemoryWStream buffer; 538 bool result = this->toGLSL(program, buffer); 539 if (result) { 540 sk_sp<SkData> data(buffer.detachAsData()); 541 *out = SkString((const char*) data->data(), data->size()); 542 } 543 return result; 544 } 545 546 547 void Compiler::error(Position position, SkString msg) { 548 fErrorCount++; 549 fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n"; 550 } 551 552 SkString Compiler::errorText() { 553 SkString result = fErrorText; 554 return result; 555 } 556 557 void Compiler::writeErrorCount() { 558 if (fErrorCount) { 559 fErrorText += to_string(fErrorCount) + " error"; 560 if (fErrorCount > 1) { 561 fErrorText += "s"; 562 } 563 fErrorText += "\n"; 564 } 565 } 566 567 } // namespace 568