diff options
| author | 2018-06-17 13:26:11 -0400 | |
|---|---|---|
| committer | 2018-06-17 15:27:48 -0400 | |
| commit | afdd657d307306af27796199b798e7441fb7e21d (patch) | |
| tree | 196b3267a4521b1bd0fb103e6e20854705499b35 /src | |
| parent | gl_shader_decompiler: Refactor LOP32I instruction a bit in support of LOP. (diff) | |
| download | yuzu-afdd657d307306af27796199b798e7441fb7e21d.tar.gz yuzu-afdd657d307306af27796199b798e7441fb7e21d.tar.xz yuzu-afdd657d307306af27796199b798e7441fb7e21d.zip | |
gl_shader_decompiler: Implement LOP instructions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 34 |
2 files changed, 42 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 800b70dbf..cefd57f4c 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -230,6 +230,14 @@ union Instruction { | |||
| 230 | } fmnmx; | 230 | } fmnmx; |
| 231 | 231 | ||
| 232 | union { | 232 | union { |
| 233 | BitField<39, 1, u64> invert_a; | ||
| 234 | BitField<40, 1, u64> invert_b; | ||
| 235 | BitField<41, 2, LogicOperation> operation; | ||
| 236 | BitField<44, 2, u64> unk44; | ||
| 237 | BitField<48, 3, Pred> pred48; | ||
| 238 | } lop; | ||
| 239 | |||
| 240 | union { | ||
| 233 | BitField<53, 2, LogicOperation> operation; | 241 | BitField<53, 2, LogicOperation> operation; |
| 234 | BitField<55, 1, u64> invert_a; | 242 | BitField<55, 1, u64> invert_a; |
| 235 | BitField<56, 1, u64> invert_b; | 243 | BitField<56, 1, u64> invert_b; |
| @@ -476,6 +484,9 @@ public: | |||
| 476 | I2I_C, | 484 | I2I_C, |
| 477 | I2I_R, | 485 | I2I_R, |
| 478 | I2I_IMM, | 486 | I2I_IMM, |
| 487 | LOP_C, | ||
| 488 | LOP_R, | ||
| 489 | LOP_IMM, | ||
| 479 | LOP32I, | 490 | LOP32I, |
| 480 | MOV_C, | 491 | MOV_C, |
| 481 | MOV_R, | 492 | MOV_R, |
| @@ -675,6 +686,9 @@ private: | |||
| 675 | INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), | 686 | INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), |
| 676 | INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), | 687 | INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), |
| 677 | INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), | 688 | INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), |
| 689 | INST("0100110001000---", Id::LOP_C, Type::ArithmeticInteger, "LOP_C"), | ||
| 690 | INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), | ||
| 691 | INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), | ||
| 678 | INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"), | 692 | INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"), |
| 679 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), | 693 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), |
| 680 | INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), | 694 | 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 b7b49cf72..6ec0a0742 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1043,12 +1043,7 @@ private: | |||
| 1043 | } | 1043 | } |
| 1044 | case OpCode::Type::ArithmeticInteger: { | 1044 | case OpCode::Type::ArithmeticInteger: { |
| 1045 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); | 1045 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); |
| 1046 | 1046 | std::string op_b; | |
| 1047 | if (instr.alu_integer.negate_a) | ||
| 1048 | op_a = '-' + op_a; | ||
| 1049 | |||
| 1050 | std::string op_b = instr.alu_integer.negate_b ? "-" : ""; | ||
| 1051 | |||
| 1052 | if (instr.is_b_imm) { | 1047 | if (instr.is_b_imm) { |
| 1053 | op_b += '(' + std::to_string(instr.alu.GetSignedImm20_20()) + ')'; | 1048 | op_b += '(' + std::to_string(instr.alu.GetSignedImm20_20()) + ')'; |
| 1054 | } else { | 1049 | } else { |
| @@ -1064,6 +1059,12 @@ private: | |||
| 1064 | case OpCode::Id::IADD_C: | 1059 | case OpCode::Id::IADD_C: |
| 1065 | case OpCode::Id::IADD_R: | 1060 | case OpCode::Id::IADD_R: |
| 1066 | case OpCode::Id::IADD_IMM: { | 1061 | case OpCode::Id::IADD_IMM: { |
| 1062 | if (instr.alu_integer.negate_a) | ||
| 1063 | op_a = "-(" + op_a + ')'; | ||
| 1064 | |||
| 1065 | if (instr.alu_integer.negate_b) | ||
| 1066 | op_b = "-(" + op_b + ')'; | ||
| 1067 | |||
| 1067 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, | 1068 | regs.SetRegisterToInteger(instr.gpr0, true, 0, op_a + " + " + op_b, 1, 1, |
| 1068 | instr.alu.saturate_d); | 1069 | instr.alu.saturate_d); |
| 1069 | break; | 1070 | break; |
| @@ -1071,12 +1072,33 @@ private: | |||
| 1071 | case OpCode::Id::ISCADD_C: | 1072 | case OpCode::Id::ISCADD_C: |
| 1072 | case OpCode::Id::ISCADD_R: | 1073 | case OpCode::Id::ISCADD_R: |
| 1073 | case OpCode::Id::ISCADD_IMM: { | 1074 | case OpCode::Id::ISCADD_IMM: { |
| 1075 | if (instr.alu_integer.negate_a) | ||
| 1076 | op_a = "-(" + op_a + ')'; | ||
| 1077 | |||
| 1078 | if (instr.alu_integer.negate_b) | ||
| 1079 | op_b = "-(" + op_b + ')'; | ||
| 1080 | |||
| 1074 | std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); | 1081 | std::string shift = std::to_string(instr.alu_integer.shift_amount.Value()); |
| 1075 | 1082 | ||
| 1076 | regs.SetRegisterToInteger(instr.gpr0, true, 0, | 1083 | regs.SetRegisterToInteger(instr.gpr0, true, 0, |
| 1077 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | 1084 | "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); |
| 1078 | break; | 1085 | break; |
| 1079 | } | 1086 | } |
| 1087 | case OpCode::Id::LOP_C: | ||
| 1088 | case OpCode::Id::LOP_R: | ||
| 1089 | case OpCode::Id::LOP_IMM: { | ||
| 1090 | ASSERT_MSG(!instr.alu.lop.unk44, "Unimplemented"); | ||
| 1091 | ASSERT_MSG(instr.alu.lop.pred48 == Pred::UnusedIndex, "Unimplemented"); | ||
| 1092 | |||
| 1093 | if (instr.alu.lop.invert_a) | ||
| 1094 | op_a = "~(" + op_a + ')'; | ||
| 1095 | |||
| 1096 | if (instr.alu.lop.invert_b) | ||
| 1097 | op_b = "~(" + op_b + ')'; | ||
| 1098 | |||
| 1099 | WriteLogicOperation(instr.gpr0, instr.alu.lop.operation, op_a, op_b); | ||
| 1100 | break; | ||
| 1101 | } | ||
| 1080 | default: { | 1102 | default: { |
| 1081 | NGLOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", | 1103 | NGLOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}", |
| 1082 | opcode->GetName()); | 1104 | opcode->GetName()); |