summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-06-07 00:58:12 -0400
committerGravatar bunnei2018-06-07 00:58:12 -0400
commit92209f905fff33eaf4812c3d4a153ff9fffb1ed0 (patch)
tree53ef881e880ba5d728c31094f00ccd56e5d7e9c5
parentMerge pull request #539 from bunnei/f2f-rounding (diff)
downloadyuzu-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.h18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp33
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 }