From e9425e101dd5667095f72fa73002e88e90969f38 Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 2 Sep 2026 01:55:48 +0400 Subject: [PATCH] shader: add missing RDNA2 ALU opcodes Add missing scalar and vector opcodes with compute tests. Original work by @Pouare514 in #176. Co-authored-by: Pouare514 --- .../frontend/decode/ScalarAluOps.cpp | 7 +- .../frontend/decode/ShaderDecoder.cpp | 3 + .../frontend/decode/ShaderDecoder.h | 5 + .../frontend/decode/VectorAluOps.cpp | 3 + .../recompiler/frontend/translate/Control.cpp | 13 +- .../recompiler/frontend/translate/Integer.cpp | 16 +++ .../recompiler/frontend/translate/Scalar.cpp | 6 +- .../frontend/translate/Translator.h | 4 +- .../recompiler/frontend/translate/Vector.cpp | 3 +- tests/ShaderRecompilerComputeTests.cpp | 122 ++++++++++++++++++ 10 files changed, 175 insertions(+), 7 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/decode/ScalarAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/ScalarAluOps.cpp index b18102ba5..d59582ffb 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ScalarAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/ScalarAluOps.cpp @@ -27,7 +27,8 @@ constexpr OpcodeMap SOP2_OPCODE_LIST[] = { {0x22u, Opcode::S_ASHR_I32}, {0x24u, Opcode::S_BFM_B32}, {0x25u, Opcode::S_BFM_B64}, {0x26u, Opcode::S_MUL_I32}, {0x27u, Opcode::S_BFE_U32}, {0x28u, Opcode::S_BFE_I32}, - {0x29u, Opcode::S_BFE_U64}, {0x2eu, Opcode::S_LSHL1_ADD_U32}, + {0x29u, Opcode::S_BFE_U64}, {0x2cu, Opcode::S_ABSDIFF_I32}, + {0x2eu, Opcode::S_LSHL1_ADD_U32}, {0x2fu, Opcode::S_LSHL2_ADD_U32}, {0x30u, Opcode::S_LSHL3_ADD_U32}, {0x31u, Opcode::S_LSHL4_ADD_U32}, {0x32u, Opcode::S_PACK_LL_B32_B16}, {0x33u, Opcode::S_PACK_LH_B32_B16}, {0x34u, Opcode::S_PACK_HH_B32_B16}, @@ -48,7 +49,9 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = { {0x15u, Opcode::S_FLBIT_I32_B32}, {0x16u, Opcode::S_FLBIT_I32_B64}, {0x1bu, Opcode::S_BITSET0_B32}, + {0x1cu, Opcode::S_BITSET0_B64}, {0x1du, Opcode::S_BITSET1_B32}, + {0x1eu, Opcode::S_BITSET1_B64}, {0x1fu, Opcode::S_GETPC_B64}, {0x20u, Opcode::S_SETPC_B64}, {0x24u, Opcode::S_AND_SAVEEXEC_B64}, @@ -93,6 +96,7 @@ constexpr OpcodeMap SOPP_OPCODE_LIST[] = { {0x0au, Opcode::S_BARRIER}, {0x0cu, Opcode::S_WAITCNT}, {0x0eu, Opcode::S_SLEEP}, + {0x0fu, Opcode::S_SETPRIO}, {0x10u, Opcode::S_SENDMSG}, {0x12u, Opcode::S_TRAP}, {0x16u, Opcode::S_TTRACEDATA}, @@ -276,6 +280,7 @@ void DecodeSopp(uint32_t pc, std::span code, uint32_t word_index : static_cast(static_cast(simm)); inst.src_count = (inst.opcode == Opcode::S_NOP || inst.opcode == Opcode::S_WAITCNT || inst.opcode == Opcode::S_WAITCNT_DEPCTR || inst.opcode == Opcode::S_SLEEP || + inst.opcode == Opcode::S_SETPRIO || inst.opcode == Opcode::S_SENDMSG || inst.opcode == Opcode::S_TRAP || inst.opcode == Opcode::S_TTRACEDATA || inst.opcode == Opcode::S_INST_PREFETCH) ? 1 diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp index 7345b3150..8ffdc374d 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.cpp @@ -479,6 +479,8 @@ std::string InstructionToString(const Instruction& inst) { case Opcode::S_FLBIT_I32_B32: case Opcode::S_FF1_I32_B32: case Opcode::S_FF1_I32_B64: + case Opcode::S_BITSET0_B64: + case Opcode::S_BITSET1_B64: case Opcode::S_NOT_B64: case Opcode::S_WQM_B64: case Opcode::S_QUADMASK_B64: @@ -505,6 +507,7 @@ std::string InstructionToString(const Instruction& inst) { case Opcode::S_WAITCNT: case Opcode::S_WAITCNT_DEPCTR: case Opcode::S_SLEEP: + case Opcode::S_SETPRIO: case Opcode::S_TRAP: case Opcode::S_SENDMSG: case Opcode::S_TTRACEDATA: diff --git a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h index 179f7cf26..aef47bfa2 100644 --- a/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h +++ b/src/graphics/shader/recompiler/frontend/decode/ShaderDecoder.h @@ -40,6 +40,7 @@ enum class Opcode { S_MOV_B64, S_MOVK_I32, S_ABS_I32, + S_ABSDIFF_I32, S_BREV_B32, S_BCNT1_I32_B32, S_BCNT1_I32_B64, @@ -69,6 +70,8 @@ enum class Opcode { S_BITCMP1_B32, S_BITSET0_B32, S_BITSET1_B32, + S_BITSET0_B64, + S_BITSET1_B64, S_MIN_I32, S_MAX_I32, S_MIN_U32, @@ -108,6 +111,7 @@ enum class Opcode { S_BFM_B64, S_CSELECT_B32, S_CSELECT_B64, + S_SETPRIO, S_PACK_LL_B32_B16, S_PACK_LH_B32_B16, S_PACK_HH_B32_B16, @@ -282,6 +286,7 @@ enum class Opcode { V_MAD_MIXHI_F16, V_ADD_NC_U32, V_ADDC_U32, + V_SUB_CO_CI_U32, V_SUBREV_CO_CI_U32, V_SUB_NC_U32, V_SUBREV_NC_U32, diff --git a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp index 8405c4bcc..71be55f33 100644 --- a/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp +++ b/src/graphics/shader/recompiler/frontend/decode/VectorAluOps.cpp @@ -61,6 +61,7 @@ constexpr Vop2OpcodeInfo VOP2_OPCODE_LIST[] = { {0x24u, Opcode::V_MBCNT_HI_U32_B32}, {0x25u, Opcode::V_ADD_NC_U32, Vop2SdwaProfile::IntegerPartialDestination}, {0x28u, Opcode::V_ADDC_U32, Vop2SdwaProfile::IntegerFullDestination}, + {0x29u, Opcode::V_SUB_CO_CI_U32}, {0x2au, Opcode::V_SUBREV_CO_CI_U32}, {0x26u, Opcode::V_SUB_NC_U32, Vop2SdwaProfile::IntegerPartialDestination}, {0x27u, Opcode::V_SUBREV_NC_U32, Vop2SdwaProfile::IntegerFullDestination}, @@ -1033,6 +1034,7 @@ void FinalizeVop2Instruction(std::span code, uint32_t word_index inst.src_count = 3; break; case Opcode::V_ADDC_U32: + case Opcode::V_SUB_CO_CI_U32: case Opcode::V_SUBREV_CO_CI_U32: inst.dst2.kind = OperandKind::VccLo; inst.src2.kind = OperandKind::VccLo; @@ -1643,6 +1645,7 @@ void DecodeVop3(uint32_t pc, std::span code, uint32_t word_index SetRawWords(inst, code, word_index, 2); const bool carry_in_out = (inst.opcode == Opcode::V_ADDC_U32 && opcode == 0x128u) || + (inst.opcode == Opcode::V_SUB_CO_CI_U32 && opcode == 0x129u) || (inst.opcode == Opcode::V_SUBREV_CO_CI_U32 && opcode == 0x12au); const bool vop3b_carry_out = IsVop3BCarryOutOpcode(inst.opcode); const bool vop3b_mad_u64 = IsVop3BMadU64Opcode(inst.opcode); diff --git a/src/graphics/shader/recompiler/frontend/translate/Control.cpp b/src/graphics/shader/recompiler/frontend/translate/Control.cpp index fdfd1eefb..8be7e2a93 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Control.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Control.cpp @@ -76,9 +76,9 @@ void Translator::SUB_U32(const Decoder::Instruction& inst, bool vector, bool rev } } -void Translator::SUBB_U32(const Decoder::Instruction& inst, bool vector) { - const auto lhs = ReadU32(vector ? inst.src1 : inst.src0); - const auto rhs = ReadU32(vector ? inst.src0 : inst.src1); +void Translator::SUBB_U32(const Decoder::Instruction& inst, bool vector, bool reverse) { + const auto lhs = ReadU32(reverse ? inst.src1 : inst.src0); + const auto rhs = ReadU32(reverse ? inst.src0 : inst.src1); const auto borrow_in = vector ? ConditionBit(inst.src2) : ConditionBit(ConditionOperand(Decoder::OperandKind::Scc)); const auto partial = ir.ISub(lhs, rhs); @@ -94,6 +94,13 @@ void Translator::SUBB_U32(const Decoder::Instruction& inst, bool vector) { } } +void Translator::S_ABSDIFF_I32(const Decoder::Instruction& inst) { + const auto difference = ir.ISub(ReadU32(inst.src0), ReadU32(inst.src1)); + const auto result = IR::U32(ir.Emit(IR::ValueOpcode::IAbs32, {difference})); + WriteOperand(DestinationOperand(inst), result); + ir.SetScc(ir.INotEqual(result, IR::U32(IR::Value(0u)))); +} + void Translator::S_ADD_SUB_I32(const Decoder::Instruction& inst, bool subtract) { const auto lhs = ReadU32(inst.src0); const auto rhs = ReadU32(inst.src1); diff --git a/src/graphics/shader/recompiler/frontend/translate/Integer.cpp b/src/graphics/shader/recompiler/frontend/translate/Integer.cpp index 39dc0b6b3..1f5714f94 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Integer.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Integer.cpp @@ -312,6 +312,22 @@ bool Translator::S_BITSET_B32(const Decoder::Instruction& inst, bool set) { return true; } +bool Translator::S_BITSET_B64(const Decoder::Instruction& inst, bool set) { + const auto offset = ir.BitwiseAnd(ReadU32(inst.src0), IR::U32(IR::Value(63u))); + const auto word_bit = ir.BitwiseAnd(offset, IR::U32(IR::Value(31u))); + const auto bit = ir.ShiftLeftLogical(IR::U32(IR::Value(1u)), word_bit); + const auto old = ReadU32Pair(inst.dst); + const auto low_value = set ? ir.BitwiseOr(old[0], bit) + : ir.BitwiseAnd(old[0], ir.BitwiseNot(bit)); + const auto high_value = set ? ir.BitwiseOr(old[1], bit) + : ir.BitwiseAnd(old[1], ir.BitwiseNot(bit)); + const auto high = IR::U1(ir.Emit(IR::ValueOpcode::UGreaterThanEqual32, + {offset, IR::Value(32u)})); + WriteU32Pair(inst.dst, + {ir.Select(high, old[0], low_value), ir.Select(high, high_value, old[1])}); + return true; +} + bool Translator::V_BCNT_U32_B32(const Decoder::Instruction& inst) { const auto count = IR::U32(ir.Emit(IR::ValueOpcode::BitCount32, {ReadU32(inst.src0)})); WriteOperand(DestinationOperand(inst), ir.IAdd(count, ReadU32(inst.src1))); diff --git a/src/graphics/shader/recompiler/frontend/translate/Scalar.cpp b/src/graphics/shader/recompiler/frontend/translate/Scalar.cpp index 06f32fb3f..8a9265479 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Scalar.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Scalar.cpp @@ -34,7 +34,8 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) { case O::S_ADD_U32: ADD_U32(inst, false, false); return true; case O::S_ADDC_U32: ADD_U32(inst, false, true); return true; case O::S_SUB_U32: SUB_U32(inst, false, false); return true; - case O::S_SUBB_U32: SUBB_U32(inst, false); return true; + case O::S_SUBB_U32: SUBB_U32(inst, false, false); return true; + case O::S_ABSDIFF_I32: S_ABSDIFF_I32(inst); return true; case O::S_ADD_I32: S_ADD_SUB_I32(inst, false); return true; case O::S_SUB_I32: S_ADD_SUB_I32(inst, true); return true; case O::S_LSHL1_ADD_U32: S_LSHL_ADD_U32(inst, 1u); return true; @@ -186,6 +187,8 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) { case O::S_BITSET0_B32: return S_BITSET_B32(inst, false); case O::S_BITSET1_B32: return S_BITSET_B32(inst, true); + case O::S_BITSET0_B64: return S_BITSET_B64(inst, false); + case O::S_BITSET1_B64: return S_BITSET_B64(inst, true); case O::S_BITREPLICATE_B64_B32: return S_BITREPLICATE_B64_B32(inst); case O::S_QUADMASK_B64: return S_QUADMASK_B64(inst); case O::S_BFM_B32: return BFM_B32(inst); @@ -201,6 +204,7 @@ bool Translator::EmitScalar(const Decoder::Instruction& inst) { case O::S_NOP: case O::S_SLEEP: + case O::S_SETPRIO: case O::S_TRAP: EmitControlNop(); return true; case O::S_WAITCNT_DEPCTR: EmitWaitcnt(); return true; case O::S_BARRIER: S_BARRIER(); return true; diff --git a/src/graphics/shader/recompiler/frontend/translate/Translator.h b/src/graphics/shader/recompiler/frontend/translate/Translator.h index 08a402060..71bab6ae7 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translator.h +++ b/src/graphics/shader/recompiler/frontend/translate/Translator.h @@ -192,6 +192,7 @@ private: bool V_SAD_U32(const Decoder::Instruction& inst); bool V_ADD3_U32(const Decoder::Instruction& inst); bool S_BITSET_B32(const Decoder::Instruction& inst, bool set); + bool S_BITSET_B64(const Decoder::Instruction& inst, bool set); bool V_BCNT_U32_B32(const Decoder::Instruction& inst); bool V_MBCNT_U32_B32(const Decoder::Instruction& inst, bool low); bool S_BITREPLICATE_B64_B32(const Decoder::Instruction& inst); @@ -218,7 +219,8 @@ private: bool negate_source, bool write_64); void ADD_U32(const Decoder::Instruction& inst, bool vector, bool use_carry_in); void SUB_U32(const Decoder::Instruction& inst, bool vector, bool reverse); - void SUBB_U32(const Decoder::Instruction& inst, bool vector); + void SUBB_U32(const Decoder::Instruction& inst, bool vector, bool reverse); + void S_ABSDIFF_I32(const Decoder::Instruction& inst); void S_ADD_SUB_I32(const Decoder::Instruction& inst, bool subtract); void S_LSHL_ADD_U32(const Decoder::Instruction& inst, uint32_t shift_amount); void ScalarMinMax32(const Decoder::Instruction& inst, IR::ValueOpcode value_opcode, diff --git a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp index 5b730c387..b2dc8f386 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Vector.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Vector.cpp @@ -10,7 +10,8 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) { case O::V_ADDC_U32: ADD_U32(inst, true, true); return true; case O::V_SUB_I32: SUB_U32(inst, true, false); return true; case O::V_SUBREV_I32: SUB_U32(inst, true, true); return true; - case O::V_SUBREV_CO_CI_U32: SUBB_U32(inst, true); return true; + case O::V_SUB_CO_CI_U32: SUBB_U32(inst, true, false); return true; + case O::V_SUBREV_CO_CI_U32: SUBB_U32(inst, true, true); return true; case O::V_MOV_B32: MOV_B32(inst, true); return true; case O::V_MOVRELS_B32: V_MOVRELS_B32(inst); return true; diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 20d6c6a19..b38ae6e80 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -12677,6 +12677,76 @@ TestCase ScalarAbsI32UpdatesScc() { O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; } +TestCase ScalarAbsdiffBitset64AndSetprio() { + using O = ShaderOpcode; + + std::vector code; + auto capture_scc = [&](u32 dst_sgpr) { + code.push_back( + EncodeSop2(0x0a, dst_sgpr, InlineU32(1), InlineU32(0))); + }; + + code.push_back(EncodeSMovB32(0, InlineU32(2))); + code.push_back(EncodeSMovB32(1, InlineU32(5))); + code.push_back(EncodeSop2(0x2c, 10, 0, 1)); + capture_scc(20); + AppendSMovLiteral(&code, 0, 0xffffffffu); + code.push_back(EncodeSMovB32(1, InlineU32(0))); + code.push_back(EncodeSop2(0x2c, 11, 0, 1)); + capture_scc(21); + AppendSMovLiteral(&code, 0, 0x80000000u); + code.push_back(EncodeSop2(0x2c, 12, 0, 1)); + capture_scc(22); + code.push_back(EncodeSMovB32(1, InlineU32(1))); + code.push_back(EncodeSop2(0x2c, 13, 0, 1)); + capture_scc(23); + code.push_back(EncodeSop2(0x2c, 14, 0, 0)); + capture_scc(24); + + AppendSMovLiteral(&code, 2, 65u); + AppendSMovLiteral(&code, 3, 101u); + code.push_back(EncodeSMovB32(4, InlineU32(0))); + code.push_back(EncodeSMovB32(5, InlineU32(0))); + code.push_back(EncodeSop1(0x1e, 4, 2)); + AppendStoreSgprPair(&code, 4, 10); + code.push_back(EncodeSop1(0x1e, 4, 3)); + AppendStoreSgprPair(&code, 4, 12); + code.push_back(EncodeSop1(0x1c, 4, 2)); + AppendStoreSgprPair(&code, 4, 14); + code.push_back(EncodeSop1(0x1c, 4, 3)); + AppendStoreSgprPair(&code, 4, 16); + code.push_back(EncodeSopp(0x0f, 3)); + + AppendStoreSgpr(&code, 10, 0); + AppendStoreSgpr(&code, 11, 1); + AppendStoreSgpr(&code, 12, 2); + AppendStoreSgpr(&code, 13, 3); + AppendStoreSgpr(&code, 14, 4); + AppendStoreSgpr(&code, 20, 5); + AppendStoreSgpr(&code, 21, 6); + AppendStoreSgpr(&code, 22, 7); + AppendStoreSgpr(&code, 23, 8); + AppendStoreSgpr(&code, 24, 9); + AppendEnd(&code); + + TestCase test; + test.name = "ScalarAbsdiffBitset64AndSetprio"; + test.code = std::move(code); + test.expected = {3u, 1u, 0x80000000u, 0x7fffffffu, 0u, + 1u, 1u, 1u, 1u, 0u, + 2u, 0u, 2u, 32u, 0u, + 32u, 0u, 0u}; + test.opcodes = {O::S_MOV_B32, O::S_ABSDIFF_I32, O::S_CSELECT_B32, + O::S_BITSET1_B64, O::S_BITSET0_B64, O::S_SETPRIO, + O::V_MOV_B32, + O::BUFFER_STORE_DWORD, O::S_ENDPGM}; + test.decoded_counts = {{"S_ABSDIFF_I32", 5}, + {"S_BITSET1_B64", 2}, + {"S_BITSET0_B64", 2}, + {"S_SETPRIO 0x00000003", 1}}; + return test; +} + TestCase ScalarShiftLeftAddSccCarryEdges() { using O = ShaderOpcode; @@ -14177,6 +14247,55 @@ TestCase VectorAddcWritesPerLaneCarryOut() { return test; } +TestCase VectorSubCoCiU32CompactAndVop3() { + using O = ShaderOpcode; + + std::vector code; + code.push_back(EncodeVop2(0x1a, 4, InlineU32(2), 0)); + AppendBufferLoadDword(&code, 1, 4); + code.push_back(EncodeVop2(0x25, 5, InlineU32(16), 4)); + AppendBufferLoadDword(&code, 2, 5); + code.push_back(EncodeVop2(0x1b, 3, InlineU32(1), 0)); + code.push_back(EncodeVopc(0xc5, InlineU32(0), 3)); + code.push_back(EncodeSop1(0x04, 20, 106)); + code.push_back(EncodeVop2(0x29, 10, Vgpr(1), 2)); + AppendVMovU32(&code, 6, 1); + code.push_back(EncodeVop2(0x01, 11, InlineU32(0), 6)); + AppendStoreVgprAtLaneDwordOffset(&code, 10, 0, 0); + AppendStoreVgprAtLaneDwordOffset(&code, 11, 0, 4); + + code.push_back(EncodeVopc(0xc2, InlineU32(0), 6)); + AppendVop3B(&code, 0x129u, 12, 22, Vgpr(1), Vgpr(2), 20); + AppendVop3(&code, 0x101u, 13, InlineU32(0), Vgpr(6), 22); + code.push_back(EncodeVop2(0x01, 14, InlineU32(0), 6)); + AppendStoreVgprAtLaneDwordOffset(&code, 12, 0, 8); + AppendStoreVgprAtLaneDwordOffset(&code, 13, 0, 12); + AppendStoreVgprAtLaneDwordOffset(&code, 14, 0, 16); + AppendEnd(&code); + + TestCase test; + test.name = "VectorSubCoCiU32CompactAndVop3"; + test.code = std::move(code); + test.initial = {5u, 5u, 3u, 3u, 3u, 3u, 5u, 3u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u}; + test.expected = {2u, 1u, 0xfffffffeu, 0xffffffffu, 0u, 0u, 1u, + 1u, 2u, 1u, 0xfffffffeu, 0xffffffffu, 0u, 0u, + 1u, 1u, 0u, 0u, 0u, 0u}; + test.opcodes = {O::V_MOV_B32, O::V_LSHLREV_B32, O::V_ADD_NC_U32, + O::V_AND_B32, O::V_CMP_NE_U32, O::V_CMP_EQ_U32, + O::V_SUB_CO_CI_U32, O::V_CNDMASK_B32, O::S_MOV_B64, + O::BUFFER_LOAD_DWORD, O::BUFFER_STORE_DWORD, O::S_ENDPGM}; + test.decoded_counts = {{"V_SUB_CO_CI_U32", 2}}; + test.required_spirv = {"OpISub", "OpUGreaterThan", "OpLogicalOr"}; + test.compute_info.threads_num[0] = 4; + test.compute_info.threads_num[1] = 1; + test.compute_info.threads_num[2] = 1; + test.compute_info.thread_ids_num = 1; + test.compute_info.wave_size = 32; + test.has_compute_info = true; + return test; +} + TestCase VectorSubrevCoCiU32ExactRawOnGpu() { using O = ShaderOpcode; @@ -21168,6 +21287,7 @@ std::vector MakeCases() { AddCase(ScalarArithmeticSccCarryBorrowOverflow); AddCase(ScalarMinMaxSccComparisonEdges); AddCase(ScalarAbsI32UpdatesScc); + AddCase(ScalarAbsdiffBitset64AndSetprio); AddCase(ScalarShiftLeftAddSccCarryEdges); AddCase(ScalarCompareOps); AddCase(ScalarShiftAddAndMaskOps); @@ -21213,6 +21333,7 @@ std::vector MakeCases() { AddCase(VectorMbcntUsesThreadMask); AddCase(VectorAddcWritesPerLaneCarryOut); AddCase(VectorAddcUsesPerLaneCarryIn); + AddCase(VectorSubCoCiU32CompactAndVop3); AddCase(VectorSubrevCoCiU32ExactRawOnGpu); AddCase(VectorVop3BSubrevCoCiUsesEncodedMasks); AddCase(VectorVop3BCarryOutWritesSgprMask); @@ -23461,6 +23582,7 @@ void CheckStorageTextureDepthTileUploadLayout() { "1x1 R8_UINT depth tile lost its 64 KiB source footprint"); std::printf("[host] %-32s ok\n", "StorageTextureDepthTileUpload"); } + void CheckImageSamplerSpecialization() { ShaderSamplerResource filtered_sampler{}; filtered_sampler.fields[2] =