summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar bunnei2019-07-11 17:36:23 -0400
committerGravatar GitHub2019-07-11 17:36:23 -0400
commitbb67091c774611ce2be1aa461438be3989601e59 (patch)
tree58e29bd5d7114019a48a62ffadb8076d73627bee /src/video_core/shader/decode
parentMerge pull request #2717 from SciresM/unmirror_memory (diff)
parentshader_ir: Add comments on missing instruction. (diff)
downloadyuzu-bb67091c774611ce2be1aa461438be3989601e59.tar.gz
yuzu-bb67091c774611ce2be1aa461438be3989601e59.tar.xz
yuzu-bb67091c774611ce2be1aa461438be3989601e59.zip
Merge pull request #2609 from FernandoS27/new-scan
Implement a New Shader Scanner, Decompile Flow Stack and implement BRX BRA.CC
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/other.cpp58
1 files changed, 54 insertions, 4 deletions
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index d46a8ab82..42e3de02f 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -91,11 +91,46 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
91 break; 91 break;
92 } 92 }
93 case OpCode::Id::BRA: { 93 case OpCode::Id::BRA: {
94 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 94 Node branch;
95 "BRA with constant buffers are not implemented"); 95 if (instr.bra.constant_buffer == 0) {
96 const u32 target = pc + instr.bra.GetBranchTarget();
97 branch = Operation(OperationCode::Branch, Immediate(target));
98 } else {
99 const u32 target = pc + 1;
100 const Node op_a = GetConstBuffer(instr.cbuf36.index, instr.cbuf36.GetOffset());
101 const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true,
102 PRECISE, op_a, Immediate(3));
103 const Node operand =
104 Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
105 branch = Operation(OperationCode::BranchIndirect, convert);
106 }
96 107
97 const u32 target = pc + instr.bra.GetBranchTarget(); 108 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
98 const Node branch = Operation(OperationCode::Branch, Immediate(target)); 109 if (cc != Tegra::Shader::ConditionCode::T) {
110 bb.push_back(Conditional(GetConditionCode(cc), {branch}));
111 } else {
112 bb.push_back(branch);
113 }
114 break;
115 }
116 case OpCode::Id::BRX: {
117 Node operand;
118 if (instr.brx.constant_buffer != 0) {
119 const s32 target = pc + 1;
120 const Node index = GetRegister(instr.gpr8);
121 const Node op_a =
122 GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index);
123 const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true,
124 PRECISE, op_a, Immediate(3));
125 operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
126 } else {
127 const s32 target = pc + instr.brx.GetBranchExtend();
128 const Node op_a = GetRegister(instr.gpr8);
129 const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight, true,
130 PRECISE, op_a, Immediate(3));
131 operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
132 }
133 const Node branch = Operation(OperationCode::BranchIndirect, operand);
99 134
100 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; 135 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
101 if (cc != Tegra::Shader::ConditionCode::T) { 136 if (cc != Tegra::Shader::ConditionCode::T) {
@@ -109,6 +144,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
109 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 144 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
110 "Constant buffer flow is not supported"); 145 "Constant buffer flow is not supported");
111 146
147 if (disable_flow_stack) {
148 break;
149 }
150
112 // 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.
113 const u32 target = pc + instr.bra.GetBranchTarget(); 152 const u32 target = pc + instr.bra.GetBranchTarget();
114 bb.push_back( 153 bb.push_back(
@@ -119,6 +158,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
119 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0, 158 UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
120 "Constant buffer PBK is not supported"); 159 "Constant buffer PBK is not supported");
121 160
161 if (disable_flow_stack) {
162 break;
163 }
164
122 // 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.
123 const u32 target = pc + instr.bra.GetBranchTarget(); 166 const u32 target = pc + instr.bra.GetBranchTarget();
124 bb.push_back( 167 bb.push_back(
@@ -130,6 +173,10 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
130 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: {}",
131 static_cast<u32>(cc)); 174 static_cast<u32>(cc));
132 175
176 if (disable_flow_stack) {
177 break;
178 }
179
133 // 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
134 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy)); 181 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Ssy));
135 break; 182 break;
@@ -138,6 +185,9 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
138 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; 185 const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
139 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: {}",
140 static_cast<u32>(cc)); 187 static_cast<u32>(cc));
188 if (disable_flow_stack) {
189 break;
190 }
141 191
142 // 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
143 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk)); 193 bb.push_back(Operation(OperationCode::PopFlowStack, MetaStackClass::Pbk));