diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 41 |
2 files changed, 60 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 f1e00c93c..94e318966 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -849,6 +849,33 @@ 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 | if (dest == Tegra::Shader::Register::ZeroIndex) { | ||
| 855 | return; | ||
| 856 | } | ||
| 857 | |||
| 858 | static constexpr std::array<const char*, 32> shift_amounts = { | ||
| 859 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", | ||
| 860 | "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", | ||
| 861 | "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"}; | ||
| 862 | |||
| 863 | std::string result; | ||
| 864 | result += '('; | ||
| 865 | |||
| 866 | for (size_t i = 0; i < shift_amounts.size(); ++i) { | ||
| 867 | if (i) | ||
| 868 | result += '|'; | ||
| 869 | result += "(((" + imm_lut + " >> (((" + op_c + " >> " + shift_amounts[i] + | ||
| 870 | ") & 1) | ((" + op_b + " >> " + shift_amounts[i] + ") & 1) << 1 | ((" + op_a + | ||
| 871 | " >> " + shift_amounts[i] + ") & 1) << 2)) & 1) << " + shift_amounts[i] + ")"; | ||
| 872 | } | ||
| 873 | |||
| 874 | result += ')'; | ||
| 875 | |||
| 876 | regs.SetRegisterToInteger(dest, true, 0, result, 1, 1); | ||
| 877 | } | ||
| 878 | |||
| 852 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, | 879 | void WriteTexsInstruction(const Instruction& instr, const std::string& coord, |
| 853 | const std::string& texture) { | 880 | const std::string& texture) { |
| 854 | // Add an extra scope and declare the texture coords inside to prevent | 881 | // Add an extra scope and declare the texture coords inside to prevent |
| @@ -1297,6 +1324,20 @@ private: | |||
| 1297 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); | 1324 | instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); |
| 1298 | break; | 1325 | break; |
| 1299 | } | 1326 | } |
| 1327 | case OpCode::Id::LOP3_C: | ||
| 1328 | case OpCode::Id::LOP3_R: | ||
| 1329 | case OpCode::Id::LOP3_IMM: { | ||
| 1330 | std::string op_c = regs.GetRegisterAsInteger(instr.gpr39); | ||
| 1331 | std::string lut; | ||
| 1332 | if (opcode->GetId() == OpCode::Id::LOP3_R) { | ||
| 1333 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')'; | ||
| 1334 | } else { | ||
| 1335 | lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')'; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut); | ||
| 1339 | break; | ||
| 1340 | } | ||
| 1300 | case OpCode::Id::IMNMX_C: | 1341 | case OpCode::Id::IMNMX_C: |
| 1301 | case OpCode::Id::IMNMX_R: | 1342 | case OpCode::Id::IMNMX_R: |
| 1302 | case OpCode::Id::IMNMX_IMM: { | 1343 | case OpCode::Id::IMNMX_IMM: { |