diff options
| author | 2021-04-11 02:07:02 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:27 -0400 | |
| commit | 3db2b3effa953ae66457b7a19b419fc4db2c4801 (patch) | |
| tree | 04c73897a74be053a610edf60703c72e985ee590 /src/shader_recompiler/frontend/ir/ir_emitter.cpp | |
| parent | nsight_aftermath_tracker: Report used shaders to Nsight Aftermath (diff) | |
| download | yuzu-3db2b3effa953ae66457b7a19b419fc4db2c4801.tar.gz yuzu-3db2b3effa953ae66457b7a19b419fc4db2c4801.tar.xz yuzu-3db2b3effa953ae66457b7a19b419fc4db2c4801.zip | |
shader: Implement ATOM/S and RED
Diffstat (limited to 'src/shader_recompiler/frontend/ir/ir_emitter.cpp')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 200 |
1 files changed, 199 insertions, 1 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 17be0c639..a3339f624 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -1284,6 +1284,204 @@ U1 IREmitter::IGreaterThanEqual(const U32& lhs, const U32& rhs, bool is_signed) | |||
| 1284 | return Inst<U1>(is_signed ? Opcode::SGreaterThanEqual : Opcode::UGreaterThanEqual, lhs, rhs); | 1284 | return Inst<U1>(is_signed ? Opcode::SGreaterThanEqual : Opcode::UGreaterThanEqual, lhs, rhs); |
| 1285 | } | 1285 | } |
| 1286 | 1286 | ||
| 1287 | U32 IREmitter::SharedAtomicIAdd(const U32& pointer_offset, const U32& value) { | ||
| 1288 | return Inst<U32>(Opcode::SharedAtomicIAdd32, pointer_offset, value); | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | U32 IREmitter::SharedAtomicSMin(const U32& pointer_offset, const U32& value) { | ||
| 1292 | return Inst<U32>(Opcode::SharedAtomicSMin32, pointer_offset, value); | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | U32 IREmitter::SharedAtomicUMin(const U32& pointer_offset, const U32& value) { | ||
| 1296 | return Inst<U32>(Opcode::SharedAtomicUMin32, pointer_offset, value); | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | U32 IREmitter::SharedAtomicIMin(const U32& pointer_offset, const U32& value, bool is_signed) { | ||
| 1300 | return is_signed ? SharedAtomicSMin(pointer_offset, value) | ||
| 1301 | : SharedAtomicUMin(pointer_offset, value); | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | U32 IREmitter::SharedAtomicSMax(const U32& pointer_offset, const U32& value) { | ||
| 1305 | return Inst<U32>(Opcode::SharedAtomicSMax32, pointer_offset, value); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | U32 IREmitter::SharedAtomicUMax(const U32& pointer_offset, const U32& value) { | ||
| 1309 | return Inst<U32>(Opcode::SharedAtomicUMax32, pointer_offset, value); | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | U32 IREmitter::SharedAtomicIMax(const U32& pointer_offset, const U32& value, bool is_signed) { | ||
| 1313 | return is_signed ? SharedAtomicSMax(pointer_offset, value) | ||
| 1314 | : SharedAtomicUMax(pointer_offset, value); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | U32 IREmitter::SharedAtomicInc(const U32& pointer_offset, const U32& value) { | ||
| 1318 | return Inst<U32>(Opcode::SharedAtomicInc32, pointer_offset, value); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | U32 IREmitter::SharedAtomicDec(const U32& pointer_offset, const U32& value) { | ||
| 1322 | return Inst<U32>(Opcode::SharedAtomicDec32, pointer_offset, value); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | U32 IREmitter::SharedAtomicAnd(const U32& pointer_offset, const U32& value) { | ||
| 1326 | return Inst<U32>(Opcode::SharedAtomicAnd32, pointer_offset, value); | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | U32 IREmitter::SharedAtomicOr(const U32& pointer_offset, const U32& value) { | ||
| 1330 | return Inst<U32>(Opcode::SharedAtomicOr32, pointer_offset, value); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | U32 IREmitter::SharedAtomicXor(const U32& pointer_offset, const U32& value) { | ||
| 1334 | return Inst<U32>(Opcode::SharedAtomicXor32, pointer_offset, value); | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | U32U64 IREmitter::SharedAtomicExchange(const U32& pointer_offset, const U32U64& value) { | ||
| 1338 | switch (value.Type()) { | ||
| 1339 | case Type::U32: | ||
| 1340 | return Inst<U32>(Opcode::SharedAtomicExchange32, pointer_offset, value); | ||
| 1341 | case Type::U64: | ||
| 1342 | return Inst<U64>(Opcode::SharedAtomicExchange64, pointer_offset, value); | ||
| 1343 | default: | ||
| 1344 | ThrowInvalidType(pointer_offset.Type()); | ||
| 1345 | } | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | U32U64 IREmitter::GlobalAtomicIAdd(const U64& pointer_offset, const U32U64& value) { | ||
| 1349 | switch (value.Type()) { | ||
| 1350 | case Type::U32: | ||
| 1351 | return Inst<U32>(Opcode::GlobalAtomicIAdd32, pointer_offset, value); | ||
| 1352 | case Type::U64: | ||
| 1353 | return Inst<U64>(Opcode::GlobalAtomicIAdd64, pointer_offset, value); | ||
| 1354 | default: | ||
| 1355 | ThrowInvalidType(value.Type()); | ||
| 1356 | } | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | U32U64 IREmitter::GlobalAtomicSMin(const U64& pointer_offset, const U32U64& value) { | ||
| 1360 | switch (value.Type()) { | ||
| 1361 | case Type::U32: | ||
| 1362 | return Inst<U32>(Opcode::GlobalAtomicSMin32, pointer_offset, value); | ||
| 1363 | case Type::U64: | ||
| 1364 | return Inst<U64>(Opcode::GlobalAtomicSMin64, pointer_offset, value); | ||
| 1365 | default: | ||
| 1366 | ThrowInvalidType(value.Type()); | ||
| 1367 | } | ||
| 1368 | } | ||
| 1369 | |||
| 1370 | U32U64 IREmitter::GlobalAtomicUMin(const U64& pointer_offset, const U32U64& value) { | ||
| 1371 | switch (value.Type()) { | ||
| 1372 | case Type::U32: | ||
| 1373 | return Inst<U32>(Opcode::GlobalAtomicUMin32, pointer_offset, value); | ||
| 1374 | case Type::U64: | ||
| 1375 | return Inst<U64>(Opcode::GlobalAtomicUMin64, pointer_offset, value); | ||
| 1376 | default: | ||
| 1377 | ThrowInvalidType(value.Type()); | ||
| 1378 | } | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | U32U64 IREmitter::GlobalAtomicIMin(const U64& pointer_offset, const U32U64& value, bool is_signed) { | ||
| 1382 | return is_signed ? GlobalAtomicSMin(pointer_offset, value) | ||
| 1383 | : GlobalAtomicUMin(pointer_offset, value); | ||
| 1384 | } | ||
| 1385 | |||
| 1386 | U32U64 IREmitter::GlobalAtomicSMax(const U64& pointer_offset, const U32U64& value) { | ||
| 1387 | switch (value.Type()) { | ||
| 1388 | case Type::U32: | ||
| 1389 | return Inst<U32>(Opcode::GlobalAtomicSMax32, pointer_offset, value); | ||
| 1390 | case Type::U64: | ||
| 1391 | return Inst<U64>(Opcode::GlobalAtomicSMax64, pointer_offset, value); | ||
| 1392 | default: | ||
| 1393 | ThrowInvalidType(value.Type()); | ||
| 1394 | } | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | U32U64 IREmitter::GlobalAtomicUMax(const U64& pointer_offset, const U32U64& value) { | ||
| 1398 | switch (value.Type()) { | ||
| 1399 | case Type::U32: | ||
| 1400 | return Inst<U32>(Opcode::GlobalAtomicUMax32, pointer_offset, value); | ||
| 1401 | case Type::U64: | ||
| 1402 | return Inst<U64>(Opcode::GlobalAtomicUMax64, pointer_offset, value); | ||
| 1403 | default: | ||
| 1404 | ThrowInvalidType(value.Type()); | ||
| 1405 | } | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | U32U64 IREmitter::GlobalAtomicIMax(const U64& pointer_offset, const U32U64& value, bool is_signed) { | ||
| 1409 | return is_signed ? GlobalAtomicSMax(pointer_offset, value) | ||
| 1410 | : GlobalAtomicUMax(pointer_offset, value); | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | U32 IREmitter::GlobalAtomicInc(const U64& pointer_offset, const U32& value) { | ||
| 1414 | return Inst<U32>(Opcode::GlobalAtomicInc32, pointer_offset, value); | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | U32 IREmitter::GlobalAtomicDec(const U64& pointer_offset, const U32& value) { | ||
| 1418 | return Inst<U32>(Opcode::GlobalAtomicDec32, pointer_offset, value); | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | U32U64 IREmitter::GlobalAtomicAnd(const U64& pointer_offset, const U32U64& value) { | ||
| 1422 | switch (value.Type()) { | ||
| 1423 | case Type::U32: | ||
| 1424 | return Inst<U32>(Opcode::GlobalAtomicAnd32, pointer_offset, value); | ||
| 1425 | case Type::U64: | ||
| 1426 | return Inst<U64>(Opcode::GlobalAtomicAnd64, pointer_offset, value); | ||
| 1427 | default: | ||
| 1428 | ThrowInvalidType(value.Type()); | ||
| 1429 | } | ||
| 1430 | } | ||
| 1431 | |||
| 1432 | U32U64 IREmitter::GlobalAtomicOr(const U64& pointer_offset, const U32U64& value) { | ||
| 1433 | switch (value.Type()) { | ||
| 1434 | case Type::U32: | ||
| 1435 | return Inst<U32>(Opcode::GlobalAtomicOr32, pointer_offset, value); | ||
| 1436 | case Type::U64: | ||
| 1437 | return Inst<U64>(Opcode::GlobalAtomicOr64, pointer_offset, value); | ||
| 1438 | default: | ||
| 1439 | ThrowInvalidType(value.Type()); | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | U32U64 IREmitter::GlobalAtomicXor(const U64& pointer_offset, const U32U64& value) { | ||
| 1444 | switch (value.Type()) { | ||
| 1445 | case Type::U32: | ||
| 1446 | return Inst<U32>(Opcode::GlobalAtomicXor32, pointer_offset, value); | ||
| 1447 | case Type::U64: | ||
| 1448 | return Inst<U64>(Opcode::GlobalAtomicXor64, pointer_offset, value); | ||
| 1449 | default: | ||
| 1450 | ThrowInvalidType(value.Type()); | ||
| 1451 | } | ||
| 1452 | } | ||
| 1453 | |||
| 1454 | U32U64 IREmitter::GlobalAtomicExchange(const U64& pointer_offset, const U32U64& value) { | ||
| 1455 | switch (value.Type()) { | ||
| 1456 | case Type::U32: | ||
| 1457 | return Inst<U32>(Opcode::GlobalAtomicExchange32, pointer_offset, value); | ||
| 1458 | case Type::U64: | ||
| 1459 | return Inst<U64>(Opcode::GlobalAtomicExchange64, pointer_offset, value); | ||
| 1460 | default: | ||
| 1461 | ThrowInvalidType(pointer_offset.Type()); | ||
| 1462 | } | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | F32 IREmitter::GlobalAtomicF32Add(const U64& pointer_offset, const Value& value, | ||
| 1466 | const FpControl control) { | ||
| 1467 | return Inst<F32>(Opcode::GlobalAtomicAddF32, Flags{control}, pointer_offset, value); | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | Value IREmitter::GlobalAtomicF16x2Add(const U64& pointer_offset, const Value& value, | ||
| 1471 | const FpControl control) { | ||
| 1472 | return Inst(Opcode::GlobalAtomicAddF16x2, Flags{control}, pointer_offset, value); | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | Value IREmitter::GlobalAtomicF16x2Min(const U64& pointer_offset, const Value& value, | ||
| 1476 | const FpControl control) { | ||
| 1477 | return Inst(Opcode::GlobalAtomicMinF16x2, Flags{control}, pointer_offset, value); | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | Value IREmitter::GlobalAtomicF16x2Max(const U64& pointer_offset, const Value& value, | ||
| 1481 | const FpControl control) { | ||
| 1482 | return Inst(Opcode::GlobalAtomicMaxF16x2, Flags{control}, pointer_offset, value); | ||
| 1483 | } | ||
| 1484 | |||
| 1287 | U1 IREmitter::LogicalOr(const U1& a, const U1& b) { | 1485 | U1 IREmitter::LogicalOr(const U1& a, const U1& b) { |
| 1288 | return Inst<U1>(Opcode::LogicalOr, a, b); | 1486 | return Inst<U1>(Opcode::LogicalOr, a, b); |
| 1289 | } | 1487 | } |
| @@ -1626,7 +1824,7 @@ Value IREmitter::ImageRead(const Value& handle, const Value& coords, TextureInst | |||
| 1626 | } | 1824 | } |
| 1627 | 1825 | ||
| 1628 | void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value& color, | 1826 | void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value& color, |
| 1629 | TextureInstInfo info) { | 1827 | TextureInstInfo info) { |
| 1630 | const Opcode op{handle.IsImmediate() ? Opcode::BoundImageWrite : Opcode::BindlessImageWrite}; | 1828 | const Opcode op{handle.IsImmediate() ? Opcode::BoundImageWrite : Opcode::BindlessImageWrite}; |
| 1631 | Inst(op, Flags{info}, handle, coords, color); | 1829 | Inst(op, Flags{info}, handle, coords, color); |
| 1632 | } | 1830 | } |