summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h16
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp43
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 3add56155..22c122fcc 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
159enum class LogicOperation : u64 {
160 And = 0,
161 Or = 1,
162 Xor = 2,
163 PassB = 3,
164};
165
159enum class SubOp : u64 { 166enum 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)};
@@ -391,6 +404,7 @@ public:
391 enum class Type { 404 enum class Type {
392 Trivial, 405 Trivial,
393 Arithmetic, 406 Arithmetic,
407 Logic,
394 Ffma, 408 Ffma,
395 Flow, 409 Flow,
396 Memory, 410 Memory,
@@ -524,7 +538,6 @@ private:
524 INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"), 538 INST("0100110010110---", Id::F2I_C, Type::Arithmetic, "F2I_C"),
525 INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"), 539 INST("0101110010110---", Id::F2I_R, Type::Arithmetic, "F2I_R"),
526 INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"), 540 INST("0011100-10110---", Id::F2I_IMM, Type::Arithmetic, "F2I_IMM"),
527 INST("000001----------", Id::LOP32I, Type::Arithmetic, "LOP32I"),
528 INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"), 541 INST("0100110010011---", Id::MOV_C, Type::Arithmetic, "MOV_C"),
529 INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"), 542 INST("0101110010011---", Id::MOV_R, Type::Arithmetic, "MOV_R"),
530 INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"), 543 INST("0011100-10011---", Id::MOV_IMM, Type::Arithmetic, "MOV_IMM"),
@@ -535,6 +548,7 @@ private:
535 INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"), 548 INST("0100110001100---", Id::FMNMX_C, Type::Arithmetic, "FMNMX_C"),
536 INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"), 549 INST("0101110001100---", Id::FMNMX_R, Type::Arithmetic, "FMNMX_R"),
537 INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"), 550 INST("0011100-01100---", Id::FMNMX_IMM, Type::Arithmetic, "FMNMX_IMM"),
551 INST("000001----------", Id::LOP32I, Type::Logic, "LOP32I"),
538 INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"), 552 INST("0100110011100---", Id::I2I_C, Type::Conversion, "I2I_C"),
539 INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"), 553 INST("0101110011100---", Id::I2I_R, Type::Conversion, "I2I_R"),
540 INST("01110001-1000---", Id::I2I_IMM, Type::Conversion, "I2I_IMM"), 554 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 8c263f15f..9943394c6 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -841,6 +841,49 @@ private:
841 } 841 }
842 break; 842 break;
843 } 843 }
844 case OpCode::Type::Logic: {
845 std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, false);
846
847 if (instr.alu.lop.invert_a)
848 op_a = "~(" + op_a + ')';
849
850 switch (opcode->GetId()) {
851 case OpCode::Id::LOP32I: {
852 u32 imm = static_cast<u32>(instr.alu.imm20_32.Value());
853
854 if (instr.alu.lop.invert_b)
855 imm = ~imm;
856
857 switch (instr.alu.lop.operation) {
858 case Tegra::Shader::LogicOperation::And: {
859 regs.SetRegisterToInteger(instr.gpr0, false, 0,
860 '(' + op_a + " & " + std::to_string(imm) + ')', 1, 1);
861 break;
862 }
863 case Tegra::Shader::LogicOperation::Or: {
864 regs.SetRegisterToInteger(instr.gpr0, false, 0,
865 '(' + op_a + " | " + std::to_string(imm) + ')', 1, 1);
866 break;
867 }
868 case Tegra::Shader::LogicOperation::Xor: {
869 regs.SetRegisterToInteger(instr.gpr0, false, 0,
870 '(' + op_a + " ^ " + std::to_string(imm) + ')', 1, 1);
871 break;
872 }
873 default:
874 NGLOG_CRITICAL(HW_GPU, "Unimplemented lop32i operation: {}",
875 static_cast<u32>(instr.alu.lop.operation.Value()));
876 UNREACHABLE();
877 }
878 break;
879 }
880 default: {
881 NGLOG_CRITICAL(HW_GPU, "Unhandled logic instruction: {}", opcode->GetName());
882 UNREACHABLE();
883 }
884 }
885 break;
886 }
844 case OpCode::Type::Ffma: { 887 case OpCode::Type::Ffma: {
845 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 888 std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
846 std::string op_b = instr.ffma.negate_b ? "-" : ""; 889 std::string op_b = instr.ffma.negate_b ? "-" : "";