summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h25
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp50
2 files changed, 75 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index d6d46d277..f84b9883c 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -574,6 +574,22 @@ union Instruction {
574 } alu_integer; 574 } alu_integer;
575 575
576 union { 576 union {
577 BitField<39, 1, u64> ftz;
578 BitField<32, 1, u64> saturate;
579 BitField<49, 2, HalfMerge> merge;
580
581 BitField<43, 1, u64> negate_a;
582 BitField<44, 1, u64> abs_a;
583 BitField<47, 2, HalfType> type_a;
584
585 BitField<31, 1, u64> negate_b;
586 BitField<30, 1, u64> abs_b;
587 BitField<47, 2, HalfType> type_b;
588
589 BitField<35, 2, HalfType> type_c;
590 } alu_half;
591
592 union {
577 BitField<40, 1, u64> invert; 593 BitField<40, 1, u64> invert;
578 } popc; 594 } popc;
579 595
@@ -1165,6 +1181,10 @@ public:
1165 LEA_RZ, 1181 LEA_RZ,
1166 LEA_IMM, 1182 LEA_IMM,
1167 LEA_HI, 1183 LEA_HI,
1184 HADD2_C,
1185 HADD2_R,
1186 HMUL2_C,
1187 HMUL2_R,
1168 POPC_C, 1188 POPC_C,
1169 POPC_R, 1189 POPC_R,
1170 POPC_IMM, 1190 POPC_IMM,
@@ -1238,6 +1258,7 @@ public:
1238 ArithmeticImmediate, 1258 ArithmeticImmediate,
1239 ArithmeticInteger, 1259 ArithmeticInteger,
1240 ArithmeticIntegerImmediate, 1260 ArithmeticIntegerImmediate,
1261 ArithmeticHalf,
1241 Bfe, 1262 Bfe,
1242 Shift, 1263 Shift,
1243 Ffma, 1264 Ffma,
@@ -1409,6 +1430,10 @@ private:
1409 INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"), 1430 INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
1410 INST("010010111101----", Id::LEA_RZ, Type::ArithmeticInteger, "LEA_RZ"), 1431 INST("010010111101----", Id::LEA_RZ, Type::ArithmeticInteger, "LEA_RZ"),
1411 INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"), 1432 INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"),
1433 INST("0111101-1-------", Id::HADD2_C, Type::ArithmeticHalf, "HADD2_C"),
1434 INST("0101110100010---", Id::HADD2_R, Type::ArithmeticHalf, "HADD2_R"),
1435 INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"),
1436 INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"),
1412 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), 1437 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
1413 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), 1438 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
1414 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), 1439 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index c6ae8c3b4..a1a0babe8 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1827,6 +1827,56 @@ private:
1827 1827
1828 break; 1828 break;
1829 } 1829 }
1830 case OpCode::Type::ArithmeticHalf: {
1831 if (opcode->GetId() == OpCode::Id::HADD2_C || opcode->GetId() == OpCode::Id::HADD2_R) {
1832 ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented");
1833 }
1834 const bool negate_a =
1835 opcode->GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
1836 const bool negate_b =
1837 opcode->GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
1838
1839 const std::string op_a =
1840 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a,
1841 instr.alu_half.abs_a != 0, negate_a);
1842
1843 std::string op_b;
1844 switch (opcode->GetId()) {
1845 case OpCode::Id::HADD2_C:
1846 case OpCode::Id::HMUL2_C:
1847 op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
1848 GLSLRegister::Type::UnsignedInteger);
1849 break;
1850 case OpCode::Id::HADD2_R:
1851 case OpCode::Id::HMUL2_R:
1852 op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, false);
1853 break;
1854 default:
1855 UNREACHABLE();
1856 op_b = "0";
1857 break;
1858 }
1859 op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b);
1860
1861 const std::string result = [&]() {
1862 switch (opcode->GetId()) {
1863 case OpCode::Id::HADD2_C:
1864 case OpCode::Id::HADD2_R:
1865 return '(' + op_a + " + " + op_b + ')';
1866 case OpCode::Id::HMUL2_C:
1867 case OpCode::Id::HMUL2_R:
1868 return '(' + op_a + " * " + op_b + ')';
1869 default:
1870 LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", opcode->GetName());
1871 UNREACHABLE();
1872 return std::string("0");
1873 }
1874 }();
1875
1876 regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.alu_half.merge, 1, 1,
1877 instr.alu_half.saturate != 0);
1878 break;
1879 }
1830 case OpCode::Type::Ffma: { 1880 case OpCode::Type::Ffma: {
1831 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); 1881 const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
1832 std::string op_b = instr.ffma.negate_b ? "-" : ""; 1882 std::string op_b = instr.ffma.negate_b ? "-" : "";