diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 36 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 67194b0e3..a36df65f9 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -280,6 +280,19 @@ union Instruction { | |||
| 280 | BitField<56, 1, u64> invert_b; | 280 | BitField<56, 1, u64> invert_b; |
| 281 | } lop32i; | 281 | } lop32i; |
| 282 | 282 | ||
| 283 | union { | ||
| 284 | BitField<28, 8, u64> imm_lut28; | ||
| 285 | BitField<48, 8, u64> imm_lut48; | ||
| 286 | |||
| 287 | u32 GetImmLut28() const { | ||
| 288 | return static_cast<u32>(imm_lut28); | ||
| 289 | } | ||
| 290 | |||
| 291 | u32 GetImmLut48() const { | ||
| 292 | return static_cast<u32>(imm_lut48); | ||
| 293 | } | ||
| 294 | } lop3; | ||
| 295 | |||
| 283 | u32 GetImm20_19() const { | 296 | u32 GetImm20_19() const { |
| 284 | u32 imm{static_cast<u32>(imm20_19)}; | 297 | u32 imm{static_cast<u32>(imm20_19)}; |
| 285 | imm <<= 12; | 298 | imm <<= 12; |
| @@ -650,6 +663,9 @@ public: | |||
| 650 | LOP_R, | 663 | LOP_R, |
| 651 | LOP_IMM, | 664 | LOP_IMM, |
| 652 | LOP32I, | 665 | LOP32I, |
| 666 | LOP3_C, | ||
| 667 | LOP3_R, | ||
| 668 | LOP3_IMM, | ||
| 653 | MOV_C, | 669 | MOV_C, |
| 654 | MOV_R, | 670 | MOV_R, |
| 655 | MOV_IMM, | 671 | MOV_IMM, |
| @@ -872,6 +888,9 @@ private: | |||
| 872 | INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), | 888 | INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), |
| 873 | INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), | 889 | INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), |
| 874 | INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"), | 890 | INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"), |
| 891 | INST("0000001---------", Id::LOP3_C, Type::ArithmeticInteger, "LOP3_C"), | ||
| 892 | INST("0101101111100---", Id::LOP3_R, Type::ArithmeticInteger, "LOP3_R"), | ||
| 893 | INST("0011110---------", Id::LOP3_IMM, Type::ArithmeticInteger, "LOP3_IMM"), | ||
| 875 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), | 894 | INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"), |
| 876 | INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), | 895 | INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"), |
| 877 | INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"), | 896 | INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 5b976b636..7926726a1 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -849,6 +849,28 @@ private: | |||
| 849 | } | 849 | } |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | void WriteLop3Instruction(Register dest, const std::string& op_a, const std::string& op_b, | ||
| 853 | const std::string& op_c, const std::string& imm_lut) { | ||
| 854 | std::string result; | ||
| 855 | result += '('; | ||
| 856 | |||
| 857 | for (u32 i = 0; i < 32; ++i) { | ||
| 858 | std::string ix = std::to_string(i); | ||
| 859 | if (i) | ||
| 860 | result += '|'; | ||
| 861 | result += "(((" + imm_lut + ">>(((" + op_c + ">>" + ix + ")&1)|((" + op_b + ">>" + ix + | ||
| 862 | ")&1)<<1|((" + op_a + ">>" + ix + ")&1)<<2))&1)<<" + ix + ")"; | ||
| 863 | } | ||
| 864 | |||
| 865 | result += ')'; | ||
| 866 | |||
| 867 | LOG_DEBUG(HW_GPU, "LOP3 Shader code: {}", result); | ||
| 868 | |||
| 869 | if (dest != Tegra::Shader::Register::ZeroIndex) { | ||
| 870 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | ||
| 871 | } | ||
| 872 | } | ||
| 873 | |||
| 852 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, | 874 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, |
| 853 | const std::string& texture) { | 875 | const std::string& texture) { |
| 854 | // Add an extra scope and declare the texture coords inside to prevent | 876 | // Add an extra scope and declare the texture coords inside to prevent |
| @@ -1297,6 +1319,20 @@ private: | |||
| 1297 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); | 1319 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); |
| 1298 | break; | 1320 | break; |
| 1299 | } | 1321 | } |
| 1322 | case OpCode::Id::LOP3_C: | ||
| 1323 | case OpCode::Id::LOP3_R: | ||
| 1324 | case OpCode::Id::LOP3_IMM: { | ||
| 1325 | std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); | ||
| 1326 | std::string lut; | ||
| 1327 | if (opcode->GetId() == OpCode::Id::LOP3_R) { | ||
| 1328 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; | ||
| 1329 | } else { | ||
| 1330 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')'; | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); | ||
| 1334 | break; | ||
| 1335 | } | ||
| 1300 | case OpCode::Id::IMNMX_C: | 1336 | case OpCode::Id::IMNMX_C: |
| 1301 | case OpCode::Id::IMNMX_R: | 1337 | case OpCode::Id::IMNMX_R: |
| 1302 | case OpCode::Id::IMNMX_IMM: { | 1338 | case OpCode::Id::IMNMX_IMM: { |