diff options
| author | 2018-10-15 02:04:31 -0300 | |
|---|---|---|
| committer | 2018-10-15 02:04:31 -0300 | |
| commit | d46e2a6e7ac22661d6debe090c8c6b25d565613a (patch) | |
| tree | 3a47cb6dc5119dafe75b5d417184c232f9a4f7c9 /src | |
| parent | gl_shader_decompiler: Setup base for half float unpacking and setting (diff) | |
| download | yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.gz yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.xz yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.zip | |
gl_shader_decompiler: Implement non-immediate HADD2 and HMUL2 instructions
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 50 |
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 ? "-" : ""; |