diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 43 |
2 files changed, 58 insertions, 1 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 3add56155..22c122fcc 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -156,6 +156,13 @@ enum class PredOperation : u64 { | |||
| 156 | Xor = 2, | 156 | Xor = 2, |
| 157 | }; | 157 | }; |
| 158 | 158 | ||
| 159 | enum class LogicOperation : u64 { | ||
| 160 | And = 0, | ||
| 161 | Or = 1, | ||
| 162 | Xor = 2, | ||
| 163 | PassB = 3, | ||
| 164 | }; | ||
| 165 | |||
| 159 | enum class SubOp : u64 { | 166 | enum class SubOp : u64 { |
| 160 | Cos = 0x0, | 167 | Cos = 0x0, |
| 161 | Sin = 0x1, | 168 | Sin = 0x1, |
| @@ -202,6 +209,12 @@ union Instruction { | |||
| 202 | BitField<42, 1, u64> negate_pred; | 209 | BitField<42, 1, u64> negate_pred; |
| 203 | } fmnmx; | 210 | } fmnmx; |
| 204 | 211 | ||
| 212 | union { | ||
| 213 | BitField<53, 2, LogicOperation> operation; | ||
| 214 | BitField<55, 1, u64> invert_a; | ||
| 215 | BitField<56, 1, u64> invert_b; | ||
| 216 | } lop; | ||
| 217 | |||
| 205 | float GetImm20_19() const { | 218 | float GetImm20_19() const { |
| 206 | float result{}; | 219 | float result{}; |
| 207 | u32 imm{static_cast<u32>(imm20_19)}; | 220 | u32 imm{static_cast<u32>(imm20_19)}; |
| @@ -391,6 +404,7 @@ public: | |||
| 391 | enum class Type { | 404 | enum class Type { |
| 392 | Trivial, | 405 | Trivial, |
| 393 | Arithmetic, | 406 | Arithmetic, |
| 407 | Logic, | ||
| 394 | Ffma, | 408 | Ffma, |
| 395 | Flow, | 409 | Flow, |
| 396 | Memory, | 410 | Memory, |
| @@ -524,7 +538,6 @@ private: | |||
| 524 | INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), | 538 | INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), |
| 525 | INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), | 539 | INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), |
| 526 | INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), | 540 | INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), |
| 527 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), | ||
| 528 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), | 541 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), |
| 529 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), | 542 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), |
| 530 | INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), | 543 | INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), |
| @@ -535,6 +548,7 @@ private: | |||
| 535 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), | 548 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), |
| 536 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), | 549 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), |
| 537 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), | 550 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), |
| 551 | INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"), | ||
| 538 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), | 552 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), |
| 539 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), | 553 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), |
| 540 | INST("01110001-1000---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), | 554 | INST("01110001-1000---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 8c263f15f..9943394c6 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -841,6 +841,49 @@ private: | |||
| 841 | } | 841 | } |
| 842 | break; | 842 | break; |
| 843 | } | 843 | } |
| 844 | case OpCode::Type::Logic: { | ||
| 845 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, false); | ||
| 846 | |||
| 847 | if (instr.alu.lop.invert_a) | ||
| 848 | op_a = "~(" + op_a + ')'; | ||
| 849 | |||
| 850 | switch (opcode->GetId()) { | ||
| 851 | case OpCode::Id::LOP32I: { | ||
| 852 | u32 imm = static_cast<u32>(instr.alu.imm20_32.Value()); | ||
| 853 | |||
| 854 | if (instr.alu.lop.invert_b) | ||
| 855 | imm = ~imm; | ||
| 856 | |||
| 857 | switch (instr.alu.lop.operation) { | ||
| 858 | case Tegra::Shader::LogicOperation::And: { | ||
| 859 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 860 | '(' + op_a + " & " + std::to_string(imm) + ')', 1, 1); | ||
| 861 | break; | ||
| 862 | } | ||
| 863 | case Tegra::Shader::LogicOperation::Or: { | ||
| 864 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 865 | '(' + op_a + " | " + std::to_string(imm) + ')', 1, 1); | ||
| 866 | break; | ||
| 867 | } | ||
| 868 | case Tegra::Shader::LogicOperation::Xor: { | ||
| 869 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 870 | '(' + op_a + " ^ " + std::to_string(imm) + ')', 1, 1); | ||
| 871 | break; | ||
| 872 | } | ||
| 873 | default: | ||
| 874 | NGLOG_CRITICAL(HW_GPU, "Unimplemented lop32i operation: {}", | ||
| 875 | static_cast<u32>(instr.alu.lop.operation.Value())); | ||
| 876 | UNREACHABLE(); | ||
| 877 | } | ||
| 878 | break; | ||
| 879 | } | ||
| 880 | default: { | ||
| 881 | NGLOG_CRITICAL(HW_GPU, "Unhandled logic instruction: {}", opcode->GetName()); | ||
| 882 | UNREACHABLE(); | ||
| 883 | } | ||
| 884 | } | ||
| 885 | break; | ||
| 886 | } | ||
| 844 | case OpCode::Type::Ffma: { | 887 | case OpCode::Type::Ffma: { |
| 845 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 888 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 846 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 889 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |