yuzu-emu
/
yuzu
Archived
1
0
Fork 0

Merge pull request #2497 from lioncash/shader-ir

shader/shader_ir: Minor changes
This commit is contained in:
Hexagon12 2019-05-19 15:51:06 +01:00 committed by GitHub
commit 2aebbe9bf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 33 deletions

View File

@ -21,6 +21,13 @@ using Tegra::Shader::PredCondition;
using Tegra::Shader::PredOperation; using Tegra::Shader::PredOperation;
using Tegra::Shader::Register; using Tegra::Shader::Register;
ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset)
: program_code{program_code}, main_offset{main_offset} {
Decode();
}
ShaderIR::~ShaderIR() = default;
Node ShaderIR::StoreNode(NodeData&& node_data) { Node ShaderIR::StoreNode(NodeData&& node_data) {
auto store = std::make_unique<NodeData>(node_data); auto store = std::make_unique<NodeData>(node_data);
const Node node = store.get(); const Node node = store.get();

View File

@ -328,40 +328,31 @@ struct MetaTexture {
u32 element{}; u32 element{};
}; };
inline constexpr MetaArithmetic PRECISE = {true}; constexpr MetaArithmetic PRECISE = {true};
inline constexpr MetaArithmetic NO_PRECISE = {false}; constexpr MetaArithmetic NO_PRECISE = {false};
using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>; using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>;
/// Holds any kind of operation that can be done in the IR /// Holds any kind of operation that can be done in the IR
class OperationNode final { class OperationNode final {
public: public:
template <typename... T> explicit OperationNode(OperationCode code) : code{code} {}
explicit constexpr OperationNode(OperationCode code) : code{code}, meta{} {}
explicit OperationNode(OperationCode code, Meta&& meta) : code{code}, meta{std::move(meta)} {}
template <typename... T> template <typename... T>
explicit constexpr OperationNode(OperationCode code, Meta&& meta) explicit OperationNode(OperationCode code, const T*... operands)
: code{code}, meta{std::move(meta)} {}
template <typename... T>
explicit constexpr OperationNode(OperationCode code, const T*... operands)
: OperationNode(code, {}, operands...) {} : OperationNode(code, {}, operands...) {}
template <typename... T> template <typename... T>
explicit constexpr OperationNode(OperationCode code, Meta&& meta, const T*... operands_) explicit OperationNode(OperationCode code, Meta&& meta, const T*... operands_)
: code{code}, meta{std::move(meta)} { : code{code}, meta{std::move(meta)}, operands{operands_...} {}
auto operands_list = {operands_...};
for (auto& operand : operands_list) {
operands.push_back(operand);
}
}
explicit OperationNode(OperationCode code, Meta&& meta, std::vector<Node>&& operands) explicit OperationNode(OperationCode code, Meta&& meta, std::vector<Node>&& operands)
: code{code}, meta{meta}, operands{std::move(operands)} {} : code{code}, meta{meta}, operands{std::move(operands)} {}
explicit OperationNode(OperationCode code, std::vector<Node>&& operands) explicit OperationNode(OperationCode code, std::vector<Node>&& operands)
: code{code}, meta{}, operands{std::move(operands)} {} : code{code}, operands{std::move(operands)} {}
OperationCode GetCode() const { OperationCode GetCode() const {
return code; return code;
@ -567,11 +558,8 @@ private:
class ShaderIR final { class ShaderIR final {
public: public:
explicit ShaderIR(const ProgramCode& program_code, u32 main_offset) explicit ShaderIR(const ProgramCode& program_code, u32 main_offset);
: program_code{program_code}, main_offset{main_offset} { ~ShaderIR();
Decode();
}
const std::map<u32, NodeBlock>& GetBasicBlocks() const { const std::map<u32, NodeBlock>& GetBasicBlocks() const {
return basic_blocks; return basic_blocks;
@ -814,11 +802,12 @@ private:
void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b, void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b,
Node op_c, Node imm_lut, bool sets_cc); Node op_c, Node imm_lut, bool sets_cc);
Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor); Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor); std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const;
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) const;
std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(NodeBlock& bb, std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(NodeBlock& bb,
Node addr_register, Node addr_register,
@ -835,12 +824,10 @@ private:
return StoreNode(OperationNode(code, std::move(meta), operands...)); return StoreNode(OperationNode(code, std::move(meta), operands...));
} }
template <typename... T>
Node Operation(OperationCode code, std::vector<Node>&& operands) { Node Operation(OperationCode code, std::vector<Node>&& operands) {
return StoreNode(OperationNode(code, std::move(operands))); return StoreNode(OperationNode(code, std::move(operands)));
} }
template <typename... T>
Node Operation(OperationCode code, Meta&& meta, std::vector<Node>&& operands) { Node Operation(OperationCode code, Meta&& meta, std::vector<Node>&& operands) {
return StoreNode(OperationNode(code, std::move(meta), std::move(operands))); return StoreNode(OperationNode(code, std::move(meta), std::move(operands)));
} }

View File

@ -17,22 +17,24 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
for (; cursor >= 0; --cursor) { for (; cursor >= 0; --cursor) {
const Node node = code.at(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};
} }
}
if (const auto conditional = std::get_if<ConditionalNode>(node)) { if (const auto conditional = std::get_if<ConditionalNode>(node)) {
const auto& conditional_code = conditional->GetCode(); const auto& conditional_code = conditional->GetCode();
const auto [found, internal_cursor] = FindOperation( const auto [found, internal_cursor] = FindOperation(
conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code); conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code);
if (found) if (found) {
return {found, cursor}; return {found, cursor};
} }
} }
}
return {}; return {};
} }
} // namespace } // namespace
Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) { Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const {
if (const auto cbuf = std::get_if<CbufNode>(tracked)) { if (const auto cbuf = std::get_if<CbufNode>(tracked)) {
// Cbuf found, but it has to be immediate // Cbuf found, but it has to be immediate
return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr; return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr;
@ -65,7 +67,7 @@ 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) { std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const {
// Reduce the cursor in one to avoid infinite loops when the instruction sets the same register // Reduce the cursor in one to avoid infinite loops when the instruction sets the same register
// that it uses as operand // that it uses as operand
const auto [found, found_cursor] = const auto [found, found_cursor] =
@ -80,7 +82,7 @@ std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code,
} }
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) const {
for (; cursor >= 0; --cursor) { for (; cursor >= 0; --cursor) {
const auto [found_node, new_cursor] = FindOperation(code, cursor, OperationCode::Assign); const auto [found_node, new_cursor] = FindOperation(code, cursor, OperationCode::Assign);
if (!found_node) { if (!found_node) {