summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h19
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp36
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: {