summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_half.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_half_immediate.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_immediate.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp1
-rw-r--r--src/video_core/shader/decode/arithmetic_integer_immediate.cpp1
-rw-r--r--src/video_core/shader/decode/bfe.cpp1
-rw-r--r--src/video_core/shader/decode/bfi.cpp1
-rw-r--r--src/video_core/shader/decode/conversion.cpp1
-rw-r--r--src/video_core/shader/decode/ffma.cpp1
-rw-r--r--src/video_core/shader/decode/float_set.cpp1
-rw-r--r--src/video_core/shader/decode/float_set_predicate.cpp1
-rw-r--r--src/video_core/shader/decode/half_set.cpp1
-rw-r--r--src/video_core/shader/decode/half_set_predicate.cpp1
-rw-r--r--src/video_core/shader/decode/hfma2.cpp1
-rw-r--r--src/video_core/shader/decode/integer_set.cpp1
-rw-r--r--src/video_core/shader/decode/integer_set_predicate.cpp1
-rw-r--r--src/video_core/shader/decode/memory.cpp9
-rw-r--r--src/video_core/shader/decode/other.cpp1
-rw-r--r--src/video_core/shader/decode/predicate_set_predicate.cpp1
-rw-r--r--src/video_core/shader/decode/predicate_set_register.cpp1
-rw-r--r--src/video_core/shader/decode/register_set_predicate.cpp1
-rw-r--r--src/video_core/shader/decode/shift.cpp1
-rw-r--r--src/video_core/shader/decode/texture.cpp9
-rw-r--r--src/video_core/shader/decode/video.cpp1
-rw-r--r--src/video_core/shader/decode/xmad.cpp1
-rw-r--r--src/video_core/shader/node_helper.cpp99
-rw-r--r--src/video_core/shader/node_helper.h60
-rw-r--r--src/video_core/shader/shader_ir.cpp102
-rw-r--r--src/video_core/shader/shader_ir.h108
-rw-r--r--src/video_core/shader/track.cpp18
32 files changed, 238 insertions, 192 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 2da595c0d..a0554c97e 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -11,6 +11,7 @@
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
#include "video_core/engines/shader_header.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp
index b4859bc1e..87d8fecaa 100644
--- a/src/video_core/shader/decode/arithmetic.cpp
+++ b/src/video_core/shader/decode/arithmetic.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp
index 3a29c4a46..b06cbe441 100644
--- a/src/video_core/shader/decode/arithmetic_half.cpp
+++ b/src/video_core/shader/decode/arithmetic_half.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic_half_immediate.cpp b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
index 5341e460f..7bcf38f23 100644
--- a/src/video_core/shader/decode/arithmetic_half_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_half_immediate.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic_immediate.cpp b/src/video_core/shader/decode/arithmetic_immediate.cpp
index 3095f2fd4..f1875967c 100644
--- a/src/video_core/shader/decode/arithmetic_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_immediate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 9fd4b273e..c8c1a7f40 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
index 679ac0d4e..73880db0e 100644
--- a/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer_immediate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/bfe.cpp b/src/video_core/shader/decode/bfe.cpp
index 1ae192c6a..e02bcd097 100644
--- a/src/video_core/shader/decode/bfe.cpp
+++ b/src/video_core/shader/decode/bfe.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/bfi.cpp b/src/video_core/shader/decode/bfi.cpp
index 0b12a0d08..8be1119df 100644
--- a/src/video_core/shader/decode/bfi.cpp
+++ b/src/video_core/shader/decode/bfi.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index b5ec9a6f5..4221f0c58 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp
index a1d04c6e5..29be25ca3 100644
--- a/src/video_core/shader/decode/ffma.cpp
+++ b/src/video_core/shader/decode/ffma.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/float_set.cpp b/src/video_core/shader/decode/float_set.cpp
index cc522f1de..f5013e44a 100644
--- a/src/video_core/shader/decode/float_set.cpp
+++ b/src/video_core/shader/decode/float_set.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/float_set_predicate.cpp b/src/video_core/shader/decode/float_set_predicate.cpp
index 9d2322a1d..2323052b0 100644
--- a/src/video_core/shader/decode/float_set_predicate.cpp
+++ b/src/video_core/shader/decode/float_set_predicate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/half_set.cpp b/src/video_core/shader/decode/half_set.cpp
index 755f2ec44..48ca7a4af 100644
--- a/src/video_core/shader/decode/half_set.cpp
+++ b/src/video_core/shader/decode/half_set.cpp
@@ -8,6 +8,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp
index fba44d714..d59d15bd8 100644
--- a/src/video_core/shader/decode/half_set_predicate.cpp
+++ b/src/video_core/shader/decode/half_set_predicate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/hfma2.cpp b/src/video_core/shader/decode/hfma2.cpp
index a425f9eb7..c3bcf1ae9 100644
--- a/src/video_core/shader/decode/hfma2.cpp
+++ b/src/video_core/shader/decode/hfma2.cpp
@@ -7,6 +7,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/integer_set.cpp b/src/video_core/shader/decode/integer_set.cpp
index a4cdaf74d..46e3d5905 100644
--- a/src/video_core/shader/decode/integer_set.cpp
+++ b/src/video_core/shader/decode/integer_set.cpp
@@ -4,6 +4,7 @@
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/integer_set_predicate.cpp b/src/video_core/shader/decode/integer_set_predicate.cpp
index a6a1fb632..dd20775d7 100644
--- a/src/video_core/shader/decode/integer_set_predicate.cpp
+++ b/src/video_core/shader/decode/integer_set_predicate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index e6a010a7d..80fc0ccfc 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -10,6 +10,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
@@ -169,7 +170,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
const Node it_offset = Immediate(i * 4);
const Node real_address =
Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
- const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor));
+ const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
SetTemporal(bb, i, gmem);
}
@@ -262,7 +263,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
const Node it_offset = Immediate(i * 4);
const Node real_address =
Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
- const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor));
+ const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1)));
}
@@ -298,9 +299,9 @@ std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeB
const Node base_address{
TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))};
- const auto cbuf = std::get_if<CbufNode>(base_address);
+ const auto cbuf = std::get_if<CbufNode>(&*base_address);
ASSERT(cbuf != nullptr);
- const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset());
+ const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset());
ASSERT(cbuf_offset_imm != nullptr);
const auto cbuf_offset = cbuf_offset_imm->GetValue();
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index a6c123573..6fc07f213 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/predicate_set_predicate.cpp b/src/video_core/shader/decode/predicate_set_predicate.cpp
index 71844c42b..9290d22eb 100644
--- a/src/video_core/shader/decode/predicate_set_predicate.cpp
+++ b/src/video_core/shader/decode/predicate_set_predicate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/predicate_set_register.cpp b/src/video_core/shader/decode/predicate_set_register.cpp
index 387491bd3..febbfeb50 100644
--- a/src/video_core/shader/decode/predicate_set_register.cpp
+++ b/src/video_core/shader/decode/predicate_set_register.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp
index f8659e48e..e6c9d287e 100644
--- a/src/video_core/shader/decode/register_set_predicate.cpp
+++ b/src/video_core/shader/decode/register_set_predicate.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp
index 44ae87ece..2ac16eeb0 100644
--- a/src/video_core/shader/decode/shift.cpp
+++ b/src/video_core/shader/decode/shift.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 5b033126d..4a356dbd4 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -11,6 +11,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
@@ -291,8 +292,8 @@ const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg,
const Node sampler_register = GetRegister(reg);
const Node base_sampler =
TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
- const auto cbuf = std::get_if<CbufNode>(base_sampler);
- const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset());
+ const auto cbuf = std::get_if<CbufNode>(&*base_sampler);
+ const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset());
ASSERT(cbuf_offset_imm != nullptr);
const auto cbuf_offset = cbuf_offset_imm->GetValue();
const auto cbuf_index = cbuf->GetIndex();
@@ -388,8 +389,8 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
Node array, Node depth_compare, u32 bias_offset,
std::vector<Node> aoffi,
std::optional<Tegra::Shader::Register> bindless_reg) {
- const bool is_array = array;
- const bool is_shadow = depth_compare;
+ const auto is_array = static_cast<bool>(array);
+ const auto is_shadow = static_cast<bool>(depth_compare);
const bool is_bindless = bindless_reg.has_value();
UNIMPLEMENTED_IF_MSG((texture_type == TextureType::Texture3D && (is_array || is_shadow)) ||
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index cb9ab72b1..97fc6f9b1 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp
index 04a776398..93dee77d1 100644
--- a/src/video_core/shader/decode/xmad.cpp
+++ b/src/video_core/shader/decode/xmad.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
diff --git a/src/video_core/shader/node_helper.cpp b/src/video_core/shader/node_helper.cpp
new file mode 100644
index 000000000..6fccbbba3
--- /dev/null
+++ b/src/video_core/shader/node_helper.cpp
@@ -0,0 +1,99 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cstring>
+#include <vector>
+
+#include "common/common_types.h"
+#include "video_core/shader/node_helper.h"
+#include "video_core/shader/shader_ir.h"
+
+namespace VideoCommon::Shader {
+
+Node Conditional(Node condition, std::vector<Node> code) {
+ return MakeNode<ConditionalNode>(condition, std::move(code));
+}
+
+Node Comment(std::string text) {
+ return MakeNode<CommentNode>(std::move(text));
+}
+
+Node Immediate(u32 value) {
+ return MakeNode<ImmediateNode>(value);
+}
+
+Node Immediate(s32 value) {
+ return Immediate(static_cast<u32>(value));
+}
+
+Node Immediate(f32 value) {
+ u32 integral;
+ std::memcpy(&integral, &value, sizeof(u32));
+ return Immediate(integral);
+}
+
+OperationCode SignedToUnsignedCode(OperationCode operation_code, bool is_signed) {
+ if (is_signed) {
+ return operation_code;
+ }
+ switch (operation_code) {
+ case OperationCode::FCastInteger:
+ return OperationCode::FCastUInteger;
+ case OperationCode::IAdd:
+ return OperationCode::UAdd;
+ case OperationCode::IMul:
+ return OperationCode::UMul;
+ case OperationCode::IDiv:
+ return OperationCode::UDiv;
+ case OperationCode::IMin:
+ return OperationCode::UMin;
+ case OperationCode::IMax:
+ return OperationCode::UMax;
+ case OperationCode::ICastFloat:
+ return OperationCode::UCastFloat;
+ case OperationCode::ICastUnsigned:
+ return OperationCode::UCastSigned;
+ case OperationCode::ILogicalShiftLeft:
+ return OperationCode::ULogicalShiftLeft;
+ case OperationCode::ILogicalShiftRight:
+ return OperationCode::ULogicalShiftRight;
+ case OperationCode::IArithmeticShiftRight:
+ return OperationCode::UArithmeticShiftRight;
+ case OperationCode::IBitwiseAnd:
+ return OperationCode::UBitwiseAnd;
+ case OperationCode::IBitwiseOr:
+ return OperationCode::UBitwiseOr;
+ case OperationCode::IBitwiseXor:
+ return OperationCode::UBitwiseXor;
+ case OperationCode::IBitwiseNot:
+ return OperationCode::UBitwiseNot;
+ case OperationCode::IBitfieldInsert:
+ return OperationCode::UBitfieldInsert;
+ case OperationCode::IBitCount:
+ return OperationCode::UBitCount;
+ case OperationCode::LogicalILessThan:
+ return OperationCode::LogicalULessThan;
+ case OperationCode::LogicalIEqual:
+ return OperationCode::LogicalUEqual;
+ case OperationCode::LogicalILessEqual:
+ return OperationCode::LogicalULessEqual;
+ case OperationCode::LogicalIGreaterThan:
+ return OperationCode::LogicalUGreaterThan;
+ case OperationCode::LogicalINotEqual:
+ return OperationCode::LogicalUNotEqual;
+ case OperationCode::LogicalIGreaterEqual:
+ return OperationCode::LogicalUGreaterEqual;
+ case OperationCode::INegate:
+ UNREACHABLE_MSG("Can't negate an unsigned integer");
+ return {};
+ case OperationCode::IAbsolute:
+ UNREACHABLE_MSG("Can't apply absolute to an unsigned integer");
+ return {};
+ default:
+ UNREACHABLE_MSG("Unknown signed operation with code={}", static_cast<u32>(operation_code));
+ return {};
+ }
+}
+
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/node_helper.h b/src/video_core/shader/node_helper.h
new file mode 100644
index 000000000..70547a03d
--- /dev/null
+++ b/src/video_core/shader/node_helper.h
@@ -0,0 +1,60 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "common/common_types.h"
+#include "video_core/shader/shader_ir.h"
+
+namespace VideoCommon::Shader {
+
+/// Creates a conditional node
+Node Conditional(Node condition, std::vector<Node> code);
+
+/// Creates a commentary node
+Node Comment(std::string text);
+
+/// Creates an u32 immediate
+Node Immediate(u32 value);
+
+/// Creates a s32 immediate
+Node Immediate(s32 value);
+
+/// Creates a f32 immediate
+Node Immediate(f32 value);
+
+/// Converts an signed operation code to an unsigned operation code
+OperationCode SignedToUnsignedCode(OperationCode operation_code, bool is_signed);
+
+template <typename T, typename... Args>
+Node MakeNode(Args&&... args) {
+ static_assert(std::is_convertible_v<T, NodeData>);
+ return std::make_shared<NodeData>(T(std::forward<Args>(args)...));
+}
+
+template <typename... Args>
+Node Operation(OperationCode code, Args&&... args) {
+ if constexpr (sizeof...(args) == 0) {
+ return MakeNode<OperationNode>(code);
+ } else if constexpr (std::is_convertible_v<std::tuple_element_t<0, std::tuple<Args...>>,
+ Meta>) {
+ return MakeNode<OperationNode>(code, std::forward<Args>(args)...);
+ } else {
+ return MakeNode<OperationNode>(code, Meta{}, std::forward<Args>(args)...);
+ }
+}
+
+template <typename... Args>
+Node SignedOperation(OperationCode code, bool is_signed, Args&&... args) {
+ return Operation(SignedToUnsignedCode(code, is_signed), std::forward<Args>(args)...);
+}
+
+} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 8a6ee5cf5..11b545cca 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -9,6 +9,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "video_core/engines/shader_bytecode.h"
+#include "video_core/shader/node_helper.h"
#include "video_core/shader/shader_ir.h"
namespace VideoCommon::Shader {
@@ -28,30 +29,11 @@ ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset)
ShaderIR::~ShaderIR() = default;
-Node ShaderIR::StoreNode(NodeData&& node_data) {
- auto store = std::make_unique<NodeData>(node_data);
- const Node node = store.get();
- stored_nodes.push_back(std::move(store));
- return node;
-}
-
-Node ShaderIR::Conditional(Node condition, std::vector<Node>&& code) {
- return StoreNode(ConditionalNode(condition, std::move(code)));
-}
-
-Node ShaderIR::Comment(std::string text) {
- return StoreNode(CommentNode(std::move(text)));
-}
-
-Node ShaderIR::Immediate(u32 value) {
- return StoreNode(ImmediateNode(value));
-}
-
Node ShaderIR::GetRegister(Register reg) {
if (reg != Register::ZeroIndex) {
used_registers.insert(static_cast<u32>(reg));
}
- return StoreNode(GprNode(reg));
+ return MakeNode<GprNode>(reg);
}
Node ShaderIR::GetImmediate19(Instruction instr) {
@@ -69,7 +51,7 @@ Node ShaderIR::GetConstBuffer(u64 index_, u64 offset_) {
const auto [entry, is_new] = used_cbufs.try_emplace(index);
entry->second.MarkAsUsed(offset);
- return StoreNode(CbufNode(index, Immediate(offset)));
+ return MakeNode<CbufNode>(index, Immediate(offset));
}
Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
@@ -80,7 +62,7 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
entry->second.MarkAsUsedIndirect();
const Node final_offset = Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset));
- return StoreNode(CbufNode(index, final_offset));
+ return MakeNode<CbufNode>(index, final_offset);
}
Node ShaderIR::GetPredicate(u64 pred_, bool negated) {
@@ -89,7 +71,7 @@ Node ShaderIR::GetPredicate(u64 pred_, bool negated) {
used_predicates.insert(pred);
}
- return StoreNode(PredicateNode(pred, negated));
+ return MakeNode<PredicateNode>(pred, negated);
}
Node ShaderIR::GetPredicate(bool immediate) {
@@ -98,12 +80,12 @@ Node ShaderIR::GetPredicate(bool immediate) {
Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
used_input_attributes.emplace(index);
- return StoreNode(AbufNode(index, static_cast<u32>(element), buffer));
+ return MakeNode<AbufNode>(index, static_cast<u32>(element), buffer);
}
Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) {
uses_physical_attributes = true;
- return StoreNode(AbufNode(GetRegister(physical_address), buffer));
+ return MakeNode<AbufNode>(GetRegister(physical_address), buffer);
}
Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) {
@@ -115,11 +97,11 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff
}
used_output_attributes.insert(index);
- return StoreNode(AbufNode(index, static_cast<u32>(element), buffer));
+ return MakeNode<AbufNode>(index, static_cast<u32>(element), buffer);
}
Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) {
- const Node node = StoreNode(InternalFlagNode(flag));
+ const Node node = MakeNode<InternalFlagNode>(flag);
if (negated) {
return Operation(OperationCode::LogicalNegate, node);
}
@@ -127,7 +109,7 @@ Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) {
}
Node ShaderIR::GetLocalMemory(Node address) {
- return StoreNode(LmemNode(address));
+ return MakeNode<LmemNode>(address);
}
Node ShaderIR::GetTemporal(u32 id) {
@@ -393,68 +375,4 @@ Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
Immediate(bits));
}
-/*static*/ OperationCode ShaderIR::SignedToUnsignedCode(OperationCode operation_code,
- bool is_signed) {
- if (is_signed) {
- return operation_code;
- }
- switch (operation_code) {
- case OperationCode::FCastInteger:
- return OperationCode::FCastUInteger;
- case OperationCode::IAdd:
- return OperationCode::UAdd;
- case OperationCode::IMul:
- return OperationCode::UMul;
- case OperationCode::IDiv:
- return OperationCode::UDiv;
- case OperationCode::IMin:
- return OperationCode::UMin;
- case OperationCode::IMax:
- return OperationCode::UMax;
- case OperationCode::ICastFloat:
- return OperationCode::UCastFloat;
- case OperationCode::ICastUnsigned:
- return OperationCode::UCastSigned;
- case OperationCode::ILogicalShiftLeft:
- return OperationCode::ULogicalShiftLeft;
- case OperationCode::ILogicalShiftRight:
- return OperationCode::ULogicalShiftRight;
- case OperationCode::IArithmeticShiftRight:
- return OperationCode::UArithmeticShiftRight;
- case OperationCode::IBitwiseAnd:
- return OperationCode::UBitwiseAnd;
- case OperationCode::IBitwiseOr:
- return OperationCode::UBitwiseOr;
- case OperationCode::IBitwiseXor:
- return OperationCode::UBitwiseXor;
- case OperationCode::IBitwiseNot:
- return OperationCode::UBitwiseNot;
- case OperationCode::IBitfieldInsert:
- return OperationCode::UBitfieldInsert;
- case OperationCode::IBitCount:
- return OperationCode::UBitCount;
- case OperationCode::LogicalILessThan:
- return OperationCode::LogicalULessThan;
- case OperationCode::LogicalIEqual:
- return OperationCode::LogicalUEqual;
- case OperationCode::LogicalILessEqual:
- return OperationCode::LogicalULessEqual;
- case OperationCode::LogicalIGreaterThan:
- return OperationCode::LogicalUGreaterThan;
- case OperationCode::LogicalINotEqual:
- return OperationCode::LogicalUNotEqual;
- case OperationCode::LogicalIGreaterEqual:
- return OperationCode::LogicalUGreaterEqual;
- case OperationCode::INegate:
- UNREACHABLE_MSG("Can't negate an unsigned integer");
- return {};
- case OperationCode::IAbsolute:
- UNREACHABLE_MSG("Can't apply absolute to an unsigned integer");
- return {};
- default:
- UNREACHABLE_MSG("Unknown signed operation with code={}", static_cast<u32>(operation_code));
- return {};
- }
-}
-
} // namespace VideoCommon::Shader
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index ff7472e30..1b2745c23 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -38,7 +38,7 @@ using ProgramCode = std::vector<u64>;
using NodeData =
std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, InternalFlagNode,
PredicateNode, AbufNode, CbufNode, LmemNode, GmemNode, CommentNode>;
-using Node = const NodeData*;
+using Node = std::shared_ptr<NodeData>;
using Node4 = std::array<Node, 4>;
using NodeBlock = std::vector<Node>;
@@ -342,23 +342,20 @@ using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>;
/// Holds any kind of operation that can be done in the IR
class OperationNode final {
public:
- explicit OperationNode(OperationCode code) : code{code} {}
+ explicit OperationNode(OperationCode code) : OperationNode(code, Meta{}) {}
- explicit OperationNode(OperationCode code, Meta&& meta) : code{code}, meta{std::move(meta)} {}
+ explicit OperationNode(OperationCode code, Meta meta)
+ : OperationNode(code, meta, std::vector<Node>{}) {}
- template <typename... T>
- explicit OperationNode(OperationCode code, const T*... operands)
- : OperationNode(code, {}, operands...) {}
+ explicit OperationNode(OperationCode code, std::vector<Node> operands)
+ : OperationNode(code, Meta{}, std::move(operands)) {}
- template <typename... T>
- explicit OperationNode(OperationCode code, Meta&& meta, const T*... operands_)
- : code{code}, meta{std::move(meta)}, operands{operands_...} {}
+ explicit OperationNode(OperationCode code, Meta meta, std::vector<Node> operands)
+ : code{code}, meta{std::move(meta)}, operands{std::move(operands)} {}
- explicit OperationNode(OperationCode code, Meta&& meta, std::vector<Node>&& operands)
- : code{code}, meta{meta}, operands{std::move(operands)} {}
-
- explicit OperationNode(OperationCode code, std::vector<Node>&& operands)
- : code{code}, operands{std::move(operands)} {}
+ template <typename... Args>
+ explicit OperationNode(OperationCode code, Meta meta, Args&&... operands)
+ : code{code}, meta{std::move(meta)}, operands{operands...} {}
OperationCode GetCode() const {
return code;
@@ -372,13 +369,13 @@ public:
return operands.size();
}
- Node operator[](std::size_t operand_index) const {
+ const Node& operator[](std::size_t operand_index) const {
return operands.at(operand_index);
}
private:
- const OperationCode code;
- const Meta meta;
+ OperationCode code{};
+ Meta meta{};
std::vector<Node> operands;
};
@@ -463,13 +460,12 @@ private:
class AbufNode final {
public:
// Initialize for standard attributes (index is explicit).
- explicit constexpr AbufNode(Tegra::Shader::Attribute::Index index, u32 element,
- Node buffer = {})
- : buffer{buffer}, index{index}, element{element} {}
+ explicit AbufNode(Tegra::Shader::Attribute::Index index, u32 element, Node buffer = {})
+ : buffer{std::move(buffer)}, index{index}, element{element} {}
// Initialize for physical attributes (index is a variable value).
- explicit constexpr AbufNode(Node physical_address, Node buffer = {})
- : physical_address{physical_address}, buffer{buffer} {}
+ explicit AbufNode(Node physical_address, Node buffer = {})
+ : physical_address{physical_address}, buffer{std::move(buffer)} {}
Tegra::Shader::Attribute::Index GetIndex() const {
return index;
@@ -484,16 +480,16 @@ public:
}
bool IsPhysicalBuffer() const {
- return physical_address != nullptr;
+ return static_cast<bool>(physical_address);
}
- Node GetPhysicalAddress() const {
+ const Node& GetPhysicalAddress() const {
return physical_address;
}
private:
- Node physical_address{};
- Node buffer{};
+ Node physical_address;
+ Node buffer;
Tegra::Shader::Attribute::Index index{};
u32 element{};
};
@@ -501,7 +497,7 @@ private:
/// Constant buffer node, usually mapped to uniform buffers in GLSL
class CbufNode final {
public:
- explicit constexpr CbufNode(u32 index, Node offset) : index{index}, offset{offset} {}
+ explicit CbufNode(u32 index, Node offset) : index{index}, offset{offset} {}
u32 GetIndex() const {
return index;
@@ -519,7 +515,7 @@ private:
/// Local memory node
class LmemNode final {
public:
- explicit constexpr LmemNode(Node address) : address{address} {}
+ explicit LmemNode(Node address) : address{address} {}
Node GetAddress() const {
return address;
@@ -532,8 +528,7 @@ private:
/// Global memory node
class GmemNode final {
public:
- explicit constexpr GmemNode(Node real_address, Node base_address,
- const GlobalMemoryBase& descriptor)
+ explicit GmemNode(Node real_address, Node base_address, const GlobalMemoryBase& descriptor)
: real_address{real_address}, base_address{base_address}, descriptor{descriptor} {}
Node GetRealAddress() const {
@@ -663,26 +658,6 @@ private:
u32 DecodeXmad(NodeBlock& bb, u32 pc);
u32 DecodeOther(NodeBlock& bb, u32 pc);
- /// Internalizes node's data and returns a managed pointer to a clone of that node
- Node StoreNode(NodeData&& node_data);
-
- /// Creates a conditional node
- Node Conditional(Node condition, std::vector<Node>&& code);
- /// Creates a commentary
- Node Comment(std::string text);
- /// Creates an u32 immediate
- Node Immediate(u32 value);
- /// Creates a s32 immediate
- Node Immediate(s32 value) {
- return Immediate(static_cast<u32>(value));
- }
- /// Creates a f32 immediate
- Node Immediate(f32 value) {
- u32 integral;
- std::memcpy(&integral, &value, sizeof(u32));
- return Immediate(integral);
- }
-
/// Generates a node for a passed register.
Node GetRegister(Tegra::Shader::Register reg);
/// Generates a node representing a 19-bit immediate value
@@ -827,37 +802,6 @@ private:
std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(
NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write);
- template <typename... T>
- Node Operation(OperationCode code, const T*... operands) {
- return StoreNode(OperationNode(code, operands...));
- }
-
- template <typename... T>
- Node Operation(OperationCode code, Meta&& meta, const T*... operands) {
- return StoreNode(OperationNode(code, std::move(meta), operands...));
- }
-
- Node Operation(OperationCode code, std::vector<Node>&& operands) {
- return StoreNode(OperationNode(code, std::move(operands)));
- }
-
- Node Operation(OperationCode code, Meta&& meta, std::vector<Node>&& operands) {
- return StoreNode(OperationNode(code, std::move(meta), std::move(operands)));
- }
-
- template <typename... T>
- Node SignedOperation(OperationCode code, bool is_signed, const T*... operands) {
- return StoreNode(OperationNode(SignedToUnsignedCode(code, is_signed), operands...));
- }
-
- template <typename... T>
- Node SignedOperation(OperationCode code, bool is_signed, Meta&& meta, const T*... operands) {
- return StoreNode(
- OperationNode(SignedToUnsignedCode(code, is_signed), std::move(meta), operands...));
- }
-
- static OperationCode SignedToUnsignedCode(OperationCode operation_code, bool is_signed);
-
const ProgramCode& program_code;
const u32 main_offset;
@@ -868,8 +812,6 @@ private:
std::map<u32, NodeBlock> basic_blocks;
NodeBlock global_code;
- std::vector<std::unique_ptr<NodeData>> stored_nodes;
-
std::set<u32> used_registers;
std::set<Tegra::Shader::Pred> used_predicates;
std::set<Tegra::Shader::Attribute::Index> used_input_attributes;
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp
index 19ede1eb9..fc957d980 100644
--- a/src/video_core/shader/track.cpp
+++ b/src/video_core/shader/track.cpp
@@ -16,12 +16,12 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
OperationCode operation_code) {
for (; cursor >= 0; --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) {
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 [found, internal_cursor] = FindOperation(
conditional_code, static_cast<s64>(conditional_code.size() - 1), operation_code);
@@ -35,11 +35,11 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
} // namespace
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
return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr;
}
- if (const auto gpr = std::get_if<GprNode>(tracked)) {
+ if (const auto gpr = std::get_if<GprNode>(&*tracked)) {
if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) {
return nullptr;
}
@@ -51,7 +51,7 @@ Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const
}
return TrackCbuf(source, code, new_cursor);
}
- if (const auto operation = std::get_if<OperationNode>(tracked)) {
+ if (const auto operation = std::get_if<OperationNode>(&*tracked)) {
for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) {
if (const auto found = TrackCbuf((*operation)[i], code, cursor)) {
// Cbuf found in operand
@@ -60,7 +60,7 @@ Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const
}
return nullptr;
}
- if (const auto conditional = std::get_if<ConditionalNode>(tracked)) {
+ if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) {
const auto& conditional_code = conditional->GetCode();
return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size()));
}
@@ -75,7 +75,7 @@ std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code,
if (!found) {
return {};
}
- if (const auto immediate = std::get_if<ImmediateNode>(found)) {
+ if (const auto immediate = std::get_if<ImmediateNode>(&*found)) {
return immediate->GetValue();
}
return {};
@@ -88,11 +88,11 @@ std::pair<Node, s64> ShaderIR::TrackRegister(const GprNode* tracked, const NodeB
if (!found_node) {
return {};
}
- const auto operation = std::get_if<OperationNode>(found_node);
+ const auto operation = std::get_if<OperationNode>(&*found_node);
ASSERT(operation);
const auto& target = (*operation)[0];
- if (const auto gpr_target = std::get_if<GprNode>(target)) {
+ if (const auto gpr_target = std::get_if<GprNode>(&*target)) {
if (gpr_target->GetIndex() == tracked->GetIndex()) {
return {(*operation)[1], new_cursor};
}