summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h30
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp43
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 ? "-" : "";