diff options
| author | 2018-06-07 00:58:12 -0400 | |
|---|---|---|
| committer | 2018-06-07 00:58:12 -0400 | |
| commit | 92209f905fff33eaf4812c3d4a153ff9fffb1ed0 (patch) | |
| tree | 53ef881e880ba5d728c31094f00ccd56e5d7e9c5 | |
| parent | Merge pull request #539 from bunnei/f2f-rounding (diff) | |
| download | yuzu-92209f905fff33eaf4812c3d4a153ff9fffb1ed0.tar.gz yuzu-92209f905fff33eaf4812c3d4a153ff9fffb1ed0.tar.xz yuzu-92209f905fff33eaf4812c3d4a153ff9fffb1ed0.zip | |
gl_shader_decompiler: Implement BFE_IMM instruction.
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 33 |
2 files changed, 44 insertions, 7 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 2cda1e63e..32800392b 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -266,6 +266,17 @@ union Instruction { | |||
| 266 | } iscadd; | 266 | } iscadd; |
| 267 | 267 | ||
| 268 | union { | 268 | union { |
| 269 | BitField<20, 8, u64> shift_position; | ||
| 270 | BitField<28, 8, u64> shift_length; | ||
| 271 | BitField<48, 1, u64> negate_b; | ||
| 272 | BitField<49, 1, u64> negate_a; | ||
| 273 | |||
| 274 | u64 GetLeftShiftValue() const { | ||
| 275 | return 32 - (shift_position + shift_length); | ||
| 276 | } | ||
| 277 | } bfe; | ||
| 278 | |||
| 279 | union { | ||
| 269 | BitField<48, 1, u64> negate_b; | 280 | BitField<48, 1, u64> negate_b; |
| 270 | BitField<49, 1, u64> negate_c; | 281 | BitField<49, 1, u64> negate_c; |
| 271 | } ffma; | 282 | } ffma; |
| @@ -478,6 +489,7 @@ public: | |||
| 478 | enum class Type { | 489 | enum class Type { |
| 479 | Trivial, | 490 | Trivial, |
| 480 | Arithmetic, | 491 | Arithmetic, |
| 492 | Bfe, | ||
| 481 | Logic, | 493 | Logic, |
| 482 | Shift, | 494 | Shift, |
| 483 | ScaledAdd, | 495 | ScaledAdd, |
| @@ -584,9 +596,6 @@ private: | |||
| 584 | std::vector<Matcher> table = { | 596 | std::vector<Matcher> table = { |
| 585 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) | 597 | #define INST(bitstring, op, type, name) Detail::GetMatcher(bitstring, op, type, name) |
| 586 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), | 598 | INST("111000110011----", Id::KIL, Type::Flow, "KIL"), |
| 587 | INST("0100110000000---", Id::BFE_C, Type::Flow, "BFE_C"), | ||
| 588 | INST("0101110000000---", Id::BFE_R, Type::Flow, "BFE_R"), | ||
| 589 | INST("0011100-00000---", Id::BFE_IMM, Type::Flow, "BFE_IMM"), | ||
| 590 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), | 599 | INST("111000100100----", Id::BRA, Type::Flow, "BRA"), |
| 591 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), | 600 | INST("1110111111011---", Id::LD_A, Type::Memory, "LD_A"), |
| 592 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), | 601 | INST("1110111110010---", Id::LD_C, Type::Memory, "LD_C"), |
| @@ -631,6 +640,9 @@ private: | |||
| 631 | INST("0100110000100---", Id::IMNMX_C, Type::Arithmetic, "FMNMX_IMM"), | 640 | INST("0100110000100---", Id::IMNMX_C, Type::Arithmetic, "FMNMX_IMM"), |
| 632 | INST("0101110000100---", Id::IMNMX_R, Type::Arithmetic, "FMNMX_IMM"), | 641 | INST("0101110000100---", Id::IMNMX_R, Type::Arithmetic, "FMNMX_IMM"), |
| 633 | INST("0011100-00100---", Id::IMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), | 642 | INST("0011100-00100---", Id::IMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), |
| 643 | INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), | ||
| 644 | INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), | ||
| 645 | INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), | ||
| 634 | INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"), | 646 | INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"), |
| 635 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), | 647 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), |
| 636 | INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), | 648 | INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 8e249584f..94c6bc4b2 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -888,8 +888,33 @@ private: | |||
| 888 | } | 888 | } |
| 889 | break; | 889 | break; |
| 890 | } | 890 | } |
| 891 | case OpCode::Type::Bfe: { | ||
| 892 | ASSERT_MSG(!instr.bfe.negate_b, "Unimplemented"); | ||
| 893 | |||
| 894 | std::string op_a = instr.bfe.negate_a ? "-" : ""; | ||
| 895 | op_a += regs.GetRegisterAsInteger(instr.gpr8); | ||
| 896 | |||
| 897 | switch (opcode->GetId()) { | ||
| 898 | case OpCode::Id::BFE_IMM: { | ||
| 899 | std::string inner_shift = | ||
| 900 | '(' + op_a + " << " + std::to_string(instr.bfe.GetLeftShiftValue()) + ')'; | ||
| 901 | std::string outer_shift = | ||
| 902 | '(' + inner_shift + " >> " + | ||
| 903 | std::to_string(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position) + ')'; | ||
| 904 | |||
| 905 | regs.SetRegisterToInteger(instr.gpr0, true, 0, outer_shift, 1, 1); | ||
| 906 | break; | ||
| 907 | } | ||
| 908 | default: { | ||
| 909 | NGLOG_CRITICAL(HW_GPU, "Unhandled BFE instruction: {}", opcode->GetName()); | ||
| 910 | UNREACHABLE(); | ||
| 911 | } | ||
| 912 | } | ||
| 913 | |||
| 914 | break; | ||
| 915 | } | ||
| 891 | case OpCode::Type::Logic: { | 916 | case OpCode::Type::Logic: { |
| 892 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, false); | 917 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, true); |
| 893 | 918 | ||
| 894 | if (instr.alu.lop.invert_a) | 919 | if (instr.alu.lop.invert_a) |
| 895 | op_a = "~(" + op_a + ')'; | 920 | op_a = "~(" + op_a + ')'; |
| @@ -903,17 +928,17 @@ private: | |||
| 903 | 928 | ||
| 904 | switch (instr.alu.lop.operation) { | 929 | switch (instr.alu.lop.operation) { |
| 905 | case Tegra::Shader::LogicOperation::And: { | 930 | case Tegra::Shader::LogicOperation::And: { |
| 906 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | 931 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 907 | '(' + op_a + " & " + std::to_string(imm) + ')', 1, 1); | 932 | '(' + op_a + " & " + std::to_string(imm) + ')', 1, 1); |
| 908 | break; | 933 | break; |
| 909 | } | 934 | } |
| 910 | case Tegra::Shader::LogicOperation::Or: { | 935 | case Tegra::Shader::LogicOperation::Or: { |
| 911 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | 936 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 912 | '(' + op_a + " | " + std::to_string(imm) + ')', 1, 1); | 937 | '(' + op_a + " | " + std::to_string(imm) + ')', 1, 1); |
| 913 | break; | 938 | break; |
| 914 | } | 939 | } |
| 915 | case Tegra::Shader::LogicOperation::Xor: { | 940 | case Tegra::Shader::LogicOperation::Xor: { |
| 916 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | 941 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 917 | '(' + op_a + " ^ " + std::to_string(imm) + ')', 1, 1); | 942 | '(' + op_a + " ^ " + std::to_string(imm) + ')', 1, 1); |
| 918 | break; | 943 | break; |
| 919 | } | 944 | } |