summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h19
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp41
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: {