Merge pull request #2738 from lioncash/shader-ir

shader-ir: Minor cleanup-related changes
This commit is contained in:
bunnei 2019-07-18 13:52:01 -04:00 committed by GitHub
commit 63bda67a34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 103 additions and 99 deletions

View file

@ -46,12 +46,12 @@ void ShaderIR::Decode() {
coverage_end = shader_info.end; coverage_end = shader_info.end;
if (shader_info.decompilable) { if (shader_info.decompilable) {
disable_flow_stack = true; disable_flow_stack = true;
const auto insert_block = ([this](NodeBlock& nodes, u32 label) { const auto insert_block = [this](NodeBlock& nodes, u32 label) {
if (label == exit_branch) { if (label == exit_branch) {
return; return;
} }
basic_blocks.insert({label, nodes}); basic_blocks.insert({label, nodes});
}); };
const auto& blocks = shader_info.blocks; const auto& blocks = shader_info.blocks;
NodeBlock current_block; NodeBlock current_block;
u32 current_label = exit_branch; u32 current_label = exit_branch;
@ -103,7 +103,7 @@ void ShaderIR::DecodeRangeInner(NodeBlock& bb, u32 begin, u32 end) {
} }
void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) { void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) {
const auto apply_conditions = ([&](const Condition& cond, Node n) -> Node { const auto apply_conditions = [&](const Condition& cond, Node n) -> Node {
Node result = n; Node result = n;
if (cond.cc != ConditionCode::T) { if (cond.cc != ConditionCode::T) {
result = Conditional(GetConditionCode(cond.cc), {result}); result = Conditional(GetConditionCode(cond.cc), {result});
@ -117,7 +117,7 @@ void ShaderIR::InsertControlFlow(NodeBlock& bb, const ShaderBlock& block) {
result = Conditional(GetPredicate(pred, is_neg), {result}); result = Conditional(GetPredicate(pred, is_neg), {result});
} }
return result; return result;
}); };
if (block.branch.address < 0) { if (block.branch.address < 0) {
if (block.branch.kills) { if (block.branch.kills) {
Node n = Operation(OperationCode::Discard); Node n = Operation(OperationCode::Discard);

View file

@ -95,10 +95,10 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
const Node op_b = const Node op_b =
GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index); GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index);
SetTemporal(bb, 0, op_a); SetTemporary(bb, 0, op_a);
SetTemporal(bb, 1, op_b); SetTemporary(bb, 1, op_b);
SetRegister(bb, instr.gpr0, GetTemporal(0)); SetRegister(bb, instr.gpr0, GetTemporary(0));
SetRegister(bb, instr.gpr0.Value() + 1, GetTemporal(1)); SetRegister(bb, instr.gpr0.Value() + 1, GetTemporary(1));
break; break;
} }
default: default:
@ -136,9 +136,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
} }
}(); }();
for (u32 i = 0; i < count; ++i) for (u32 i = 0; i < count; ++i)
SetTemporal(bb, i, GetLmem(i * 4)); SetTemporary(bb, i, GetLmem(i * 4));
for (u32 i = 0; i < count; ++i) for (u32 i = 0; i < count; ++i)
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
break; break;
} }
default: default:
@ -172,10 +172,10 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset); Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
SetTemporal(bb, i, gmem); SetTemporary(bb, i, gmem);
} }
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
} }
break; break;
} }
@ -253,11 +253,11 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
TrackAndGetGlobalMemory(bb, instr, true); TrackAndGetGlobalMemory(bb, instr, true);
// Encode in temporary registers like this: real_base_address, {registers_to_be_written...} // Encode in temporary registers like this: real_base_address, {registers_to_be_written...}
SetTemporal(bb, 0, real_address_base); SetTemporary(bb, 0, real_address_base);
const u32 count = GetUniformTypeElementsCount(type); const u32 count = GetUniformTypeElementsCount(type);
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
SetTemporal(bb, i + 1, GetRegister(instr.gpr0.Value() + i)); SetTemporary(bb, i + 1, GetRegister(instr.gpr0.Value() + i));
} }
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
const Node it_offset = Immediate(i * 4); const Node it_offset = Immediate(i * 4);
@ -265,7 +265,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset); Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
const Node gmem = MakeNode<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))); bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporary(i + 1)));
} }
break; break;
} }

