diff options
author | Subv <subv2112@gmail.com> | 2018-06-02 21:45:50 +0200 |
---|---|---|
committer | Subv <subv2112@gmail.com> | 2018-06-04 05:26:36 +0200 |
commit | b481d8a00d5f09e091e03ed4b7c4d9f9652e0969 (patch) | |
tree | 14653c8ff9828be0cc11fbb06d41be89dc0ae41e /src/video_core/renderer_opengl | |
parent | GPU: Added decoding for the BRA instruction. (diff) | |
download | yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar.gz yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar.bz2 yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar.lz yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar.xz yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.tar.zst yuzu-b481d8a00d5f09e091e03ed4b7c4d9f9652e0969.zip |
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index bb5209a7e..4cfd6f042 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -88,6 +88,20 @@ private: return *subroutines.insert(std::move(subroutine)).first; } + /// Merges exit method of two parallel branches. + static ExitMethod ParallelExit(ExitMethod a, ExitMethod b) { + if (a == ExitMethod::Undetermined) { + return b; + } + if (b == ExitMethod::Undetermined) { + return a; + } + if (a == b) { + return a; + } + return ExitMethod::Conditional; + } + /// Scans a range of code for labels and determines the exit method. ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels) { auto [iter, inserted] = @@ -97,11 +111,19 @@ private: return exit_method; for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { - if (const auto opcode = OpCode::Decode({program_code[offset]})) { + const Instruction instr = {program_code[offset]}; + if (const auto opcode = OpCode::Decode(instr)) { switch (opcode->GetId()) { case OpCode::Id::EXIT: { return exit_method = ExitMethod::AlwaysEnd; } + case OpCode::Id::BRA: { + u32 target = offset + instr.bra.GetBranchTarget(); + labels.insert(target); + ExitMethod no_jmp = Scan(offset + 1, end, labels); + ExitMethod jmp = Scan(target, end, labels); + return exit_method = ParallelExit(no_jmp, jmp); + } } } } @@ -1081,6 +1103,13 @@ private: shader.AddLine("discard;"); break; } + case OpCode::Id::BRA: { + ASSERT_MSG(instr.bra.constant_buffer == 0, + "BRA with constant buffers are not implemented"); + u32 target = offset + instr.bra.GetBranchTarget(); + shader.AddLine("{ jmp_to = " + std::to_string(target) + "u; break; }"); + break; + } case OpCode::Id::IPA: { const auto& attribute = instr.attribute.fmt28; regs.SetRegisterToInputAttibute(instr.gpr0, attribute.element, attribute.index); |