mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-24 11:48:39 +08:00
[AGC] Support the clamp modifier on packed f16 VOP3P ops (#460)
The VOP3P emitter rejected any packed op with the clamp bit set. Clamp saturates each f16 output half to [0, 1] (and flushes NaN to 0, matching RDNA), so games that emit clamped packed arithmetic fell back to a loud emit failure. Apply the saturation to the f32 result of each lane, before it is narrowed back to f16. Because 0.0 and 1.0 are exact in both f32 and f16 and the clamp is monotonic, clamping in f32 and then rounding to f16 yields the same value as clamping the f16 result directly; for the fused multiply-add the pre-narrowing value is the round-to-odd f32, which preserves that equivalence through the final round-to-nearest-even. The saturation uses ordered compares so a NaN result collapses to 0 without a separate IsNan test. Verification: - The local exact-reference harness now also clamps: add, mul, and fma each compared against an f16-domain clamp reference (NaN -> 0, else [0, 1]) over directed boundary inputs and 24M random cases. 0 mismatches, alongside the existing 34M unclamped fma cases. - ShaderDump pk-f16 gains a clamped add and a clamped fma; all decode and emit. - The exec program computes the pinned fma with clamp (both lanes exceed 1.0, so each saturates to 0x3C00) and stores it at offset 28; GpuConformance checks it on device. All values match on an AMD Radeon RX 7700 XT.
This commit is contained in:
committed by
GitHub
parent
33be88bdf9
commit
472fc96a37
@@ -57,6 +57,8 @@ const ulong ProgramAddress = 0x100000;
|
||||
0xCC114006, 0x18020300, // v_pk_min_f16 v6, v0, v1
|
||||
0xCC124007, 0x18020300, // v_pk_max_f16 v7, v0, v1
|
||||
0xCC0E4408, 0x9C0A0300, // v_pk_fma_f16 v8, v0, v1, neg_lo:[0,0,1] neg_hi:[0,0,1] v2
|
||||
0xCC0FC009, 0x18020000, // v_pk_add_f16 v9, v0, v0 clamp (2.5+2.5=5 -> saturates to 1.0)
|
||||
0xCC0EC40A, 0x1C0A0300, // v_pk_fma_f16 v10, v0, v1, v2 clamp
|
||||
0xBF810000, // s_endpgm
|
||||
]),
|
||||
("mrt", true, [
|
||||
@@ -158,8 +160,10 @@ const ulong ProgramAddress = 0x100000;
|
||||
0x7E1202FF, 0x04EA04EA, // v_mov_b32 v9, 0x04EA04EA (~7.496e-5 packed)
|
||||
0xCC0E400A, 0x1C261107, // v_pk_fma_f16 v10, v7, v8, v9
|
||||
0xCC0E440B, 0x9C261107, // v_pk_fma_f16 v11, v7, v8, neg_lo:[0,0,1] neg_hi:[0,0,1] v9
|
||||
0xCC0EC00C, 0x1C261107, // v_pk_fma_f16 v12, v7, v8, v9 clamp (>=1 -> saturates to 1.0)
|
||||
0xE0700014, 0x80020A00, // buffer_store_dword v10, off, s[8:11], 0 offset:20
|
||||
0xE0700018, 0x80020B00, // buffer_store_dword v11, off, s[8:11], 0 offset:24
|
||||
0xE070001C, 0x80020C00, // buffer_store_dword v12, off, s[8:11], 0 offset:28
|
||||
0xBF810000, // s_endpgm
|
||||
]),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user