diff options
| author | 2019-07-16 14:58:35 -0400 | |
|---|---|---|
| committer | 2019-07-16 14:58:35 -0400 | |
| commit | b56e7f870add41d0300745342d24315e8fa3f881 (patch) | |
| tree | 13f920af2c14ab8ae89bb3d9751c885c60789c03 /src/video_core/shader/track.cpp | |
| parent | Merge pull request #2695 from ReinUsesLisp/layer-viewport (diff) | |
| parent | shader: Allow tracking of indirect buffers without variable offset (diff) | |
| download | yuzu-b56e7f870add41d0300745342d24315e8fa3f881.tar.gz yuzu-b56e7f870add41d0300745342d24315e8fa3f881.tar.xz yuzu-b56e7f870add41d0300745342d24315e8fa3f881.zip | |
Merge pull request #2565 from ReinUsesLisp/track-indirect
shader/track: Track indirect buffers
Diffstat (limited to 'src/video_core/shader/track.cpp')
| -rw-r--r-- | src/video_core/shader/track.cpp | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp index fc957d980..dc132a4a3 100644 --- a/src/video_core/shader/track.cpp +++ b/src/video_core/shader/track.cpp | |||
| @@ -32,39 +32,44 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor, | |||
| 32 | } | 32 | } |
| 33 | return {}; | 33 | return {}; |
| 34 | } | 34 | } |
| 35 | } // namespace | 35 | } // Anonymous namespace |
| 36 | 36 | ||
| 37 | Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const { | 37 | std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, |
| 38 | s64 cursor) const { | ||
| 38 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { | 39 | if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { |
| 39 | // Cbuf found, but it has to be immediate | 40 | // Constant buffer found, test if it's an immediate |
| 40 | return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr; | 41 | const auto offset = cbuf->GetOffset(); |
| 42 | if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) { | ||
| 43 | return {tracked, cbuf->GetIndex(), immediate->GetValue()}; | ||
| 44 | } | ||
| 45 | return {}; | ||
| 41 | } | 46 | } |
| 42 | if (const auto gpr = std::get_if<GprNode>(&*tracked)) { | 47 | if (const auto gpr = std::get_if<GprNode>(&*tracked)) { |
| 43 | if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { | 48 | if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { |
| 44 | return nullptr; | 49 | return {}; |
| 45 | } | 50 | } |
| 46 | // Reduce the cursor in one to avoid infinite loops when the instruction sets the same | 51 | // Reduce the cursor in one to avoid infinite loops when the instruction sets the same |
| 47 | // register that it uses as operand | 52 | // register that it uses as operand |
| 48 | const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1); | 53 | const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1); |
| 49 | if (!source) { | 54 | if (!source) { |
| 50 | return nullptr; | 55 | return {}; |
| 51 | } | 56 | } |
| 52 | return TrackCbuf(source, code, new_cursor); | 57 | return TrackCbuf(source, code, new_cursor); |
| 53 | } | 58 | } |
| 54 | if (const auto operation = std::get_if<OperationNode>(&*tracked)) { | 59 | if (const auto operation = std::get_if<OperationNode>(&*tracked)) { |
| 55 | for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { | 60 | for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { |
| 56 | if (const auto found = TrackCbuf((*operation)[i], code, cursor)) { | 61 | if (auto found = TrackCbuf((*operation)[i], code, cursor); std::get<0>(found)) { |
| 57 | // Cbuf found in operand | 62 | // Cbuf found in operand. |
| 58 | return found; | 63 | return found; |
| 59 | } | 64 | } |
| 60 | } | 65 | } |
| 61 | return nullptr; | 66 | return {}; |
| 62 | } | 67 | } |
| 63 | if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) { | 68 | if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) { |
| 64 | const auto& conditional_code = conditional->GetCode(); | 69 | const auto& conditional_code = conditional->GetCode(); |
| 65 | return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size())); | 70 | return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size())); |
| 66 | } | 71 | } |
| 67 | return nullptr; | 72 | return {}; |
| 68 | } | 73 | } |
| 69 | 74 | ||
| 70 | std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { | 75 | std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { |