From bf4dfb3ad4c6419216e8154c970f5577bc1bc475 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 4 Jun 2019 22:44:06 -0300 Subject: shader: Use shared_ptr to store nodes and move initialization to file Instead of having a vector of unique_ptr stored in a vector and returning star pointers to this, use shared_ptr. While changing initialization code, move it to a separate file when possible. This is a first step to allow code analysis and node generation beyond the ShaderIR class. --- src/video_core/shader/decode.cpp | 1 + src/video_core/shader/decode/arithmetic.cpp | 1 + src/video_core/shader/decode/arithmetic_half.cpp | 1 + .../shader/decode/arithmetic_half_immediate.cpp | 1 + .../shader/decode/arithmetic_immediate.cpp | 1 + .../shader/decode/arithmetic_integer.cpp | 1 + .../shader/decode/arithmetic_integer_immediate.cpp | 1 + src/video_core/shader/decode/bfe.cpp | 1 + src/video_core/shader/decode/bfi.cpp | 1 + src/video_core/shader/decode/conversion.cpp | 1 + src/video_core/shader/decode/ffma.cpp | 1 + src/video_core/shader/decode/float_set.cpp | 1 + .../shader/decode/float_set_predicate.cpp | 1 + src/video_core/shader/decode/half_set.cpp | 1 + .../shader/decode/half_set_predicate.cpp | 1 + src/video_core/shader/decode/hfma2.cpp | 1 + src/video_core/shader/decode/integer_set.cpp | 1 + .../shader/decode/integer_set_predicate.cpp | 1 + src/video_core/shader/decode/memory.cpp | 9 +- src/video_core/shader/decode/other.cpp | 1 + .../shader/decode/predicate_set_predicate.cpp | 1 + .../shader/decode/predicate_set_register.cpp | 1 + .../shader/decode/register_set_predicate.cpp | 1 + src/video_core/shader/decode/shift.cpp | 1 + src/video_core/shader/decode/texture.cpp | 9 +- src/video_core/shader/decode/video.cpp | 1 + src/video_core/shader/decode/xmad.cpp | 1 + src/video_core/shader/node_helper.cpp | 99 +++++++++++++++++++ src/video_core/shader/node_helper.h | 60 ++++++++++++ src/video_core/shader/shader_ir.cpp | 102 ++----------------- src/video_core/shader/shader_ir.h | 108 +++++---------------- src/video_core/shader/track.cpp | 18 ++-- 32 files changed, 238 insertions(+), 192 deletions(-) create mode 100644 src/video_core/shader/node_helper.cpp create mode 100644 src/video_core/shader/node_helper.h (limited to 'src/video_core/shader') 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(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(real_address, base_address, descriptor); bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1))); } @@ -298,9 +299,9 @@ std::tuple ShaderIR::TrackAndGetGlobalMemory(NodeB const Node base_address{ TrackCbuf(addr_register, global_code, static_cast(global_code.size()))}; - const auto cbuf = std::get_if(base_address); + const auto cbuf = std::get_if(&*base_address); ASSERT(cbuf != nullptr); - const auto cbuf_offset_imm = std::get_if(cbuf->GetOffset()); + const auto cbuf_offset_imm = std::get_if(&*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(global_code.size())); - const auto cbuf = std::get_if(base_sampler); - const auto cbuf_offset_imm = std::get_if(cbuf->GetOffset()); + const auto cbuf = std::get_if(&*base_sampler); + const auto cbuf_offset_imm = std::get_if(&*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 aoffi, std::optional bindless_reg) { - const bool is_array = array; - const bool is_shadow = depth_compare; + const auto is_array = static_cast(array); + const auto is_shadow = static_cast(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 +#include + +#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 code) { + return MakeNode(condition, std::move(code)); +} + +Node Comment(std::string text) { + return MakeNode(std::move(text)); +} + +Node Immediate(u32 value) { + return MakeNode(value); +} + +Node Immediate(s32 value) { + return Immediate(static_cast(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(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 +#include +#include +#include +#include +#include + +#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 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 +Node MakeNode(Args&&... args) { + static_assert(std::is_convertible_v); + return std::make_shared(T(std::forward(args)...)); +} + +template +Node Operation(OperationCode code, Args&&... args) { + if constexpr (sizeof...(args) == 0) { + return MakeNode(code); + } else if constexpr (std::is_convertible_v>, + Meta>) { + return MakeNode(code, std::forward(args)...); + } else { + return MakeNode(code, Meta{}, std::forward(args)...); + } +} + +template +Node SignedOperation(OperationCode code, bool is_signed, Args&&... args) { + return Operation(SignedToUnsignedCode(code, is_signed), std::forward(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(node_data); - const Node node = store.get(); - stored_nodes.push_back(std::move(store)); - return node; -} - -Node ShaderIR::Conditional(Node condition, std::vector&& 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(reg)); } - return StoreNode(GprNode(reg)); + return MakeNode(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(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(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(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(element), buffer)); + return MakeNode(index, static_cast(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(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(element), buffer)); + return MakeNode(index, static_cast(element), buffer); } Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) { - const Node node = StoreNode(InternalFlagNode(flag)); + const Node node = MakeNode(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(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(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; using NodeData = std::variant; -using Node = const NodeData*; +using Node = std::shared_ptr; using Node4 = std::array; using NodeBlock = std::vector; @@ -342,23 +342,20 @@ using Meta = std::variant; /// 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{}) {} - template - explicit OperationNode(OperationCode code, const T*... operands) - : OperationNode(code, {}, operands...) {} + explicit OperationNode(OperationCode code, std::vector operands) + : OperationNode(code, Meta{}, std::move(operands)) {} - template - 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 operands) + : code{code}, meta{std::move(meta)}, operands{std::move(operands)} {} - explicit OperationNode(OperationCode code, Meta&& meta, std::vector&& operands) - : code{code}, meta{meta}, operands{std::move(operands)} {} - - explicit OperationNode(OperationCode code, std::vector&& operands) - : code{code}, operands{std::move(operands)} {} + template + 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 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(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&& 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(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 TrackAndGetGlobalMemory( NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write); - template - Node Operation(OperationCode code, const T*... operands) { - return StoreNode(OperationNode(code, operands...)); - } - - template - Node Operation(OperationCode code, Meta&& meta, const T*... operands) { - return StoreNode(OperationNode(code, std::move(meta), operands...)); - } - - Node Operation(OperationCode code, std::vector&& operands) { - return StoreNode(OperationNode(code, std::move(operands))); - } - - Node Operation(OperationCode code, Meta&& meta, std::vector&& operands) { - return StoreNode(OperationNode(code, std::move(meta), std::move(operands))); - } - - template - Node SignedOperation(OperationCode code, bool is_signed, const T*... operands) { - return StoreNode(OperationNode(SignedToUnsignedCode(code, is_signed), operands...)); - } - - template - 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 basic_blocks; NodeBlock global_code; - std::vector> stored_nodes; - std::set used_registers; std::set used_predicates; std::set 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 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(node)) { + if (const auto operation = std::get_if(&*node)) { if (operation->GetCode() == operation_code) { return {node, cursor}; } } - if (const auto conditional = std::get_if(node)) { + if (const auto conditional = std::get_if(&*node)) { const auto& conditional_code = conditional->GetCode(); const auto [found, internal_cursor] = FindOperation( conditional_code, static_cast(conditional_code.size() - 1), operation_code); @@ -35,11 +35,11 @@ std::pair 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(tracked)) { + if (const auto cbuf = std::get_if(&*tracked)) { // Cbuf found, but it has to be immediate return std::holds_alternative(*cbuf->GetOffset()) ? tracked : nullptr; } - if (const auto gpr = std::get_if(tracked)) { + if (const auto gpr = std::get_if(&*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(tracked)) { + 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 @@ -60,7 +60,7 @@ Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const } return nullptr; } - if (const auto conditional = std::get_if(tracked)) { + if (const auto conditional = std::get_if(&*tracked)) { const auto& conditional_code = conditional->GetCode(); return TrackCbuf(tracked, conditional_code, static_cast(conditional_code.size())); } @@ -75,7 +75,7 @@ std::optional ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, if (!found) { return {}; } - if (const auto immediate = std::get_if(found)) { + if (const auto immediate = std::get_if(&*found)) { return immediate->GetValue(); } return {}; @@ -88,11 +88,11 @@ std::pair ShaderIR::TrackRegister(const GprNode* tracked, const NodeB if (!found_node) { return {}; } - const auto operation = std::get_if(found_node); + const auto operation = std::get_if(&*found_node); ASSERT(operation); const auto& target = (*operation)[0]; - if (const auto gpr_target = std::get_if(target)) { + if (const auto gpr_target = std::get_if(&*target)) { if (gpr_target->GetIndex() == tracked->GetIndex()) { return {(*operation)[1], new_cursor}; } -- cgit v1.2.3