diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 43 |
2 files changed, 73 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index f84b9883c..3fbdd20b8 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -590,6 +590,31 @@ union Instruction { | |||
| 590 | } alu_half; | 590 | } alu_half; |
| 591 | 591 | ||
| 592 | union { | 592 | union { |
| 593 | BitField<39, 2, HalfPrecision> precision; | ||
| 594 | BitField<39, 1, u64> ftz; | ||
| 595 | BitField<52, 1, u64> saturate; | ||
| 596 | BitField<49, 2, HalfMerge> merge; | ||
| 597 | |||
| 598 | BitField<43, 1, u64> negate_a; | ||
| 599 | BitField<44, 1, u64> abs_a; | ||
| 600 | BitField<47, 2, HalfType> type_a; | ||
| 601 | } alu_half_imm; | ||
| 602 | |||
| 603 | union { | ||
| 604 | BitField<29, 1, u64> first_negate; | ||
| 605 | BitField<20, 9, u64> first; | ||
| 606 | |||
| 607 | BitField<56, 1, u64> second_negate; | ||
| 608 | BitField<30, 9, u64> second; | ||
| 609 | |||
| 610 | u32 PackImmediates() const { | ||
| 611 | // Immediates are half floats shifted. | ||
| 612 | constexpr u32 imm_shift = 6; | ||
| 613 | return static_cast<u32>((first << imm_shift) | (second << (16 + imm_shift))); | ||
| 614 | } | ||
| 615 | } half_imm; | ||
| 616 | |||
| 617 | union { | ||
| 593 | BitField<40, 1, u64> invert; | 618 | BitField<40, 1, u64> invert; |
| 594 | } popc; | 619 | } popc; |
| 595 | 620 | ||
| @@ -1183,8 +1208,10 @@ public: | |||
| 1183 | LEA_HI, | 1208 | LEA_HI, |
| 1184 | HADD2_C, | 1209 | HADD2_C, |
| 1185 | HADD2_R, | 1210 | HADD2_R, |
| 1211 | HADD2_IMM, | ||
| 1186 | HMUL2_C, | 1212 | HMUL2_C, |
| 1187 | HMUL2_R, | 1213 | HMUL2_R, |
| 1214 | HMUL2_IMM, | ||
| 1188 | POPC_C, | 1215 | POPC_C, |
| 1189 | POPC_R, | 1216 | POPC_R, |
| 1190 | POPC_IMM, | 1217 | POPC_IMM, |
| @@ -1259,6 +1286,7 @@ public: | |||
| 1259 | ArithmeticInteger, | 1286 | ArithmeticInteger, |
| 1260 | ArithmeticIntegerImmediate, | 1287 | ArithmeticIntegerImmediate, |
| 1261 | ArithmeticHalf, | 1288 | ArithmeticHalf, |
| 1289 | ArithmeticHalfImmediate, | ||
| 1262 | Bfe, | 1290 | Bfe, |
| 1263 | Shift, | 1291 | Shift, |
| 1264 | Ffma, | 1292 | Ffma, |
| @@ -1432,8 +1460,10 @@ private: | |||
| 1432 | INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"), | 1460 | INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"), |
| 1433 | INST("0111101-1-------", Id::HADD2_C, Type::ArithmeticHalf, "HADD2_C"), | 1461 | INST("0111101-1-------", Id::HADD2_C, Type::ArithmeticHalf, "HADD2_C"), |
| 1434 | INST("0101110100010---", Id::HADD2_R, Type::ArithmeticHalf, "HADD2_R"), | 1462 | INST("0101110100010---", Id::HADD2_R, Type::ArithmeticHalf, "HADD2_R"), |
| 1463 | INST("0111101-0-------", Id::HADD2_IMM, Type::ArithmeticHalfImmediate, "HADD2_IMM"), | ||
| 1435 | INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"), | 1464 | INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"), |
| 1436 | INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"), | 1465 | INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"), |
| 1466 | INST("0111100-0-------", Id::HMUL2_IMM, Type::ArithmeticHalfImmediate, "HMUL2_IMM"), | ||
| 1437 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), | 1467 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), |
| 1438 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), | 1468 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), |
| 1439 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), | 1469 | 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 a1a0babe8..ab30aafc3 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -920,6 +920,19 @@ private: | |||
| 920 | return fmt::format("uintBitsToFloat({})", instr.alu.GetImm20_32()); | 920 | return fmt::format("uintBitsToFloat({})", instr.alu.GetImm20_32()); |
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | /// Generates code representing a vec2 pair unpacked from a half float immediate | ||
| 924 | static std::string UnpackHalfImmediate(const Instruction& instr, bool negate) { | ||
| 925 | const std::string immediate = GetHalfFloat(std::to_string(instr.half_imm.PackImmediates())); | ||
| 926 | if (!negate) { | ||
| 927 | return immediate; | ||
| 928 | } | ||
| 929 | const std::string negate_first = instr.half_imm.first_negate != 0 ? "-" : ""; | ||
| 930 | const std::string negate_second = instr.half_imm.second_negate != 0 ? "-" : ""; | ||
| 931 | const std::string negate_vec = "vec2(" + negate_first + "1, " + negate_second + "1)"; | ||
| 932 | |||
| 933 | return '(' + immediate + " * " + negate_vec + ')'; | ||
| 934 | } | ||
| 935 | |||
| 923 | /// Generates code representing a texture sampler. | 936 | /// Generates code representing a texture sampler. |
| 924 | std::string GetSampler(const Sampler& sampler, Tegra::Shader::TextureType type, bool is_array, | 937 | std::string GetSampler(const Sampler& sampler, Tegra::Shader::TextureType type, bool is_array, |
| 925 | bool is_shadow) { | 938 | bool is_shadow) { |
| @@ -1877,6 +1890,36 @@ private: | |||
| 1877 | instr.alu_half.saturate != 0); | 1890 | instr.alu_half.saturate != 0); |
| 1878 | break; | 1891 | break; |
| 1879 | } | 1892 | } |
| 1893 | case OpCode::Type::ArithmeticHalfImmediate: { | ||
| 1894 | if (opcode->GetId() == OpCode::Id::HADD2_IMM) { | ||
| 1895 | ASSERT_MSG(instr.alu_half_imm.ftz == 0, "Unimplemented"); | ||
| 1896 | } else { | ||
| 1897 | ASSERT_MSG(instr.alu_half_imm.precision == Tegra::Shader::HalfPrecision::None, | ||
| 1898 | "Unimplemented"); | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | const std::string op_a = GetHalfFloat( | ||
| 1902 | regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half_imm.type_a, | ||
| 1903 | instr.alu_half_imm.abs_a != 0, instr.alu_half_imm.negate_a != 0); | ||
| 1904 | |||
| 1905 | const std::string op_b = UnpackHalfImmediate(instr, true); | ||
| 1906 | |||
| 1907 | const std::string result = [&]() { | ||
| 1908 | switch (opcode->GetId()) { | ||
| 1909 | case OpCode::Id::HADD2_IMM: | ||
| 1910 | return op_a + " + " + op_b; | ||
| 1911 | case OpCode::Id::HMUL2_IMM: | ||
| 1912 | return op_a + " * " + op_b; | ||
| 1913 | default: | ||
| 1914 | UNREACHABLE(); | ||
| 1915 | return std::string("0"); | ||
| 1916 | } | ||
| 1917 | }(); | ||
| 1918 | |||
| 1919 | regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.alu_half_imm.merge, 1, 1, | ||
| 1920 | instr.alu_half_imm.saturate != 0); | ||
| 1921 | break; | ||
| 1922 | } | ||
| 1880 | case OpCode::Type::Ffma: { | 1923 | case OpCode::Type::Ffma: { |
| 1881 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | 1924 | const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |
| 1882 | std::string op_b = instr.ffma.negate_b ? "-" : ""; | 1925 | std::string op_b = instr.ffma.negate_b ? "-" : ""; |