diff options
| author | 2021-02-24 20:31:15 -0500 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | 8810c88b7e3de2766bf47e07e941fb2c58c6b4b0 (patch) | |
| tree | 73619b1563eefc7103687de8e78bcf3f750812f7 | |
| parent | spirv: Move phi arguments emit to a separate function (diff) | |
| download | yuzu-8810c88b7e3de2766bf47e07e941fb2c58c6b4b0.tar.gz yuzu-8810c88b7e3de2766bf47e07e941fb2c58c6b4b0.tar.xz yuzu-8810c88b7e3de2766bf47e07e941fb2c58c6b4b0.zip | |
shader: Implement SEL
4 files changed, 53 insertions, 16 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 5574feaa6..17ccb3d98 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -79,6 +79,7 @@ add_library(shader_recompiler STATIC | |||
| 79 | frontend/maxwell/translate/impl/move_register.cpp | 79 | frontend/maxwell/translate/impl/move_register.cpp |
| 80 | frontend/maxwell/translate/impl/move_special_register.cpp | 80 | frontend/maxwell/translate/impl/move_special_register.cpp |
| 81 | frontend/maxwell/translate/impl/not_implemented.cpp | 81 | frontend/maxwell/translate/impl/not_implemented.cpp |
| 82 | frontend/maxwell/translate/impl/select_source_with_predicate.cpp | ||
| 82 | frontend/maxwell/translate/translate.cpp | 83 | frontend/maxwell/translate/translate.cpp |
| 83 | frontend/maxwell/translate/translate.h | 84 | frontend/maxwell/translate/translate.h |
| 84 | ir_opt/collect_shader_info_pass.cpp | 85 | ir_opt/collect_shader_info_pass.cpp |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 3f6dedfdd..82c73bf8c 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -729,18 +729,6 @@ void TranslatorVisitor::SAM(u64) { | |||
| 729 | ThrowNotImplemented(Opcode::SAM); | 729 | ThrowNotImplemented(Opcode::SAM); |
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | void TranslatorVisitor::SEL_reg(u64) { | ||
| 733 | ThrowNotImplemented(Opcode::SEL_reg); | ||
| 734 | } | ||
| 735 | |||
| 736 | void TranslatorVisitor::SEL_cbuf(u64) { | ||
| 737 | ThrowNotImplemented(Opcode::SEL_cbuf); | ||
| 738 | } | ||
| 739 | |||
| 740 | void TranslatorVisitor::SEL_imm(u64) { | ||
| 741 | ThrowNotImplemented(Opcode::SEL_imm); | ||
| 742 | } | ||
| 743 | |||
| 744 | void TranslatorVisitor::SETCRSPTR(u64) { | 732 | void TranslatorVisitor::SETCRSPTR(u64) { |
| 745 | ThrowNotImplemented(Opcode::SETCRSPTR); | 733 | ThrowNotImplemented(Opcode::SETCRSPTR); |
| 746 | } | 734 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp new file mode 100644 index 000000000..25fc6b437 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/select_source_with_predicate.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | |||
| 12 | void SEL(TranslatorVisitor& v, u64 insn, const IR::U32& src) { | ||
| 13 | union { | ||
| 14 | u64 raw; | ||
| 15 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 16 | BitField<8, 8, IR::Reg> op_a; | ||
| 17 | BitField<39, 3, IR::Pred> pred; | ||
| 18 | BitField<42, 1, u64> neg_pred; | ||
| 19 | } const sel{insn}; | ||
| 20 | |||
| 21 | const IR::U1 pred = v.ir.GetPred(sel.pred); | ||
| 22 | IR::U32 op_a{v.X(sel.op_a)}; | ||
| 23 | IR::U32 op_b{src}; | ||
| 24 | if (sel.neg_pred != 0) { | ||
| 25 | std::swap(op_a, op_b); | ||
| 26 | } | ||
| 27 | const IR::U32 result{v.ir.Select(pred, op_a, op_b)}; | ||
| 28 | |||
| 29 | v.X(sel.dest_reg, result); | ||
| 30 | } | ||
| 31 | } // Anonymous namespace | ||
| 32 | |||
| 33 | void TranslatorVisitor::SEL_reg(u64 insn) { | ||
| 34 | SEL(*this, insn, GetReg20(insn)); | ||
| 35 | } | ||
| 36 | |||
| 37 | void TranslatorVisitor::SEL_cbuf(u64 insn) { | ||
| 38 | SEL(*this, insn, GetCbuf(insn)); | ||
| 39 | } | ||
| 40 | |||
| 41 | void TranslatorVisitor::SEL_imm(u64 insn) { | ||
| 42 | SEL(*this, insn, GetImm20(insn)); | ||
| 43 | } | ||
| 44 | } // namespace Shader::Maxwell | ||
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 13f9c914a..19d35b1f8 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -109,11 +109,13 @@ IR::Opcode UndefOpcode(const FlagTag&) noexcept { | |||
| 109 | 109 | ||
| 110 | class Pass { | 110 | class Pass { |
| 111 | public: | 111 | public: |
| 112 | void WriteVariable(auto variable, IR::Block* block, const IR::Value& value) { | 112 | template <typename Type> |
| 113 | void WriteVariable(Type variable, IR::Block* block, const IR::Value& value) { | ||
| 113 | current_def[variable].insert_or_assign(block, value); | 114 | current_def[variable].insert_or_assign(block, value); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | IR::Value ReadVariable(auto variable, IR::Block* block) { | 117 | template <typename Type> |
| 118 | IR::Value ReadVariable(Type variable, IR::Block* block) { | ||
| 117 | const ValueMap& def{current_def[variable]}; | 119 | const ValueMap& def{current_def[variable]}; |
| 118 | if (const auto it{def.find(block)}; it != def.end()) { | 120 | if (const auto it{def.find(block)}; it != def.end()) { |
| 119 | return it->second; | 121 | return it->second; |
| @@ -132,7 +134,8 @@ public: | |||
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | private: | 136 | private: |
| 135 | IR::Value ReadVariableRecursive(auto variable, IR::Block* block) { | 137 | template <typename Type> |
| 138 | IR::Value ReadVariableRecursive(Type variable, IR::Block* block) { | ||
| 136 | IR::Value val; | 139 | IR::Value val; |
| 137 | if (!sealed_blocks.contains(block)) { | 140 | if (!sealed_blocks.contains(block)) { |
| 138 | // Incomplete CFG | 141 | // Incomplete CFG |
| @@ -154,7 +157,8 @@ private: | |||
| 154 | return val; | 157 | return val; |
| 155 | } | 158 | } |
| 156 | 159 | ||
| 157 | IR::Value AddPhiOperands(auto variable, IR::Inst& phi, IR::Block* block) { | 160 | template <typename Type> |
| 161 | IR::Value AddPhiOperands(Type variable, IR::Inst& phi, IR::Block* block) { | ||
| 158 | for (IR::Block* const imm_pred : block->ImmediatePredecessors()) { | 162 | for (IR::Block* const imm_pred : block->ImmediatePredecessors()) { |
| 159 | phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred)); | 163 | phi.AddPhiOperand(imm_pred, ReadVariable(variable, imm_pred)); |
| 160 | } | 164 | } |