diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 32 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 53 |
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: { |