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

Side by Side Diff: src/sksl/SkSLSPIRVCodeGenerator.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/SkSLSPIRVCodeGenerator.h ('k') | src/sksl/SkSLToken.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 "SkSLSPIRVCodeGenerator.h" 8 #include "SkSLSPIRVCodeGenerator.h"
9 9
10 #include "string.h" 10 #include "string.h"
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 if (entry == fTypeMap.end()) { 1144 if (entry == fTypeMap.end()) {
1145 SpvId result = this->nextId(); 1145 SpvId result = this->nextId();
1146 this->writeInstruction(SpvOpTypePointer, result, storageClass, 1146 this->writeInstruction(SpvOpTypePointer, result, storageClass,
1147 this->getType(type), fConstantBuffer); 1147 this->getType(type), fConstantBuffer);
1148 fTypeMap[key] = result; 1148 fTypeMap[key] = result;
1149 return result; 1149 return result;
1150 } 1150 }
1151 return entry->second; 1151 return entry->second;
1152 } 1152 }
1153 1153
1154 SpvId SPIRVCodeGenerator::writeExpression(Expression& expr, std::ostream& out) { 1154 SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, std::ostream& out) {
1155 switch (expr.fKind) { 1155 switch (expr.fKind) {
1156 case Expression::kBinary_Kind: 1156 case Expression::kBinary_Kind:
1157 return this->writeBinaryExpression((BinaryExpression&) expr, out); 1157 return this->writeBinaryExpression((BinaryExpression&) expr, out);
1158 case Expression::kBoolLiteral_Kind: 1158 case Expression::kBoolLiteral_Kind:
1159 return this->writeBoolLiteral((BoolLiteral&) expr); 1159 return this->writeBoolLiteral((BoolLiteral&) expr);
1160 case Expression::kConstructor_Kind: 1160 case Expression::kConstructor_Kind:
1161 return this->writeConstructor((Constructor&) expr, out); 1161 return this->writeConstructor((Constructor&) expr, out);
1162 case Expression::kIntLiteral_Kind: 1162 case Expression::kIntLiteral_Kind:
1163 return this->writeIntLiteral((IntLiteral&) expr); 1163 return this->writeIntLiteral((IntLiteral&) expr);
1164 case Expression::kFieldAccess_Kind: 1164 case Expression::kFieldAccess_Kind:
(...skipping 13 matching lines...) Expand all
1178 case Expression::kTernary_Kind: 1178 case Expression::kTernary_Kind:
1179 return this->writeTernaryExpression((TernaryExpression&) expr, out); 1179 return this->writeTernaryExpression((TernaryExpression&) expr, out);
1180 case Expression::kIndex_Kind: 1180 case Expression::kIndex_Kind:
1181 return this->writeIndexExpression((IndexExpression&) expr, out); 1181 return this->writeIndexExpression((IndexExpression&) expr, out);
1182 default: 1182 default:
1183 ABORT("unsupported expression: %s", expr.description().c_str()); 1183 ABORT("unsupported expression: %s", expr.description().c_str());
1184 } 1184 }
1185 return -1; 1185 return -1;
1186 } 1186 }
1187 1187
1188 SpvId SPIRVCodeGenerator::writeIntrinsicCall(FunctionCall& c, std::ostream& out) { 1188 SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, std::ostream & out) {
1189 auto intrinsic = fIntrinsicMap.find(c.fFunction.fName); 1189 auto intrinsic = fIntrinsicMap.find(c.fFunction.fName);
1190 ASSERT(intrinsic != fIntrinsicMap.end()); 1190 ASSERT(intrinsic != fIntrinsicMap.end());
1191 const Type& type = c.fArguments[0]->fType; 1191 const Type& type = c.fArguments[0]->fType;
1192 int32_t intrinsicId; 1192 int32_t intrinsicId;
1193 if (std::get<0>(intrinsic->second) == kSpecial_IntrinsicKind || is_float(fCo ntext, type)) { 1193 if (std::get<0>(intrinsic->second) == kSpecial_IntrinsicKind || is_float(fCo ntext, type)) {
1194 intrinsicId = std::get<1>(intrinsic->second); 1194 intrinsicId = std::get<1>(intrinsic->second);
1195 } else if (is_signed(fContext, type)) { 1195 } else if (is_signed(fContext, type)) {
1196 intrinsicId = std::get<2>(intrinsic->second); 1196 intrinsicId = std::get<2>(intrinsic->second);
1197 } else if (is_unsigned(fContext, type)) { 1197 } else if (is_unsigned(fContext, type)) {
1198 intrinsicId = std::get<3>(intrinsic->second); 1198 intrinsicId = std::get<3>(intrinsic->second);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 } 1233 }
1234 return result; 1234 return result;
1235 } 1235 }
1236 case kSpecial_IntrinsicKind: 1236 case kSpecial_IntrinsicKind:
1237 return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId , out); 1237 return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId , out);
1238 default: 1238 default:
1239 ABORT("unsupported intrinsic kind"); 1239 ABORT("unsupported intrinsic kind");
1240 } 1240 }
1241 } 1241 }
1242 1242
1243 SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsi c kind, 1243 SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn trinsic kind,
1244 std::ostream& out) { 1244 std::ostream& out) {
1245 SpvId result = this->nextId(); 1245 SpvId result = this->nextId();
1246 switch (kind) { 1246 switch (kind) {
1247 case kAtan_SpecialIntrinsic: { 1247 case kAtan_SpecialIntrinsic: {
1248 std::vector<SpvId> arguments; 1248 std::vector<SpvId> arguments;
1249 for (size_t i = 0; i < c.fArguments.size(); i++) { 1249 for (size_t i = 0; i < c.fArguments.size(); i++) {
1250 arguments.push_back(this->writeExpression(*c.fArguments[i], out) ); 1250 arguments.push_back(this->writeExpression(*c.fArguments[i], out) );
1251 } 1251 }
1252 this->writeOpCode(SpvOpExtInst, 5 + (int32_t) arguments.size(), out) ; 1252 this->writeOpCode(SpvOpExtInst, 5 + (int32_t) arguments.size(), out) ;
1253 this->writeWord(this->getType(c.fType), out); 1253 this->writeWord(this->getType(c.fType), out);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 result, 1298 result,
1299 img, 1299 img,
1300 coords, 1300 coords,
1301 out); 1301 out);
1302 break; 1302 break;
1303 } 1303 }
1304 } 1304 }
1305 return result; 1305 return result;
1306 } 1306 }
1307 1307
1308 SpvId SPIRVCodeGenerator::writeFunctionCall(FunctionCall& c, std::ostream& out) { 1308 SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, std::ostream& out) {
1309 const auto& entry = fFunctionMap.find(&c.fFunction); 1309 const auto& entry = fFunctionMap.find(&c.fFunction);
1310 if (entry == fFunctionMap.end()) { 1310 if (entry == fFunctionMap.end()) {
1311 return this->writeIntrinsicCall(c, out); 1311 return this->writeIntrinsicCall(c, out);
1312 } 1312 }
1313 // stores (variable, type, lvalue) pairs to extract and save after the funct ion call is complete 1313 // stores (variable, type, lvalue) pairs to extract and save after the funct ion call is complete
1314 std::vector<std::tuple<SpvId, SpvId, std::unique_ptr<LValue>>> lvalues; 1314 std::vector<std::tuple<SpvId, SpvId, std::unique_ptr<LValue>>> lvalues;
1315 std::vector<SpvId> arguments; 1315 std::vector<SpvId> arguments;
1316 for (size_t i = 0; i < c.fArguments.size(); i++) { 1316 for (size_t i = 0; i < c.fArguments.size(); i++) {
1317 // id of temporary variable that we will use to hold this argument, or 0 if it is being 1317 // id of temporary variable that we will use to hold this argument, or 0 if it is being
1318 // passed directly 1318 // passed directly
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 // now that the call is complete, we may need to update some lvalues with th e new values of out 1359 // now that the call is complete, we may need to update some lvalues with th e new values of out
1360 // arguments 1360 // arguments
1361 for (const auto& tuple : lvalues) { 1361 for (const auto& tuple : lvalues) {
1362 SpvId load = this->nextId(); 1362 SpvId load = this->nextId();
1363 this->writeInstruction(SpvOpLoad, std::get<1>(tuple), load, std::get<0>( tuple), out); 1363 this->writeInstruction(SpvOpLoad, std::get<1>(tuple), load, std::get<0>( tuple), out);
1364 std::get<2>(tuple)->store(load, out); 1364 std::get<2>(tuple)->store(load, out);
1365 } 1365 }
1366 return result; 1366 return result;
1367 } 1367 }
1368 1368
1369 SpvId SPIRVCodeGenerator::writeConstantVector(Constructor& c) { 1369 SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) {
1370 ASSERT(c.fType.kind() == Type::kVector_Kind && c.isConstant()); 1370 ASSERT(c.fType.kind() == Type::kVector_Kind && c.isConstant());
1371 SpvId result = this->nextId(); 1371 SpvId result = this->nextId();
1372 std::vector<SpvId> arguments; 1372 std::vector<SpvId> arguments;
1373 for (size_t i = 0; i < c.fArguments.size(); i++) { 1373 for (size_t i = 0; i < c.fArguments.size(); i++) {
1374 arguments.push_back(this->writeExpression(*c.fArguments[i], fConstantBuf fer)); 1374 arguments.push_back(this->writeExpression(*c.fArguments[i], fConstantBuf fer));
1375 } 1375 }
1376 SpvId type = this->getType(c.fType); 1376 SpvId type = this->getType(c.fType);
1377 if (c.fArguments.size() == 1) { 1377 if (c.fArguments.size() == 1) {
1378 // with a single argument, a vector will have all of its entries equal t o the argument 1378 // with a single argument, a vector will have all of its entries equal t o the argument
1379 this->writeOpCode(SpvOpConstantComposite, 3 + c.fType.columns(), fConsta ntBuffer); 1379 this->writeOpCode(SpvOpConstantComposite, 3 + c.fType.columns(), fConsta ntBuffer);
1380 this->writeWord(type, fConstantBuffer); 1380 this->writeWord(type, fConstantBuffer);
1381 this->writeWord(result, fConstantBuffer); 1381 this->writeWord(result, fConstantBuffer);
1382 for (int i = 0; i < c.fType.columns(); i++) { 1382 for (int i = 0; i < c.fType.columns(); i++) {
1383 this->writeWord(arguments[0], fConstantBuffer); 1383 this->writeWord(arguments[0], fConstantBuffer);
1384 } 1384 }
1385 } else { 1385 } else {
1386 this->writeOpCode(SpvOpConstantComposite, 3 + (int32_t) c.fArguments.siz e(), 1386 this->writeOpCode(SpvOpConstantComposite, 3 + (int32_t) c.fArguments.siz e(),
1387 fConstantBuffer); 1387 fConstantBuffer);
1388 this->writeWord(type, fConstantBuffer); 1388 this->writeWord(type, fConstantBuffer);
1389 this->writeWord(result, fConstantBuffer); 1389 this->writeWord(result, fConstantBuffer);
1390 for (SpvId id : arguments) { 1390 for (SpvId id : arguments) {
1391 this->writeWord(id, fConstantBuffer); 1391 this->writeWord(id, fConstantBuffer);
1392 } 1392 }
1393 } 1393 }
1394 return result; 1394 return result;
1395 } 1395 }
1396 1396
1397 SpvId SPIRVCodeGenerator::writeFloatConstructor(Constructor& c, std::ostream& ou t) { 1397 SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, std::ostre am& out) {
1398 ASSERT(c.fType == *fContext.fFloat_Type); 1398 ASSERT(c.fType == *fContext.fFloat_Type);
1399 ASSERT(c.fArguments.size() == 1); 1399 ASSERT(c.fArguments.size() == 1);
1400 ASSERT(c.fArguments[0]->fType.isNumber()); 1400 ASSERT(c.fArguments[0]->fType.isNumber());
1401 SpvId result = this->nextId(); 1401 SpvId result = this->nextId();
1402 SpvId parameter = this->writeExpression(*c.fArguments[0], out); 1402 SpvId parameter = this->writeExpression(*c.fArguments[0], out);
1403 if (c.fArguments[0]->fType == *fContext.fInt_Type) { 1403 if (c.fArguments[0]->fType == *fContext.fInt_Type) {
1404 this->writeInstruction(SpvOpConvertSToF, this->getType(c.fType), result, parameter, 1404 this->writeInstruction(SpvOpConvertSToF, this->getType(c.fType), result, parameter,
1405 out); 1405 out);
1406 } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) { 1406 } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) {
1407 this->writeInstruction(SpvOpConvertUToF, this->getType(c.fType), result, parameter, 1407 this->writeInstruction(SpvOpConvertUToF, this->getType(c.fType), result, parameter,
1408 out); 1408 out);
1409 } else if (c.fArguments[0]->fType == *fContext.fFloat_Type) { 1409 } else if (c.fArguments[0]->fType == *fContext.fFloat_Type) {
1410 return parameter; 1410 return parameter;
1411 } 1411 }
1412 return result; 1412 return result;
1413 } 1413 }
1414 1414
1415 SpvId SPIRVCodeGenerator::writeIntConstructor(Constructor& c, std::ostream& out) { 1415 SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, std::ostream & out) {
1416 ASSERT(c.fType == *fContext.fInt_Type); 1416 ASSERT(c.fType == *fContext.fInt_Type);
1417 ASSERT(c.fArguments.size() == 1); 1417 ASSERT(c.fArguments.size() == 1);
1418 ASSERT(c.fArguments[0]->fType.isNumber()); 1418 ASSERT(c.fArguments[0]->fType.isNumber());
1419 SpvId result = this->nextId(); 1419 SpvId result = this->nextId();
1420 SpvId parameter = this->writeExpression(*c.fArguments[0], out); 1420 SpvId parameter = this->writeExpression(*c.fArguments[0], out);
1421 if (c.fArguments[0]->fType == *fContext.fFloat_Type) { 1421 if (c.fArguments[0]->fType == *fContext.fFloat_Type) {
1422 this->writeInstruction(SpvOpConvertFToS, this->getType(c.fType), result, parameter, 1422 this->writeInstruction(SpvOpConvertFToS, this->getType(c.fType), result, parameter,
1423 out); 1423 out);
1424 } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) { 1424 } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) {
1425 this->writeInstruction(SpvOpSatConvertUToS, this->getType(c.fType), resu lt, parameter, 1425 this->writeInstruction(SpvOpSatConvertUToS, this->getType(c.fType), resu lt, parameter,
1426 out); 1426 out);
1427 } else if (c.fArguments[0]->fType == *fContext.fInt_Type) { 1427 } else if (c.fArguments[0]->fType == *fContext.fInt_Type) {
1428 return parameter; 1428 return parameter;
1429 } 1429 }
1430 return result; 1430 return result;
1431 } 1431 }
1432 1432
1433 SpvId SPIRVCodeGenerator::writeMatrixConstructor(Constructor& c, std::ostream& o ut) { 1433 SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, std::ostr eam& out) {
1434 ASSERT(c.fType.kind() == Type::kMatrix_Kind); 1434 ASSERT(c.fType.kind() == Type::kMatrix_Kind);
1435 // go ahead and write the arguments so we don't try to write new instruction s in the middle of 1435 // go ahead and write the arguments so we don't try to write new instruction s in the middle of
1436 // an instruction 1436 // an instruction
1437 std::vector<SpvId> arguments; 1437 std::vector<SpvId> arguments;
1438 for (size_t i = 0; i < c.fArguments.size(); i++) { 1438 for (size_t i = 0; i < c.fArguments.size(); i++) {
1439 arguments.push_back(this->writeExpression(*c.fArguments[i], out)); 1439 arguments.push_back(this->writeExpression(*c.fArguments[i], out));
1440 } 1440 }
1441 SpvId result = this->nextId(); 1441 SpvId result = this->nextId();
1442 int rows = c.fType.rows(); 1442 int rows = c.fType.rows();
1443 int columns = c.fType.columns(); 1443 int columns = c.fType.columns();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 this->writeOpCode(SpvOpCompositeConstruct, 3 + columns, out); 1495 this->writeOpCode(SpvOpCompositeConstruct, 3 + columns, out);
1496 this->writeWord(this->getType(c.fType), out); 1496 this->writeWord(this->getType(c.fType), out);
1497 this->writeWord(result, out); 1497 this->writeWord(result, out);
1498 for (SpvId id : columnIds) { 1498 for (SpvId id : columnIds) {
1499 this->writeWord(id, out); 1499 this->writeWord(id, out);
1500 } 1500 }
1501 } 1501 }
1502 return result; 1502 return result;
1503 } 1503 }
1504 1504
1505 SpvId SPIRVCodeGenerator::writeVectorConstructor(Constructor& c, std::ostream& o ut) { 1505 SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, std::ostr eam& out) {
1506 ASSERT(c.fType.kind() == Type::kVector_Kind); 1506 ASSERT(c.fType.kind() == Type::kVector_Kind);
1507 if (c.isConstant()) { 1507 if (c.isConstant()) {
1508 return this->writeConstantVector(c); 1508 return this->writeConstantVector(c);
1509 } 1509 }
1510 // go ahead and write the arguments so we don't try to write new instruction s in the middle of 1510 // go ahead and write the arguments so we don't try to write new instruction s in the middle of
1511 // an instruction 1511 // an instruction
1512 std::vector<SpvId> arguments; 1512 std::vector<SpvId> arguments;
1513 for (size_t i = 0; i < c.fArguments.size(); i++) { 1513 for (size_t i = 0; i < c.fArguments.size(); i++) {
1514 arguments.push_back(this->writeExpression(*c.fArguments[i], out)); 1514 arguments.push_back(this->writeExpression(*c.fArguments[i], out));
1515 } 1515 }
1516 SpvId result = this->nextId(); 1516 SpvId result = this->nextId();
1517 if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kScalar_ Kind) { 1517 if (arguments.size() == 1 && c.fArguments[0]->fType.kind() == Type::kScalar_ Kind) {
1518 this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.columns(), out); 1518 this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.columns(), out);
1519 this->writeWord(this->getType(c.fType), out); 1519 this->writeWord(this->getType(c.fType), out);
1520 this->writeWord(result, out); 1520 this->writeWord(result, out);
1521 for (int i = 0; i < c.fType.columns(); i++) { 1521 for (int i = 0; i < c.fType.columns(); i++) {
1522 this->writeWord(arguments[0], out); 1522 this->writeWord(arguments[0], out);
1523 } 1523 }
1524 } else { 1524 } else {
1525 this->writeOpCode(SpvOpCompositeConstruct, 3 + (int32_t) c.fArguments.si ze(), out); 1525 this->writeOpCode(SpvOpCompositeConstruct, 3 + (int32_t) c.fArguments.si ze(), out);
1526 this->writeWord(this->getType(c.fType), out); 1526 this->writeWord(this->getType(c.fType), out);
1527 this->writeWord(result, out); 1527 this->writeWord(result, out);
1528 for (SpvId id : arguments) { 1528 for (SpvId id : arguments) {
1529 this->writeWord(id, out); 1529 this->writeWord(id, out);
1530 } 1530 }
1531 } 1531 }
1532 return result; 1532 return result;
1533 } 1533 }
1534 1534
1535 SpvId SPIRVCodeGenerator::writeConstructor(Constructor& c, std::ostream& out) { 1535 SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, std::ostream& o ut) {
1536 if (c.fType == *fContext.fFloat_Type) { 1536 if (c.fType == *fContext.fFloat_Type) {
1537 return this->writeFloatConstructor(c, out); 1537 return this->writeFloatConstructor(c, out);
1538 } else if (c.fType == *fContext.fInt_Type) { 1538 } else if (c.fType == *fContext.fInt_Type) {
1539 return this->writeIntConstructor(c, out); 1539 return this->writeIntConstructor(c, out);
1540 } 1540 }
1541 switch (c.fType.kind()) { 1541 switch (c.fType.kind()) {
1542 case Type::kVector_Kind: 1542 case Type::kVector_Kind:
1543 return this->writeVectorConstructor(c, out); 1543 return this->writeVectorConstructor(c, out);
1544 case Type::kMatrix_Kind: 1544 case Type::kMatrix_Kind:
1545 return this->writeMatrixConstructor(c, out); 1545 return this->writeMatrixConstructor(c, out);
1546 default: 1546 default:
1547 ABORT("unsupported constructor: %s", c.description().c_str()); 1547 ABORT("unsupported constructor: %s", c.description().c_str());
1548 } 1548 }
1549 } 1549 }
1550 1550
1551 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) { 1551 SpvStorageClass_ get_storage_class(const Modifiers& modifiers) {
1552 if (modifiers.fFlags & Modifiers::kIn_Flag) { 1552 if (modifiers.fFlags & Modifiers::kIn_Flag) {
1553 return SpvStorageClassInput; 1553 return SpvStorageClassInput;
1554 } else if (modifiers.fFlags & Modifiers::kOut_Flag) { 1554 } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
1555 return SpvStorageClassOutput; 1555 return SpvStorageClassOutput;
1556 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) { 1556 } else if (modifiers.fFlags & Modifiers::kUniform_Flag) {
1557 return SpvStorageClassUniform; 1557 return SpvStorageClassUniform;
1558 } else { 1558 } else {
1559 return SpvStorageClassFunction; 1559 return SpvStorageClassFunction;
1560 } 1560 }
1561 } 1561 }
1562 1562
1563 SpvStorageClass_ get_storage_class(Expression& expr) { 1563 SpvStorageClass_ get_storage_class(const Expression& expr) {
1564 switch (expr.fKind) { 1564 switch (expr.fKind) {
1565 case Expression::kVariableReference_Kind: 1565 case Expression::kVariableReference_Kind:
1566 return get_storage_class(((VariableReference&) expr).fVariable.fModi fiers); 1566 return get_storage_class(((VariableReference&) expr).fVariable.fModi fiers);
1567 case Expression::kFieldAccess_Kind: 1567 case Expression::kFieldAccess_Kind:
1568 return get_storage_class(*((FieldAccess&) expr).fBase); 1568 return get_storage_class(*((FieldAccess&) expr).fBase);
1569 case Expression::kIndex_Kind: 1569 case Expression::kIndex_Kind:
1570 return get_storage_class(*((IndexExpression&) expr).fBase); 1570 return get_storage_class(*((IndexExpression&) expr).fBase);
1571 default: 1571 default:
1572 return SpvStorageClassFunction; 1572 return SpvStorageClassFunction;
1573 } 1573 }
1574 } 1574 }
1575 1575
1576 std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(Expression& expr, std::ost ream& out) { 1576 std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, st d::ostream& out) {
1577 std::vector<SpvId> chain; 1577 std::vector<SpvId> chain;
1578 switch (expr.fKind) { 1578 switch (expr.fKind) {
1579 case Expression::kIndex_Kind: { 1579 case Expression::kIndex_Kind: {
1580 IndexExpression& indexExpr = (IndexExpression&) expr; 1580 IndexExpression& indexExpr = (IndexExpression&) expr;
1581 chain = this->getAccessChain(*indexExpr.fBase, out); 1581 chain = this->getAccessChain(*indexExpr.fBase, out);
1582 chain.push_back(this->writeExpression(*indexExpr.fIndex, out)); 1582 chain.push_back(this->writeExpression(*indexExpr.fIndex, out));
1583 break; 1583 break;
1584 } 1584 }
1585 case Expression::kFieldAccess_Kind: { 1585 case Expression::kFieldAccess_Kind: {
1586 FieldAccess& fieldExpr = (FieldAccess&) expr; 1586 FieldAccess& fieldExpr = (FieldAccess&) expr;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 } 1690 }
1691 1691
1692 private: 1692 private:
1693 SPIRVCodeGenerator& fGen; 1693 SPIRVCodeGenerator& fGen;
1694 const SpvId fVecPointer; 1694 const SpvId fVecPointer;
1695 const std::vector<int>& fComponents; 1695 const std::vector<int>& fComponents;
1696 const Type& fBaseType; 1696 const Type& fBaseType;
1697 const Type& fSwizzleType; 1697 const Type& fSwizzleType;
1698 }; 1698 };
1699 1699
1700 std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(Expres sion& expr, 1700 std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr,
1701 std::o stream& out) { 1701 std::o stream& out) {
1702 switch (expr.fKind) { 1702 switch (expr.fKind) {
1703 case Expression::kVariableReference_Kind: { 1703 case Expression::kVariableReference_Kind: {
1704 const Variable& var = ((VariableReference&) expr).fVariable; 1704 const Variable& var = ((VariableReference&) expr).fVariable;
1705 auto entry = fVariableMap.find(&var); 1705 auto entry = fVariableMap.find(&var);
1706 ASSERT(entry != fVariableMap.end()); 1706 ASSERT(entry != fVariableMap.end());
1707 return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue ( 1707 return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue (
1708 *this, 1708 *this,
1709 entry->se cond, 1709 entry->se cond,
1710 this->get Type(expr.fType))); 1710 this->get Type(expr.fType)));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 this->writeInstruction(SpvOpVariable, type, result, SpvStorageClassF unction, 1764 this->writeInstruction(SpvOpVariable, type, result, SpvStorageClassF unction,
1765 fVariableBuffer); 1765 fVariableBuffer);
1766 this->writeInstruction(SpvOpStore, result, this->writeExpression(exp r, out), out); 1766 this->writeInstruction(SpvOpStore, result, this->writeExpression(exp r, out), out);
1767 return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue ( 1767 return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue (
1768 *this, 1768 *this,
1769 result, 1769 result,
1770 this->get Type(expr.fType))); 1770 this->get Type(expr.fType)));
1771 } 1771 }
1772 } 1772 }
1773 1773
1774 SpvId SPIRVCodeGenerator::writeVariableReference(VariableReference& ref, std::os tream& out) { 1774 SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, s td::ostream& out) {
1775 auto entry = fVariableMap.find(&ref.fVariable); 1775 auto entry = fVariableMap.find(&ref.fVariable);
1776 ASSERT(entry != fVariableMap.end()); 1776 ASSERT(entry != fVariableMap.end());
1777 SpvId var = entry->second; 1777 SpvId var = entry->second;
1778 SpvId result = this->nextId(); 1778 SpvId result = this->nextId();
1779 this->writeInstruction(SpvOpLoad, this->getType(ref.fVariable.fType), result , var, out); 1779 this->writeInstruction(SpvOpLoad, this->getType(ref.fVariable.fType), result , var, out);
1780 return result; 1780 return result;
1781 } 1781 }
1782 1782
1783 SpvId SPIRVCodeGenerator::writeIndexExpression(IndexExpression& expr, std::ostre am& out) { 1783 SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, std: :ostream& out) {
1784 return getLValue(expr, out)->load(out); 1784 return getLValue(expr, out)->load(out);
1785 } 1785 }
1786 1786
1787 SpvId SPIRVCodeGenerator::writeFieldAccess(FieldAccess& f, std::ostream& out) { 1787 SpvId SPIRVCodeGenerator::writeFieldAccess(const FieldAccess& f, std::ostream& o ut) {
1788 return getLValue(f, out)->load(out); 1788 return getLValue(f, out)->load(out);
1789 } 1789 }
1790 1790
1791 SpvId SPIRVCodeGenerator::writeSwizzle(Swizzle& swizzle, std::ostream& out) { 1791 SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, std::ostream& out ) {
1792 SpvId base = this->writeExpression(*swizzle.fBase, out); 1792 SpvId base = this->writeExpression(*swizzle.fBase, out);
1793 SpvId result = this->nextId(); 1793 SpvId result = this->nextId();
1794 size_t count = swizzle.fComponents.size(); 1794 size_t count = swizzle.fComponents.size();
1795 if (count == 1) { 1795 if (count == 1) {
1796 this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.fTyp e), result, base, 1796 this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.fTyp e), result, base,
1797 swizzle.fComponents[0], out); 1797 swizzle.fComponents[0], out);
1798 } else { 1798 } else {
1799 this->writeOpCode(SpvOpVectorShuffle, 5 + (int32_t) count, out); 1799 this->writeOpCode(SpvOpVectorShuffle, 5 + (int32_t) count, out);
1800 this->writeWord(this->getType(swizzle.fType), out); 1800 this->writeWord(this->getType(swizzle.fType), out);
1801 this->writeWord(result, out); 1801 this->writeWord(result, out);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 case Token::BITWISEANDEQ: // fall through 1842 case Token::BITWISEANDEQ: // fall through
1843 case Token::LOGICALOREQ: // fall through 1843 case Token::LOGICALOREQ: // fall through
1844 case Token::LOGICALXOREQ: // fall through 1844 case Token::LOGICALXOREQ: // fall through
1845 case Token::LOGICALANDEQ: 1845 case Token::LOGICALANDEQ:
1846 return true; 1846 return true;
1847 default: 1847 default:
1848 return false; 1848 return false;
1849 } 1849 }
1850 } 1850 }
1851 1851
1852 SpvId SPIRVCodeGenerator::writeBinaryExpression(BinaryExpression& b, std::ostrea m& out) { 1852 SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, std:: ostream& out) {
1853 // handle cases where we don't necessarily evaluate both LHS and RHS 1853 // handle cases where we don't necessarily evaluate both LHS and RHS
1854 switch (b.fOperator) { 1854 switch (b.fOperator) {
1855 case Token::EQ: { 1855 case Token::EQ: {
1856 SpvId rhs = this->writeExpression(*b.fRight, out); 1856 SpvId rhs = this->writeExpression(*b.fRight, out);
1857 this->getLValue(*b.fLeft, out)->store(rhs, out); 1857 this->getLValue(*b.fLeft, out)->store(rhs, out);
1858 return rhs; 1858 return rhs;
1859 } 1859 }
1860 case Token::LOGICALAND: 1860 case Token::LOGICALAND:
1861 return this->writeLogicalAnd(b, out); 1861 return this->writeLogicalAnd(b, out);
1862 case Token::LOGICALOR: 1862 case Token::LOGICALOR:
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 ASSERT(lvalue); 2034 ASSERT(lvalue);
2035 lvalue->store(result, out); 2035 lvalue->store(result, out);
2036 return result; 2036 return result;
2037 } 2037 }
2038 default: 2038 default:
2039 // FIXME: missing support for some operators (bitwise, &&=, ||=, shi ft...) 2039 // FIXME: missing support for some operators (bitwise, &&=, ||=, shi ft...)
2040 ABORT("unsupported binary expression: %s", b.description().c_str()); 2040 ABORT("unsupported binary expression: %s", b.description().c_str());
2041 } 2041 }
2042 } 2042 }
2043 2043
2044 SpvId SPIRVCodeGenerator::writeLogicalAnd(BinaryExpression& a, std::ostream& out ) { 2044 SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, std::ostrea m& out) {
2045 ASSERT(a.fOperator == Token::LOGICALAND); 2045 ASSERT(a.fOperator == Token::LOGICALAND);
2046 BoolLiteral falseLiteral(fContext, Position(), false); 2046 BoolLiteral falseLiteral(fContext, Position(), false);
2047 SpvId falseConstant = this->writeBoolLiteral(falseLiteral); 2047 SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
2048 SpvId lhs = this->writeExpression(*a.fLeft, out); 2048 SpvId lhs = this->writeExpression(*a.fLeft, out);
2049 SpvId rhsLabel = this->nextId(); 2049 SpvId rhsLabel = this->nextId();
2050 SpvId end = this->nextId(); 2050 SpvId end = this->nextId();
2051 SpvId lhsBlock = fCurrentBlock; 2051 SpvId lhsBlock = fCurrentBlock;
2052 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone , out); 2052 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone , out);
2053 this->writeInstruction(SpvOpBranchConditional, lhs, rhsLabel, end, out); 2053 this->writeInstruction(SpvOpBranchConditional, lhs, rhsLabel, end, out);
2054 this->writeLabel(rhsLabel, out); 2054 this->writeLabel(rhsLabel, out);
2055 SpvId rhs = this->writeExpression(*a.fRight, out); 2055 SpvId rhs = this->writeExpression(*a.fRight, out);
2056 SpvId rhsBlock = fCurrentBlock; 2056 SpvId rhsBlock = fCurrentBlock;
2057 this->writeInstruction(SpvOpBranch, end, out); 2057 this->writeInstruction(SpvOpBranch, end, out);
2058 this->writeLabel(end, out); 2058 this->writeLabel(end, out);
2059 SpvId result = this->nextId(); 2059 SpvId result = this->nextId();
2060 this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result , falseConstant, 2060 this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result , falseConstant,
2061 lhsBlock, rhs, rhsBlock, out); 2061 lhsBlock, rhs, rhsBlock, out);
2062 return result; 2062 return result;
2063 } 2063 }
2064 2064
2065 SpvId SPIRVCodeGenerator::writeLogicalOr(BinaryExpression& o, std::ostream& out) { 2065 SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, std::ostream & out) {
2066 ASSERT(o.fOperator == Token::LOGICALOR); 2066 ASSERT(o.fOperator == Token::LOGICALOR);
2067 BoolLiteral trueLiteral(fContext, Position(), true); 2067 BoolLiteral trueLiteral(fContext, Position(), true);
2068 SpvId trueConstant = this->writeBoolLiteral(trueLiteral); 2068 SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
2069 SpvId lhs = this->writeExpression(*o.fLeft, out); 2069 SpvId lhs = this->writeExpression(*o.fLeft, out);
2070 SpvId rhsLabel = this->nextId(); 2070 SpvId rhsLabel = this->nextId();
2071 SpvId end = this->nextId(); 2071 SpvId end = this->nextId();
2072 SpvId lhsBlock = fCurrentBlock; 2072 SpvId lhsBlock = fCurrentBlock;
2073 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone , out); 2073 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone , out);
2074 this->writeInstruction(SpvOpBranchConditional, lhs, end, rhsLabel, out); 2074 this->writeInstruction(SpvOpBranchConditional, lhs, end, rhsLabel, out);
2075 this->writeLabel(rhsLabel, out); 2075 this->writeLabel(rhsLabel, out);
2076 SpvId rhs = this->writeExpression(*o.fRight, out); 2076 SpvId rhs = this->writeExpression(*o.fRight, out);
2077 SpvId rhsBlock = fCurrentBlock; 2077 SpvId rhsBlock = fCurrentBlock;
2078 this->writeInstruction(SpvOpBranch, end, out); 2078 this->writeInstruction(SpvOpBranch, end, out);
2079 this->writeLabel(end, out); 2079 this->writeLabel(end, out);
2080 SpvId result = this->nextId(); 2080 SpvId result = this->nextId();
2081 this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result , trueConstant, 2081 this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result , trueConstant,
2082 lhsBlock, rhs, rhsBlock, out); 2082 lhsBlock, rhs, rhsBlock, out);
2083 return result; 2083 return result;
2084 } 2084 }
2085 2085
2086 SpvId SPIRVCodeGenerator::writeTernaryExpression(TernaryExpression& t, std::ostr eam& out) { 2086 SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, std ::ostream& out) {
2087 SpvId test = this->writeExpression(*t.fTest, out); 2087 SpvId test = this->writeExpression(*t.fTest, out);
2088 if (t.fIfTrue->isConstant() && t.fIfFalse->isConstant()) { 2088 if (t.fIfTrue->isConstant() && t.fIfFalse->isConstant()) {
2089 // both true and false are constants, can just use OpSelect 2089 // both true and false are constants, can just use OpSelect
2090 SpvId result = this->nextId(); 2090 SpvId result = this->nextId();
2091 SpvId trueId = this->writeExpression(*t.fIfTrue, out); 2091 SpvId trueId = this->writeExpression(*t.fIfTrue, out);
2092 SpvId falseId = this->writeExpression(*t.fIfFalse, out); 2092 SpvId falseId = this->writeExpression(*t.fIfFalse, out);
2093 this->writeInstruction(SpvOpSelect, this->getType(t.fType), result, test , trueId, falseId, 2093 this->writeInstruction(SpvOpSelect, this->getType(t.fType), result, test , trueId, falseId,
2094 out); 2094 out);
2095 return result; 2095 return result;
2096 } 2096 }
(...skipping 23 matching lines...) Expand all
2120 if (type == *context.fInt_Type) { 2120 if (type == *context.fInt_Type) {
2121 return std::unique_ptr<Expression>(new IntLiteral(context, Position(), 1 )); 2121 return std::unique_ptr<Expression>(new IntLiteral(context, Position(), 1 ));
2122 } 2122 }
2123 else if (type == *context.fFloat_Type) { 2123 else if (type == *context.fFloat_Type) {
2124 return std::unique_ptr<Expression>(new FloatLiteral(context, Position(), 1.0)); 2124 return std::unique_ptr<Expression>(new FloatLiteral(context, Position(), 1.0));
2125 } else { 2125 } else {
2126 ABORT("math is unsupported on type '%s'") 2126 ABORT("math is unsupported on type '%s'")
2127 } 2127 }
2128 } 2128 }
2129 2129
2130 SpvId SPIRVCodeGenerator::writePrefixExpression(PrefixExpression& p, std::ostrea m& out) { 2130 SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, std:: ostream& out) {
2131 if (p.fOperator == Token::MINUS) { 2131 if (p.fOperator == Token::MINUS) {
2132 SpvId result = this->nextId(); 2132 SpvId result = this->nextId();
2133 SpvId typeId = this->getType(p.fType); 2133 SpvId typeId = this->getType(p.fType);
2134 SpvId expr = this->writeExpression(*p.fOperand, out); 2134 SpvId expr = this->writeExpression(*p.fOperand, out);
2135 if (is_float(fContext, p.fType)) { 2135 if (is_float(fContext, p.fType)) {
2136 this->writeInstruction(SpvOpFNegate, typeId, result, expr, out); 2136 this->writeInstruction(SpvOpFNegate, typeId, result, expr, out);
2137 } else if (is_signed(fContext, p.fType)) { 2137 } else if (is_signed(fContext, p.fType)) {
2138 this->writeInstruction(SpvOpSNegate, typeId, result, expr, out); 2138 this->writeInstruction(SpvOpSNegate, typeId, result, expr, out);
2139 } else { 2139 } else {
2140 ABORT("unsupported prefix expression %s", p.description().c_str()); 2140 ABORT("unsupported prefix expression %s", p.description().c_str());
(...skipping 26 matching lines...) Expand all
2167 SpvId result = this->nextId(); 2167 SpvId result = this->nextId();
2168 this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fT ype), result, 2168 this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fT ype), result,
2169 this->writeExpression(*p.fOperand, out), out) ; 2169 this->writeExpression(*p.fOperand, out), out) ;
2170 return result; 2170 return result;
2171 } 2171 }
2172 default: 2172 default:
2173 ABORT("unsupported prefix expression: %s", p.description().c_str()); 2173 ABORT("unsupported prefix expression: %s", p.description().c_str());
2174 } 2174 }
2175 } 2175 }
2176 2176
2177 SpvId SPIRVCodeGenerator::writePostfixExpression(PostfixExpression& p, std::ostr eam& out) { 2177 SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, std ::ostream& out) {
2178 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); 2178 std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
2179 SpvId result = lv->load(out); 2179 SpvId result = lv->load(out);
2180 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out) ; 2180 SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out) ;
2181 switch (p.fOperator) { 2181 switch (p.fOperator) {
2182 case Token::PLUSPLUS: { 2182 case Token::PLUSPLUS: {
2183 SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, on e, SpvOpFAdd, 2183 SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, on e, SpvOpFAdd,
2184 SpvOpIAdd, SpvOpIAdd, SpvOpU ndef, out); 2184 SpvOpIAdd, SpvOpIAdd, SpvOpU ndef, out);
2185 lv->store(temp, out); 2185 lv->store(temp, out);
2186 return result; 2186 return result;
2187 } 2187 }
2188 case Token::MINUSMINUS: { 2188 case Token::MINUSMINUS: {
2189 SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, on e, SpvOpFSub, 2189 SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, on e, SpvOpFSub,
2190 SpvOpISub, SpvOpISub, SpvOpU ndef, out); 2190 SpvOpISub, SpvOpISub, SpvOpU ndef, out);
2191 lv->store(temp, out); 2191 lv->store(temp, out);
2192 return result; 2192 return result;
2193 } 2193 }
2194 default: 2194 default:
2195 ABORT("unsupported postfix expression %s", p.description().c_str()); 2195 ABORT("unsupported postfix expression %s", p.description().c_str());
2196 } 2196 }
2197 } 2197 }
2198 2198
2199 SpvId SPIRVCodeGenerator::writeBoolLiteral(BoolLiteral& b) { 2199 SpvId SPIRVCodeGenerator::writeBoolLiteral(const BoolLiteral& b) {
2200 if (b.fValue) { 2200 if (b.fValue) {
2201 if (fBoolTrue == 0) { 2201 if (fBoolTrue == 0) {
2202 fBoolTrue = this->nextId(); 2202 fBoolTrue = this->nextId();
2203 this->writeInstruction(SpvOpConstantTrue, this->getType(b.fType), fB oolTrue, 2203 this->writeInstruction(SpvOpConstantTrue, this->getType(b.fType), fB oolTrue,
2204 fConstantBuffer); 2204 fConstantBuffer);
2205 } 2205 }
2206 return fBoolTrue; 2206 return fBoolTrue;
2207 } else { 2207 } else {
2208 if (fBoolFalse == 0) { 2208 if (fBoolFalse == 0) {
2209 fBoolFalse = this->nextId(); 2209 fBoolFalse = this->nextId();
2210 this->writeInstruction(SpvOpConstantFalse, this->getType(b.fType), f BoolFalse, 2210 this->writeInstruction(SpvOpConstantFalse, this->getType(b.fType), f BoolFalse,
2211 fConstantBuffer); 2211 fConstantBuffer);
2212 } 2212 }
2213 return fBoolFalse; 2213 return fBoolFalse;
2214 } 2214 }
2215 } 2215 }
2216 2216
2217 SpvId SPIRVCodeGenerator::writeIntLiteral(IntLiteral& i) { 2217 SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) {
2218 if (i.fType == *fContext.fInt_Type) { 2218 if (i.fType == *fContext.fInt_Type) {
2219 auto entry = fIntConstants.find(i.fValue); 2219 auto entry = fIntConstants.find(i.fValue);
2220 if (entry == fIntConstants.end()) { 2220 if (entry == fIntConstants.end()) {
2221 SpvId result = this->nextId(); 2221 SpvId result = this->nextId();
2222 this->writeInstruction(SpvOpConstant, this->getType(i.fType), result , (SpvId) i.fValue, 2222 this->writeInstruction(SpvOpConstant, this->getType(i.fType), result , (SpvId) i.fValue,
2223 fConstantBuffer); 2223 fConstantBuffer);
2224 fIntConstants[i.fValue] = result; 2224 fIntConstants[i.fValue] = result;
2225 return result; 2225 return result;
2226 } 2226 }
2227 return entry->second; 2227 return entry->second;
2228 } else { 2228 } else {
2229 ASSERT(i.fType == *fContext.fUInt_Type); 2229 ASSERT(i.fType == *fContext.fUInt_Type);
2230 auto entry = fUIntConstants.find(i.fValue); 2230 auto entry = fUIntConstants.find(i.fValue);
2231 if (entry == fUIntConstants.end()) { 2231 if (entry == fUIntConstants.end()) {
2232 SpvId result = this->nextId(); 2232 SpvId result = this->nextId();
2233 this->writeInstruction(SpvOpConstant, this->getType(i.fType), result , (SpvId) i.fValue, 2233 this->writeInstruction(SpvOpConstant, this->getType(i.fType), result , (SpvId) i.fValue,
2234 fConstantBuffer); 2234 fConstantBuffer);
2235 fUIntConstants[i.fValue] = result; 2235 fUIntConstants[i.fValue] = result;
2236 return result; 2236 return result;
2237 } 2237 }
2238 return entry->second; 2238 return entry->second;
2239 } 2239 }
2240 } 2240 }
2241 2241
2242 SpvId SPIRVCodeGenerator::writeFloatLiteral(FloatLiteral& f) { 2242 SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
2243 if (f.fType == *fContext.fFloat_Type) { 2243 if (f.fType == *fContext.fFloat_Type) {
2244 float value = (float) f.fValue; 2244 float value = (float) f.fValue;
2245 auto entry = fFloatConstants.find(value); 2245 auto entry = fFloatConstants.find(value);
2246 if (entry == fFloatConstants.end()) { 2246 if (entry == fFloatConstants.end()) {
2247 SpvId result = this->nextId(); 2247 SpvId result = this->nextId();
2248 uint32_t bits; 2248 uint32_t bits;
2249 ASSERT(sizeof(bits) == sizeof(value)); 2249 ASSERT(sizeof(bits) == sizeof(value));
2250 memcpy(&bits, &value, sizeof(bits)); 2250 memcpy(&bits, &value, sizeof(bits));
2251 this->writeInstruction(SpvOpConstant, this->getType(f.fType), result , bits, 2251 this->writeInstruction(SpvOpConstant, this->getType(f.fType), result , bits,
2252 fConstantBuffer); 2252 fConstantBuffer);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 if (layout.fSet >= 0) { 2343 if (layout.fSet >= 0) {
2344 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nDescriptorSet, 2344 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nDescriptorSet,
2345 layout.fSet, fDecorationBuffer); 2345 layout.fSet, fDecorationBuffer);
2346 } 2346 }
2347 if (layout.fBuiltin >= 0) { 2347 if (layout.fBuiltin >= 0) {
2348 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nBuiltIn, 2348 this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecoratio nBuiltIn,
2349 layout.fBuiltin, fDecorationBuffer); 2349 layout.fBuiltin, fDecorationBuffer);
2350 } 2350 }
2351 } 2351 }
2352 2352
2353 SpvId SPIRVCodeGenerator::writeInterfaceBlock(InterfaceBlock& intf) { 2353 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
2354 SpvId type = this->getType(intf.fVariable.fType); 2354 SpvId type = this->getType(intf.fVariable.fType);
2355 SpvId result = this->nextId(); 2355 SpvId result = this->nextId();
2356 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB uffer); 2356 this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationB uffer);
2357 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers) ; 2357 SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers) ;
2358 SpvId ptrType = this->nextId(); 2358 SpvId ptrType = this->nextId();
2359 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst antBuffer); 2359 this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConst antBuffer);
2360 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta ntBuffer); 2360 this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConsta ntBuffer);
2361 this->writeLayout(intf.fVariable.fModifiers.fLayout, result); 2361 this->writeLayout(intf.fVariable.fModifiers.fLayout, result);
2362 fVariableMap[&intf.fVariable] = result; 2362 fVariableMap[&intf.fVariable] = result;
2363 return result; 2363 return result;
2364 } 2364 }
2365 2365
2366 void SPIRVCodeGenerator::writeGlobalVars(VarDeclaration& decl, std::ostream& out ) { 2366 void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostrea m& out) {
2367 for (size_t i = 0; i < decl.fVars.size(); i++) { 2367 for (size_t i = 0; i < decl.fVars.size(); i++) {
2368 if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo && 2368 if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo &&
2369 !(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag | 2369 !(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag |
2370 Modifiers::kOut_Flag | 2370 Modifiers::kOut_Flag |
2371 Modifiers::kUniform_Flag)) ) { 2371 Modifiers::kUniform_Flag)) ) {
2372 // variable is dead and not an input / output var (the Vulkan debug layers complain if 2372 // variable is dead and not an input / output var (the Vulkan debug layers complain if
2373 // we elide an interface var, even if it's dead) 2373 // we elide an interface var, even if it's dead)
2374 continue; 2374 continue;
2375 } 2375 }
2376 SpvStorageClass_ storageClass; 2376 SpvStorageClass_ storageClass;
(...skipping 15 matching lines...) Expand all
2392 SpvId type = this->getPointerType(decl.fVars[i]->fType, storageClass); 2392 SpvId type = this->getPointerType(decl.fVars[i]->fType, storageClass);
2393 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB uffer); 2393 this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantB uffer);
2394 this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNam eBuffer); 2394 this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNam eBuffer);
2395 if (decl.fVars[i]->fType.kind() == Type::kMatrix_Kind) { 2395 if (decl.fVars[i]->fType.kind() == Type::kMatrix_Kind) {
2396 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionColMajor, 2396 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionColMajor,
2397 fDecorationBuffer); 2397 fDecorationBuffer);
2398 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionMatrixStride, 2398 this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecora tionMatrixStride,
2399 (SpvId) decl.fVars[i]->fType.stride(), fDecor ationBuffer); 2399 (SpvId) decl.fVars[i]->fType.stride(), fDecor ationBuffer);
2400 } 2400 }
2401 if (decl.fValues[i]) { 2401 if (decl.fValues[i]) {
2402 » » » ASSERT(!fCurrentBlock); 2402 ASSERT(!fCurrentBlock);
2403 » » » fCurrentBlock = -1; 2403 fCurrentBlock = -1;
2404 SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitial izersBuffer); 2404 SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitial izersBuffer);
2405 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf fer); 2405 this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuf fer);
2406 » » » fCurrentBlock = 0; 2406 fCurrentBlock = 0;
2407 } 2407 }
2408 this->writeLayout(decl.fVars[i]->fModifiers.fLayout, id); 2408 this->writeLayout(decl.fVars[i]->fModifiers.fLayout, id);
2409 } 2409 }
2410 } 2410 }
2411 2411
2412 void SPIRVCodeGenerator::writeVarDeclaration(VarDeclaration& decl, std::ostream& out) { 2412 void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& decl, std::os tream& out) {
2413 for (size_t i = 0; i < decl.fVars.size(); i++) { 2413 for (size_t i = 0; i < decl.fVars.size(); i++) {
2414 SpvId id = this->nextId(); 2414 SpvId id = this->nextId();
2415 fVariableMap[decl.fVars[i]] = id; 2415 fVariableMap[decl.fVars[i]] = id;
2416 SpvId type = this->getPointerType(decl.fVars[i]->fType, SpvStorageClassF unction); 2416 SpvId type = this->getPointerType(decl.fVars[i]->fType, SpvStorageClassF unction);
2417 this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer); 2417 this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
2418 this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNam eBuffer); 2418 this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNam eBuffer);
2419 if (decl.fValues[i]) { 2419 if (decl.fValues[i]) {
2420 SpvId value = this->writeExpression(*decl.fValues[i], out); 2420 SpvId value = this->writeExpression(*decl.fValues[i], out);
2421 this->writeInstruction(SpvOpStore, id, value, out); 2421 this->writeInstruction(SpvOpStore, id, value, out);
2422 } 2422 }
2423 } 2423 }
2424 } 2424 }
2425 2425
2426 void SPIRVCodeGenerator::writeStatement(Statement& s, std::ostream& out) { 2426 void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
2427 switch (s.fKind) { 2427 switch (s.fKind) {
2428 case Statement::kBlock_Kind: 2428 case Statement::kBlock_Kind:
2429 this->writeBlock((Block&) s, out); 2429 this->writeBlock((Block&) s, out);
2430 break; 2430 break;
2431 case Statement::kExpression_Kind: 2431 case Statement::kExpression_Kind:
2432 this->writeExpression(*((ExpressionStatement&) s).fExpression, out); 2432 this->writeExpression(*((ExpressionStatement&) s).fExpression, out);
2433 break; 2433 break;
2434 case Statement::kReturn_Kind: 2434 case Statement::kReturn_Kind:
2435 this->writeReturnStatement((ReturnStatement&) s, out); 2435 this->writeReturnStatement((ReturnStatement&) s, out);
2436 break; 2436 break;
(...skipping 13 matching lines...) Expand all
2450 this->writeInstruction(SpvOpBranch, fContinueTarget.top(), out); 2450 this->writeInstruction(SpvOpBranch, fContinueTarget.top(), out);
2451 break; 2451 break;
2452 case Statement::kDiscard_Kind: 2452 case Statement::kDiscard_Kind:
2453 this->writeInstruction(SpvOpKill, out); 2453 this->writeInstruction(SpvOpKill, out);
2454 break; 2454 break;
2455 default: 2455 default:
2456 ABORT("unsupported statement: %s", s.description().c_str()); 2456 ABORT("unsupported statement: %s", s.description().c_str());
2457 } 2457 }
2458 } 2458 }
2459 2459
2460 void SPIRVCodeGenerator::writeBlock(Block& b, std::ostream& out) { 2460 void SPIRVCodeGenerator::writeBlock(const Block& b, std::ostream& out) {
2461 for (size_t i = 0; i < b.fStatements.size(); i++) { 2461 for (size_t i = 0; i < b.fStatements.size(); i++) {
2462 this->writeStatement(*b.fStatements[i], out); 2462 this->writeStatement(*b.fStatements[i], out);
2463 } 2463 }
2464 } 2464 }
2465 2465
2466 void SPIRVCodeGenerator::writeIfStatement(IfStatement& stmt, std::ostream& out) { 2466 void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, std::ostream& out) {
2467 SpvId test = this->writeExpression(*stmt.fTest, out); 2467 SpvId test = this->writeExpression(*stmt.fTest, out);
2468 SpvId ifTrue = this->nextId(); 2468 SpvId ifTrue = this->nextId();
2469 SpvId ifFalse = this->nextId(); 2469 SpvId ifFalse = this->nextId();
2470 if (stmt.fIfFalse) { 2470 if (stmt.fIfFalse) {
2471 SpvId end = this->nextId(); 2471 SpvId end = this->nextId();
2472 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMask None, out); 2472 this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMask None, out);
2473 this->writeInstruction(SpvOpBranchConditional, test, ifTrue, ifFalse, ou t); 2473 this->writeInstruction(SpvOpBranchConditional, test, ifTrue, ifFalse, ou t);
2474 this->writeLabel(ifTrue, out); 2474 this->writeLabel(ifTrue, out);
2475 this->writeStatement(*stmt.fIfTrue, out); 2475 this->writeStatement(*stmt.fIfTrue, out);
2476 if (fCurrentBlock) { 2476 if (fCurrentBlock) {
(...skipping 10 matching lines...) Expand all
2487 this->writeInstruction(SpvOpBranchConditional, test, ifTrue, ifFalse, ou t); 2487 this->writeInstruction(SpvOpBranchConditional, test, ifTrue, ifFalse, ou t);
2488 this->writeLabel(ifTrue, out); 2488 this->writeLabel(ifTrue, out);
2489 this->writeStatement(*stmt.fIfTrue, out); 2489 this->writeStatement(*stmt.fIfTrue, out);
2490 if (fCurrentBlock) { 2490 if (fCurrentBlock) {
2491 this->writeInstruction(SpvOpBranch, ifFalse, out); 2491 this->writeInstruction(SpvOpBranch, ifFalse, out);
2492 } 2492 }
2493 this->writeLabel(ifFalse, out); 2493 this->writeLabel(ifFalse, out);
2494 } 2494 }
2495 } 2495 }
2496 2496
2497 void SPIRVCodeGenerator::writeForStatement(ForStatement& f, std::ostream& out) { 2497 void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, std::ostream& out) {
2498 if (f.fInitializer) { 2498 if (f.fInitializer) {
2499 this->writeStatement(*f.fInitializer, out); 2499 this->writeStatement(*f.fInitializer, out);
2500 } 2500 }
2501 SpvId header = this->nextId(); 2501 SpvId header = this->nextId();
2502 SpvId start = this->nextId(); 2502 SpvId start = this->nextId();
2503 SpvId body = this->nextId(); 2503 SpvId body = this->nextId();
2504 SpvId next = this->nextId(); 2504 SpvId next = this->nextId();
2505 fContinueTarget.push(next); 2505 fContinueTarget.push(next);
2506 SpvId end = this->nextId(); 2506 SpvId end = this->nextId();
2507 fBreakTarget.push(end); 2507 fBreakTarget.push(end);
2508 this->writeInstruction(SpvOpBranch, header, out); 2508 this->writeInstruction(SpvOpBranch, header, out);
2509 this->writeLabel(header, out); 2509 this->writeLabel(header, out);
2510 this->writeInstruction(SpvOpLoopMerge, end, next, SpvLoopControlMaskNone, ou t); 2510 this->writeInstruction(SpvOpLoopMerge, end, next, SpvLoopControlMaskNone, ou t);
2511 » this->writeInstruction(SpvOpBranch, start, out); 2511 this->writeInstruction(SpvOpBranch, start, out);
2512 this->writeLabel(start, out); 2512 this->writeLabel(start, out);
2513 SpvId test = this->writeExpression(*f.fTest, out); 2513 SpvId test = this->writeExpression(*f.fTest, out);
2514 this->writeInstruction(SpvOpBranchConditional, test, body, end, out); 2514 this->writeInstruction(SpvOpBranchConditional, test, body, end, out);
2515 this->writeLabel(body, out); 2515 this->writeLabel(body, out);
2516 this->writeStatement(*f.fStatement, out); 2516 this->writeStatement(*f.fStatement, out);
2517 if (fCurrentBlock) { 2517 if (fCurrentBlock) {
2518 this->writeInstruction(SpvOpBranch, next, out); 2518 this->writeInstruction(SpvOpBranch, next, out);
2519 } 2519 }
2520 this->writeLabel(next, out); 2520 this->writeLabel(next, out);
2521 if (f.fNext) { 2521 if (f.fNext) {
2522 this->writeExpression(*f.fNext, out); 2522 this->writeExpression(*f.fNext, out);
2523 } 2523 }
2524 this->writeInstruction(SpvOpBranch, header, out); 2524 this->writeInstruction(SpvOpBranch, header, out);
2525 this->writeLabel(end, out); 2525 this->writeLabel(end, out);
2526 fBreakTarget.pop(); 2526 fBreakTarget.pop();
2527 fContinueTarget.pop(); 2527 fContinueTarget.pop();
2528 } 2528 }
2529 2529
2530 void SPIRVCodeGenerator::writeReturnStatement(ReturnStatement& r, std::ostream& out) { 2530 void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, std::ost ream& out) {
2531 if (r.fExpression) { 2531 if (r.fExpression) {
2532 this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpre ssion, out), 2532 this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpre ssion, out),
2533 out); 2533 out);
2534 } else { 2534 } else {
2535 this->writeInstruction(SpvOpReturn, out); 2535 this->writeInstruction(SpvOpReturn, out);
2536 } 2536 }
2537 } 2537 }
2538 2538
2539 void SPIRVCodeGenerator::writeInstructions(Program& program, std::ostream& out) { 2539 void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream& out) {
2540 fGLSLExtendedInstructions = this->nextId(); 2540 fGLSLExtendedInstructions = this->nextId();
2541 std::stringstream body; 2541 std::stringstream body;
2542 std::vector<SpvId> interfaceVars; 2542 std::vector<SpvId> interfaceVars;
2543 // assign IDs to functions 2543 // assign IDs to functions
2544 for (size_t i = 0; i < program.fElements.size(); i++) { 2544 for (size_t i = 0; i < program.fElements.size(); i++) {
2545 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) { 2545 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) {
2546 FunctionDefinition& f = (FunctionDefinition&) *program.fElements[i]; 2546 FunctionDefinition& f = (FunctionDefinition&) *program.fElements[i];
2547 fFunctionMap[&f.fDeclaration] = this->nextId(); 2547 fFunctionMap[&f.fDeclaration] = this->nextId();
2548 } 2548 }
2549 } 2549 }
(...skipping 12 matching lines...) Expand all
2562 this->writeGlobalVars(((VarDeclaration&) *program.fElements[i]), bod y); 2562 this->writeGlobalVars(((VarDeclaration&) *program.fElements[i]), bod y);
2563 } 2563 }
2564 } 2564 }
2565 for (size_t i = 0; i < program.fElements.size(); i++) { 2565 for (size_t i = 0; i < program.fElements.size(); i++) {
2566 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) { 2566 if (program.fElements[i]->fKind == ProgramElement::kFunction_Kind) {
2567 this->writeFunction(((FunctionDefinition&) *program.fElements[i]), b ody); 2567 this->writeFunction(((FunctionDefinition&) *program.fElements[i]), b ody);
2568 } 2568 }
2569 } 2569 }
2570 const FunctionDeclaration* main = nullptr; 2570 const FunctionDeclaration* main = nullptr;
2571 for (auto entry : fFunctionMap) { 2571 for (auto entry : fFunctionMap) {
2572 » » if (entry.first->fName == "main") { 2572 if (entry.first->fName == "main") {
2573 main = entry.first; 2573 main = entry.first;
2574 } 2574 }
2575 } 2575 }
2576 ASSERT(main); 2576 ASSERT(main);
2577 for (auto entry : fVariableMap) { 2577 for (auto entry : fVariableMap) {
2578 const Variable* var = entry.first; 2578 const Variable* var = entry.first;
2579 if (var->fStorage == Variable::kGlobal_Storage && 2579 if (var->fStorage == Variable::kGlobal_Storage &&
2580 ((var->fModifiers.fFlags & Modifiers::kIn_Flag) || 2580 ((var->fModifiers.fFlags & Modifiers::kIn_Flag) ||
2581 (var->fModifiers.fFlags & Modifiers::kOut_Flag))) { 2581 (var->fModifiers.fFlags & Modifiers::kOut_Flag))) {
2582 interfaceVars.push_back(entry.second); 2582 interfaceVars.push_back(entry.second);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2614 } 2614 }
2615 } 2615 }
2616 2616
2617 out << fNameBuffer.str(); 2617 out << fNameBuffer.str();
2618 out << fDecorationBuffer.str(); 2618 out << fDecorationBuffer.str();
2619 out << fConstantBuffer.str(); 2619 out << fConstantBuffer.str();
2620 out << fExternalFunctionsBuffer.str(); 2620 out << fExternalFunctionsBuffer.str();
2621 out << body.str(); 2621 out << body.str();
2622 } 2622 }
2623 2623
2624 void SPIRVCodeGenerator::generateCode(Program& program, std::ostream& out) { 2624 void SPIRVCodeGenerator::generateCode(const Program& program, std::ostream& out) {
2625 this->writeWord(SpvMagicNumber, out); 2625 this->writeWord(SpvMagicNumber, out);
2626 this->writeWord(SpvVersion, out); 2626 this->writeWord(SpvVersion, out);
2627 this->writeWord(SKSL_MAGIC, out); 2627 this->writeWord(SKSL_MAGIC, out);
2628 std::stringstream buffer; 2628 std::stringstream buffer;
2629 this->writeInstructions(program, buffer); 2629 this->writeInstructions(program, buffer);
2630 this->writeWord(fIdCount, out); 2630 this->writeWord(fIdCount, out);
2631 this->writeWord(0, out); // reserved, always zero 2631 this->writeWord(0, out); // reserved, always zero
2632 out << buffer.str(); 2632 out << buffer.str();
2633 } 2633 }
2634 2634
2635 } 2635 }
OLDNEW
« no previous file with comments | « src/sksl/SkSLSPIRVCodeGenerator.h ('k') | src/sksl/SkSLToken.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698