From 839c1726127d5a0d09685fc9eb65e540bcda5c03 Mon Sep 17 00:00:00 2001 From: nmzik Date: Tue, 8 Sep 2026 14:01:46 +0400 Subject: [PATCH] shader: reuse operands and remove duplicate helpers --- .../recompiler/frontend/cfg/ShaderCFG.cpp | 21 ++-- .../frontend/decode/VectorAluOps.cpp | 96 +++---------------- .../recompiler/frontend/translate/Convert.cpp | 4 +- .../recompiler/frontend/translate/Float.cpp | 25 +++-- .../recompiler/frontend/translate/Integer.cpp | 14 ++- .../recompiler/frontend/translate/Memory.cpp | 30 +++--- .../frontend/translate/Translate.cpp | 12 +-- .../frontend/translate/Translator.h | 4 +- .../shader/recompiler/ir/passes/SrtWalker.cpp | 3 +- 9 files changed, 57 insertions(+), 152 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp index 64e8e48bc..7c53bba5c 100644 --- a/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp +++ b/src/graphics/shader/recompiler/frontend/cfg/ShaderCFG.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Libs::Graphics::ShaderRecompiler::CFG { @@ -861,15 +862,15 @@ void ComputeNaturalLoops(Graph& graph) { loop.header = edge.to; loop.latch = edge.from; loop.continue_block = edge.from; - loop.body_blocks = body; + loop.body_blocks = std::move(body); - for (auto block_id: body) { + for (auto block_id: loop.body_blocks) { const auto* block = graph.FindBlock(block_id); if (block == nullptr) { continue; } for (auto succ: block->successors) { - if (!Contains(body, succ)) { + if (!Contains(loop.body_blocks, succ)) { AddUnique(loop.exit_blocks, succ); } } @@ -1749,7 +1750,7 @@ bool RouteOneSharedArm(Graph& graph, uint32_t original_block_count, uint32_t out inner_is_true ? outer->terminator.false_block : outer->terminator.true_block; const auto* inner = graph.FindBlock(inner_id); if (inner == nullptr || inner->inst_begin == inner->inst_end || - inner->predecessors != std::vector {outer_id} || + inner->predecessors.size() != 1u || inner->predecessors.front() != outer_id || inner->terminator.kind != TerminatorKind::ConditionalBranch || IsInnermostLoopControlConditional(graph, *inner)) { continue; @@ -1941,9 +1942,9 @@ Graph BuildGraph(const Decoder::Program& program) { graph, FailureKind::InvalidBranchTarget, UINT32_MAX, fmt::format("unsupported dynamic S_SETPC_B64 at pc 0x{:08x}", inst.pc)); } - const auto& target_pcs = target_info.indirect - ? target_info.target_pcs - : std::vector {target_info.target}; + const auto target_pcs = target_info.indirect + ? std::span(target_info.target_pcs) + : std::span(&target_info.target, 1); for (const auto target: target_pcs) { if (!IsValidTarget(target, instruction_pcs, first_pc, end_pc)) { ExitBuildFailure( @@ -2103,11 +2104,7 @@ Graph BuildGraph(const Decoder::Program& program) { } SortUnique(graph.code_table_load_pcs); - ComputeDominators(graph); - ComputePostDominators(graph); - ComputeBackEdges(graph); - ComputeNaturalLoops(graph); - ComputeComponents(graph); + RecomputeAnalyses(graph); if (indirect_setpc) { graph.irreducible = true; diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index de79ca4fd..6dde3dab3 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -714,57 +714,7 @@ void DecodeVop1Dpp(uint32_t pc, std::span code, uint32_t word_in ReadLiteralOperands(code, word_index, inst); } -using Vop1ModifierDecodeFn = void (*)(uint32_t pc, std::span code, - uint32_t word_index, uint32_t opcode, uint32_t vdst, - Instruction& inst); - -struct Vop1ModifierDecoder { - uint32_t escape = 0; - Vop1ModifierDecodeFn decode = nullptr; -}; - -constexpr Vop1ModifierDecoder VOP1_MODIFIER_DECODERS[] = { - {249u, DecodeVop1Sdwa}, - {250u, DecodeVop1Dpp}, -}; - -bool TryDecodeVop1Modifier(uint32_t pc, std::span code, uint32_t word_index, - uint32_t src0, uint32_t opcode, uint32_t vdst, Instruction& inst) { - for (const auto& decoder: VOP1_MODIFIER_DECODERS) { - if (decoder.escape == src0) { - decoder.decode(pc, code, word_index, opcode, vdst, inst); - return true; - } - } - return false; -} - -bool IsVop2FloatSourceOpcode(Opcode opcode) { - switch (opcode) { - case Opcode::V_ADD_F32: - case Opcode::V_SUB_F32: - case Opcode::V_SUBREV_F32: - case Opcode::V_MUL_F32: - case Opcode::V_MIN_F32: - case Opcode::V_MAX_F32: - case Opcode::V_MAC_F32: - case Opcode::V_MADMK_F32: - case Opcode::V_MADAK_F32: - case Opcode::V_CVT_PKRTZ_F16_F32: - case Opcode::V_ADD_F16: - case Opcode::V_SUB_F16: - case Opcode::V_SUBREV_F16: - case Opcode::V_MUL_F16: - case Opcode::V_FMAC_F16: - case Opcode::V_FMAMK_F16: - case Opcode::V_FMAAK_F16: - case Opcode::V_MAX_F16: - case Opcode::V_MIN_F16: return true; - default: return false; - } -} - -bool IsVop2FloatResultOpcode(Opcode opcode) { +bool IsVop2FloatOpcode(Opcode opcode) { switch (opcode) { case Opcode::V_ADD_F32: case Opcode::V_SUB_F32: @@ -975,12 +925,12 @@ bool ValidateVop2Sdwa(Instruction& inst, uint32_t opcode, const Vop2SdwaFields& SetUnsupported(inst, Family::VOP2, opcode, "VOP2 SDWA selector is invalid"); return false; } - if ((fields.clamp != 0u || fields.omod != 0u) && !IsVop2FloatResultOpcode(inst.opcode)) { + if ((fields.clamp != 0u || fields.omod != 0u) && !IsVop2FloatOpcode(inst.opcode)) { SetUnsupported(inst, Family::VOP2, opcode, "VOP2 SDWA output modifiers are not supported"); return false; } if (IsFullWidthVop2Sdwa(fields)) { - if (!IsVop2FloatSourceOpcode(inst.opcode) && inst.opcode != Opcode::V_CNDMASK_B32 && + if (!IsVop2FloatOpcode(inst.opcode) && inst.opcode != Opcode::V_CNDMASK_B32 && (fields.src0_neg != 0u || fields.src0_abs != 0u || fields.src1_neg != 0u || fields.src1_abs != 0u)) { SetUnsupported(inst, Family::VOP2, opcode, @@ -1098,7 +1048,7 @@ void DecodeVop2Dpp(uint32_t pc, std::span code, uint32_t word_in inst.src1.negate_hi = inst.src1.negate; } - if (!IsVop2FloatSourceOpcode(inst.opcode) && !packed_fmac && + if (!IsVop2FloatOpcode(inst.opcode) && !packed_fmac && (inst.src0.negate || inst.src0.absolute || inst.src1.negate || inst.src1.absolute)) { SetUnsupported(inst, Family::VOP2, opcode, "VOP2 DPP integer source modifiers are not supported"); @@ -1107,32 +1057,6 @@ void DecodeVop2Dpp(uint32_t pc, std::span code, uint32_t word_in FinalizeVop2Instruction(code, word_index, inst); } -using Vop2ModifierDecodeFn = void (*)(uint32_t pc, std::span code, - uint32_t word_index, uint32_t opcode, uint32_t vdst, - uint32_t vsrc1, Instruction& inst); - -struct Vop2ModifierDecoder { - uint32_t escape = 0; - Vop2ModifierDecodeFn decode = nullptr; -}; - -constexpr Vop2ModifierDecoder VOP2_MODIFIER_DECODERS[] = { - {249u, DecodeVop2Sdwa}, - {250u, DecodeVop2Dpp}, -}; - -bool TryDecodeVop2Modifier(uint32_t pc, std::span code, uint32_t word_index, - uint32_t src0, uint32_t opcode, uint32_t vdst, uint32_t vsrc1, - Instruction& inst) { - for (const auto& decoder: VOP2_MODIFIER_DECODERS) { - if (decoder.escape == src0) { - decoder.decode(pc, code, word_index, opcode, vdst, vsrc1, inst); - return true; - } - } - return false; -} - struct VopcSdwaFields { uint32_t src0 = 0; uint32_t sdst = 0; @@ -1543,8 +1467,10 @@ void DecodeVop2(uint32_t pc, std::span code, uint32_t word_index SetUnsupported(inst, Family::VOP2, opcode, "VOP2 opcode is not implemented"); return; } - if (TryDecodeVop2Modifier(pc, code, word_index, src0, opcode, vdst, vsrc1, inst)) { - return; + switch (src0) { + case 249u: DecodeVop2Sdwa(pc, code, word_index, opcode, vdst, vsrc1, inst); return; + case 250u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return; + default: break; } DecodeVectorGpr(vdst, inst.dst); @@ -1575,8 +1501,10 @@ void DecodeVop1(uint32_t pc, std::span code, uint32_t word_index inst.src_count = 0; return; } - if (TryDecodeVop1Modifier(pc, code, word_index, src0, opcode, vdst, inst)) { - return; + switch (src0) { + case 249u: DecodeVop1Sdwa(pc, code, word_index, opcode, vdst, inst); return; + case 250u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return; + default: break; } const bool scalar_dst = UsesScalarDestination(inst.opcode); if (scalar_dst) { diff --git a/src/graphics/shader/recompiler/frontend/translate/Convert.cpp b/src/graphics/shader/recompiler/frontend/translate/Convert.cpp index 6c12aac33..1369a9418 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Convert.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Convert.cpp @@ -89,10 +89,10 @@ void Translator::V_CVT_16_F16(const Decoder::Instruction& inst, bool signed_valu if (signed_value) { const auto converted = ConvertF32ToI32Saturated(value, -32768.0f, 32768.0f, 32767.0f, 0xffff8000u, 0x7fffu); - WriteU16(DestinationOperand(inst), ir.BitwiseAnd(converted, IR::U32(IR::Value(0xffffu)))); + Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(converted, IR::U32(IR::Value(0xffffu)))); return; } - WriteU16(DestinationOperand(inst), + Write16Bits(DestinationOperand(inst), ConvertF32ToU32Saturated(value, 65536.0f, 65535.0f, 0xffffu)); } diff --git a/src/graphics/shader/recompiler/frontend/translate/Float.cpp b/src/graphics/shader/recompiler/frontend/translate/Float.cpp index 25e29c4fb..3b4643134 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Float.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Float.cpp @@ -59,7 +59,7 @@ bool Translator::Float16Unary(const Decoder::Instruction& inst, IR::ValueOpcode result = ApplyF32ResultModifiers(inst.dst, result); const auto bits = PackHalf2x16(result, IR::F32(IR::Value::F32(0.0f))); const auto invalid = IR::U32(IR::Value(inst.dst.clamp ? 0u : 0xfe00u)); - WriteU16(DestinationOperand(inst), ir.Select(negative, invalid, bits)); + Write16Bits(DestinationOperand(inst), ir.Select(negative, invalid, bits)); return true; } @@ -95,7 +95,7 @@ bool Translator::Float16Trig(const Decoder::Instruction& inst, IR::ValueOpcode o result = ApplyF32ResultModifiers(inst.dst, result); const auto bits = PackHalf2x16(result, IR::F32(IR::Value::F32(0.0f))); const auto invalid = IR::U32(IR::Value(inst.dst.clamp ? 0u : 0xfe00u)); - WriteU16(DestinationOperand(inst), ir.Select(infinite, invalid, bits)); + Write16Bits(DestinationOperand(inst), ir.Select(infinite, invalid, bits)); return true; } @@ -111,7 +111,7 @@ bool Translator::Float16Ternary(const Decoder::Instruction& inst, IR::ValueOpcod bool accumulator, bool mix) { std::array args; for (uint32_t index = 0; index < args.size(); index++) { - const auto operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index); + const auto& operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index); args[index] = mix ? IR::Value(ReadMixF32(operand)) : IR::Value(ReadF16AsF32(operand)); } WriteF16(DestinationOperand(inst), IR::F32(ir.Emit(opcode, {args[0], args[1], args[2]}))); @@ -128,7 +128,7 @@ bool Translator::FloatBinary(const Decoder::Instruction& inst, IR::ValueOpcode o bool reverse) { std::array args; for (uint32_t index = 0; index < args.size(); index++) { - const auto operand = SourceAt(inst, reverse ? 1u - index : index); + const auto& operand = SourceAt(inst, reverse ? 1u - index : index); args[index] = ReadOperand(operand, IR::ArgTypeOf(opcode, index)); } WriteOperand(DestinationOperand(inst), ir.Emit(opcode, {args[0], args[1]})); @@ -139,7 +139,7 @@ bool Translator::FloatTernary(const Decoder::Instruction& inst, IR::ValueOpcode bool accumulator, bool mix) { std::array args; for (uint32_t index = 0; index < args.size(); index++) { - const auto operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index); + const auto& operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index); const auto type = IR::ArgTypeOf(opcode, index); args[index] = type == IR::Type::F32 && mix ? IR::Value(ReadMixF32(operand)) : ReadOperand(operand, type); @@ -203,9 +203,6 @@ bool Translator::V_CUBEMA_F32(const Decoder::Instruction& inst) { } bool Translator::FloatCube(const Decoder::Instruction& inst, uint32_t result_kind) { - const auto select_f32 = [&](IR::U1 condition, IR::F32 true_value, IR::F32 false_value) { - return IR::F32(ir.Emit(IR::ValueOpcode::SelectF32, {condition, true_value, false_value})); - }; const auto x = ReadMixF32(inst.src0); const auto y = ReadMixF32(inst.src1); const auto z = ReadMixF32(inst.src2); @@ -223,18 +220,18 @@ bool Translator::FloatCube(const Decoder::Instruction& inst, uint32_t result_kin const auto y_neg = IR::U1(ir.Emit(IR::ValueOpcode::FPOrdLessThan32, {y, IR::Value::F32(0.0f)})); const auto z_neg = IR::U1(ir.Emit(IR::ValueOpcode::FPOrdLessThan32, {z, IR::Value::F32(0.0f)})); const auto select_face = [&](IR::F32 x_value, IR::F32 y_value, IR::F32 z_value) { - return select_f32(z_face, z_value, select_f32(y_face, y_value, x_value)); + return SelectF32(z_face, z_value, SelectF32(y_face, y_value, x_value)); }; IR::F32 result; switch (result_kind) { case 0u: result = select_face( - select_f32(x_neg, IR::F32(IR::Value::F32(1.0f)), IR::F32(IR::Value::F32(0.0f))), - select_f32(y_neg, IR::F32(IR::Value::F32(3.0f)), IR::F32(IR::Value::F32(2.0f))), - select_f32(z_neg, IR::F32(IR::Value::F32(5.0f)), IR::F32(IR::Value::F32(4.0f)))); + SelectF32(x_neg, IR::F32(IR::Value::F32(1.0f)), IR::F32(IR::Value::F32(0.0f))), + SelectF32(y_neg, IR::F32(IR::Value::F32(3.0f)), IR::F32(IR::Value::F32(2.0f))), + SelectF32(z_neg, IR::F32(IR::Value::F32(5.0f)), IR::F32(IR::Value::F32(4.0f)))); break; - case 1u: result = select_face(select_f32(x_neg, z, nz), x, select_f32(z_neg, nx, x)); break; - case 2u: result = select_face(ny, select_f32(y_neg, nz, z), ny); break; + case 1u: result = select_face(SelectF32(x_neg, z, nz), x, SelectF32(z_neg, nx, x)); break; + case 2u: result = select_face(ny, SelectF32(y_neg, nz, z), ny); break; case 3u: { const auto two = IR::F32(IR::Value::F32(2.0f)); result = select_face(IR::F32(ir.Emit(IR::ValueOpcode::FPMul32, {x, two})), diff --git a/src/graphics/shader/recompiler/frontend/translate/Integer.cpp b/src/graphics/shader/recompiler/frontend/translate/Integer.cpp index f03f7a169..183028e66 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Integer.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Integer.cpp @@ -9,7 +9,7 @@ bool Translator::Integer16Shift(const Decoder::Instruction& inst, IR::ValueOpcod const auto value = ReadU16AsU32(inst.src1, arithmetic); const auto count = ir.BitwiseAnd(ReadU16AsU32(inst.src0, false), IR::U32(IR::Value(15u))); const auto result = IR::U32(ir.Emit(opcode, {value, count})); - WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); + Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); return true; } @@ -18,7 +18,7 @@ bool Translator::Integer16Binary(const Decoder::Instruction& inst, IR::ValueOpco const auto lhs = ReadU16AsU32(inst.src0, sign); const auto rhs = ReadU16AsU32(inst.src1, sign); const auto result = IR::U32(ir.Emit(opcode, {lhs, rhs})); - WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); + Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); return true; } @@ -26,7 +26,7 @@ bool Translator::V_MED3_I16(const Decoder::Instruction& inst) { const auto result = IR::U32(ir.Emit( IR::ValueOpcode::SMedTri32, {ReadU16AsU32(inst.src0, true), ReadU16AsU32(inst.src1, true), ReadU16AsU32(inst.src2, true)})); - WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); + Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu)))); return true; } @@ -143,7 +143,7 @@ bool Translator::SimpleInteger(const Decoder::Instruction& inst, IR::ValueOpcode std::array args; for (uint32_t index = 0; index < inst.src_count; index++) { const auto arg_type = IR::ArgTypeOf(opcode, index); - const auto operand = SourceAt(inst, reverse && index < 2u ? 1u - index : index); + const auto& operand = SourceAt(inst, reverse && index < 2u ? 1u - index : index); args[index] = ReadOperand(operand, arg_type == IR::Type::Void ? type : arg_type); if (mask_shift_count && index == 1u) { args[index] = ir.BitwiseAnd(IR::U32(args[index]), IR::U32(IR::Value(31u))); @@ -563,10 +563,8 @@ bool Translator::PackB16(const Decoder::Instruction& inst, bool high0, bool high : ReadU32(inst.src0); const auto hi = high1 ? ir.ShiftRightLogical(ReadU32(inst.src1), IR::U32(IR::Value(16u))) : ReadU32(inst.src1); - const auto low_bits = ir.BitwiseAnd(lo, IR::U32(IR::Value(0xffffu))); - const auto high_bits = ir.ShiftLeftLogical(ir.BitwiseAnd(hi, IR::U32(IR::Value(0xffffu))), - IR::U32(IR::Value(16u))); - WriteOperand(DestinationOperand(inst), ir.BitwiseOr(low_bits, high_bits)); + const auto result = PackU16Lanes(lo, hi); + WriteOperand(DestinationOperand(inst), result); return true; } diff --git a/src/graphics/shader/recompiler/frontend/translate/Memory.cpp b/src/graphics/shader/recompiler/frontend/translate/Memory.cpp index 0e413a597..b03318308 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Memory.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Memory.cpp @@ -71,16 +71,22 @@ ResourceKind FlatSegmentResourceKind(uint32_t segment) { } } +bool IsScalarAddressLoad(Decoder::Opcode opcode) { + switch (opcode) { + case Decoder::Opcode::S_LOAD_DWORD: + case Decoder::Opcode::S_LOAD_DWORDX2: + case Decoder::Opcode::S_LOAD_DWORDX4: + case Decoder::Opcode::S_LOAD_DWORDX8: + case Decoder::Opcode::S_LOAD_DWORDX16: return true; + default: return false; + } +} + ResourceKind MemoryKind(const Decoder::Instruction& decoded) { switch (decoded.family) { case Decoder::Family::SMEM: - return decoded.opcode == Decoder::Opcode::S_LOAD_DWORD || - decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX2 || - decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX4 || - decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX8 || - decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX16 - ? ResourceKind::ScalarAddress - : ResourceKind::ScalarBuffer; + return IsScalarAddressLoad(decoded.opcode) ? ResourceKind::ScalarAddress + : ResourceKind::ScalarBuffer; case Decoder::Family::MUBUF: case Decoder::Family::MTBUF: return ResourceKind::Buffer; case Decoder::Family::FLAT: return FlatSegmentResourceKind(decoded.memory_segment); @@ -146,16 +152,6 @@ IR::MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded) { return memory; } -bool IsScalarAddressLoad(Decoder::Opcode opcode) { - switch (opcode) { - case Decoder::Opcode::S_LOAD_DWORD: - case Decoder::Opcode::S_LOAD_DWORDX2: - case Decoder::Opcode::S_LOAD_DWORDX4: - case Decoder::Opcode::S_LOAD_DWORDX8: - case Decoder::Opcode::S_LOAD_DWORDX16: return true; - default: return false; - } -} bool IsScalarBufferLoad(Decoder::Opcode opcode) { switch (opcode) { diff --git a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp index 07ca02763..d2208e51b 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp @@ -9,7 +9,7 @@ namespace Libs::Graphics::ShaderRecompiler::Frontend { -Decoder::Operand Translator::SourceAt(const Decoder::Instruction& inst, uint32_t index) { +const Decoder::Operand& Translator::SourceAt(const Decoder::Instruction& inst, uint32_t index) { switch (index) { case 0: return inst.src0; case 1: return inst.src1; @@ -25,7 +25,7 @@ Decoder::Operand Translator::DestinationOperand(const Decoder::Instruction& inst return destination; } for (uint32_t index = 0; index < std::min(inst.src_count, 3u); index++) { - const auto source = SourceAt(inst, index); + const auto& source = SourceAt(inst, index); if (!source.dpp) { continue; } @@ -440,10 +440,6 @@ void Translator::WriteF16(const Decoder::Operand& operand, IR::F32 value) { Write16Bits(operand, bits); } -void Translator::WriteU16(const Decoder::Operand& operand, IR::U32 value) { - Write16Bits(operand, value); -} - IR::U32 Translator::ReadU32(const Decoder::Operand& operand) { return IR::U32(ReadOperand(operand, IR::Type::U32)); } @@ -604,10 +600,6 @@ IR::U1 Translator::ThreadBit(const std::array& mask) { IR::U32(IR::Value(0u))); } -IR::U1 Translator::ReadCondition(const Decoder::Operand& operand) { - return IR::U1(ReadOperand(operand, IR::Type::U1)); -} - IR::U32 Translator::ConditionBit(const Decoder::Operand& operand) { return ir.Select(ReadMask(operand), IR::U32(IR::Value(1u)), IR::U32(IR::Value(0u))); } diff --git a/src/graphics/shader/recompiler/frontend/translate/Translator.h b/src/graphics/shader/recompiler/frontend/translate/Translator.h index 2dbdfbeca..f903e2196 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translator.h +++ b/src/graphics/shader/recompiler/frontend/translate/Translator.h @@ -18,7 +18,7 @@ public: void AddBranchCondition(const CFG::BasicBlock& source, IR::BlockInfo& info); private: - Decoder::Operand SourceAt(const Decoder::Instruction& inst, uint32_t index); + const Decoder::Operand& SourceAt(const Decoder::Instruction& inst, uint32_t index); Decoder::Operand DestinationOperand(const Decoder::Instruction& inst); Decoder::Operand OffsetOperand(const Decoder::Operand& operand, uint32_t offset); Decoder::Operand ScalarDestinationOperand(const Decoder::Operand& operand, uint32_t offset); @@ -35,7 +35,6 @@ private: IR::U32 PackHalf2x16(IR::F32 low, IR::F32 high); void Write16Bits(const Decoder::Operand& operand, IR::U32 value); void WriteF16(const Decoder::Operand& operand, IR::F32 value); - void WriteU16(const Decoder::Operand& operand, IR::U32 value); IR::U32 ReadU32(const Decoder::Operand& operand); std::array ReadU32Pair(const Decoder::Operand& operand); IR::U64 ReadU64(const Decoder::Operand& operand); @@ -48,7 +47,6 @@ private: IR::U32 ReadF16LaneBits(const Decoder::Operand& operand, bool high_lane); std::array ExtractU64(IR::U64 value); void WriteU32Pair(const Decoder::Operand& operand, const std::array& value); - IR::U1 ReadCondition(const Decoder::Operand& operand); IR::U32 ConditionBit(const Decoder::Operand& operand); IR::U1 ReadMask(const Decoder::Operand& operand); IR::U1 ReadMaskValid(const Decoder::Operand& operand); diff --git a/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp b/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp index b7aaac262..2947c0f14 100644 --- a/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp +++ b/src/graphics/shader/recompiler/ir/passes/SrtWalker.cpp @@ -280,8 +280,7 @@ private: return finish(false); } } - if (op == ValueOpcode::GetBufferResource || op == ValueOpcode::GetImageResource || - op == ValueOpcode::GetSamplerResource || op == ValueOpcode::GetAddressResource) { + if (IsDescriptorHandle(op)) { size_t expected = 4u; if (op == ValueOpcode::GetImageResource) { expected = 8u;