diff options
| author | 2019-09-23 22:55:25 -0400 | |
|---|---|---|
| committer | 2019-10-25 09:01:30 -0400 | |
| commit | 8909f52166bf9c27d52b5a722efbd46d1a11e876 (patch) | |
| tree | 2e21bbc3c3f5422325d8003d72cdb4bb120a26e5 /src/video_core/shader/decode.cpp | |
| parent | Shader_Cache: setup connection of ConstBufferLocker (diff) | |
| download | yuzu-8909f52166bf9c27d52b5a722efbd46d1a11e876.tar.gz yuzu-8909f52166bf9c27d52b5a722efbd46d1a11e876.tar.xz yuzu-8909f52166bf9c27d52b5a722efbd46d1a11e876.zip | |
Shader_IR: Implement Fast BRX and allow multi-branches in the CFG.
Diffstat (limited to 'src/video_core/shader/decode.cpp')
| -rw-r--r-- | src/video_core/shader/decode.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 3f87b87ca..053241128 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp | |||
| @@ -198,24 +198,38 @@ void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) { | |||
| 198 | } | 198 | } |
| 199 | return result; | 199 | return result; |
| 200 | }; | 200 | }; |
| 201 | if (block.branch.address < 0) { | 201 | if (std::holds_alternative<SingleBranch>(*block.branch)) { |
| 202 | if (block.branch.kills) { | 202 | auto branch = std::get_if<SingleBranch>(block.branch.get()); |
| 203 | Node n = Operation(OperationCode::Discard); | 203 | if (branch->address < 0) { |
| 204 | n = apply_conditions(block.branch.cond, n); | 204 | if (branch->kill) { |
| 205 | Node n = Operation(OperationCode::Discard); | ||
| 206 | n = apply_conditions(branch->condition, n); | ||
| 207 | bb.push_back(n); | ||
| 208 | global_code.push_back(n); | ||
| 209 | return; | ||
| 210 | } | ||
| 211 | Node n = Operation(OperationCode::Exit); | ||
| 212 | n = apply_conditions(branch->condition, n); | ||
| 205 | bb.push_back(n); | 213 | bb.push_back(n); |
| 206 | global_code.push_back(n); | 214 | global_code.push_back(n); |
| 207 | return; | 215 | return; |
| 208 | } | 216 | } |
| 209 | Node n = Operation(OperationCode::Exit); | 217 | Node n = Operation(OperationCode::Branch, Immediate(branch->address)); |
| 210 | n = apply_conditions(block.branch.cond, n); | 218 | n = apply_conditions(branch->condition, n); |
| 211 | bb.push_back(n); | 219 | bb.push_back(n); |
| 212 | global_code.push_back(n); | 220 | global_code.push_back(n); |
| 213 | return; | 221 | return; |
| 214 | } | 222 | } |
| 215 | Node n = Operation(OperationCode::Branch, Immediate(block.branch.address)); | 223 | auto multi_branch = std::get_if<MultiBranch>(block.branch.get()); |
| 216 | n = apply_conditions(block.branch.cond, n); | 224 | Node op_a = GetRegister(multi_branch->gpr); |
| 217 | bb.push_back(n); | 225 | for (auto& branch_case : multi_branch->branches) { |
| 218 | global_code.push_back(n); | 226 | Node n = Operation(OperationCode::Branch, Immediate(branch_case.address)); |
| 227 | Node op_b = Immediate(branch_case.cmp_value); | ||
| 228 | Node condition = GetPredicateComparisonInteger(Tegra::Shader::PredCondition::Equal, false, op_a, op_b); | ||
| 229 | auto result = Conditional(condition, {n}); | ||
| 230 | bb.push_back(result); | ||
| 231 | global_code.push_back(result); | ||
| 232 | } | ||
| 219 | } | 233 | } |
| 220 | 234 | ||
| 221 | u32 ShaderIR::DecodeInstr(NodeBlock& bb, u32 pc) { | 235 | u32 ShaderIR::DecodeInstr(NodeBlock& bb, u32 pc) { |