summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2018-04-10 05:39:44 +0200
committerbunnei <bunneidev@gmail.com>2018-04-14 22:01:40 +0200
commit86135864da9bbbd5906e96862994bd24f3cd4da5 (patch)
tree6e8c52749b512101f9733314a40c1461d6f6c77b /src/video_core/renderer_opengl
parentshader_bytecode: Add FSETP and KIL to GetInfo. (diff)
downloadyuzu-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')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp77
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: {