mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: fix crash from packed ancillary used as DPP old operand (#1769)
shader: emit plain EXEC selects for DPP writes that reach every active lane (Street Fighter 6)
This commit is contained in:
@@ -132,7 +132,7 @@ uint32_t EmitDppWriteCondition(ValueEmitContext& ctx, const IR::DppMoveFlags& fl
|
|||||||
enable(flags.bank_mask, 2u);
|
enable(flags.bank_mask, 2u);
|
||||||
enable(flags.row_mask, 4u);
|
enable(flags.row_mask, 4u);
|
||||||
// Only row shifts (0x101-0x10f, 0x111-0x11f) can vacate a lane; other controls always read one.
|
// Only row shifts (0x101-0x10f, 0x111-0x11f) can vacate a lane; other controls always read one.
|
||||||
const bool row_shift = !flags.dpp8 && flags.control > 0x100u && flags.control < 0x120u &&
|
const bool row_shift = flags.control > 0x100u && flags.control < 0x120u &&
|
||||||
flags.control != 0x110u;
|
flags.control != 0x110u;
|
||||||
if (!flags.bound_control && row_shift) {
|
if (!flags.bound_control && row_shift) {
|
||||||
writable = Binary(state, spv::OpLogicalAnd, TypeBool(state), writable,
|
writable = Binary(state, spv::OpLogicalAnd, TypeBool(state), writable,
|
||||||
|
|||||||
@@ -319,7 +319,10 @@ void Translator::WriteRawU32(const Decoder::Operand& operand, IR::U32 value) {
|
|||||||
case Decoder::OperandKind::Vgpr: {
|
case Decoder::OperandKind::Vgpr: {
|
||||||
const auto reg = static_cast<IR::VectorReg>(operand.reg);
|
const auto reg = static_cast<IR::VectorReg>(operand.reg);
|
||||||
const auto old = ir.GetVectorReg(reg);
|
const auto old = ir.GetVectorReg(reg);
|
||||||
if (operand.dpp) {
|
// DPP skips EXEC lanes only through row/bank masks, or for invalid sources without
|
||||||
|
// BOUND_CTRL (dpp8 reads zero); otherwise it is a plain masked write.
|
||||||
|
if (operand.dpp && (operand.dpp_row_mask != 0xfu || operand.dpp_bank_mask != 0xfu ||
|
||||||
|
(!operand.dpp_bound_ctrl && !operand.dpp8))) {
|
||||||
value = IR::U32(ir.Emit(IR::ValueOpcode::DppUpdateU32, {value, old, ir.GetExec()},
|
value = IR::U32(ir.Emit(IR::ValueOpcode::DppUpdateU32, {value, old, ir.GetExec()},
|
||||||
DppFlags(operand)));
|
DppFlags(operand)));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7045,6 +7045,17 @@ void TestPixelAncillaryLayerInput() {
|
|||||||
CheckSpirvBinaryValidates(wqm_result.spirv);
|
CheckSpirvBinaryValidates(wqm_result.spirv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t dpp[] = {
|
||||||
|
EncodeVop3Word0(0x148, 6), EncodeVop3Word1(5 + 256, 128 + 16, 128 + 11),
|
||||||
|
EncodeVop1(0x01, 5, 250), EncodeVop1Dpp(6) | (1u << 19u), // Bound-zero DPP overwrite.
|
||||||
|
EncodeExp0(0x00, 0x1), EncodeExp1(5, 0, 0, 0), EncodeSopp(0x01),
|
||||||
|
};
|
||||||
|
auto dpp_result = RecompileForTest(dpp, options);
|
||||||
|
Check(ProgramHasInput(dpp_result.program, StageInputKind::Layer) &&
|
||||||
|
!ProgramHasInput(dpp_result.program, StageInputKind::PackedAncillary),
|
||||||
|
"DPP write retained the old ancillary register value");
|
||||||
|
CheckSpirvBinaryValidates(dpp_result.spirv);
|
||||||
|
|
||||||
const uint32_t loop[] = {
|
const uint32_t loop[] = {
|
||||||
EncodeSop1(0x04, 8, 126), // Save the original EXEC mask.
|
EncodeSop1(0x04, 8, 126), // Save the original EXEC mask.
|
||||||
EncodeSop1(0x0a, 126, 8), // Widen for helper lanes.
|
EncodeSop1(0x0a, 126, 8), // Widen for helper lanes.
|
||||||
@@ -7098,6 +7109,9 @@ void TestPixelAncillaryLayerInput() {
|
|||||||
shader[5] = EncodeExp1(6, 7, 5, 0);
|
shader[5] = EncodeExp1(6, 7, 5, 0);
|
||||||
ExpectFatal([&] { (void)RecompileForTest(shader, options); },
|
ExpectFatal([&] { (void)RecompileForTest(shader, options); },
|
||||||
"direct raw ancillary export was silently replaced after field lowering");
|
"direct raw ancillary export was silently replaced after field lowering");
|
||||||
|
dpp[3] = EncodeVop1Dpp(6); // Without BOUND_CTRL, lanes with inactive sources keep the value.
|
||||||
|
ExpectFatal([&] { (void)RecompileForTest(dpp, options); },
|
||||||
|
"DPP write without BOUND_CTRL silently replaced the ancillary value");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user