| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |