diff options
| author | 2019-06-25 13:03:51 -0400 | |
|---|---|---|
| committer | 2019-07-09 08:14:39 -0400 | |
| commit | d5533b440c764093c04a4859b30fc78ddb0e0bbe (patch) | |
| tree | f9fea3823e0f55787549f2f1d9fc332118449bfc /src/video_core/shader/decode | |
| parent | shader_ir: Decompile Flow Stack (diff) | |
| download | yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.gz yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.tar.xz yuzu-d5533b440c764093c04a4859b30fc78ddb0e0bbe.zip | |
shader_ir: Unify blocks in decompiled shaders.
Diffstat (limited to 'src/video_core/shader/decode')
| -rw-r--r-- | src/video_core/shader/decode/other.cpp | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index ed3c63781..42e3de02f 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp | |||
| @@ -98,9 +98,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 98 | } else { | 98 | } else { |
| 99 | const u32 target = pc + 1; | 99 | const u32 target = pc + 1; |
| 100 | const Node op_a = GetConstBuffer(instr.cbuf36.index, instr.cbuf36.GetOffset()); | 100 | const Node op_a = GetConstBuffer(instr.cbuf36.index, instr.cbuf36.GetOffset()); |
| 101 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, | 101 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true, |
| 102 | true, PRECISE, op_a, Immediate(3)); | 102 | PRECISE, op_a, Immediate(3)); |
| 103 | const Node operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); | 103 | const Node operand = |
| 104 | Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); | ||
| 104 | branch = Operation(OperationCode::BranchIndirect, convert); | 105 | branch = Operation(OperationCode::BranchIndirect, convert); |
| 105 | } | 106 | } |
| 106 | 107 | ||
| @@ -119,14 +120,14 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 119 | const Node index = GetRegister(instr.gpr8); | 120 | const Node index = GetRegister(instr.gpr8); |
| 120 | const Node op_a = | 121 | const Node op_a = |
| 121 | GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index); | 122 | GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index); |
| 122 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, | 123 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true, |
| 123 | true, PRECISE, op_a, Immediate(3)); | 124 | PRECISE, op_a, Immediate(3)); |
| 124 | operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); | 125 | operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); |
| 125 | } else { | 126 | } else { |
| 126 | const s32 target = pc + instr.brx.GetBranchExtend(); | 127 | const s32 target = pc + instr.brx.GetBranchExtend(); |
| 127 | const Node op_a = GetRegister(instr.gpr8); | 128 | const Node op_a = GetRegister(instr.gpr8); |
| 128 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, | 129 | const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true, |
| 129 | true, PRECISE, op_a, Immediate(3)); | 130 | PRECISE, op_a, Immediate(3)); |
| 130 | operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); | 131 | operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); |
| 131 | } | 132 | } |
| 132 | const Node branch = Operation(OperationCode::BranchIndirect, operand); | 133 | const Node branch = Operation(OperationCode::BranchIndirect, operand); |
| @@ -143,6 +144,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 143 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, | 144 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, |
| 144 | "Constant buffer flow is not supported"); | 145 | "Constant buffer flow is not supported"); |
| 145 | 146 | ||
| 147 | if (disable_flow_stack) { | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | |||
| 146 | // The SSY opcode tells the GPU where to re-converge divergent execution paths with SYNC. | 151 | // The SSY opcode tells the GPU where to re-converge divergent execution paths with SYNC. |
| 147 | const u32 target = pc + instr.bra.GetBranchTarget(); | 152 | const u32 target = pc + instr.bra.GetBranchTarget(); |
| 148 | bb.push_back( | 153 | bb.push_back( |
| @@ -153,6 +158,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 153 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, | 158 | UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, |
| 154 | "Constant buffer PBK is not supported"); | 159 | "Constant buffer PBK is not supported"); |
| 155 | 160 | ||
| 161 | if (disable_flow_stack) { | ||
| 162 | break; | ||
| 163 | } | ||
| 164 | |||
| 156 | // PBK pushes to a stack the address where BRK will jump to. | 165 | // PBK pushes to a stack the address where BRK will jump to. |
| 157 | const u32 target = pc + instr.bra.GetBranchTarget(); | 166 | const u32 target = pc + instr.bra.GetBranchTarget(); |
| 158 | bb.push_back( | 167 | bb.push_back( |
| @@ -164,6 +173,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 164 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "SYNC condition code used: {}", | 173 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "SYNC condition code used: {}", |
| 165 | static_cast<u32>(cc)); | 174 | static_cast<u32>(cc)); |
| 166 | 175 | ||
| 176 | if (disable_flow_stack) { | ||
| 177 | break; | ||
| 178 | } | ||
| 179 | |||
| 167 | // The SYNC opcode jumps to the address previously set by the SSY opcode | 180 | // The SYNC opcode jumps to the address previously set by the SSY opcode |
| 168 | bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy)); | 181 | bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy)); |
| 169 | break; | 182 | break; |
| @@ -172,6 +185,9 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 172 | const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; | 185 | const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; |
| 173 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "BRK condition code used: {}", | 186 | UNIMPLEMENTED_IF_MSG(cc != Tegra::Shader::ConditionCode::T, "BRK condition code used: {}", |
| 174 | static_cast<u32>(cc)); | 187 | static_cast<u32>(cc)); |
| 188 | if (disable_flow_stack) { | ||
| 189 | break; | ||
| 190 | } | ||
| 175 | 191 | ||
| 176 | // The BRK opcode jumps to the address previously set by the PBK opcode | 192 | // The BRK opcode jumps to the address previously set by the PBK opcode |
| 177 | bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk)); | 193 | bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk)); |