From 9f6d305eabd6534cdb80a20f611f92977d3953f0 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 20 Apr 2018 20:49:05 -0400 Subject: shader_bytecode: Decode instructions based on bit strings. --- .../renderer_opengl/gl_shader_decompiler.cpp | 49 +++++++++++++--------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 2395945c3..5919b3c9e 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -97,11 +97,12 @@ private: return exit_method; for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { - const Instruction instr = {program_code[offset]}; - switch (instr.opcode.EffectiveOpCode()) { - case OpCode::Id::EXIT: { - return exit_method = ExitMethod::AlwaysEnd; - } + if (const auto opcode = OpCode::Decode({program_code[offset]})) { + switch (opcode->GetId()) { + case OpCode::Id::EXIT: { + return exit_method = ExitMethod::AlwaysEnd; + } + } } } return exit_method = ExitMethod::AlwaysReturn; @@ -332,12 +333,20 @@ private: */ u32 CompileInstr(u32 offset) { // Ignore sched instructions when generating code. - if (IsSchedInstruction(offset)) + if (IsSchedInstruction(offset)) { return offset + 1; + } const Instruction instr = {program_code[offset]}; + const auto opcode = OpCode::Decode(instr); + + // Decoding failure + if (!opcode) { + NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", instr.value); + UNREACHABLE(); + } - shader.AddLine("// " + std::to_string(offset) + ": " + OpCode::GetInfo(instr.opcode).name); + shader.AddLine("// " + std::to_string(offset) + ": " + opcode->GetName()); using Tegra::Shader::Pred; ASSERT_MSG(instr.pred.full_pred != Pred::NeverExecute, @@ -349,7 +358,7 @@ private: ++shader.scope; } - switch (OpCode::GetInfo(instr.opcode).type) { + switch (opcode->GetType()) { case OpCode::Type::Arithmetic: { std::string dest = GetRegister(instr.gpr0); std::string op_a = instr.alu.negate_a ? "-" : ""; @@ -374,7 +383,7 @@ private: op_b = "abs(" + op_b + ")"; } - switch (instr.opcode.EffectiveOpCode()) { + switch (opcode->GetId()) { case OpCode::Id::FMUL_C: case OpCode::Id::FMUL_R: case OpCode::Id::FMUL_IMM: { @@ -424,8 +433,8 @@ private: } default: { NGLOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {} ({}): {}", - static_cast(instr.opcode.EffectiveOpCode()), - OpCode::GetInfo(instr.opcode).name, instr.hex); + static_cast(opcode->GetId()), opcode->GetName(), + instr.value); UNREACHABLE(); } } @@ -437,7 +446,7 @@ private: std::string op_b = instr.ffma.negate_b ? "-" : ""; std::string op_c = instr.ffma.negate_c ? "-" : ""; - switch (instr.opcode.EffectiveOpCode()) { + switch (opcode->GetId()) { case OpCode::Id::FFMA_CR: { op_b += GetUniform(instr.uniform); op_c += GetRegister(instr.gpr39); @@ -460,8 +469,8 @@ private: } default: { NGLOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {} ({}): {}", - static_cast(instr.opcode.EffectiveOpCode()), - OpCode::GetInfo(instr.opcode).name, instr.hex); + static_cast(opcode->GetId()), opcode->GetName(), + instr.value); UNREACHABLE(); } } @@ -473,7 +482,7 @@ private: std::string gpr0 = GetRegister(instr.gpr0); const Attribute::Index attribute = instr.attribute.fmt20.index; - switch (instr.opcode.EffectiveOpCode()) { + switch (opcode->GetId()) { case OpCode::Id::LD_A: { ASSERT_MSG(instr.attribute.fmt20.size == 0, "untested"); SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4); @@ -505,8 +514,8 @@ private: } default: { NGLOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {} ({}): {}", - static_cast(instr.opcode.EffectiveOpCode()), - OpCode::GetInfo(instr.opcode).name, instr.hex); + static_cast(opcode->GetId()), opcode->GetName(), + instr.value); UNREACHABLE(); } } @@ -564,7 +573,7 @@ private: break; } default: { - switch (instr.opcode.EffectiveOpCode()) { + switch (opcode->GetId()) { case OpCode::Id::EXIT: { ASSERT_MSG(instr.pred.pred_index == static_cast(Pred::UnusedIndex), "Predicated exits not implemented"); @@ -584,8 +593,8 @@ private: } default: { NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {} ({}): {}", - static_cast(instr.opcode.EffectiveOpCode()), - OpCode::GetInfo(instr.opcode).name, instr.hex); + static_cast(opcode->GetId()), opcode->GetName(), + instr.value); UNREACHABLE(); } } -- cgit v1.2.3 From 8b28dc55e6f5465302125923ef55175a2594173b Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 20 Apr 2018 22:25:29 -0400 Subject: gl_shader_decompiler: Cleanup error logging. --- .../renderer_opengl/gl_shader_decompiler.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 5919b3c9e..6e901f627 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -342,7 +342,7 @@ private: // Decoding failure if (!opcode) { - NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", instr.value); + NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {0:x}", instr.value); UNREACHABLE(); } @@ -425,16 +425,14 @@ private: SetDest(0, dest, "min(" + op_a + "," + op_b + ")", 1, 1, instr.alu.abs_d); break; default: - NGLOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {}", + NGLOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}", static_cast(instr.sub_op.Value())); UNREACHABLE(); } break; } default: { - NGLOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {} ({}): {}", - static_cast(opcode->GetId()), opcode->GetName(), - instr.value); + NGLOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName()); UNREACHABLE(); } } @@ -468,9 +466,7 @@ private: break; } default: { - NGLOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {} ({}): {}", - static_cast(opcode->GetId()), opcode->GetName(), - instr.value); + NGLOG_CRITICAL(HW_GPU, "Unhandled FFMA instruction: {}", opcode->GetName()); UNREACHABLE(); } } @@ -513,9 +509,7 @@ private: break; } default: { - NGLOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {} ({}): {}", - static_cast(opcode->GetId()), opcode->GetName(), - instr.value); + NGLOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName()); UNREACHABLE(); } } @@ -592,9 +586,7 @@ private: break; } default: { - NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {} ({}): {}", - static_cast(opcode->GetId()), opcode->GetName(), - instr.value); + NGLOG_CRITICAL(HW_GPU, "Unhandled instruction: {}", opcode->GetName()); UNREACHABLE(); } } -- cgit v1.2.3 From d08fd7e86d75cc28cf53384d629b27d666ee9068 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 20 Apr 2018 22:27:17 -0400 Subject: gl_shader_decompiler: Skip RRO instruction. --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6e901f627..086424395 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -431,6 +431,10 @@ private: } break; } + case OpCode::Id::RRO: { + NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction"); + break; + } default: { NGLOG_CRITICAL(HW_GPU, "Unhandled arithmetic instruction: {}", opcode->GetName()); UNREACHABLE(); -- cgit v1.2.3