diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/shader/shader_ir.h | 3 | ||||
-rw-r--r-- | src/video_core/shader/track.cpp | 17 |
2 files changed, 19 insertions, 1 deletions
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 5bc3a3900..7a4a231dc 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -7,6 +7,7 @@ #include <array> #include <cstring> #include <map> +#include <optional> #include <set> #include <string> #include <tuple> @@ -773,6 +774,8 @@ private: Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor); + std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor); + std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, s64 cursor); template <typename... T> diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp index 33b071747..4505667ff 100644 --- a/src/video_core/shader/track.cpp +++ b/src/video_core/shader/track.cpp @@ -6,6 +6,7 @@ #include <utility> #include <variant> +#include "common/common_types.h" #include "video_core/shader/shader_ir.h" namespace VideoCommon::Shader { @@ -14,7 +15,7 @@ namespace { std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor, OperationCode operation_code) { for (; cursor >= 0; --cursor) { - const Node node = code[cursor]; + const Node node = code.at(cursor); if (const auto operation = std::get_if<OperationNode>(node)) { if (operation->GetCode() == operation_code) return {node, cursor}; @@ -64,6 +65,20 @@ Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) { return nullptr; } +std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) { + // Reduce the cursor in one to avoid infinite loops when the instruction sets the same register + // that it uses as operand + const auto [found, found_cursor] = + TrackRegister(&std::get<GprNode>(*tracked), code, cursor - 1); + if (!found) { + return {}; + } + if (const auto immediate = std::get_if<ImmediateNode>(found)) { + return immediate->GetValue(); + } + return {}; +} + std::pair<Node, s64> ShaderIR::TrackRegister(const GprNode* tracked, const NodeBlock& code, s64 cursor) { for (; cursor >= 0; --cursor) { |