diff options
Diffstat (limited to 'src/video_core/shader')
-rw-r--r-- | src/video_core/shader/decode.cpp | 8 | ||||
-rw-r--r-- | src/video_core/shader/decode/arithmetic.cpp | 13 | ||||
-rw-r--r-- | src/video_core/shader/decode/arithmetic_half_immediate.cpp | 4 | ||||
-rw-r--r-- | src/video_core/shader/decode/ffma.cpp | 10 | ||||
-rw-r--r-- | src/video_core/shader/decode/half_set_predicate.cpp | 71 | ||||
-rw-r--r-- | src/video_core/shader/decode/hfma2.cpp | 4 | ||||
-rw-r--r-- | src/video_core/shader/decode/memory.cpp | 22 | ||||
-rw-r--r-- | src/video_core/shader/decode/other.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/texture.cpp | 26 | ||||
-rw-r--r-- | src/video_core/shader/decode/xmad.cpp | 12 | ||||
-rw-r--r-- | src/video_core/shader/node.h | 3 | ||||
-rw-r--r-- | src/video_core/shader/node_helper.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/shader_ir.cpp | 111 | ||||
-rw-r--r-- | src/video_core/shader/shader_ir.h | 11 | ||||
-rw-r--r-- | src/video_core/shader/track.cpp | 10 |
15 files changed, 166 insertions, 143 deletions
diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp index 29c8895c5..afffd157f 100644 --- a/src/video_core/shader/decode.cpp +++ b/src/video_core/shader/decode.cpp @@ -46,12 +46,12 @@ void ShaderIR::Decode() { coverage_end = shader_info.end; if (shader_info.decompilable) { 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) { return; } basic_blocks.insert({label, nodes}); - }); + }; const auto& blocks = shader_info.blocks; NodeBlock current_block; 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) { - const auto apply_conditions = ([&](const Condition& cond, Node n) -> Node { + const auto apply_conditions = [&](const Condition& cond, Node n) -> Node { Node result = n; if (cond.cc != ConditionCode::T) { 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}); } return result; - }); + }; if (block.branch.address < 0) { if (block.branch.kills) { Node n = Operation(OperationCode::Discard); diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index 87d8fecaa..1473c282a 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp @@ -42,11 +42,14 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) { case OpCode::Id::FMUL_R: case OpCode::Id::FMUL_IMM: { // FMUL does not have 'abs' bits and only the second operand has a 'neg' bit. - UNIMPLEMENTED_IF_MSG(instr.fmul.tab5cb8_2 != 0, "FMUL tab5cb8_2({}) is not implemented", - instr.fmul.tab5cb8_2.Value()); - UNIMPLEMENTED_IF_MSG( - instr.fmul.tab5c68_0 != 1, "FMUL tab5cb8_0({}) is not implemented", - instr.fmul.tab5c68_0.Value()); // SMO typical sends 1 here which seems to be the default + if (instr.fmul.tab5cb8_2 != 0) { + LOG_WARNING(HW_GPU, "FMUL tab5cb8_2({}) is not implemented", + instr.fmul.tab5cb8_2.Value()); + } + if (instr.fmul.tab5c68_0 != 1) { + LOG_WARNING(HW_GPU, "FMUL tab5cb8_0({}) is not implemented", + instr.fmul.tab5c68_0.Value()); + } op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b); diff --git a/src/video_core/shader/decode/arithmetic_half_immediate.cpp b/src/video_core/shader/decode/arithmetic_half_immediate.cpp index 7bcf38f23..6466fc011 100644 --- a/src/video_core/shader/decode/arithmetic_half_immediate.cpp +++ b/src/video_core/shader/decode/arithmetic_half_immediate.cpp @@ -23,7 +23,9 @@ u32 ShaderIR::DecodeArithmeticHalfImmediate(NodeBlock& bb, u32 pc) { LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); } } else { - UNIMPLEMENTED_IF(instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::None); + if (instr.alu_half_imm.precision != Tegra::Shader::HalfPrecision::None) { + LOG_WARNING(HW_GPU, "{} FTZ not implemented", opcode->get().GetName()); + } } Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.alu_half_imm.type_a); diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp index 29be25ca3..ca2f39e8d 100644 --- a/src/video_core/shader/decode/ffma.cpp +++ b/src/video_core/shader/decode/ffma.cpp @@ -18,10 +18,12 @@ u32 ShaderIR::DecodeFfma(NodeBlock& bb, u32 pc) { const auto opcode = OpCode::Decode(instr); UNIMPLEMENTED_IF_MSG(instr.ffma.cc != 0, "FFMA cc not implemented"); - UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_0 != 1, "FFMA tab5980_0({}) not implemented", - instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO - UNIMPLEMENTED_IF_MSG(instr.ffma.tab5980_1 != 0, "FFMA tab5980_1({}) not implemented", - instr.ffma.tab5980_1.Value()); + if (instr.ffma.tab5980_0 != 1) { + LOG_WARNING(HW_GPU, "FFMA tab5980_0({}) not implemented", instr.ffma.tab5980_0.Value()); + } + if (instr.ffma.tab5980_1 != 0) { + LOG_WARNING(HW_GPU, "FFMA tab5980_1({}) not implemented", instr.ffma.tab5980_1.Value()); + } const Node op_a = GetRegister(instr.gpr8); diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp index d59d15bd8..a82a6a15c 100644 --- a/src/video_core/shader/decode/half_set_predicate.cpp +++ b/src/video_core/shader/decode/half_set_predicate.cpp @@ -18,43 +18,56 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) { const Instruction instr = {program_code[pc]}; const auto opcode = OpCode::Decode(instr); - UNIMPLEMENTED_IF(instr.hsetp2.ftz != 0); + DEBUG_ASSERT(instr.hsetp2.ftz == 0); Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.hsetp2.type_a); op_a = GetOperandAbsNegHalf(op_a, instr.hsetp2.abs_a, instr.hsetp2.negate_a); - Node op_b = [&]() { - switch (opcode->get().GetId()) { - case OpCode::Id::HSETP2_R: - return GetOperandAbsNegHalf(GetRegister(instr.gpr20), instr.hsetp2.abs_a, - instr.hsetp2.negate_b); - default: - UNREACHABLE(); - return Immediate(0); - } - }(); - op_b = UnpackHalfFloat(op_b, instr.hsetp2.type_b); - - // We can't use the constant predicate as destination. - ASSERT(instr.hsetp2.pred3 != static_cast<u64>(Pred::UnusedIndex)); - - const Node second_pred = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0); + Tegra::Shader::PredCondition cond{}; + bool h_and{}; + Node op_b{}; + switch (opcode->get().GetId()) { + case OpCode::Id::HSETP2_C: + cond = instr.hsetp2.cbuf_and_imm.cond; + h_and = instr.hsetp2.cbuf_and_imm.h_and; + op_b = GetOperandAbsNegHalf(GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), + instr.hsetp2.cbuf.abs_b, instr.hsetp2.cbuf.negate_b); + break; + case OpCode::Id::HSETP2_IMM: + cond = instr.hsetp2.cbuf_and_imm.cond; + h_and = instr.hsetp2.cbuf_and_imm.h_and; + op_b = UnpackHalfImmediate(instr, true); + break; + case OpCode::Id::HSETP2_R: + cond = instr.hsetp2.reg.cond; + h_and = instr.hsetp2.reg.h_and; + op_b = + UnpackHalfFloat(GetOperandAbsNegHalf(GetRegister(instr.gpr20), instr.hsetp2.reg.abs_b, + instr.hsetp2.reg.negate_b), + instr.hsetp2.reg.type_b); + break; + default: + UNREACHABLE(); + op_b = Immediate(0); + } const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op); - const OperationCode pair_combiner = - instr.hsetp2.h_and ? OperationCode::LogicalAll2 : OperationCode::LogicalAny2; - - const Node comparison = GetPredicateComparisonHalf(instr.hsetp2.cond, op_a, op_b); - const Node first_pred = Operation(pair_combiner, comparison); + const Node pred39 = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred); - // Set the primary predicate to the result of Predicate OP SecondPredicate - const Node value = Operation(combiner, first_pred, second_pred); - SetPredicate(bb, instr.hsetp2.pred3, value); + const auto Write = [&](u64 dest, Node src) { + SetPredicate(bb, dest, Operation(combiner, std::move(src), pred39)); + }; - if (instr.hsetp2.pred0 != static_cast<u64>(Pred::UnusedIndex)) { - // Set the secondary predicate to the result of !Predicate OP SecondPredicate, if enabled - const Node negated_pred = Operation(OperationCode::LogicalNegate, first_pred); - SetPredicate(bb, instr.hsetp2.pred0, Operation(combiner, negated_pred, second_pred)); + const Node comparison = GetPredicateComparisonHalf(cond, op_a, op_b); + const u64 first = instr.hsetp2.pred0; + const u64 second = instr.hsetp2.pred3; + if (h_and) { + const Node joined = Operation(OperationCode::LogicalAnd2, comparison); + Write(first, joined); + Write(second, Operation(OperationCode::LogicalNegate, joined)); + } else { + Write(first, Operation(OperationCode::LogicalPick2, comparison, Immediate(0u))); + Write(second, Operation(OperationCode::LogicalPick2, comparison, Immediate(1u))); } return pc; diff --git a/src/video_core/shader/decode/hfma2.cpp b/src/video_core/shader/decode/hfma2.cpp index c3bcf1ae9..5b44cb79c 100644 --- a/src/video_core/shader/decode/hfma2.cpp +++ b/src/video_core/shader/decode/hfma2.cpp @@ -22,9 +22,9 @@ u32 ShaderIR::DecodeHfma2(NodeBlock& bb, u32 pc) { const auto opcode = OpCode::Decode(instr); if (opcode->get().GetId() == OpCode::Id::HFMA2_RR) { - UNIMPLEMENTED_IF(instr.hfma2.rr.precision != HalfPrecision::None); + DEBUG_ASSERT(instr.hfma2.rr.precision == HalfPrecision::None); } else { - UNIMPLEMENTED_IF(instr.hfma2.precision != HalfPrecision::None); + DEBUG_ASSERT(instr.hfma2.precision == HalfPrecision::None); } constexpr auto identity = HalfType::H0_H1; diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index ab207a33b..ed108bea8 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -95,10 +95,10 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { const Node op_b = GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index); - SetTemporal(bb, 0, op_a); - SetTemporal(bb, 1, op_b); - SetRegister(bb, instr.gpr0, GetTemporal(0)); - SetRegister(bb, instr.gpr0.Value() + 1, GetTemporal(1)); + SetTemporary(bb, 0, op_a); + SetTemporary(bb, 1, op_b); + SetRegister(bb, instr.gpr0, GetTemporary(0)); + SetRegister(bb, instr.gpr0.Value() + 1, GetTemporary(1)); break; } default: @@ -136,9 +136,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { } }(); 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) - SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); break; } default: @@ -172,10 +172,10 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset); 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) { - SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); } break; } @@ -253,11 +253,11 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { TrackAndGetGlobalMemory(bb, instr, true); // 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); 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) { 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); 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; } diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index 42e3de02f..c0f64d7a0 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp @@ -102,7 +102,7 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { PRECISE, op_a, Immediate(3)); const Node operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target)); - branch = Operation(OperationCode::BranchIndirect, convert); + branch = Operation(OperationCode::BranchIndirect, operand); } const Tegra::Shader::ConditionCode cc = instr.flow_condition_code; diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index e1ee5c190..0b934a069 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp @@ -181,10 +181,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { const Node value = Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0))); - SetTemporal(bb, indexer++, value); + SetTemporary(bb, indexer++, value); } for (u32 i = 0; i < indexer; ++i) { - SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); } break; } @@ -238,10 +238,10 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { auto params = coords; MetaTexture meta{sampler, {}, {}, {}, {}, {}, {}, element}; 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) { - SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); + SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); } break; } @@ -336,11 +336,11 @@ void ShaderIR::WriteTexInstructionFloat(NodeBlock& bb, Instruction instr, const // Skip disabled components continue; } - SetTemporal(bb, dest_elem++, components[elem]); + SetTemporary(bb, dest_elem++, components[elem]); } // After writing values in temporals, move them to the real registers 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) { if (!instr.texs.IsComponentEnabled(component)) continue; - SetTemporal(bb, dest_elem++, components[component]); + SetTemporary(bb, dest_elem++, components[component]); } for (u32 i = 0; i < dest_elem; ++i) { if (i < 2) { // 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 { ASSERT(instr.texs.HasTwoDestinations()); // 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; } - SetTemporal(bb, 0, first_value); - SetTemporal(bb, 1, Operation(OperationCode::HPack2, values[2], values[3])); + SetTemporary(bb, 0, first_value); + SetTemporary(bb, 1, Operation(OperationCode::HPack2, values[2], values[3])); - SetRegister(bb, instr.gpr0, GetTemporal(0)); - SetRegister(bb, instr.gpr28, GetTemporal(1)); + SetRegister(bb, instr.gpr0, GetTemporary(0)); + SetRegister(bb, instr.gpr28, GetTemporary(1)); } Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp index 93dee77d1..206961909 100644 --- a/src/video_core/shader/decode/xmad.cpp +++ b/src/video_core/shader/decode/xmad.cpp @@ -73,8 +73,8 @@ u32 ShaderIR::DecodeXmad(NodeBlock& bb, u32 pc) { if (is_psl) { product = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, product, Immediate(16)); } - SetTemporal(bb, 0, product); - product = GetTemporal(0); + SetTemporary(bb, 0, product); + product = GetTemporary(0); const Node original_c = op_c; 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); - op_c = GetTemporal(1); + SetTemporary(bb, 1, op_c); + op_c = GetTemporary(1); // TODO(Rodrigo): Use an appropiate sign for this operation Node sum = Operation(OperationCode::IAdd, product, op_c); - SetTemporal(bb, 2, sum); - sum = GetTemporal(2); + SetTemporary(bb, 2, sum); + sum = GetTemporary(2); if (is_merge) { const Node a = BitfieldExtract(sum, 0, 16); const Node b = diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 7427ed896..715184d67 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -101,8 +101,7 @@ enum class OperationCode { LogicalXor, /// (bool a, bool b) -> bool LogicalNegate, /// (bool a) -> bool LogicalPick2, /// (bool2 pair, uint index) -> bool - LogicalAll2, /// (bool2 a) -> bool - LogicalAny2, /// (bool2 a) -> bool + LogicalAnd2, /// (bool2 a) -> bool LogicalFLessThan, /// (float a, float b) -> bool LogicalFEqual, /// (float a, float b) -> bool diff --git a/src/video_core/shader/node_helper.cpp b/src/video_core/shader/node_helper.cpp index 6fccbbba3..b3dcd291c 100644 --- a/src/video_core/shader/node_helper.cpp +++ b/src/video_core/shader/node_helper.cpp @@ -12,7 +12,7 @@ namespace VideoCommon::Shader { 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) { diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 78bd1cf1e..5e91fe129 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -61,7 +61,7 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) { const auto [entry, is_new] = used_cbufs.try_emplace(index); entry->second.MarkAsUsedIndirect(); - const Node final_offset = [&]() { + Node final_offset = [&] { // Attempt to inline constant buffer without a variable offset. This is done to allow // tracking LDC calls. 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 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) { @@ -89,7 +89,7 @@ Node ShaderIR::GetPredicate(bool immediate) { Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffer) { 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) { @@ -122,7 +122,7 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff } 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) { @@ -134,19 +134,19 @@ Node ShaderIR::GetInternalFlag(InternalFlag flag, bool negated) { } 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); } Node ShaderIR::GetOperandAbsNegFloat(Node value, bool absolute, bool negate) { if (absolute) { - value = Operation(OperationCode::FAbsolute, NO_PRECISE, value); + value = Operation(OperationCode::FAbsolute, NO_PRECISE, std::move(value)); } if (negate) { - value = Operation(OperationCode::FNegate, NO_PRECISE, value); + value = Operation(OperationCode::FNegate, NO_PRECISE, std::move(value)); } return value; } @@ -155,24 +155,26 @@ Node ShaderIR::GetSaturatedFloat(Node value, bool saturate) { if (!saturate) { return value; } - const Node positive_zero = Immediate(std::copysignf(0, 1)); - const Node positive_one = Immediate(1.0f); - return Operation(OperationCode::FClamp, NO_PRECISE, value, positive_zero, positive_one); + + Node positive_zero = Immediate(std::copysignf(0, 1)); + 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) { case Register::Size::Byte: - value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, - Immediate(24)); - value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, - Immediate(24)); + value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, + std::move(value), Immediate(24)); + value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, + std::move(value), Immediate(24)); return value; case Register::Size::Short: - value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, value, - Immediate(16)); - value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, value, - Immediate(16)); + value = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, NO_PRECISE, + std::move(value), Immediate(16)); + value = SignedOperation(OperationCode::IArithmeticShiftRight, is_signed, NO_PRECISE, + std::move(value), Immediate(16)); case Register::Size::Word: // Default - do nothing return value; @@ -188,27 +190,29 @@ Node ShaderIR::GetOperandAbsNegInteger(Node value, bool absolute, bool negate, b return value; } if (absolute) { - value = Operation(OperationCode::IAbsolute, NO_PRECISE, value); + value = Operation(OperationCode::IAbsolute, NO_PRECISE, std::move(value)); } if (negate) { - value = Operation(OperationCode::INegate, NO_PRECISE, value); + value = Operation(OperationCode::INegate, NO_PRECISE, std::move(value)); } return value; } 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) { 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) { - 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) { @@ -216,11 +220,11 @@ Node ShaderIR::HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge) { case Tegra::Shader::HalfMerge::H0_H1: return src; case Tegra::Shader::HalfMerge::F32: - return Operation(OperationCode::HMergeF32, src); + return Operation(OperationCode::HMergeF32, std::move(src)); 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: - return Operation(OperationCode::HMergeH1, dest, src); + return Operation(OperationCode::HMergeH1, std::move(dest), std::move(src)); } UNREACHABLE(); 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) { if (absolute) { - value = Operation(OperationCode::HAbsolute, NO_PRECISE, value); + value = Operation(OperationCode::HAbsolute, NO_PRECISE, std::move(value)); } if (negate) { - value = Operation(OperationCode::HNegate, NO_PRECISE, value, GetPredicate(true), + value = Operation(OperationCode::HNegate, NO_PRECISE, std::move(value), GetPredicate(true), GetPredicate(true)); } return value; @@ -241,9 +245,11 @@ Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) { if (!saturate) { return value; } - const Node positive_zero = Immediate(std::copysignf(0, 1)); - const Node positive_one = Immediate(1.0f); - return Operation(OperationCode::HClamp, NO_PRECISE, value, positive_zero, positive_one); + + Node positive_zero = Immediate(std::copysignf(0, 1)); + 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) { @@ -271,7 +277,6 @@ Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, N condition == PredCondition::LessEqualWithNan || condition == PredCondition::GreaterThanWithNan || condition == PredCondition::GreaterEqualWithNan) { - predicate = Operation(OperationCode::LogicalOr, predicate, Operation(OperationCode::LogicalFIsNan, op_a)); predicate = Operation(OperationCode::LogicalOr, predicate, @@ -300,7 +305,8 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), "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 || condition == PredCondition::NotEqualWithNan || @@ -330,9 +336,7 @@ Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), "Unknown predicate comparison operation"); - const Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b); - - return predicate; + return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b)); } 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) { - 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) { - 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) { - 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) { - 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) { - SetRegister(bb, Register::ZeroIndex + 1 + id, value); +void ShaderIR::SetTemporary(NodeBlock& bb, u32 id, Node value) { + SetRegister(bb, Register::ZeroIndex + 1 + id, std::move(value)); } void ShaderIR::SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc) { if (!sets_cc) { return; } - const Node zerop = Operation(OperationCode::LogicalFEqual, value, Immediate(0.0f)); - SetInternalFlag(bb, InternalFlag::Zero, zerop); + Node zerop = Operation(OperationCode::LogicalFEqual, std::move(value), Immediate(0.0f)); + SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop)); 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) { return; } - const Node zerop = Operation(OperationCode::LogicalIEqual, value, Immediate(0)); - SetInternalFlag(bb, InternalFlag::Zero, zerop); + Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0)); + SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop)); LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete"); } Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) { - return Operation(OperationCode::UBitfieldExtract, NO_PRECISE, value, Immediate(offset), - Immediate(bits)); + return Operation(OperationCode::UBitfieldExtract, NO_PRECISE, std::move(value), + Immediate(offset), Immediate(bits)); } } // namespace VideoCommon::Shader diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 126c78136..59a083d90 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -5,13 +5,10 @@ #pragma once #include <array> -#include <cstring> #include <map> #include <optional> #include <set> -#include <string> #include <tuple> -#include <variant> #include <vector> #include "common/common_types.h" @@ -210,8 +207,8 @@ private: Node GetInternalFlag(InternalFlag flag, bool negated = false); /// Generates a node representing a local memory address Node GetLocalMemory(Node address); - /// Generates a temporal, internally it uses a post-RZ register - Node GetTemporal(u32 id); + /// Generates a temporary, internally it uses a post-RZ register + Node GetTemporary(u32 id); /// Sets a register. src value must be a number-evaluated node. void SetRegister(NodeBlock& bb, Tegra::Shader::Register dest, Node src); @@ -221,8 +218,8 @@ private: void SetInternalFlag(NodeBlock& bb, InternalFlag flag, Node value); /// Sets a local memory address. address and value must be a number-evaluated node void SetLocalMemory(NodeBlock& bb, Node address, Node value); - /// Sets a temporal. Internally it uses a post-RZ register - void SetTemporal(NodeBlock& bb, u32 id, Node value); + /// Sets a temporary. Internally it uses a post-RZ register + void SetTemporary(NodeBlock& bb, u32 id, Node value); /// Sets internal flags from a float void SetInternalFlagsFromFloat(NodeBlock& bb, Node value, bool sets_cc = true); diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp index 92ff2423e..55f5949e4 100644 --- a/src/video_core/shader/track.cpp +++ b/src/video_core/shader/track.cpp @@ -15,18 +15,20 @@ namespace { std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor, OperationCode operation_code) { 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 (operation->GetCode() == operation_code) { - return {node, cursor}; + return {std::move(node), cursor}; } } + if (const auto conditional = std::get_if<ConditionalNode>(&*node)) { 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); if (found) { - return {found, cursor}; + return {std::move(found), cursor}; } } } |