summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2018-10-15 07:08:31 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2018-10-15 07:55:51 +0200
commit3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c (patch)
tree39d062165482925c7e0b584daaecbfa97df26939 /src/video_core/renderer_opengl/gl_shader_decompiler.cpp
parentgl_shader_decompiler: Implement HADD2_IMM and HMUL2_IMM (diff)
downloadyuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar.gz
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar.bz2
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar.lz
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar.xz
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.tar.zst
yuzu-3d65aa4caf88a440eeaf2082b1f5ca3e2c41317c.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp53
1 files changed, 53 insertions, 0 deletions
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:
instr.alu.saturate_d);
break;
}
+ case OpCode::Type::Hfma2: {
+ if (opcode->GetId() == OpCode::Id::HFMA2_RR) {
+ ASSERT_MSG(instr.hfma2.rr.precision == Tegra::Shader::HalfPrecision::None,
+ "Unimplemented");
+ } else {
+ ASSERT_MSG(instr.hfma2.precision == Tegra::Shader::HalfPrecision::None,
+ "Unimplemented");
+ }
+ const bool saturate = opcode->GetId() == OpCode::Id::HFMA2_RR
+ ? instr.hfma2.rr.saturate != 0
+ : instr.hfma2.saturate != 0;
+
+ const std::string op_a =
+ GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.hfma2.type_a);
+ std::string op_b, op_c;
+
+ switch (opcode->GetId()) {
+ case OpCode::Id::HFMA2_CR:
+ op_b = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+ GLSLRegister::Type::UnsignedInteger),
+ instr.hfma2.type_b, false, instr.hfma2.negate_b);
+ op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
+ instr.hfma2.type_reg39, false, instr.hfma2.negate_c);
+ break;
+ case OpCode::Id::HFMA2_RC:
+ op_b = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
+ instr.hfma2.type_reg39, false, instr.hfma2.negate_b);
+ op_c = GetHalfFloat(regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+ GLSLRegister::Type::UnsignedInteger),
+ instr.hfma2.type_b, false, instr.hfma2.negate_c);
+ break;
+ case OpCode::Id::HFMA2_RR:
+ op_b = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr20, 0, false),
+ instr.hfma2.type_b, false, instr.hfma2.negate_b);
+ op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
+ instr.hfma2.rr.type_c, false, instr.hfma2.rr.negate_c);
+ break;
+ case OpCode::Id::HFMA2_IMM_R:
+ op_b = UnpackHalfImmediate(instr, true);
+ op_c = GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr39, 0, false),
+ instr.hfma2.type_reg39, false, instr.hfma2.negate_c);
+ break;
+ default:
+ UNREACHABLE();
+ op_c = op_b = "vec2(0)";
+ break;
+ }
+
+ const std::string result = '(' + op_a + " * " + op_b + " + " + op_c + ')';
+
+ regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.hfma2.merge, 1, 1, saturate);
+ break;
+ }
case OpCode::Type::Conversion: {
switch (opcode->GetId()) {
case OpCode::Id::I2I_R: {