diff options
author | bunnei <bunneidev@gmail.com> | 2018-04-10 05:39:44 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-04-14 22:01:40 +0200 |
commit | 86135864da9bbbd5906e96862994bd24f3cd4da5 (patch) | |
tree | 6e8c52749b512101f9733314a40c1461d6f6c77b /src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |
parent | shader_bytecode: Add FSETP and KIL to GetInfo. (diff) | |
download | yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.gz yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.bz2 yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.lz yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.xz yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.zst yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.zip |
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 77 |
1 files changed, 57 insertions, 20 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 704b24307..792b4b12e 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -17,6 +17,7 @@ using Tegra::Shader::Attribute; using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; using Tegra::Shader::Register; +using Tegra::Shader::SubOp; using Tegra::Shader::Uniform; constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH; @@ -235,31 +236,67 @@ private: switch (OpCode::GetInfo(instr.opcode).type) { case OpCode::Type::Arithmetic: { - ASSERT(!instr.nb); - ASSERT(!instr.aa); - ASSERT(!instr.na); - ASSERT(!instr.ab); - ASSERT(!instr.ad); + ASSERT(!instr.alu.abs_d, "unimplemented"); - std::string gpr1 = GetRegister(instr.gpr1); - std::string gpr2 = GetRegister(instr.gpr2); - std::string uniform = GetUniform(instr.uniform); + std::string dest = GetRegister(instr.gpr0); + std::string op_a = instr.alu.negate_a ? "-" : ""; + op_a += GetRegister(instr.gpr8); + if (instr.alu.abs_a) { + op_a = "abs(" + op_a + ")"; + } + + std::string op_b = instr.alu.negate_b ? "-" : ""; + if (instr.is_b_gpr) { + op_b += GetRegister(instr.gpr20); + } else { + op_b += GetUniform(instr.uniform); + } + if (instr.alu.abs_b) { + op_b = "abs(" + op_b + ")"; + } switch (instr.opcode.EffectiveOpCode()) { - case OpCode::Id::FMUL_C: { - SetDest(0, gpr1, gpr2 + " * " + uniform, 1, 1); + case OpCode::Id::FMUL_C: + case OpCode::Id::FMUL_R: { + SetDest(0, dest, op_a + " * " + op_b, 1, 1); + break; + } + case OpCode::Id::FADD_C: + case OpCode::Id::FADD_R: { + SetDest(0, dest, op_a + " + " + op_b, 1, 1); break; } - case OpCode::Id::FADD_C: { - SetDest(0, gpr1, gpr2 + " + " + uniform, 1, 1); + default: { + LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", + (int)instr.opcode.EffectiveOpCode(), OpCode::GetInfo(instr.opcode).name, + instr.hex); + throw DecompileFail("Unhandled instruction"); break; } + } + break; + } + case OpCode::Type::Ffma: { + ASSERT_MSG(!instr.ffma.negate_b, "untested"); + ASSERT_MSG(!instr.ffma.negate_c, "untested"); + + std::string dest = GetRegister(instr.gpr0); + std::string op_a = GetRegister(instr.gpr8); + + std::string op_b = instr.ffma.negate_b ? "-" : ""; + op_b += GetUniform(instr.uniform); + + std::string op_c = instr.ffma.negate_c ? "-" : ""; + op_c += GetRegister(instr.gpr39); + + switch (instr.opcode.EffectiveOpCode()) { case OpCode::Id::FFMA_CR: { - SetDest(0, gpr1, gpr2 + " * " + uniform + " + " + GetRegister(instr.gpr3), 1, 1); + SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1); break; } + default: { - LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", + LOG_ERROR(HW_GPU, "Unhandled arithmetic FFMA instruction: 0x%02x (%s): 0x%08x", (int)instr.opcode.EffectiveOpCode(), OpCode::GetInfo(instr.opcode).name, instr.hex); throw DecompileFail("Unhandled instruction"); @@ -269,18 +306,18 @@ private: break; } case OpCode::Type::Memory: { - ASSERT(instr.attribute.size == 0); - - std::string gpr1 = GetRegister(instr.gpr1); - const Attribute::Index attribute = instr.attribute.GetIndex(); + std::string gpr0 = GetRegister(instr.gpr0); + const Attribute::Index attribute = instr.attribute.fmt20.index; switch (instr.opcode.EffectiveOpCode()) { case OpCode::Id::LD_A: { - SetDest(instr.attribute.element, gpr1, GetInputAttribute(attribute), 1, 4); + ASSERT(instr.attribute.fmt20.size == 0); + SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4); break; } case OpCode::Id::ST_A: { - SetDest(instr.attribute.element, GetOutputAttribute(attribute), gpr1, 4, 1); + ASSERT(instr.attribute.fmt20.size == 0); + SetDest(instr.attribute.fmt20.element, GetOutputAttribute(attribute), gpr0, 4, 1); break; } default: { |