Commit Graph

1 Commits

Author SHA1 Message Date
Dean Galvin b37365d2dd fix(recompiler): zero the high half of 16-bit SDWA results written as a whole dword
A 16-bit VOP1/VOP2 result in SDWA form with dst_sel:DWORD writes the whole register, so with
dst_unused:UNUSED_PAD the high half is zero. write16Bits treated dst_sel:DWORD as the plain
encoding and kept the old high half, which is right only for the non-SDWA form (GFX10 16-bit
instructions preserve the high bits). The decoder already marks SDWA destinations with
explicitSdwaDst; write16Bits now sends those through writeRawU32 like the other selectors.

GFX10 compilers rely on this to zero-extend f16 results before packing two of them with an
integer add, e.g. v_cvt_f16_f32_sdwa ... dst_sel:DWORD dst_unused:UNUSED_PAD followed by
v_lshl_add_u32 v2, hi, 16, lo. PPSA21564's FidelityFX depth-of-field combine pass packs its
near/far colours into LDS this way 60 times: whatever the low register held before leaked
into the high half, so green (and alpha) of the packed pairs came back huge or infinite while
red and blue stayed right. The bloom then spread the bad green over the intro cinematic.

agc_driver_sdwa_destination_tests runs the padded, preserved and plain encodings and the
packing idiom on the GPU against a model of the guest instructions.
2026-10-02 01:07:59 +13:00