diff options
| author | 2018-06-04 13:24:31 -0500 | |
|---|---|---|
| committer | 2018-06-04 13:56:31 -0500 | |
| commit | 0c688b421cf3488c9b4a46a8ca58053be9defad3 (patch) | |
| tree | bab57d98c4a5a2339a313af4e07725f74f2c9acc /src | |
| parent | Merge pull request #499 from bunnei/am-stuff (diff) | |
| download | yuzu-0c688b421cf3488c9b4a46a8ca58053be9defad3.tar.gz yuzu-0c688b421cf3488c9b4a46a8ca58053be9defad3.tar.xz yuzu-0c688b421cf3488c9b4a46a8ca58053be9defad3.zip | |
GPU: Implemented the LOP32I instruction.
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 da64430e9..14d72920f 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)}; |
| @@ -367,6 +380,7 @@ public: | |||
| 367 | enum class Type { | 380 | enum class Type { |
| 368 | Trivial, | 381 | Trivial, |
| 369 | Arithmetic, | 382 | Arithmetic, |
| 383 | Logic, | ||
| 370 | Ffma, | 384 | Ffma, |
| 371 | Flow, | 385 | Flow, |
| 372 | Memory, | 386 | Memory, |
| @@ -499,7 +513,6 @@ private: | |||
| 499 | INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), | 513 | INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), |
| 500 | INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), | 514 | INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), |
| 501 | INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), | 515 | INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), |
| 502 | INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"), | ||
| 503 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), | 516 | INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), |
| 504 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), | 517 | INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), |
| 505 | INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), | 518 | INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), |
| @@ -510,6 +523,7 @@ private: | |||
| 510 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), | 523 | INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), |
| 511 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), | 524 | INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), |
| 512 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), | 525 | INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), |
| 526 | INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"), | ||
| 513 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), | 527 | INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), |
| 514 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), | 528 | INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), |
| 515 | INST("01110001-1000---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), | 529 | 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 bb5209a7e..e29f0a1d3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -808,6 +808,49 @@ private: | |||
| 808 | } | 808 | } |
| 809 | break; | 809 | break; |
| 810 | } | 810 | } |
| 811 | case OpCode::Type::Logic: { | ||
| 812 | std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, false); | ||
| 813 | |||
| 814 | if (instr.alu.lop.invert_a) | ||
| 815 | op_a = "~(" + op_a + ')'; | ||
| 816 | |||
| 817 | switch (opcode->GetId()) { | ||
| 818 | case OpCode::Id::LOP32I: { | ||
| 819 | u32 imm = static_cast<u32>(instr.alu.imm20_32.Value()); | ||
| 820 | |||
| 821 | if (instr.alu.lop.invert_b) | ||
| 822 | imm = ~imm; | ||
| 823 | |||
| 824 | switch (instr.alu.lop.operation) { | ||
| 825 | case Tegra::Shader::LogicOperation::And: { | ||
| 826 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 827 | '(' + op_a + " & " + std::to_string(imm) + ')', 1, 1); | ||
| 828 | break; | ||
| 829 | } | ||
| 830 | case Tegra::Shader::LogicOperation::Or: { | ||
| 831 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 832 | '(' + op_a + " | " + std::to_string(imm) + ')', 1, 1); | ||
| 833 | break; | ||
| 834 | } | ||
| 835 | case Tegra::Shader::LogicOperation::Xor: { | ||
| 836 | regs.SetRegisterToInteger(instr.gpr0, false, 0, | ||
| 837 | '(' + op_a + " ^ " + std::to_string(imm) + ')', 1, 1); | ||
| 838 | break; | ||
| 839 | } | ||
| 840 | default: | ||
| 841 | NGLOG_CRITICAL(HW_GPU, "Unimplemented lop32i operation: {}", | ||
| 842 | static_cast<u32>(instr.alu.lop.operation.Value())); | ||
| 843 | UNREACHABLE(); | ||
| 844 | } | ||
| 845 | break; | ||
| 846 | } | ||
| 847 | default: { | ||
| 848 | NGLOG_CRITICAL(HW_GPU, "Unhandled logic instruction: {}", opcode->GetName()); | ||
| 849 | UNREACHABLE(); | ||
| 850 | } | ||
| 851 | } | ||
| 852 | break; | ||
| 853 | } | ||
| 811 | case OpCode::Type::Ffma: { | 854 | case OpCode::Type::Ffma: { |
| 812 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 855 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 813 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 856 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |