diff options
| author | 2020-03-13 14:13:31 +0700 | |
|---|---|---|
| committer | 2020-03-13 14:13:31 +0700 | |
| commit | 96a4abe12d69a3fa35dd39e359438da18056f6ad (patch) | |
| tree | 60291c47f7c2c73a1a4adf3cb95893f4c3cf3561 /src | |
| parent | shader_bytecode: update BFE instructions struct. (diff) | |
| download | yuzu-96a4abe12d69a3fa35dd39e359438da18056f6ad.tar.gz yuzu-96a4abe12d69a3fa35dd39e359438da18056f6ad.tar.xz yuzu-96a4abe12d69a3fa35dd39e359438da18056f6ad.zip | |
shader_decode: implement BREV on BFE
Implement reverse parallel follow: https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/bfe.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/video_core/shader/decode/bfe.cpp b/src/video_core/shader/decode/bfe.cpp index c3ef88373..911d53657 100644 --- a/src/video_core/shader/decode/bfe.cpp +++ b/src/video_core/shader/decode/bfe.cpp | |||
| @@ -33,17 +33,36 @@ u32 ShaderIR::DecodeBfe(NodeBlock& bb, u32 pc) { | |||
| 33 | }(); | 33 | }(); |
| 34 | 34 | ||
| 35 | UNIMPLEMENTED_IF_MSG(instr.bfe.rd_cc, "Condition codes in BFE is not implemented"); | 35 | UNIMPLEMENTED_IF_MSG(instr.bfe.rd_cc, "Condition codes in BFE is not implemented"); |
| 36 | UNIMPLEMENTED_IF_MSG(instr.bfe.brev, "BREV in BFE is not implemented"); | ||
| 37 | 36 | ||
| 38 | const bool is_signed = instr.bfe.is_signed; | 37 | const bool is_signed = instr.bfe.is_signed; |
| 39 | 38 | ||
| 40 | const auto start_position = SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_b, | 39 | if (instr.bfe.brev) { |
| 41 | Immediate(0), Immediate(8)); | 40 | const auto swap = [&](u32 s, u32 mask) { |
| 41 | Node v1 = | ||
| 42 | SignedOperation(OperationCode::ILogicalShiftRight, is_signed, op_a, Immediate(s)); | ||
| 43 | if (mask != 0) { | ||
| 44 | v1 = SignedOperation(OperationCode::IBitwiseAnd, is_signed, v1, Immediate(mask)); | ||
| 45 | } | ||
| 46 | Node v2 = op_a; | ||
| 47 | if (mask != 0) { | ||
| 48 | v2 = SignedOperation(OperationCode::IBitwiseAnd, is_signed, op_a, Immediate(mask)); | ||
| 49 | } | ||
| 50 | v2 = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, v2, Immediate(s)); | ||
| 51 | return SignedOperation(OperationCode::IBitwiseOr, is_signed, v1, v2); | ||
| 52 | }; | ||
| 53 | op_a = swap(1, 0x55555555U); | ||
| 54 | op_a = swap(2, 0x33333333U); | ||
| 55 | op_a = swap(4, 0x0F0F0F0FU); | ||
| 56 | op_a = swap(8, 0x00FF00FFU); | ||
| 57 | op_a = swap(16, 0); | ||
| 58 | } | ||
| 59 | |||
| 60 | const auto offset = SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_b, | ||
| 61 | Immediate(0), Immediate(8)); | ||
| 42 | const auto bits = SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_b, | 62 | const auto bits = SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_b, |
| 43 | Immediate(8), Immediate(8)); | 63 | Immediate(8), Immediate(8)); |
| 44 | 64 | const auto result = | |
| 45 | auto result = | 65 | SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_a, offset, bits); |
| 46 | SignedOperation(OperationCode::IBitfieldExtract, is_signed, op_a, start_position, bits); | ||
| 47 | SetRegister(bb, instr.gpr0, result); | 66 | SetRegister(bb, instr.gpr0, result); |
| 48 | 67 | ||
| 49 | return pc; | 68 | return pc; |