diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 152 |
1 files changed, 79 insertions, 73 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 1640207a7..37d17efdc 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -34,29 +34,29 @@ struct Register { | |||
| 34 | 34 | ||
| 35 | constexpr Register(u64 value_) : value(value_) {} | 35 | constexpr Register(u64 value_) : value(value_) {} |
| 36 | 36 | ||
| 37 | constexpr operator u64() const { | 37 | [[nodiscard]] constexpr operator u64() const { |
| 38 | return value; | 38 | return value; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | template <typename T> | 41 | template <typename T> |
| 42 | constexpr u64 operator-(const T& oth) const { | 42 | [[nodiscard]] constexpr u64 operator-(const T& oth) const { |
| 43 | return value - oth; | 43 | return value - oth; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | template <typename T> | 46 | template <typename T> |
| 47 | constexpr u64 operator&(const T& oth) const { | 47 | [[nodiscard]] constexpr u64 operator&(const T& oth) const { |
| 48 | return value & oth; | 48 | return value & oth; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | constexpr u64 operator&(const Register& oth) const { | 51 | [[nodiscard]] constexpr u64 operator&(const Register& oth) const { |
| 52 | return value & oth.value; | 52 | return value & oth.value; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | constexpr u64 operator~() const { | 55 | [[nodiscard]] constexpr u64 operator~() const { |
| 56 | return ~value; | 56 | return ~value; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | u64 GetSwizzledIndex(u64 elem) const { | 59 | [[nodiscard]] u64 GetSwizzledIndex(u64 elem) const { |
| 60 | elem = (value + elem) & 3; | 60 | elem = (value + elem) & 3; |
| 61 | return (value & ~3) + elem; | 61 | return (value & ~3) + elem; |
| 62 | } | 62 | } |
| @@ -107,7 +107,7 @@ union Attribute { | |||
| 107 | BitField<31, 1, u64> patch; | 107 | BitField<31, 1, u64> patch; |
| 108 | BitField<47, 3, AttributeSize> size; | 108 | BitField<47, 3, AttributeSize> size; |
| 109 | 109 | ||
| 110 | bool IsPhysical() const { | 110 | [[nodiscard]] bool IsPhysical() const { |
| 111 | return patch == 0 && element == 0 && static_cast<u64>(index.Value()) == 0; | 111 | return patch == 0 && element == 0 && static_cast<u64>(index.Value()) == 0; |
| 112 | } | 112 | } |
| 113 | } fmt20; | 113 | } fmt20; |
| @@ -505,14 +505,14 @@ struct IpaMode { | |||
| 505 | IpaInterpMode interpolation_mode; | 505 | IpaInterpMode interpolation_mode; |
| 506 | IpaSampleMode sampling_mode; | 506 | IpaSampleMode sampling_mode; |
| 507 | 507 | ||
| 508 | bool operator==(const IpaMode& a) const { | 508 | [[nodiscard]] bool operator==(const IpaMode& a) const { |
| 509 | return std::tie(interpolation_mode, sampling_mode) == | 509 | return std::tie(interpolation_mode, sampling_mode) == |
| 510 | std::tie(a.interpolation_mode, a.sampling_mode); | 510 | std::tie(a.interpolation_mode, a.sampling_mode); |
| 511 | } | 511 | } |
| 512 | bool operator!=(const IpaMode& a) const { | 512 | [[nodiscard]] bool operator!=(const IpaMode& a) const { |
| 513 | return !operator==(a); | 513 | return !operator==(a); |
| 514 | } | 514 | } |
| 515 | bool operator<(const IpaMode& a) const { | 515 | [[nodiscard]] bool operator<(const IpaMode& a) const { |
| 516 | return std::tie(interpolation_mode, sampling_mode) < | 516 | return std::tie(interpolation_mode, sampling_mode) < |
| 517 | std::tie(a.interpolation_mode, a.sampling_mode); | 517 | std::tie(a.interpolation_mode, a.sampling_mode); |
| 518 | } | 518 | } |
| @@ -661,7 +661,7 @@ union Instruction { | |||
| 661 | constexpr Instruction(u64 value_) : value{value_} {} | 661 | constexpr Instruction(u64 value_) : value{value_} {} |
| 662 | constexpr Instruction(const Instruction& instr) : value(instr.value) {} | 662 | constexpr Instruction(const Instruction& instr) : value(instr.value) {} |
| 663 | 663 | ||
| 664 | constexpr bool Bit(u64 offset) const { | 664 | [[nodiscard]] constexpr bool Bit(u64 offset) const { |
| 665 | return ((value >> offset) & 1) != 0; | 665 | return ((value >> offset) & 1) != 0; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| @@ -746,34 +746,34 @@ union Instruction { | |||
| 746 | BitField<28, 8, u64> imm_lut28; | 746 | BitField<28, 8, u64> imm_lut28; |
| 747 | BitField<48, 8, u64> imm_lut48; | 747 | BitField<48, 8, u64> imm_lut48; |
| 748 | 748 | ||
| 749 | u32 GetImmLut28() const { | 749 | [[nodiscard]] u32 GetImmLut28() const { |
| 750 | return static_cast<u32>(imm_lut28); | 750 | return static_cast<u32>(imm_lut28); |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | u32 GetImmLut48() const { | 753 | [[nodiscard]] u32 GetImmLut48() const { |
| 754 | return static_cast<u32>(imm_lut48); | 754 | return static_cast<u32>(imm_lut48); |
| 755 | } | 755 | } |
| 756 | } lop3; | 756 | } lop3; |
| 757 | 757 | ||
| 758 | u16 GetImm20_16() const { | 758 | [[nodiscard]] u16 GetImm20_16() const { |
| 759 | return static_cast<u16>(imm20_16); | 759 | return static_cast<u16>(imm20_16); |
| 760 | } | 760 | } |
| 761 | 761 | ||
| 762 | u32 GetImm20_19() const { | 762 | [[nodiscard]] u32 GetImm20_19() const { |
| 763 | u32 imm{static_cast<u32>(imm20_19)}; | 763 | u32 imm{static_cast<u32>(imm20_19)}; |
| 764 | imm <<= 12; | 764 | imm <<= 12; |
| 765 | imm |= negate_imm ? 0x80000000 : 0; | 765 | imm |= negate_imm ? 0x80000000 : 0; |
| 766 | return imm; | 766 | return imm; |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | u32 GetImm20_32() const { | 769 | [[nodiscard]] u32 GetImm20_32() const { |
| 770 | return static_cast<u32>(imm20_32); | 770 | return static_cast<u32>(imm20_32); |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | s32 GetSignedImm20_20() const { | 773 | [[nodiscard]] s32 GetSignedImm20_20() const { |
| 774 | u32 immediate = static_cast<u32>(imm20_19 | (negate_imm << 19)); | 774 | const auto immediate = static_cast<u32>(imm20_19 | (negate_imm << 19)); |
| 775 | // Sign extend the 20-bit value. | 775 | // Sign extend the 20-bit value. |
| 776 | u32 mask = 1U << (20 - 1); | 776 | const auto mask = 1U << (20 - 1); |
| 777 | return static_cast<s32>((immediate ^ mask) - mask); | 777 | return static_cast<s32>((immediate ^ mask) - mask); |
| 778 | } | 778 | } |
| 779 | } alu; | 779 | } alu; |
| @@ -857,7 +857,7 @@ union Instruction { | |||
| 857 | BitField<56, 1, u64> second_negate; | 857 | BitField<56, 1, u64> second_negate; |
| 858 | BitField<30, 9, u64> second; | 858 | BitField<30, 9, u64> second; |
| 859 | 859 | ||
| 860 | u32 PackImmediates() const { | 860 | [[nodiscard]] u32 PackImmediates() const { |
| 861 | // Immediates are half floats shifted. | 861 | // Immediates are half floats shifted. |
| 862 | constexpr u32 imm_shift = 6; | 862 | constexpr u32 imm_shift = 6; |
| 863 | return static_cast<u32>((first << imm_shift) | (second << (16 + imm_shift))); | 863 | return static_cast<u32>((first << imm_shift) | (second << (16 + imm_shift))); |
| @@ -1033,7 +1033,7 @@ union Instruction { | |||
| 1033 | BitField<28, 2, AtomicType> type; | 1033 | BitField<28, 2, AtomicType> type; |
| 1034 | BitField<30, 22, s64> offset; | 1034 | BitField<30, 22, s64> offset; |
| 1035 | 1035 | ||
| 1036 | s32 GetImmediateOffset() const { | 1036 | [[nodiscard]] s32 GetImmediateOffset() const { |
| 1037 | return static_cast<s32>(offset << 2); | 1037 | return static_cast<s32>(offset << 2); |
| 1038 | } | 1038 | } |
| 1039 | } atoms; | 1039 | } atoms; |
| @@ -1215,7 +1215,7 @@ union Instruction { | |||
| 1215 | BitField<39, 4, u64> rounding; | 1215 | BitField<39, 4, u64> rounding; |
| 1216 | // H0, H1 extract for F16 missing | 1216 | // H0, H1 extract for F16 missing |
| 1217 | BitField<41, 1, u64> selector; // Guessed as some games set it, TODO: reverse this value | 1217 | BitField<41, 1, u64> selector; // Guessed as some games set it, TODO: reverse this value |
| 1218 | F2fRoundingOp GetRoundingMode() const { | 1218 | [[nodiscard]] F2fRoundingOp GetRoundingMode() const { |
| 1219 | constexpr u64 rounding_mask = 0x0B; | 1219 | constexpr u64 rounding_mask = 0x0B; |
| 1220 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); | 1220 | return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); |
| 1221 | } | 1221 | } |
| @@ -1239,15 +1239,15 @@ union Instruction { | |||
| 1239 | BitField<54, 1, u64> aoffi_flag; | 1239 | BitField<54, 1, u64> aoffi_flag; |
| 1240 | BitField<55, 3, TextureProcessMode> process_mode; | 1240 | BitField<55, 3, TextureProcessMode> process_mode; |
| 1241 | 1241 | ||
| 1242 | bool IsComponentEnabled(std::size_t component) const { | 1242 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1243 | return ((1ull << component) & component_mask) != 0; | 1243 | return ((1ULL << component) & component_mask) != 0; |
| 1244 | } | 1244 | } |
| 1245 | 1245 | ||
| 1246 | TextureProcessMode GetTextureProcessMode() const { | 1246 | [[nodiscard]] TextureProcessMode GetTextureProcessMode() const { |
| 1247 | return process_mode; | 1247 | return process_mode; |
| 1248 | } | 1248 | } |
| 1249 | 1249 | ||
| 1250 | bool UsesMiscMode(TextureMiscMode mode) const { | 1250 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1251 | switch (mode) { | 1251 | switch (mode) { |
| 1252 | case TextureMiscMode::DC: | 1252 | case TextureMiscMode::DC: |
| 1253 | return dc_flag != 0; | 1253 | return dc_flag != 0; |
| @@ -1271,15 +1271,15 @@ union Instruction { | |||
| 1271 | BitField<36, 1, u64> aoffi_flag; | 1271 | BitField<36, 1, u64> aoffi_flag; |
| 1272 | BitField<37, 3, TextureProcessMode> process_mode; | 1272 | BitField<37, 3, TextureProcessMode> process_mode; |
| 1273 | 1273 | ||
| 1274 | bool IsComponentEnabled(std::size_t component) const { | 1274 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1275 | return ((1ULL << component) & component_mask) != 0; | 1275 | return ((1ULL << component) & component_mask) != 0; |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | TextureProcessMode GetTextureProcessMode() const { | 1278 | [[nodiscard]] TextureProcessMode GetTextureProcessMode() const { |
| 1279 | return process_mode; | 1279 | return process_mode; |
| 1280 | } | 1280 | } |
| 1281 | 1281 | ||
| 1282 | bool UsesMiscMode(TextureMiscMode mode) const { | 1282 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1283 | switch (mode) { | 1283 | switch (mode) { |
| 1284 | case TextureMiscMode::DC: | 1284 | case TextureMiscMode::DC: |
| 1285 | return dc_flag != 0; | 1285 | return dc_flag != 0; |
| @@ -1299,7 +1299,7 @@ union Instruction { | |||
| 1299 | BitField<31, 4, u64> component_mask; | 1299 | BitField<31, 4, u64> component_mask; |
| 1300 | BitField<49, 1, u64> nodep_flag; | 1300 | BitField<49, 1, u64> nodep_flag; |
| 1301 | 1301 | ||
| 1302 | bool UsesMiscMode(TextureMiscMode mode) const { | 1302 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1303 | switch (mode) { | 1303 | switch (mode) { |
| 1304 | case TextureMiscMode::NODEP: | 1304 | case TextureMiscMode::NODEP: |
| 1305 | return nodep_flag != 0; | 1305 | return nodep_flag != 0; |
| @@ -1309,7 +1309,7 @@ union Instruction { | |||
| 1309 | return false; | 1309 | return false; |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | bool IsComponentEnabled(std::size_t component) const { | 1312 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1313 | return ((1ULL << component) & component_mask) != 0; | 1313 | return ((1ULL << component) & component_mask) != 0; |
| 1314 | } | 1314 | } |
| 1315 | } txq; | 1315 | } txq; |
| @@ -1321,11 +1321,11 @@ union Instruction { | |||
| 1321 | BitField<35, 1, u64> ndv_flag; | 1321 | BitField<35, 1, u64> ndv_flag; |
| 1322 | BitField<49, 1, u64> nodep_flag; | 1322 | BitField<49, 1, u64> nodep_flag; |
| 1323 | 1323 | ||
| 1324 | bool IsComponentEnabled(std::size_t component) const { | 1324 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1325 | return ((1ull << component) & component_mask) != 0; | 1325 | return ((1ULL << component) & component_mask) != 0; |
| 1326 | } | 1326 | } |
| 1327 | 1327 | ||
| 1328 | bool UsesMiscMode(TextureMiscMode mode) const { | 1328 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1329 | switch (mode) { | 1329 | switch (mode) { |
| 1330 | case TextureMiscMode::NDV: | 1330 | case TextureMiscMode::NDV: |
| 1331 | return (ndv_flag != 0); | 1331 | return (ndv_flag != 0); |
| @@ -1347,7 +1347,7 @@ union Instruction { | |||
| 1347 | BitField<54, 2, u64> offset_mode; | 1347 | BitField<54, 2, u64> offset_mode; |
| 1348 | BitField<56, 2, u64> component; | 1348 | BitField<56, 2, u64> component; |
| 1349 | 1349 | ||
| 1350 | bool UsesMiscMode(TextureMiscMode mode) const { | 1350 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1351 | switch (mode) { | 1351 | switch (mode) { |
| 1352 | case TextureMiscMode::NDV: | 1352 | case TextureMiscMode::NDV: |
| 1353 | return ndv_flag != 0; | 1353 | return ndv_flag != 0; |
| @@ -1373,7 +1373,7 @@ union Instruction { | |||
| 1373 | BitField<33, 2, u64> offset_mode; | 1373 | BitField<33, 2, u64> offset_mode; |
| 1374 | BitField<37, 2, u64> component; | 1374 | BitField<37, 2, u64> component; |
| 1375 | 1375 | ||
| 1376 | bool UsesMiscMode(TextureMiscMode mode) const { | 1376 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1377 | switch (mode) { | 1377 | switch (mode) { |
| 1378 | case TextureMiscMode::NDV: | 1378 | case TextureMiscMode::NDV: |
| 1379 | return ndv_flag != 0; | 1379 | return ndv_flag != 0; |
| @@ -1399,7 +1399,7 @@ union Instruction { | |||
| 1399 | BitField<52, 2, u64> component; | 1399 | BitField<52, 2, u64> component; |
| 1400 | BitField<55, 1, u64> fp16_flag; | 1400 | BitField<55, 1, u64> fp16_flag; |
| 1401 | 1401 | ||
| 1402 | bool UsesMiscMode(TextureMiscMode mode) const { | 1402 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1403 | switch (mode) { | 1403 | switch (mode) { |
| 1404 | case TextureMiscMode::DC: | 1404 | case TextureMiscMode::DC: |
| 1405 | return dc_flag != 0; | 1405 | return dc_flag != 0; |
| @@ -1422,16 +1422,20 @@ union Instruction { | |||
| 1422 | BitField<53, 4, u64> texture_info; | 1422 | BitField<53, 4, u64> texture_info; |
| 1423 | BitField<59, 1, u64> fp32_flag; | 1423 | BitField<59, 1, u64> fp32_flag; |
| 1424 | 1424 | ||
| 1425 | TextureType GetTextureType() const { | 1425 | [[nodiscard]] TextureType GetTextureType() const { |
| 1426 | // The TEXS instruction has a weird encoding for the texture type. | 1426 | // The TEXS instruction has a weird encoding for the texture type. |
| 1427 | if (texture_info == 0) | 1427 | if (texture_info == 0) { |
| 1428 | return TextureType::Texture1D; | 1428 | return TextureType::Texture1D; |
| 1429 | if (texture_info >= 1 && texture_info <= 9) | 1429 | } |
| 1430 | if (texture_info >= 1 && texture_info <= 9) { | ||
| 1430 | return TextureType::Texture2D; | 1431 | return TextureType::Texture2D; |
| 1431 | if (texture_info >= 10 && texture_info <= 11) | 1432 | } |
| 1433 | if (texture_info >= 10 && texture_info <= 11) { | ||
| 1432 | return TextureType::Texture3D; | 1434 | return TextureType::Texture3D; |
| 1433 | if (texture_info >= 12 && texture_info <= 13) | 1435 | } |
| 1436 | if (texture_info >= 12 && texture_info <= 13) { | ||
| 1434 | return TextureType::TextureCube; | 1437 | return TextureType::TextureCube; |
| 1438 | } | ||
| 1435 | 1439 | ||
| 1436 | LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}", | 1440 | LOG_CRITICAL(HW_GPU, "Unhandled texture_info: {}", |
| 1437 | static_cast<u32>(texture_info.Value())); | 1441 | static_cast<u32>(texture_info.Value())); |
| @@ -1439,7 +1443,7 @@ union Instruction { | |||
| 1439 | return TextureType::Texture1D; | 1443 | return TextureType::Texture1D; |
| 1440 | } | 1444 | } |
| 1441 | 1445 | ||
| 1442 | TextureProcessMode GetTextureProcessMode() const { | 1446 | [[nodiscard]] TextureProcessMode GetTextureProcessMode() const { |
| 1443 | switch (texture_info) { | 1447 | switch (texture_info) { |
| 1444 | case 0: | 1448 | case 0: |
| 1445 | case 2: | 1449 | case 2: |
| @@ -1458,7 +1462,7 @@ union Instruction { | |||
| 1458 | return TextureProcessMode::None; | 1462 | return TextureProcessMode::None; |
| 1459 | } | 1463 | } |
| 1460 | 1464 | ||
| 1461 | bool UsesMiscMode(TextureMiscMode mode) const { | 1465 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1462 | switch (mode) { | 1466 | switch (mode) { |
| 1463 | case TextureMiscMode::DC: | 1467 | case TextureMiscMode::DC: |
| 1464 | return (texture_info >= 4 && texture_info <= 6) || texture_info == 9; | 1468 | return (texture_info >= 4 && texture_info <= 6) || texture_info == 9; |
| @@ -1470,16 +1474,16 @@ union Instruction { | |||
| 1470 | return false; | 1474 | return false; |
| 1471 | } | 1475 | } |
| 1472 | 1476 | ||
| 1473 | bool IsArrayTexture() const { | 1477 | [[nodiscard]] bool IsArrayTexture() const { |
| 1474 | // TEXS only supports Texture2D arrays. | 1478 | // TEXS only supports Texture2D arrays. |
| 1475 | return texture_info >= 7 && texture_info <= 9; | 1479 | return texture_info >= 7 && texture_info <= 9; |
| 1476 | } | 1480 | } |
| 1477 | 1481 | ||
| 1478 | bool HasTwoDestinations() const { | 1482 | [[nodiscard]] bool HasTwoDestinations() const { |
| 1479 | return gpr28.Value() != Register::ZeroIndex; | 1483 | return gpr28.Value() != Register::ZeroIndex; |
| 1480 | } | 1484 | } |
| 1481 | 1485 | ||
| 1482 | bool IsComponentEnabled(std::size_t component) const { | 1486 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1483 | static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ | 1487 | static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ |
| 1484 | {}, | 1488 | {}, |
| 1485 | {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, | 1489 | {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, |
| @@ -1506,7 +1510,7 @@ union Instruction { | |||
| 1506 | BitField<54, 1, u64> cl; | 1510 | BitField<54, 1, u64> cl; |
| 1507 | BitField<55, 1, u64> process_mode; | 1511 | BitField<55, 1, u64> process_mode; |
| 1508 | 1512 | ||
| 1509 | TextureProcessMode GetTextureProcessMode() const { | 1513 | [[nodiscard]] TextureProcessMode GetTextureProcessMode() const { |
| 1510 | return process_mode == 0 ? TextureProcessMode::LZ : TextureProcessMode::LL; | 1514 | return process_mode == 0 ? TextureProcessMode::LZ : TextureProcessMode::LL; |
| 1511 | } | 1515 | } |
| 1512 | } tld; | 1516 | } tld; |
| @@ -1516,7 +1520,7 @@ union Instruction { | |||
| 1516 | BitField<53, 4, u64> texture_info; | 1520 | BitField<53, 4, u64> texture_info; |
| 1517 | BitField<59, 1, u64> fp32_flag; | 1521 | BitField<59, 1, u64> fp32_flag; |
| 1518 | 1522 | ||
| 1519 | TextureType GetTextureType() const { | 1523 | [[nodiscard]] TextureType GetTextureType() const { |
| 1520 | // The TLDS instruction has a weird encoding for the texture type. | 1524 | // The TLDS instruction has a weird encoding for the texture type. |
| 1521 | if (texture_info <= 1) { | 1525 | if (texture_info <= 1) { |
| 1522 | return TextureType::Texture1D; | 1526 | return TextureType::Texture1D; |
| @@ -1535,13 +1539,14 @@ union Instruction { | |||
| 1535 | return TextureType::Texture1D; | 1539 | return TextureType::Texture1D; |
| 1536 | } | 1540 | } |
| 1537 | 1541 | ||
| 1538 | TextureProcessMode GetTextureProcessMode() const { | 1542 | [[nodiscard]] TextureProcessMode GetTextureProcessMode() const { |
| 1539 | if (texture_info == 1 || texture_info == 5 || texture_info == 12) | 1543 | if (texture_info == 1 || texture_info == 5 || texture_info == 12) { |
| 1540 | return TextureProcessMode::LL; | 1544 | return TextureProcessMode::LL; |
| 1545 | } | ||
| 1541 | return TextureProcessMode::LZ; | 1546 | return TextureProcessMode::LZ; |
| 1542 | } | 1547 | } |
| 1543 | 1548 | ||
| 1544 | bool UsesMiscMode(TextureMiscMode mode) const { | 1549 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1545 | switch (mode) { | 1550 | switch (mode) { |
| 1546 | case TextureMiscMode::AOFFI: | 1551 | case TextureMiscMode::AOFFI: |
| 1547 | return texture_info == 12 || texture_info == 4; | 1552 | return texture_info == 12 || texture_info == 4; |
| @@ -1555,7 +1560,7 @@ union Instruction { | |||
| 1555 | return false; | 1560 | return false; |
| 1556 | } | 1561 | } |
| 1557 | 1562 | ||
| 1558 | bool IsArrayTexture() const { | 1563 | [[nodiscard]] bool IsArrayTexture() const { |
| 1559 | // TEXS only supports Texture2D arrays. | 1564 | // TEXS only supports Texture2D arrays. |
| 1560 | return texture_info == 8; | 1565 | return texture_info == 8; |
| 1561 | } | 1566 | } |
| @@ -1567,7 +1572,7 @@ union Instruction { | |||
| 1567 | BitField<35, 1, u64> aoffi_flag; | 1572 | BitField<35, 1, u64> aoffi_flag; |
| 1568 | BitField<49, 1, u64> nodep_flag; | 1573 | BitField<49, 1, u64> nodep_flag; |
| 1569 | 1574 | ||
| 1570 | bool UsesMiscMode(TextureMiscMode mode) const { | 1575 | [[nodiscard]] bool UsesMiscMode(TextureMiscMode mode) const { |
| 1571 | switch (mode) { | 1576 | switch (mode) { |
| 1572 | case TextureMiscMode::AOFFI: | 1577 | case TextureMiscMode::AOFFI: |
| 1573 | return aoffi_flag != 0; | 1578 | return aoffi_flag != 0; |
| @@ -1591,7 +1596,7 @@ union Instruction { | |||
| 1591 | BitField<20, 3, StoreType> store_data_layout; | 1596 | BitField<20, 3, StoreType> store_data_layout; |
| 1592 | BitField<20, 4, u64> component_mask_selector; | 1597 | BitField<20, 4, u64> component_mask_selector; |
| 1593 | 1598 | ||
| 1594 | bool IsComponentEnabled(std::size_t component) const { | 1599 | [[nodiscard]] bool IsComponentEnabled(std::size_t component) const { |
| 1595 | ASSERT(mode == SurfaceDataMode::P); | 1600 | ASSERT(mode == SurfaceDataMode::P); |
| 1596 | constexpr u8 R = 0b0001; | 1601 | constexpr u8 R = 0b0001; |
| 1597 | constexpr u8 G = 0b0010; | 1602 | constexpr u8 G = 0b0010; |
| @@ -1604,7 +1609,7 @@ union Instruction { | |||
| 1604 | return std::bitset<4>{mask.at(component_mask_selector)}.test(component); | 1609 | return std::bitset<4>{mask.at(component_mask_selector)}.test(component); |
| 1605 | } | 1610 | } |
| 1606 | 1611 | ||
| 1607 | StoreType GetStoreDataLayout() const { | 1612 | [[nodiscard]] StoreType GetStoreDataLayout() const { |
| 1608 | ASSERT(mode == SurfaceDataMode::D_BA); | 1613 | ASSERT(mode == SurfaceDataMode::D_BA); |
| 1609 | return store_data_layout; | 1614 | return store_data_layout; |
| 1610 | } | 1615 | } |
| @@ -1622,7 +1627,7 @@ union Instruction { | |||
| 1622 | BitField<20, 24, u64> target; | 1627 | BitField<20, 24, u64> target; |
| 1623 | BitField<5, 1, u64> constant_buffer; | 1628 | BitField<5, 1, u64> constant_buffer; |
| 1624 | 1629 | ||
| 1625 | s32 GetBranchTarget() const { | 1630 | [[nodiscard]] s32 GetBranchTarget() const { |
| 1626 | // Sign extend the branch target offset | 1631 | // Sign extend the branch target offset |
| 1627 | const auto mask = 1U << (24 - 1); | 1632 | const auto mask = 1U << (24 - 1); |
| 1628 | const auto target_value = static_cast<u32>(target); | 1633 | const auto target_value = static_cast<u32>(target); |
| @@ -1638,7 +1643,7 @@ union Instruction { | |||
| 1638 | BitField<20, 24, u64> target; | 1643 | BitField<20, 24, u64> target; |
| 1639 | BitField<5, 1, u64> constant_buffer; | 1644 | BitField<5, 1, u64> constant_buffer; |
| 1640 | 1645 | ||
| 1641 | s32 GetBranchExtend() const { | 1646 | [[nodiscard]] s32 GetBranchExtend() const { |
| 1642 | // Sign extend the branch target offset | 1647 | // Sign extend the branch target offset |
| 1643 | const auto mask = 1U << (24 - 1); | 1648 | const auto mask = 1U << (24 - 1); |
| 1644 | const auto target_value = static_cast<u32>(target); | 1649 | const auto target_value = static_cast<u32>(target); |
| @@ -1699,7 +1704,7 @@ union Instruction { | |||
| 1699 | BitField<50, 1, u64> is_op_b_register; | 1704 | BitField<50, 1, u64> is_op_b_register; |
| 1700 | BitField<51, 3, VmnmxOperation> operation; | 1705 | BitField<51, 3, VmnmxOperation> operation; |
| 1701 | 1706 | ||
| 1702 | VmnmxType SourceFormatA() const { | 1707 | [[nodiscard]] VmnmxType SourceFormatA() const { |
| 1703 | switch (src_format_a) { | 1708 | switch (src_format_a) { |
| 1704 | case 0b11: | 1709 | case 0b11: |
| 1705 | return VmnmxType::Bits32; | 1710 | return VmnmxType::Bits32; |
| @@ -1710,7 +1715,7 @@ union Instruction { | |||
| 1710 | } | 1715 | } |
| 1711 | } | 1716 | } |
| 1712 | 1717 | ||
| 1713 | VmnmxType SourceFormatB() const { | 1718 | [[nodiscard]] VmnmxType SourceFormatB() const { |
| 1714 | switch (src_format_b) { | 1719 | switch (src_format_b) { |
| 1715 | case 0b11: | 1720 | case 0b11: |
| 1716 | return VmnmxType::Bits32; | 1721 | return VmnmxType::Bits32; |
| @@ -1741,7 +1746,7 @@ union Instruction { | |||
| 1741 | BitField<20, 14, u64> shifted_offset; | 1746 | BitField<20, 14, u64> shifted_offset; |
| 1742 | BitField<34, 5, u64> index; | 1747 | BitField<34, 5, u64> index; |
| 1743 | 1748 | ||
| 1744 | u64 GetOffset() const { | 1749 | [[nodiscard]] u64 GetOffset() const { |
| 1745 | return shifted_offset * 4; | 1750 | return shifted_offset * 4; |
| 1746 | } | 1751 | } |
| 1747 | } cbuf34; | 1752 | } cbuf34; |
| @@ -1750,7 +1755,7 @@ union Instruction { | |||
| 1750 | BitField<20, 16, s64> offset; | 1755 | BitField<20, 16, s64> offset; |
| 1751 | BitField<36, 5, u64> index; | 1756 | BitField<36, 5, u64> index; |
| 1752 | 1757 | ||
| 1753 | s64 GetOffset() const { | 1758 | [[nodiscard]] s64 GetOffset() const { |
| 1754 | return offset; | 1759 | return offset; |
| 1755 | } | 1760 | } |
| 1756 | } cbuf36; | 1761 | } cbuf36; |
| @@ -1999,7 +2004,7 @@ public: | |||
| 1999 | 2004 | ||
| 2000 | /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be | 2005 | /// Returns whether an opcode has an execution predicate field or not (ie, whether it can be |
| 2001 | /// conditionally executed). | 2006 | /// conditionally executed). |
| 2002 | static bool IsPredicatedInstruction(Id opcode) { | 2007 | [[nodiscard]] static bool IsPredicatedInstruction(Id opcode) { |
| 2003 | // TODO(Subv): Add the rest of unpredicated instructions. | 2008 | // TODO(Subv): Add the rest of unpredicated instructions. |
| 2004 | return opcode != Id::SSY && opcode != Id::PBK; | 2009 | return opcode != Id::SSY && opcode != Id::PBK; |
| 2005 | } | 2010 | } |
| @@ -2009,19 +2014,19 @@ public: | |||
| 2009 | constexpr Matcher(const char* const name_, u16 mask_, u16 expected_, Id id_, Type type_) | 2014 | constexpr Matcher(const char* const name_, u16 mask_, u16 expected_, Id id_, Type type_) |
| 2010 | : name{name_}, mask{mask_}, expected{expected_}, id{id_}, type{type_} {} | 2015 | : name{name_}, mask{mask_}, expected{expected_}, id{id_}, type{type_} {} |
| 2011 | 2016 | ||
| 2012 | constexpr const char* GetName() const { | 2017 | [[nodiscard]] constexpr const char* GetName() const { |
| 2013 | return name; | 2018 | return name; |
| 2014 | } | 2019 | } |
| 2015 | 2020 | ||
| 2016 | constexpr u16 GetMask() const { | 2021 | [[nodiscard]] constexpr u16 GetMask() const { |
| 2017 | return mask; | 2022 | return mask; |
| 2018 | } | 2023 | } |
| 2019 | 2024 | ||
| 2020 | constexpr Id GetId() const { | 2025 | [[nodiscard]] constexpr Id GetId() const { |
| 2021 | return id; | 2026 | return id; |
| 2022 | } | 2027 | } |
| 2023 | 2028 | ||
| 2024 | constexpr Type GetType() const { | 2029 | [[nodiscard]] constexpr Type GetType() const { |
| 2025 | return type; | 2030 | return type; |
| 2026 | } | 2031 | } |
| 2027 | 2032 | ||
| @@ -2030,7 +2035,7 @@ public: | |||
| 2030 | * @param instruction The instruction to test | 2035 | * @param instruction The instruction to test |
| 2031 | * @returns true if the given instruction matches. | 2036 | * @returns true if the given instruction matches. |
| 2032 | */ | 2037 | */ |
| 2033 | constexpr bool Matches(u16 instruction) const { | 2038 | [[nodiscard]] constexpr bool Matches(u16 instruction) const { |
| 2034 | return (instruction & mask) == expected; | 2039 | return (instruction & mask) == expected; |
| 2035 | } | 2040 | } |
| 2036 | 2041 | ||
| @@ -2042,7 +2047,8 @@ public: | |||
| 2042 | Type type; | 2047 | Type type; |
| 2043 | }; | 2048 | }; |
| 2044 | 2049 | ||
| 2045 | static std::optional<std::reference_wrapper<const Matcher>> Decode(Instruction instr) { | 2050 | using DecodeResult = std::optional<std::reference_wrapper<const Matcher>>; |
| 2051 | [[nodiscard]] static DecodeResult Decode(Instruction instr) { | ||
| 2046 | static const auto table{GetDecodeTable()}; | 2052 | static const auto table{GetDecodeTable()}; |
| 2047 | 2053 | ||
| 2048 | const auto matches_instruction = [instr](const auto& matcher) { | 2054 | const auto matches_instruction = [instr](const auto& matcher) { |
| @@ -2064,7 +2070,7 @@ private: | |||
| 2064 | * A '0' in a bitstring indicates that a zero must be present at that bit position. | 2070 | * A '0' in a bitstring indicates that a zero must be present at that bit position. |
| 2065 | * A '1' in a bitstring indicates that a one must be present at that bit position. | 2071 | * A '1' in a bitstring indicates that a one must be present at that bit position. |
| 2066 | */ | 2072 | */ |
| 2067 | static constexpr auto GetMaskAndExpect(const char* const bitstring) { | 2073 | [[nodiscard]] static constexpr auto GetMaskAndExpect(const char* const bitstring) { |
| 2068 | u16 mask = 0, expect = 0; | 2074 | u16 mask = 0, expect = 0; |
| 2069 | for (std::size_t i = 0; i < opcode_bitsize; i++) { | 2075 | for (std::size_t i = 0; i < opcode_bitsize; i++) { |
| 2070 | const std::size_t bit_position = opcode_bitsize - i - 1; | 2076 | const std::size_t bit_position = opcode_bitsize - i - 1; |
| @@ -2086,14 +2092,14 @@ private: | |||
| 2086 | 2092 | ||
| 2087 | public: | 2093 | public: |
| 2088 | /// Creates a matcher that can match and parse instructions based on bitstring. | 2094 | /// Creates a matcher that can match and parse instructions based on bitstring. |
| 2089 | static constexpr auto GetMatcher(const char* const bitstring, Id op, Type type, | 2095 | [[nodiscard]] static constexpr auto GetMatcher(const char* const bitstring, Id op, |
| 2090 | const char* const name) { | 2096 | Type type, const char* const name) { |
| 2091 | const auto [mask, expected] = GetMaskAndExpect(bitstring); | 2097 | const auto [mask, expected] = GetMaskAndExpect(bitstring); |
| 2092 | return Matcher(name, mask, expected, op, type); | 2098 | return Matcher(name, mask, expected, op, type); |
| 2093 | } | 2099 | } |
| 2094 | }; | 2100 | }; |
| 2095 | 2101 | ||
| 2096 | static std::vector<Matcher> GetDecodeTable() { | 2102 | [[nodiscard]] static std::vector<Matcher> GetDecodeTable() { |
| 2097 | std::vector<Matcher> table = { | 2103 | std::vector<Matcher> table = { |
| 2098 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) | 2104 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) |
| 2099 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), | 2105 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), |