View file

@ -181,10 +181,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
const Node value = const Node value =
Operation(OperationCode::TextureQueryDimensions, meta, Operation(OperationCode::TextureQueryDimensions, meta,
GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
SetTemporal(bb, indexer++, value); SetTemporary(bb, indexer++, value);
} }
for (u32 i = 0; i < indexer; ++i) { for (u32 i = 0; i < indexer; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
} }
break; break;
} }
@ -238,10 +238,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
auto params = coords; auto params = coords;
MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element};
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
SetTemporal(bb, indexer++, value); SetTemporary(bb, indexer++, value);
} }
for (u32 i = 0; i < indexer; ++i) { for (u32 i = 0; i < indexer; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
} }
break; break;
} }
@ -336,11 +336,11 @@ void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const
// Skip disabled components // Skip disabled components
continue; continue;
} }
SetTemporal(bb, dest_elem++, components[elem]); SetTemporary(bb, dest_elem++, components[elem]);
} }
// After writing values in temporals, move them to the real registers // After writing values in temporals, move them to the real registers
for (u32 i = 0; i < dest_elem; ++i) { for (u32 i = 0; i < dest_elem; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i));
} }
} }
@ -353,17 +353,17 @@ void ShaderIR::WriteTexsInstructionFloat(NodeBlock& bb, Instruction instr,
for (u32 component = 0; component < 4; ++component) { for (u32 component = 0; component < 4; ++component) {
if (!instr.texs.IsComponentEnabled(component)) if (!instr.texs.IsComponentEnabled(component))
continue; continue;
SetTemporal(bb, dest_elem++, components[component]); SetTemporary(bb, dest_elem++, components[component]);
} }
for (u32 i = 0; i < dest_elem; ++i) { for (u32 i = 0; i < dest_elem; ++i) {
if (i < 2) { if (i < 2) {
// Write the first two swizzle components to gpr0 and gpr0+1 // Write the first two swizzle components to gpr0 and gpr0+1
SetRegister(bb, instr.gpr0.Value() + i % 2, GetTemporal(i)); SetRegister(bb, instr.gpr0.Value() + i % 2, GetTemporary(i));
} else { } else {
ASSERT(instr.texs.HasTwoDestinations()); ASSERT(instr.texs.HasTwoDestinations());
// Write the rest of the swizzle components to gpr28 and gpr28+1 // Write the rest of the swizzle components to gpr28 and gpr28+1
SetRegister(bb, instr.gpr28.Value() + i % 2, GetTemporal(i)); SetRegister(bb, instr.gpr28.Value() + i % 2, GetTemporary(i));
} }
} }
} }
@ -391,11 +391,11 @@ void ShaderIR::WriteTexsInstructionHalfFloat(NodeBlock& bb, Instruction instr,
return; return;
} }
SetTemporal(bb, 0, first_value); SetTemporary(bb, 0, first_value);
SetTemporal(bb, 1, Operation(OperationCode::HPack2, values[2], values[3])); SetTemporary(bb, 1, Operation(OperationCode::HPack2, values[2], values[3]));
SetRegister(bb, instr.gpr0, GetTemporal(0)); SetRegister(bb, instr.gpr0, GetTemporary(0));
SetRegister(bb, instr.gpr28, GetTemporal(1)); SetRegister(bb, instr.gpr28, GetTemporary(1));
} }
Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,

View file

