Merge pull request #2738 from lioncash/shader-ir
shader-ir: Minor cleanup-related changes
This commit is contained in:
		
						commit
						63bda67a34
					
				| @ -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); | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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 = | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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}; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei