mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
shader: take the high half per lane in V_PK_FMAC_F16 (#404)
Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
1 parent
39ee9972b8
commit
18af08460f
3 files changed
+74
-2
No files matched your search
@@ -1059,6 +1059,13 @@ bool FinalizeVop2Instruction(uint32_t pc, std::span<const uint32_t> code, uint32
|
||||
inst.src2.kind = OperandKind::VccLo;
|
||||
inst.src_count = 3;
|
||||
break;
|
||||
case Opcode::V_PK_FMAC_F16:
|
||||
// VOP2 has no OP_SEL fields, so the high operation implicitly reads high halves.
|
||||
inst.src0.op_sel_hi = true;
|
||||
inst.src1.op_sel_hi = true;
|
||||
inst.dst.op_sel_hi = true;
|
||||
inst.src_count = 2;
|
||||
break;
|
||||
default: inst.src_count = 2; break;
|
||||
}
|
||||
ReadLiteralOperands(code, word_index, inst);
|
||||
@@ -1107,12 +1114,17 @@ bool DecodeVop2Dpp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_in
|
||||
if (!DecodeScalarSource(src0 + 256u, pc, inst.src0, error)) {
|
||||
return false;
|
||||
}
|
||||
ApplyDefaultVop2F16Destination(inst);
|
||||
ApplyDppModifier(inst.src0, modifier);
|
||||
inst.src1.negate = ((modifier >> 22u) & 0x1u) != 0u;
|
||||
inst.src1.absolute = ((modifier >> 23u) & 0x1u) != 0u;
|
||||
ApplyDefaultVop2F16Destination(inst);
|
||||
const bool packed_fmac = inst.opcode == Opcode::V_PK_FMAC_F16;
|
||||
if (packed_fmac) {
|
||||
inst.src0.negate_hi = inst.src0.negate;
|
||||
inst.src1.negate_hi = inst.src1.negate;
|
||||
}
|
||||
|
||||
if (!IsVop2FloatSourceOpcode(inst.opcode) &&
|
||||
if (!IsVop2FloatSourceOpcode(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");
|
||||
|
||||
@@ -14250,6 +14250,53 @@ TestCase VectorLaneAndPackedOps() {
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase Vop2PkFmacF16AccumulatesPackedHalvesIndependently() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovLiteral(&code, 0, 0x50004c00u); // low=16.0h, high=32.0h
|
||||
AppendVMovLiteral(&code, 1, 0x42003c00u); // low=1.0h, high=3.0h
|
||||
AppendVMovLiteral(&code, 2, 0x48004400u); // low=4.0h, high=8.0h
|
||||
|
||||
code.push_back(EncodeVop2(0x3c, 0, Vgpr(1), 2));
|
||||
AppendStoreVgpr(&code, 0, 0);
|
||||
code.push_back(EncodeVop2(0x3c, 0, Vgpr(1), 2));
|
||||
AppendStoreVgpr(&code, 0, 1);
|
||||
|
||||
AppendVMovLiteral(&code, 3, 0x50004c00u);
|
||||
code.push_back(EncodeVop2(0x3c, 3, 242, 2)); // Inline 1.0h is {1.0h, 0.0h}.
|
||||
AppendStoreVgpr(&code, 3, 2);
|
||||
AppendEnd(&code);
|
||||
|
||||
return {"Vop2PkFmacF16AccumulatesPackedHalvesIndependently",
|
||||
code,
|
||||
{},
|
||||
{0x53004d00u, 0x55004e00u, 0x50004d00u},
|
||||
{O::V_MOV_B32, O::V_PK_FMAC_F16, O::BUFFER_STORE_DWORD,
|
||||
O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase Vop2PkFmacF16DppNegatesBothPackedHalves() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovLiteral(&code, 0, 0x50004c00u); // low=16.0h, high=32.0h
|
||||
AppendVMovLiteral(&code, 1, 0x42003c00u); // low=1.0h, high=3.0h
|
||||
AppendVMovLiteral(&code, 2, 0x48004400u); // low=4.0h, high=8.0h
|
||||
|
||||
code.push_back(EncodeVop2(0x3c, 0, 250, 2));
|
||||
code.push_back(EncodeVop2Dpp(1, 0, 0xf, 0xf, 1));
|
||||
AppendStoreVgpr(&code, 0, 0);
|
||||
AppendEnd(&code);
|
||||
|
||||
return {"Vop2PkFmacF16DppNegatesBothPackedHalves",
|
||||
code,
|
||||
{},
|
||||
{0x48004a00u},
|
||||
{O::V_MOV_B32, O::V_PK_FMAC_F16, O::BUFFER_STORE_DWORD,
|
||||
O::S_ENDPGM}};
|
||||
}
|
||||
|
||||
TestCase Vop3pOpselHiUsesArchitecturalSourceBits() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
@@ -20800,6 +20847,8 @@ std::vector<TestCase> MakeCases() {
|
||||
AddCase(VectorVop3BSubCoU32UsesRdna2Opcode310);
|
||||
AddCase(VectorMadU64U32UnsignedCarryOut);
|
||||
AddCase(VectorLaneAndPackedOps);
|
||||
AddCase(Vop2PkFmacF16AccumulatesPackedHalvesIndependently);
|
||||
AddCase(Vop2PkFmacF16DppNegatesBothPackedHalves);
|
||||
AddCase(Vop3pOpselHiUsesArchitecturalSourceBits);
|
||||
AddCase(CvtPkU8F32PacksSelectedByte);
|
||||
AddCase(CvtPkrtzF16F32SubnormalRoundsTowardZero);
|
||||
|
||||
@@ -4203,6 +4203,17 @@ void TestNewShaderDecoderArchitecture() {
|
||||
packed_inst.src2.op_sel_hi == (source == 2u),
|
||||
"VOP3P OPSEL_HI source bit mapping is incorrect");
|
||||
}
|
||||
|
||||
const uint32_t packed_fmac_dpp[] = {0x780402fau, 0xff500000u};
|
||||
Instruction packed_fmac;
|
||||
Check(DecodeInstruction(packed_fmac_dpp, 0u, packed_fmac, &error),
|
||||
error.c_str());
|
||||
Check(packed_fmac.opcode == Opcode::V_PK_FMAC_F16 &&
|
||||
packed_fmac.src0.dpp && packed_fmac.src0.op_sel_hi &&
|
||||
packed_fmac.src1.op_sel_hi && packed_fmac.dst.op_sel_hi &&
|
||||
packed_fmac.src0.negate && packed_fmac.src0.negate_hi &&
|
||||
packed_fmac.src1.negate && packed_fmac.src1.negate_hi,
|
||||
"VOP2 DPP V_PK_FMAC_F16 lost its implicit packed modifiers");
|
||||
}
|
||||
|
||||
void TestNewShaderRecompilerRejectsDppOn64BitCompares() {
|
||||
|
||||
Reference in new issue
Block a user