@ -73,8 +73,8 @@ u32 ShaderIR::DecodeXmad(NodeBlock& bb, u32 pc) {
if (is_psl) { if (is_psl) {
product = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, product, Immediate(16)); product = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, product, Immediate(16));
} }
SetTemporal(bb, 0, product); SetTemporary(bb, 0, product);
product = GetTemporal(0); product = GetTemporary(0);
const Node original_c = op_c; const Node original_c = op_c;
const Tegra::Shader::XmadMode set_mode = mode; // Workaround to clang compile error const Tegra::Shader::XmadMode set_mode = mode; // Workaround to clang compile error
@ -98,13 +98,13 @@ u32 ShaderIR::DecodeXmad(NodeBlock& bb, u32 pc) {
} }
}(); }();
SetTemporal(bb, 1, op_c); SetTemporary(bb, 1, op_c);
op_c = GetTemporal(1); op_c = GetTemporary(1);
// TODO(Rodrigo): Use an appropiate sign for this operation // TODO(Rodrigo): Use an appropiate sign for this operation
Node sum = Operation(OperationCode::IAdd, product, op_c); Node sum = Operation(OperationCode::IAdd, product, op_c);
SetTemporal(bb, 2, sum); SetTemporary(bb, 2, sum);
sum = GetTemporal(2); sum = GetTemporary(2);
if (is_merge) { if (is_merge) {
const Node a = BitfieldExtract(sum, 0, 16); const Node a = BitfieldExtract(sum, 0, 16);
const Node b = const Node b =

View file

@ -12,7 +12,7 @@
namespace VideoCommon::Shader { namespace VideoCommon::Shader {
Node Conditional(Node condition, std::vector<Node> code) { Node Conditional(Node condition, std::vector<Node> code) {
return MakeNode<ConditionalNode>(condition, std::move(code)); return MakeNode<ConditionalNode>(std::move(condition), std::move(code));
} }
Node Comment(std::string text) { Node Comment(std::string text) {

View file

@ -61,7 +61,7 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
const auto [entry, is_new] = used_cbufs.try_emplace(index); const auto [entry, is_new] = used_cbufs.try_emplace(index);
entry->second.MarkAsUsedIndirect(); entry->second.MarkAsUsedIndirect();
const Node final_offset = [&]() { Node final_offset = [&] {
// Attempt to inline constant buffer without a variable offset. This is done to allow // Attempt to inline constant buffer without a variable offset. This is done to allow
// tracking LDC calls. // tracking LDC calls.
if (const auto gpr = std::get_if<GprNode>(&*node)) { if (const auto gpr = std::get_if<GprNode>(&*node)) {
@ -69,9 +69,9 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
return Immediate(offset); return Immediate(offset);
} }
} }
return Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset)); return Operation(OperationCode::UAdd, NO_PRECISE, std::move(node), Immediate(offset));
}(); }();
return MakeNode<CbufNode>(index, final_offset); return MakeNode<CbufNode>(index, std::move(final_offset));
} }
Node ShaderIR::GetPredicate(u64 pred_, bool negated) { Node ShaderIR::GetPredicate(u64 pred_, bool negated) {
@ -89,7 +89,7 @@ Node ShaderIR::GetPredicate(bool immediate) {
Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) { Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) {
used_input_attributes.emplace(index); used_input_attributes.emplace(index);
return MakeNode<AbufNode>(index, static_cast<u32>(element), buffer); return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
} }
Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) { Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) {
@ -122,7 +122,7 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff
} }
used_output_attributes.insert(index); used_output_attributes.insert(index);
return MakeNode<AbufNode>(index, static_cast<u32>(element), buffer); return MakeNode<AbufNode>(index, static_cast<u32>(element), std::move(buffer));
} }
Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) { Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) {
@ -134,19 +134,19 @@ Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) {
} }
Node ShaderIR::GetLocalMemory(Node address) { Node ShaderIR::GetLocalMemory(Node address) {
return MakeNode<LmemNode>(address); return MakeNode<LmemNode>(std::move(address));
} }
Node ShaderIR::GetTemporal(u32 id) { Node ShaderIR::GetTemporary(u32 id) {
return GetRegister(Register::ZeroIndex + 1 + id); return GetRegister(Register::ZeroIndex + 1 + id);
} }
Node ShaderIR::GetOperandAbsNegFloat(Node value, bool absolute, bool negate) { Node ShaderIR::GetOperandAbsNegFloat(Node value, bool absolute, bool negate) {
if (absolute) { if (absolute) {
value = Operation(OperationCode::FAbsolute, NO_PRECISE, value); value = Operation(OperationCode::FAbsolute, NO_PRECISE, std::move(value));
} }
if (negate) { if (negate) {
value = Operation(OperationCode::FNegate, NO_PRECISE, value); value = Operation(OperationCode::FNegate, NO_PRECISE, std::move(value));
} }
return value; return value;
} }
@ -155,24 +155,26 @@ Node ShaderIR::GetSaturatedFloat(Node value, bool saturate) {
if (!saturate) { if (!saturate) {
return value; return value;
} }
const Node positive_zero = Immediate(std::copysignf(0, 1));
const Node positive_one = Immediate(1.0f); Node positive_zero = Immediate(std::copysignf(0, 1));
return Operation(OperationCode::FClamp, NO_PRECISE, value, positive_zero, positive_one); Node positive_one = Immediate(1.0f);
return Operation(OperationCode::FClamp, NO_PRECISE, std::move(value), std::move(positive_zero),
std::move(positive_one));
} }
Node ShaderIR::ConvertIntegerSize(Node value, Tegra::Shader::Register::Size size, bool is_signed) { Node ShaderIR::ConvertIntegerSize(Node value, Register::Size size, bool is_signed) {
switch (size) { switch (size) {
case Register::Size::Byte: case Register::Size::Byte:
value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE,
Immediate(24)); std::move(value), Immediate(24));
value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE,
Immediate(24)); std::move(value), Immediate(24));
return value; return value;
case Register::Size::Short: case Register::Size::Short:
value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE,
Immediate(16)); std::move(value), Immediate(16));
value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE,
Immediate(16)); std::move(value), Immediate(16));
case Register::Size::Word: case Register::Size::Word:
// Default - do nothing // Default - do nothing
return value; return value;
@ -188,27 +190,29 @@ Node ShaderIR::GetOperandAbsNegInteger(Node value, bool absolute, bool negate, b
return value; return value;
} }
if (absolute) { if (absolute) {
value = Operation(OperationCode::IAbsolute, NO_PRECISE, value); value = Operation(OperationCode::IAbsolute, NO_PRECISE, std::move(value));
} }
if (negate) { if (negate) {
value = Operation(OperationCode::INegate, NO_PRECISE, value); value = Operation(OperationCode::INegate, NO_PRECISE, std::move(value));
} }
return value; return value;
} }
Node ShaderIR::UnpackHalfImmediate(Instruction instr, bool has_negation) { Node ShaderIR::UnpackHalfImmediate(Instruction instr, bool has_negation) {
const Node value = Immediate(instr.half_imm.PackImmediates()); Node value = Immediate(instr.half_imm.PackImmediates());
if (!has_negation) { if (!has_negation) {
return value; return value;
} }
const Node first_negate = GetPredicate(instr.half_imm.first_negate != 0);
const Node second_negate = GetPredicate(instr.half_imm.second_negate != 0);
return Operation(OperationCode::HNegate, NO_PRECISE, value, first_negate, second_negate); Node first_negate = GetPredicate(instr.half_imm.first_negate != 0);
Node second_negate = GetPredicate(instr.half_imm.second_negate != 0);
return Operation(OperationCode::HNegate, NO_PRECISE, std::move(value), std::move(first_negate),
std::move(second_negate));
} }
Node ShaderIR::UnpackHalfFloat(Node value, Tegra::Shader::HalfType type) { Node ShaderIR::UnpackHalfFloat(Node value, Tegra::Shader::HalfType type) {
return Operation(OperationCode::HUnpack, type, value); return Operation(OperationCode::HUnpack, type, std::move(value));
} }
Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) { Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) {
@ -216,11 +220,11 @@ Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) {
case Tegra::Shader::HalfMerge::H0_H1: case Tegra::Shader::HalfMerge::H0_H1:
return src; return src;
case Tegra::Shader::HalfMerge::F32: case Tegra::Shader::HalfMerge::F32:
return Operation(OperationCode::HMergeF32, src); return Operation(OperationCode::HMergeF32, std::move(src));
case Tegra::Shader::HalfMerge::Mrg_H0: case Tegra::Shader::HalfMerge::Mrg_H0:
return Operation(OperationCode::HMergeH0, dest, src); return Operation(OperationCode::HMergeH0, std::move(dest), std::move(src));
case Tegra::Shader::HalfMerge::Mrg_H1: case Tegra::Shader::HalfMerge::Mrg_H1:
return Operation(OperationCode::HMergeH1, dest, src); return Operation(OperationCode::HMergeH1, std::move(dest), std::move(src));
} }
UNREACHABLE(); UNREACHABLE();
return src; return src;
@ -228,10 +232,10 @@ Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) {
Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) { Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
if (absolute) { if (absolute) {
value = Operation(OperationCode::HAbsolute, NO_PRECISE, value); value = Operation(OperationCode::HAbsolute, NO_PRECISE, std::move(value));
} }
if (negate) { if (negate) {
value = Operation(OperationCode::HNegate, NO_PRECISE, value, GetPredicate(true), value = Operation(OperationCode::HNegate, NO_PRECISE, std::move(value), GetPredicate(true),
GetPredicate(true)); GetPredicate(true));
} }
return value; return value;
@ -241,9 +245,11 @@ Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) {
if (!saturate) { if (!saturate) {
return value; return value;
} }
const Node positive_zero = Immediate(std::copysignf(0, 1));
const Node positive_one = Immediate(1.0f); Node positive_zero = Immediate(std::copysignf(0, 1));
return Operation(OperationCode::HClamp, NO_PRECISE, value, positive_zero, positive_one); Node positive_one = Immediate(1.0f);
return Operation(OperationCode::HClamp, NO_PRECISE, std::move(value), std::move(positive_zero),
std::move(positive_one));
} }
Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) { Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
@ -271,7 +277,6 @@ Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, N
condition == PredCondition::LessEqualWithNan || condition == PredCondition::LessEqualWithNan ||
condition == PredCondition::GreaterThanWithNan || condition == PredCondition::GreaterThanWithNan ||
condition == PredCondition::GreaterEqualWithNan) { condition == PredCondition::GreaterEqualWithNan) {
predicate = Operation(OperationCode::LogicalOr, predicate, predicate = Operation(OperationCode::LogicalOr, predicate,
Operation(OperationCode::LogicalFIsNan, op_a)); Operation(OperationCode::LogicalFIsNan, op_a));
predicate = Operation(OperationCode::LogicalOr, predicate, predicate = Operation(OperationCode::LogicalOr, predicate,
@ -300,7 +305,8 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
"Unknown predicate comparison operation"); "Unknown predicate comparison operation");
Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b); Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a),
std::move(op_b));
UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan || UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
condition == PredCondition::NotEqualWithNan || condition == PredCondition::NotEqualWithNan ||
@ -330,9 +336,7 @@ Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
"Unknown predicate comparison operation"); "Unknown predicate comparison operation");
const Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b); return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b));
return predicate;
} }
OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) { OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) {
@ -358,31 +362,32 @@ Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) {
} }
void ShaderIR::SetRegister(NodeBlock& bb, Register dest, Node src) { void ShaderIR::SetRegister(NodeBlock& bb, Register dest, Node src) {
bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), std::move(src)));
} }
void ShaderIR::SetPredicate(NodeBlock& bb, u64 dest, Node src) { void ShaderIR::SetPredicate(NodeBlock& bb, u64 dest, Node src) {
bb.push_back(Operation(OperationCode::LogicalAssign, GetPredicate(dest), src)); bb.push_back(Operation(OperationCode::LogicalAssign, GetPredicate(dest), std::move(src)));
} }
void ShaderIR::SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value) { void ShaderIR::SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value) {
bb.push_back(Operation(OperationCode::LogicalAssign, GetInternalFlag(flag), value)); bb.push_back(Operation(OperationCode::LogicalAssign, GetInternalFlag(flag), std::move(value)));
} }
void ShaderIR::SetLocalMemory(NodeBlock& bb, Node address, Node value) { void ShaderIR::SetLocalMemory(NodeBlock& bb, Node address, Node value) {
bb.push_back(Operation(OperationCode::Assign, GetLocalMemory(address), value)); bb.push_back(
Operation(OperationCode::Assign, GetLocalMemory(std::move(address)), std::move(value)));
} }
void ShaderIR::SetTemporal(NodeBlock& bb, u32 id, Node value) { void ShaderIR::SetTemporary(NodeBlock& bb, u32 id, Node value) {
SetRegister(bb, Register::ZeroIndex + 1 + id, value); SetRegister(bb, Register::ZeroIndex + 1 + id, std::move(value));
} }
void ShaderIR::SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc) { void ShaderIR::SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc) {
if (!sets_cc) { if (!sets_cc) {
return; return;
} }
const Node zerop = Operation(OperationCode::LogicalFEqual, value, Immediate(0.0f)); Node zerop = Operation(OperationCode::LogicalFEqual, std::move(value), Immediate(0.0f));
SetInternalFlag(bb, InternalFlag::Zero, zerop); SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete"); LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete");
} }
@ -390,14 +395,14 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
if (!sets_cc) { if (!sets_cc) {
return; return;
} }
const Node zerop = Operation(OperationCode::LogicalIEqual, value, Immediate(0)); Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0));
SetInternalFlag(bb, InternalFlag::Zero, zerop); SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete"); LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete");
} }
Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) { Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
return Operation(OperationCode::UBitfieldExtract, NO_PRECISE, value, Immediate(offset), return Operation(OperationCode::UBitfieldExtract, NO_PRECISE, std::move(value),
Immediate(bits)); Immediate(offset), Immediate(bits));
} }
} // namespace VideoCommon::Shader } // namespace VideoCommon::Shader

