diff options
| author | 2019-01-29 22:02:01 -0500 | |
|---|---|---|
| committer | 2019-01-29 22:02:01 -0500 | |
| commit | 52bb5245268e113bfacc4c4bb27a74ea3058adbc (patch) | |
| tree | 4ba30f0ad404bd4120dd5b2e4f21193bf03952fd /src/video_core/shader/track.cpp | |
| parent | video_core/GPU Implemented the GPU PFIFO puller semaphore operations. (#1908) (diff) | |
| parent | gl_rasterizer: Implement global memory management (diff) | |
| download | yuzu-52bb5245268e113bfacc4c4bb27a74ea3058adbc.tar.gz yuzu-52bb5245268e113bfacc4c4bb27a74ea3058adbc.tar.xz yuzu-52bb5245268e113bfacc4c4bb27a74ea3058adbc.zip | |
Merge pull request #1960 from ReinUsesLisp/shader-ir-ldg
video_core: Implement LDG through heuristics based on IR
Diffstat (limited to 'src/video_core/shader/track.cpp')
| -rw-r--r-- | src/video_core/shader/track.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp new file mode 100644 index 000000000..d6d29ee9f --- /dev/null +++ b/src/video_core/shader/track.cpp | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <utility> | ||
| 7 | #include <variant> | ||
| 8 | |||
| 9 | #include "video_core/shader/shader_ir.h" | ||
| 10 | |||
| 11 | namespace VideoCommon::Shader { | ||
| 12 | |||
| 13 | namespace { | ||
| 14 | std::pair<Node, s64> FindOperation(const BasicBlock& code, s64 cursor, | ||
| 15 | OperationCode operation_code) { | ||
| 16 | for (; cursor >= 0; --cursor) { | ||
| 17 | const Node node = code[cursor]; | ||
| 18 | if (const auto operation = std::get_if<OperationNode>(node)) { | ||
| 19 | if (operation->GetCode() == operation_code) | ||
| 20 | return {node, cursor}; | ||
| 21 | } | ||
| 22 | } | ||
| 23 | return {}; | ||
| 24 | } | ||
| 25 | } // namespace | ||
| 26 | |||
| 27 | Node ShaderIR::TrackCbuf(Node tracked, const BasicBlock& code, s64 cursor) { | ||
| 28 | if (const auto cbuf = std::get_if<CbufNode>(tracked)) { | ||
| 29 | // Cbuf found, but it has to be immediate | ||
| 30 | return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr; | ||
| 31 | } | ||
| 32 | if (const auto gpr = std::get_if<GprNode>(tracked)) { | ||
| 33 | if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { | ||
| 34 | return nullptr; | ||
| 35 | } | ||
| 36 | // Reduce the cursor in one to avoid infinite loops when the instruction sets the same | ||
| 37 | // register that it uses as operand | ||
| 38 | const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1); | ||
| 39 | if (!source) { | ||
| 40 | return nullptr; | ||
| 41 | } | ||
| 42 | return TrackCbuf(source, code, new_cursor); | ||
| 43 | } | ||
| 44 | if (const auto operation = std::get_if<OperationNode>(tracked)) { | ||
| 45 | for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { | ||
| 46 | if (const auto found = TrackCbuf((*operation)[i], code, cursor)) { | ||
| 47 | // Cbuf found in operand | ||
| 48 | return found; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | return nullptr; | ||
| 52 | } | ||
| 53 | return nullptr; | ||
| 54 | } | ||
| 55 | |||
| 56 | std::pair<Node, s64> ShaderIR::TrackRegister(const GprNode* tracked, const BasicBlock& code, | ||
| 57 | s64 cursor) { | ||
| 58 | for (; cursor >= 0; --cursor) { | ||
| 59 | const auto [found_node, new_cursor] = FindOperation(code, cursor, OperationCode::Assign); | ||
| 60 | if (!found_node) { | ||
| 61 | return {}; | ||
| 62 | } | ||
| 63 | const auto operation = std::get_if<OperationNode>(found_node); | ||
| 64 | ASSERT(operation); | ||
| 65 | |||
| 66 | const auto& target = (*operation)[0]; | ||
| 67 | if (const auto gpr_target = std::get_if<GprNode>(target)) { | ||
| 68 | if (gpr_target->GetIndex() == tracked->GetIndex()) { | ||
| 69 | return {(*operation)[1], new_cursor}; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | return {}; | ||
| 74 | } | ||
| 75 | |||
| 76 | } // namespace VideoCommon::Shader | ||