diff options
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.cpp | 200 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/ir_emitter.h | 39 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/microinstruction.cpp | 66 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/ir/opcodes.inc | 70 |
4 files changed, 374 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 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index ec60070ef..f9cbf1304 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -228,6 +228,45 @@ public: | |||
| 228 | [[nodiscard]] U1 INotEqual(const U32& lhs, const U32& rhs); | 228 | [[nodiscard]] U1 INotEqual(const U32& lhs, const U32& rhs); |
| 229 | [[nodiscard]] U1 IGreaterThanEqual(const U32& lhs, const U32& rhs, bool is_signed); | 229 | [[nodiscard]] U1 IGreaterThanEqual(const U32& lhs, const U32& rhs, bool is_signed); |
| 230 | 230 | ||
| 231 | [[nodiscard]] U32 SharedAtomicIAdd(const U32& pointer_offset, const U32& value); | ||
| 232 | [[nodiscard]] U32 SharedAtomicSMin(const U32& pointer_offset, const U32& value); | ||
| 233 | [[nodiscard]] U32 SharedAtomicUMin(const U32& pointer_offset, const U32& value); | ||
| 234 | [[nodiscard]] U32 SharedAtomicIMin(const U32& pointer_offset, const U32& value, bool is_signed); | ||
| 235 | [[nodiscard]] U32 SharedAtomicSMax(const U32& pointer_offset, const U32& value); | ||
| 236 | [[nodiscard]] U32 SharedAtomicUMax(const U32& pointer_offset, const U32& value); | ||
| 237 | [[nodiscard]] U32 SharedAtomicIMax(const U32& pointer_offset, const U32& value, bool is_signed); | ||
| 238 | [[nodiscard]] U32 SharedAtomicInc(const U32& pointer_offset, const U32& value); | ||
| 239 | [[nodiscard]] U32 SharedAtomicDec(const U32& pointer_offset, const U32& value); | ||
| 240 | [[nodiscard]] U32 SharedAtomicAnd(const U32& pointer_offset, const U32& value); | ||
| 241 | [[nodiscard]] U32 SharedAtomicOr(const U32& pointer_offset, const U32& value); | ||
| 242 | [[nodiscard]] U32 SharedAtomicXor(const U32& pointer_offset, const U32& value); | ||
| 243 | [[nodiscard]] U32U64 SharedAtomicExchange(const U32& pointer_offset, const U32U64& value); | ||
| 244 | |||
| 245 | [[nodiscard]] U32U64 GlobalAtomicIAdd(const U64& pointer_offset, const U32U64& value); | ||
| 246 | [[nodiscard]] U32U64 GlobalAtomicSMin(const U64& pointer_offset, const U32U64& value); | ||
| 247 | [[nodiscard]] U32U64 GlobalAtomicUMin(const U64& pointer_offset, const U32U64& value); | ||
| 248 | [[nodiscard]] U32U64 GlobalAtomicIMin(const U64& pointer_offset, const U32U64& value, | ||
| 249 | bool is_signed); | ||
| 250 | [[nodiscard]] U32U64 GlobalAtomicSMax(const U64& pointer_offset, const U32U64& value); | ||
| 251 | [[nodiscard]] U32U64 GlobalAtomicUMax(const U64& pointer_offset, const U32U64& value); | ||
| 252 | [[nodiscard]] U32U64 GlobalAtomicIMax(const U64& pointer_offset, const U32U64& value, | ||
| 253 | bool is_signed); | ||
| 254 | [[nodiscard]] U32 GlobalAtomicInc(const U64& pointer_offset, const U32& value); | ||
| 255 | [[nodiscard]] U32 GlobalAtomicDec(const U64& pointer_offset, const U32& value); | ||
| 256 | [[nodiscard]] U32U64 GlobalAtomicAnd(const U64& pointer_offset, const U32U64& value); | ||
| 257 | [[nodiscard]] U32U64 GlobalAtomicOr(const U64& pointer_offset, const U32U64& value); | ||
| 258 | [[nodiscard]] U32U64 GlobalAtomicXor(const U64& pointer_offset, const U32U64& value); | ||
| 259 | [[nodiscard]] U32U64 GlobalAtomicExchange(const U64& pointer_offset, const U32U64& value); | ||
| 260 | |||
| 261 | [[nodiscard]] F32 GlobalAtomicF32Add(const U64& pointer_offset, const Value& value, | ||
| 262 | const FpControl control = {}); | ||
| 263 | [[nodiscard]] Value GlobalAtomicF16x2Add(const U64& pointer_offset, const Value& value, | ||
| 264 | const FpControl control = {}); | ||
| 265 | [[nodiscard]] Value GlobalAtomicF16x2Min(const U64& pointer_offset, const Value& value, | ||
| 266 | const FpControl control = {}); | ||
| 267 | [[nodiscard]] Value GlobalAtomicF16x2Max(const U64& pointer_offset, const Value& value, | ||
| 268 | const FpControl control = {}); | ||
| 269 | |||
| 231 | [[nodiscard]] U1 LogicalOr(const U1& a, const U1& b); | 270 | [[nodiscard]] U1 LogicalOr(const U1& a, const U1& b); |
| 232 | [[nodiscard]] U1 LogicalAnd(const U1& a, const U1& b); | 271 | [[nodiscard]] U1 LogicalAnd(const U1& a, const U1& b); |
| 233 | [[nodiscard]] U1 LogicalXor(const U1& a, const U1& b); | 272 | [[nodiscard]] U1 LogicalXor(const U1& a, const U1& b); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 2df631791..0f66c5627 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -93,6 +93,72 @@ bool Inst::MayHaveSideEffects() const noexcept { | |||
| 93 | case Opcode::WriteSharedU32: | 93 | case Opcode::WriteSharedU32: |
| 94 | case Opcode::WriteSharedU64: | 94 | case Opcode::WriteSharedU64: |
| 95 | case Opcode::WriteSharedU128: | 95 | case Opcode::WriteSharedU128: |
| 96 | case Opcode::SharedAtomicIAdd32: | ||
| 97 | case Opcode::SharedAtomicSMin32: | ||
| 98 | case Opcode::SharedAtomicUMin32: | ||
| 99 | case Opcode::SharedAtomicSMax32: | ||
| 100 | case Opcode::SharedAtomicUMax32: | ||
| 101 | case Opcode::SharedAtomicInc32: | ||
| 102 | case Opcode::SharedAtomicDec32: | ||
| 103 | case Opcode::SharedAtomicAnd32: | ||
| 104 | case Opcode::SharedAtomicOr32: | ||
| 105 | case Opcode::SharedAtomicXor32: | ||
| 106 | case Opcode::SharedAtomicExchange32: | ||
| 107 | case Opcode::SharedAtomicExchange64: | ||
| 108 | case Opcode::GlobalAtomicIAdd32: | ||
| 109 | case Opcode::GlobalAtomicSMin32: | ||
| 110 | case Opcode::GlobalAtomicUMin32: | ||
| 111 | case Opcode::GlobalAtomicSMax32: | ||
| 112 | case Opcode::GlobalAtomicUMax32: | ||
| 113 | case Opcode::GlobalAtomicInc32: | ||
| 114 | case Opcode::GlobalAtomicDec32: | ||
| 115 | case Opcode::GlobalAtomicAnd32: | ||
| 116 | case Opcode::GlobalAtomicOr32: | ||
| 117 | case Opcode::GlobalAtomicXor32: | ||
| 118 | case Opcode::GlobalAtomicExchange32: | ||
| 119 | case Opcode::GlobalAtomicIAdd64: | ||
| 120 | case Opcode::GlobalAtomicSMin64: | ||
| 121 | case Opcode::GlobalAtomicUMin64: | ||
| 122 | case Opcode::GlobalAtomicSMax64: | ||
| 123 | case Opcode::GlobalAtomicUMax64: | ||
| 124 | case Opcode::GlobalAtomicAnd64: | ||
| 125 | case Opcode::GlobalAtomicOr64: | ||
| 126 | case Opcode::GlobalAtomicXor64: | ||
| 127 | case Opcode::GlobalAtomicExchange64: | ||
| 128 | case Opcode::GlobalAtomicAddF32: | ||
| 129 | case Opcode::GlobalAtomicAddF16x2: | ||
| 130 | case Opcode::GlobalAtomicAddF32x2: | ||
| 131 | case Opcode::GlobalAtomicMinF16x2: | ||
| 132 | case Opcode::GlobalAtomicMinF32x2: | ||
| 133 | case Opcode::GlobalAtomicMaxF16x2: | ||
| 134 | case Opcode::GlobalAtomicMaxF32x2: | ||
| 135 | case Opcode::StorageAtomicIAdd32: | ||
| 136 | case Opcode::StorageAtomicSMin32: | ||
| 137 | case Opcode::StorageAtomicUMin32: | ||
| 138 | case Opcode::StorageAtomicSMax32: | ||
| 139 | case Opcode::StorageAtomicUMax32: | ||
| 140 | case Opcode::StorageAtomicInc32: | ||
| 141 | case Opcode::StorageAtomicDec32: | ||
| 142 | case Opcode::StorageAtomicAnd32: | ||
| 143 | case Opcode::StorageAtomicOr32: | ||
| 144 | case Opcode::StorageAtomicXor32: | ||
| 145 | case Opcode::StorageAtomicExchange32: | ||
| 146 | case Opcode::StorageAtomicIAdd64: | ||
| 147 | case Opcode::StorageAtomicSMin64: | ||
| 148 | case Opcode::StorageAtomicUMin64: | ||
| 149 | case Opcode::StorageAtomicSMax64: | ||
| 150 | case Opcode::StorageAtomicUMax64: | ||
| 151 | case Opcode::StorageAtomicAnd64: | ||
| 152 | case Opcode::StorageAtomicOr64: | ||
| 153 | case Opcode::StorageAtomicXor64: | ||
| 154 | case Opcode::StorageAtomicExchange64: | ||
| 155 | case Opcode::StorageAtomicAddF32: | ||
| 156 | case Opcode::StorageAtomicAddF16x2: | ||
| 157 | case Opcode::StorageAtomicAddF32x2: | ||
| 158 | case Opcode::StorageAtomicMinF16x2: | ||
| 159 | case Opcode::StorageAtomicMinF32x2: | ||
| 160 | case Opcode::StorageAtomicMaxF16x2: | ||
| 161 | case Opcode::StorageAtomicMaxF32x2: | ||
| 96 | case Opcode::BindlessImageWrite: | 162 | case Opcode::BindlessImageWrite: |
| 97 | case Opcode::BoundImageWrite: | 163 | case Opcode::BoundImageWrite: |
| 98 | case Opcode::ImageWrite: | 164 | case Opcode::ImageWrite: |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 86ea02560..dc776a73e 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -321,6 +321,76 @@ OPCODE(INotEqual, U1, U32, | |||
| 321 | OPCODE(SGreaterThanEqual, U1, U32, U32, ) | 321 | OPCODE(SGreaterThanEqual, U1, U32, U32, ) |
| 322 | OPCODE(UGreaterThanEqual, U1, U32, U32, ) | 322 | OPCODE(UGreaterThanEqual, U1, U32, U32, ) |
| 323 | 323 | ||
| 324 | // Atomic operations | ||
| 325 | OPCODE(SharedAtomicIAdd32, U32, U32, U32, ) | ||
| 326 | OPCODE(SharedAtomicSMin32, U32, U32, U32, ) | ||
| 327 | OPCODE(SharedAtomicUMin32, U32, U32, U32, ) | ||
| 328 | OPCODE(SharedAtomicSMax32, U32, U32, U32, ) | ||
| 329 | OPCODE(SharedAtomicUMax32, U32, U32, U32, ) | ||
| 330 | OPCODE(SharedAtomicInc32, U32, U32, U32, ) | ||
| 331 | OPCODE(SharedAtomicDec32, U32, U32, U32, ) | ||
| 332 | OPCODE(SharedAtomicAnd32, U32, U32, U32, ) | ||
| 333 | OPCODE(SharedAtomicOr32, U32, U32, U32, ) | ||
| 334 | OPCODE(SharedAtomicXor32, U32, U32, U32, ) | ||
| 335 | OPCODE(SharedAtomicExchange32, U32, U32, U32, ) | ||
| 336 | OPCODE(SharedAtomicExchange64, U64, U32, U64, ) | ||
| 337 | |||
| 338 | OPCODE(GlobalAtomicIAdd32, U32, U64, U32, ) | ||
| 339 | OPCODE(GlobalAtomicSMin32, U32, U64, U32, ) | ||
| 340 | OPCODE(GlobalAtomicUMin32, U32, U64, U32, ) | ||
| 341 | OPCODE(GlobalAtomicSMax32, U32, U64, U32, ) | ||
| 342 | OPCODE(GlobalAtomicUMax32, U32, U64, U32, ) | ||
| 343 | OPCODE(GlobalAtomicInc32, U32, U64, U32, ) | ||
| 344 | OPCODE(GlobalAtomicDec32, U32, U64, U32, ) | ||
| 345 | OPCODE(GlobalAtomicAnd32, U32, U64, U32, ) | ||
| 346 | OPCODE(GlobalAtomicOr32, U32, U64, U32, ) | ||
| 347 | OPCODE(GlobalAtomicXor32, U32, U64, U32, ) | ||
| 348 | OPCODE(GlobalAtomicExchange32, U32, U64, U32, ) | ||
| 349 | OPCODE(GlobalAtomicIAdd64, U64, U64, U64, ) | ||
| 350 | OPCODE(GlobalAtomicSMin64, U64, U64, U64, ) | ||
| 351 | OPCODE(GlobalAtomicUMin64, U64, U64, U64, ) | ||
| 352 | OPCODE(GlobalAtomicSMax64, U64, U64, U64, ) | ||
| 353 | OPCODE(GlobalAtomicUMax64, U64, U64, U64, ) | ||
| 354 | OPCODE(GlobalAtomicAnd64, U64, U64, U64, ) | ||
| 355 | OPCODE(GlobalAtomicOr64, U64, U64, U64, ) | ||
| 356 | OPCODE(GlobalAtomicXor64, U64, U64, U64, ) | ||
| 357 | OPCODE(GlobalAtomicExchange64, U64, U64, U64, ) | ||
| 358 | OPCODE(GlobalAtomicAddF32, F32, U64, F32, ) | ||
| 359 | OPCODE(GlobalAtomicAddF16x2, U32, U64, F16x2, ) | ||
| 360 | OPCODE(GlobalAtomicAddF32x2, U32, U64, F32x2, ) | ||
| 361 | OPCODE(GlobalAtomicMinF16x2, U32, U64, F16x2, ) | ||
| 362 | OPCODE(GlobalAtomicMinF32x2, U32, U64, F32x2, ) | ||
| 363 | OPCODE(GlobalAtomicMaxF16x2, U32, U64, F16x2, ) | ||
| 364 | OPCODE(GlobalAtomicMaxF32x2, U32, U64, F32x2, ) | ||
| 365 | |||
| 366 | OPCODE(StorageAtomicIAdd32, U32, U32, U32, U32, ) | ||
| 367 | OPCODE(StorageAtomicSMin32, U32, U32, U32, U32, ) | ||
| 368 | OPCODE(StorageAtomicUMin32, U32, U32, U32, U32, ) | ||
| 369 | OPCODE(StorageAtomicSMax32, U32, U32, U32, U32, ) | ||
| 370 | OPCODE(StorageAtomicUMax32, U32, U32, U32, U32, ) | ||
| 371 | OPCODE(StorageAtomicInc32, U32, U32, U32, U32, ) | ||
| 372 | OPCODE(StorageAtomicDec32, U32, U32, U32, U32, ) | ||
| 373 | OPCODE(StorageAtomicAnd32, U32, U32, U32, U32, ) | ||
| 374 | OPCODE(StorageAtomicOr32, U32, U32, U32, U32, ) | ||
| 375 | OPCODE(StorageAtomicXor32, U32, U32, U32, U32, ) | ||
| 376 | OPCODE(StorageAtomicExchange32, U32, U32, U32, U32, ) | ||
| 377 | OPCODE(StorageAtomicIAdd64, U64, U32, U32, U64, ) | ||
| 378 | OPCODE(StorageAtomicSMin64, U64, U32, U32, U64, ) | ||
| 379 | OPCODE(StorageAtomicUMin64, U64, U32, U32, U64, ) | ||
| 380 | OPCODE(StorageAtomicSMax64, U64, U32, U32, U64, ) | ||
| 381 | OPCODE(StorageAtomicUMax64, U64, U32, U32, U64, ) | ||
| 382 | OPCODE(StorageAtomicAnd64, U64, U32, U32, U64, ) | ||
| 383 | OPCODE(StorageAtomicOr64, U64, U32, U32, U64, ) | ||
| 384 | OPCODE(StorageAtomicXor64, U64, U32, U32, U64, ) | ||
| 385 | OPCODE(StorageAtomicExchange64, U64, U32, U32, U64, ) | ||
| 386 | OPCODE(StorageAtomicAddF32, F32, U32, U32, F32, ) | ||
| 387 | OPCODE(StorageAtomicAddF16x2, U32, U32, U32, F16x2, ) | ||
| 388 | OPCODE(StorageAtomicAddF32x2, U32, U32, U32, F32x2, ) | ||
| 389 | OPCODE(StorageAtomicMinF16x2, U32, U32, U32, F16x2, ) | ||
| 390 | OPCODE(StorageAtomicMinF32x2, U32, U32, U32, F32x2, ) | ||
| 391 | OPCODE(StorageAtomicMaxF16x2, U32, U32, U32, F16x2, ) | ||
| 392 | OPCODE(StorageAtomicMaxF32x2, U32, U32, U32, F32x2, ) | ||
| 393 | |||
| 324 | // Logical operations | 394 | // Logical operations |
| 325 | OPCODE(LogicalOr, U1, U1, U1, ) | 395 | OPCODE(LogicalOr, U1, U1, U1, ) |
| 326 | OPCODE(LogicalAnd, U1, U1, U1, ) | 396 | OPCODE(LogicalAnd, U1, U1, U1, ) |