From afa8096df5e3c24cb3b639a7fbc65f7225a17137 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 31 May 2019 19:14:34 -0300 Subject: shader: Allow tracking of indirect buffers without variable offset While changing this code, simplify tracking code to allow returning the base address node, this way callers don't have to manually rebuild it on each invocation. --- src/video_core/shader/track.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/video_core/shader/track.cpp') 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 FindOperation(const NodeBlock& code, s64 cursor, } return {}; } -} // namespace +} // Anonymous namespace -Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const { +std::tuple ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, + s64 cursor) const { if (const auto cbuf = std::get_if(&*tracked)) { - // Cbuf found, but it has to be immediate - return std::holds_alternative(*cbuf->GetOffset()) ? tracked : nullptr; + // Constant buffer found, test if it's an immediate + const auto offset = cbuf->GetOffset(); + if (const auto immediate = std::get_if(&*offset)) { + return {tracked, cbuf->GetIndex(), immediate->GetValue()}; + } + return {}; } if (const auto gpr = std::get_if(&*tracked)) { if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { - return nullptr; + return {}; } // Reduce the cursor in one to avoid infinite loops when the instruction sets the same // register that it uses as operand const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1); if (!source) { - return nullptr; + return {}; } return TrackCbuf(source, code, new_cursor); } if (const auto operation = std::get_if(&*tracked)) { for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { - if (const auto found = TrackCbuf((*operation)[i], code, cursor)) { - // Cbuf found in operand + if (auto found = TrackCbuf((*operation)[i], code, cursor); std::get<0>(found)) { + // Cbuf found in operand. return found; } } - return nullptr; + return {}; } if (const auto conditional = std::get_if(&*tracked)) { const auto& conditional_code = conditional->GetCode(); return TrackCbuf(tracked, conditional_code, static_cast(conditional_code.size())); } - return nullptr; + return {}; } std::optional ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { -- cgit v1.2.3