View file

@ -5,13 +5,10 @@
#pragma once #pragma once
#include <array> #include <array>
#include <cstring>
#include <map> #include <map>
#include <optional> #include <optional>
#include <set> #include <set>
#include <string>
#include <tuple> #include <tuple>
#include <variant>
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
@ -210,8 +207,8 @@ private:
Node GetInternalFlag(InternalFlag flag, bool negated = false); Node GetInternalFlag(InternalFlag flag, bool negated = false);
/// Generates a node representing a local memory address /// Generates a node representing a local memory address
Node GetLocalMemory(Node address); Node GetLocalMemory(Node address);
/// Generates a temporal, internally it uses a post-RZ register /// Generates a temporary, internally it uses a post-RZ register
Node GetTemporal(u32 id); Node GetTemporary(u32 id);
/// Sets a register. src value must be a number-evaluated node. /// Sets a register. src value must be a number-evaluated node.
void SetRegister(NodeBlock& bb, Tegra::Shader::Register dest, Node src); void SetRegister(NodeBlock& bb, Tegra::Shader::Register dest, Node src);
@ -221,8 +218,8 @@ private:
void SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value); void SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value);
/// Sets a local memory address. address and value must be a number-evaluated node /// Sets a local memory address. address and value must be a number-evaluated node
void SetLocalMemory(NodeBlock& bb, Node address, Node value); void SetLocalMemory(NodeBlock& bb, Node address, Node value);
/// Sets a temporal. Internally it uses a post-RZ register /// Sets a temporary. Internally it uses a post-RZ register
void SetTemporal(NodeBlock& bb, u32 id, Node value); void SetTemporary(NodeBlock& bb, u32 id, Node value);
/// Sets internal flags from a float /// Sets internal flags from a float
void SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc = true); void SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc = true);

View file

@ -15,18 +15,20 @@ 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.at(cursor); 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 {std::move(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( 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 {std::move(found), cursor};
} }
} }
} }