summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/shader_bytecode.h32
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp53
2 files changed, 85 insertions, 0 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 3fbdd20b8..23bfd8988 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -615,6 +615,29 @@ union Instruction {
615 } half_imm; 615 } half_imm;
616 616
617 union { 617 union {
618 union {
619 BitField<37, 2, HalfPrecision> precision;
620 BitField<32, 1, u64> saturate;
621
622 BitField<30, 1, u64> negate_c;
623 BitField<35, 2, HalfType> type_c;
624 } rr;
625
626 BitField<57, 2, HalfPrecision> precision;
627 BitField<52, 1, u64> saturate;
628
629 BitField<49, 2, HalfMerge> merge;
630
631 BitField<47, 2, HalfType> type_a;
632
633 BitField<56, 1, u64> negate_b;
634 BitField<28, 2, HalfType> type_b;
635
636 BitField<51, 1, u64> negate_c;
637 BitField<53, 2, HalfType> type_reg39;
638 } hfma2;
639
640 union {
618 BitField<40, 1, u64> invert; 641 BitField<40, 1, u64> invert;
619 } popc; 642 } popc;
620 643
@@ -1212,6 +1235,10 @@ public:
1212 HMUL2_C, 1235 HMUL2_C,
1213 HMUL2_R, 1236 HMUL2_R,
1214 HMUL2_IMM, 1237 HMUL2_IMM,
1238 HFMA2_CR,
1239 HFMA2_RC,
1240 HFMA2_RR,
1241 HFMA2_IMM_R,
1215 POPC_C, 1242 POPC_C,
1216 POPC_R, 1243 POPC_R,
1217 POPC_IMM, 1244 POPC_IMM,
@@ -1290,6 +1317,7 @@ public:
1290 Bfe, 1317 Bfe,
1291 Shift, 1318 Shift,
1292 Ffma, 1319 Ffma,
1320 Hfma2,
1293 Flow, 1321 Flow,
1294 Synch, 1322 Synch,
1295 Memory, 1323 Memory,
@@ -1464,6 +1492,10 @@ private:
1464 INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"), 1492 INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"),
1465 INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"), 1493 INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"),
1466 INST("0111100-0-------", Id::HMUL2_IMM, Type::ArithmeticHalfImmediate, "HMUL2_IMM"), 1494 INST("0111100-0-------", Id::HMUL2_IMM, Type::ArithmeticHalfImmediate, "HMUL2_IMM"),
1495 INST("01110---1-------", Id::HFMA2_CR, Type::Hfma2, "HFMA2_CR"),
1496 INST("01100---1-------", Id::HFMA2_RC, Type::Hfma2, "HFMA2_RC"),
1497 INST("0101110100000---", Id::HFMA2_RR, Type::Hfma2, "HFMA2_RR"),
1498 INST("01110---0-------", Id::HFMA2_IMM_R, Type::Hfma2, "HFMA2_R_IMM"),
1467 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), 1499 INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
1468 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), 1500 INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
1469 INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), 1501 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 ab30aafc3..ca2030e97 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1964,6 +1964,59 @@ private:
1964 instr.alu.saturate_d); 1964 instr.alu.saturate_d);
1965 break; 1965 break;
1966 } 1966 }
1967 case OpCode::Type::Hfma2: {
1968 if (opcode->GetId() == OpCode::Id::HFMA2_RR) {
1969 ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None,
1970 "Unimplemented");
1971 } else {
1972 ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None,
1973 "Unimplemented");
1974 }
1975 const bool saturate = opcode->GetId() == OpCode::Id::HFMA2_RR
1976 ? instr.hfma2.rr.saturate != 0
1977 : instr.hfma2.saturate != 0;
1978
1979 const std::string op_a =
1980 GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a);
1981 std::string op_b, op_c;
1982
1983 switch (opcode->GetId()) {
1984 case OpCode::Id::HFMA2_CR:
1985 op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
1986 GLSLRegister::Type::UnsignedInteger),
1987 instr.hfma2.type_b, false, instr.hfma2.negate_b);
1988 op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
1989 instr.hfma2.type_reg39, false, instr.hfma2.negate_c);
1990 break;
1991 case OpCode::Id::HFMA2_RC:
1992 op_b = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
1993 instr.hfma2.type_reg39, false, instr.hfma2.negate_b);
1994 op_c = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
1995 GLSLRegister::Type::UnsignedInteger),
1996 instr.hfma2.type_b, false, instr.hfma2.negate_c);
1997 break;
1998 case OpCode::Id::HFMA2_RR:
1999 op_b = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
2000 instr.hfma2.type_b, false, instr.hfma2.negate_b);
2001 op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
2002 instr.hfma2.rr.type_c, false, instr.hfma2.rr.negate_c);
2003 break;
2004 case OpCode::Id::HFMA2_IMM_R:
2005 op_b = UnpackHalfImmediate(instr, true);
2006 op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
2007 instr.hfma2.type_reg39, false, instr.hfma2.negate_c);
2008 break;
2009 default:
2010 UNREACHABLE();
2011 op_c = op_b = "vec2(0)";
2012 break;
2013 }
2014
2015 const std::string result = '(' + op_a + " * " + op_b + " + " + op_c + ')';
2016
2017 regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.hfma2.merge, 1, 1, saturate);
2018 break;
2019 }
1967 case OpCode::Type::Conversion: { 2020 case OpCode::Type::Conversion: {
1968 switch (opcode->GetId()) { 2021 switch (opcode->GetId()) {
1969 case OpCode::Id::I2I_R: { 2022 case OpCode::Id::I2I_R: {