diff options
| author | 2018-12-17 17:44:20 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:51 -0300 | |
| commit | becfdb863845d9ea81c1844c8ee3c681d03fd9ea (patch) | |
| tree | e324530e67e44794791f50290a144dfd6f3fe184 /src | |
| parent | shader_decode: Implement LOP (diff) | |
| download | yuzu-becfdb863845d9ea81c1844c8ee3c681d03fd9ea.tar.gz yuzu-becfdb863845d9ea81c1844c8ee3c681d03fd9ea.tar.xz yuzu-becfdb863845d9ea81c1844c8ee3c681d03fd9ea.zip | |
shader_decode: Implement PBK and BRK
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/other.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index ef0598d4f..0416d7eaa 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp | |||
| @@ -64,7 +64,19 @@ u32 ShaderIR::DecodeOther(BasicBlock& bb, u32 pc) { | |||
| 64 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it sets the | 64 | // The SSY opcode tells the GPU where to re-converge divergent execution paths, it sets the |
| 65 | // target of the jump that the SYNC instruction will make. The SSY opcode has a similar | 65 | // target of the jump that the SYNC instruction will make. The SSY opcode has a similar |
| 66 | // structure to the BRA opcode. | 66 | // structure to the BRA opcode. |
| 67 | bb.push_back(Operation(OperationCode::Ssy, Immediate(pc + instr.bra.GetBranchTarget()))); | 67 | const u32 target = pc + instr.bra.GetBranchTarget(); |
| 68 | bb.push_back(Operation(OperationCode::Ssy, Immediate(target))); | ||
| 69 | break; | ||
| 70 | } | ||
| 71 | case OpCode::Id::PBK: { | ||
| 72 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, | ||
| 73 | "Constant buffer PBK is not supported"); | ||
| 74 | |||
| 75 | // PBK pushes to a stack the address where BRK will jump to. This shares stack with SSY but | ||
| 76 | // using SYNC on a PBK address will kill the shader execution. We don't emulate this because | ||
| 77 | // it's very unlikely a driver will emit such invalid shader. | ||
| 78 | const u32 target = pc + instr.bra.GetBranchTarget(); | ||
| 79 | bb.push_back(Operation(OperationCode::Pbk, Immediate(target))); | ||
| 68 | break; | 80 | break; |
| 69 | } | 81 | } |
| 70 | case OpCode::Id::SYNC: { | 82 | case OpCode::Id::SYNC: { |
| @@ -76,6 +88,15 @@ u32 ShaderIR::DecodeOther(BasicBlock& bb, u32 pc) { | |||
| 76 | bb.push_back(Operation(OperationCode::Sync)); | 88 | bb.push_back(Operation(OperationCode::Sync)); |
| 77 | break; | 89 | break; |
| 78 | } | 90 | } |
| 91 | case OpCode::Id::BRK: { | ||
| 92 | const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; | ||
| 93 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "BRK condition code used: {}", | ||
| 94 | static_cast<u32>(cc)); | ||
| 95 | |||
| 96 | // The BRK opcode jumps to the address previously set by the PBK opcode | ||
| 97 | bb.push_back(Operation(OperationCode::Brk)); | ||
| 98 | break; | ||
| 99 | } | ||
| 79 | case OpCode::Id::IPA: { | 100 | case OpCode::Id::IPA: { |
| 80 | const auto& attribute = instr.attribute.fmt28; | 101 | const auto& attribute = instr.attribute.fmt28; |
| 81 | const Tegra::Shader::IpaMode input_mode{instr.ipa.interp_mode.Value(), | 102 | const Tegra::Shader::IpaMode input_mode{instr.ipa.interp_mode.Value(), |