shader_ir: Implement immediate register tracking
This commit is contained in:
parent
f770c17d01
commit
cf4ecc1945
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
@ -773,6 +774,8 @@ private:
|
||||||
|
|
||||||
Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor);
|
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);
|
std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, s64 cursor);
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
#include "video_core/shader/shader_ir.h"
|
#include "video_core/shader/shader_ir.h"
|
||||||
|
|
||||||
namespace VideoCommon::Shader {
|
namespace VideoCommon::Shader {
|
||||||
|
@ -14,7 +15,7 @@ namespace {
|
||||||
std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
|
std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
|
||||||
OperationCode operation_code) {
|
OperationCode operation_code) {
|
||||||
for (; cursor >= 0; --cursor) {
|
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 (const auto operation = std::get_if<OperationNode>(node)) {
|
||||||
if (operation->GetCode() == operation_code)
|
if (operation->GetCode() == operation_code)
|
||||||
return {node, cursor};
|
return {node, cursor};
|
||||||
|
@ -64,6 +65,20 @@ Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) {
|
||||||
return nullptr;
|
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,
|
std::pair<Node, s64> ShaderIR::TrackRegister(const GprNode* tracked, const NodeBlock& code,
|
||||||
s64 cursor) {
|
s64 cursor) {
|
||||||
for (; cursor >= 0; --cursor) {
|
for (; cursor >= 0; --cursor) {
|
||||||
|
|
Reference in New Issue