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:04:31 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2018-10-15 07:04:31 +0200
commitd46e2a6e7ac22661d6debe090c8c6b25d565613a (patch)
tree3a47cb6dc5119dafe75b5d417184c232f9a4f7c9 /src/video_core/renderer_opengl/gl_shader_decompiler.cpp
parentgl_shader_decompiler: Setup base for half float unpacking and setting (diff)
downloadyuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.gz
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.bz2
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.lz
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.xz
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.tar.zst
yuzu-d46e2a6e7ac22661d6debe090c8c6b25d565613a.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp50
1 files changed, 50 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 c6ae8c3b4..a1a0babe8 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1827,6 +1827,56 @@ private:
break;
}
+ case OpCode::Type::ArithmeticHalf: {
+ if (opcode->GetId() == OpCode::Id::HADD2_C || opcode->GetId() == OpCode::Id::HADD2_R) {
+ ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented");
+ }
+ const bool negate_a =
+ opcode->GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
+ const bool negate_b =
+ opcode->GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
+
+ const std::string op_a =
+ GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a,
+ instr.alu_half.abs_a != 0, negate_a);
+
+ std::string op_b;
+ switch (opcode->GetId()) {
+ case OpCode::Id::HADD2_C:
+ case OpCode::Id::HMUL2_C:
+ op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+ GLSLRegister::Type::UnsignedInteger);
+ break;
+ case OpCode::Id::HADD2_R:
+ case OpCode::Id::HMUL2_R:
+ op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, false);
+ break;
+ default:
+ UNREACHABLE();
+ op_b = "0";
+ break;
+ }
+ op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b);
+
+ const std::string result = [&]() {
+ switch (opcode->GetId()) {
+ case OpCode::Id::HADD2_C:
+ case OpCode::Id::HADD2_R:
+ return '(' + op_a + " + " + op_b + ')';
+ case OpCode::Id::HMUL2_C:
+ case OpCode::Id::HMUL2_R:
+ return '(' + op_a + " * " + op_b + ')';
+ default:
+ LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", opcode->GetName());
+ UNREACHABLE();
+ return std::string("0");
+ }
+ }();
+
+ regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.alu_half.merge, 1, 1,
+ instr.alu_half.saturate != 0);
+ break;
+ }
case OpCode::Type::Ffma: {
const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
std::string op_b = instr.ffma.negate_b ? "-" : "";