Commit Graph

120 Commits

Author SHA1 Message Date
Dean d4c1bca1e1
Merge pull request #497 from adriadam10/feat/mimg-dlc
feat(shader): accept the dlc cache bit on MIMG
2026-10-05 12:09:53 +13:00
Dean 037b905684
Merge pull request #499 from MichonGoddijn231849/fix/vmov-sdwa-byte-destinations
fix(shader): v_mov_b32 SDWA writes byte destinations
2026-10-05 12:09:34 +13:00
Dean 3fe90689ca
Merge pull request #562 from adriadam10/feat/image-atomics-float
feat(shader): implement image_atomic_fmin, fmax and fcmpswap
2026-10-05 11:44:47 +13:00
Dean a6c363a51b
Merge pull request #383 from DotDebian/test/sopk-waitcnt-counters
test(shader): cover the SOPK s_waitcnt counters and count them as decoded
2026-10-05 11:42:41 +13:00
Dean b44b308c53
Merge pull request #333 from adriadam10/feat/sopk-misc
feat(shader): implement s_cmovk_i32, s_version and s_setreg_imm32_b32
2026-10-05 11:41:47 +13:00
Dean 1db03d7e93
Merge pull request #264 from adriadam10/feat/div-scale-fmas-fixup
feat(shader): implement v_div_scale/fmas/fixup_f32 and s_denorm_mode (f32 division macro)
2026-10-05 11:41:37 +13:00
Dean b2558631b7
Merge pull request #332 from adriadam10/feat/buffer-atomics-float
feat(shader): implement the float and 64-bit inc/dec buffer atomics
2026-10-05 11:40:03 +13:00
Dean f83fcdbb0e
Merge pull request #321 from adriadam10/feat/buffer-atomics
feat(shader): implement buffer_atomic_inc/dec and the 64-bit integer buffer atomics
2026-10-05 11:39:22 +13:00
Dean 8e5e42539a
Merge pull request #561 from adriadam10/feat/image-store-pck
feat(shader): implement image_store_pck and image_store_mip_pck
2026-10-05 10:24:50 +13:00
Dean cbb358726c
Merge pull request #557 from adriadam10/feat/image-load-pck
feat(shader): implement image_load_pck and image_load_mip_pck with signed variants
2026-10-05 10:24:35 +13:00
Dean 0ea51eba27
Merge pull request #547 from adriadam10/test/flat-global-loads
test(shader): execute flat and global loads against hardware results
2026-10-05 10:24:04 +13:00
Dean c11fbe5484
Merge pull request #544 from adriadam10/test/buffer-ops
test(shader): execute the untested buffer byte/short/dwordx2/x3 loads and stores and the 32-bit integer buffer atomics
2026-10-05 10:23:49 +13:00
Dean 3403c80595
Merge pull request #543 from adriadam10/test/lds-ops
test(shader): execute the untested LDS reads, writes and integer atomics against values measured on RDNA
2026-10-05 10:23:33 +13:00
Dean 0f15a6c515
Merge pull request #539 from adriadam10/test/vopc-compare-table
test(shader): execute every non-f64 VOPC compare against values measured on RDNA
2026-10-05 10:21:52 +13:00
Dean 55e915abdb
Merge pull request #527 from DotDebian/test/vop3-carry-out-add-sub
test(shader): cover the VOP3 carry-out add and subtracts and count v_sub_co_u32 as decoded
2026-10-05 10:15:36 +13:00
Dean 61cb722a25
Merge pull request #502 from adriadam10/fix/vop3p-pk-mad-clamp
fix(shader): VOP3P integer clamp on v_pk_mad/add/sub_{i16,u16}
2026-10-05 10:10:54 +13:00
Dean 6842123d01
Merge pull request #530 from DotDebian/feat/global-load-dword-addtid
feat(shader): implement global_load_dword_addtid
2026-10-05 10:10:42 +13:00
Adrià Franch d1f77107bc feat(shader): implement image_atomic_fmin, fmax and fcmpswap
The three MIMG float atomics threw as unknown opcodes. They now run as a
compare-and-swap loop on the 32-bit texel with the bit-level rules the
float buffer atomics already use (NaN, signed zero and sNaN quieting as
measured on RDNA2), so no float atomic feature is needed from the driver.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 23:01:27 +02:00
Adrià Franch e9cdd9b0f3 feat(shader): implement the float and 64-bit inc/dec buffer atomics
buffer_atomic_fcmpswap, fcmpswap_x2, fmin_x2, fmax_x2, inc_x2 and
dec_x2 are compare-and-swap loops on the dword or qword. fcmpswap
compares as floats (-0 equals +0, NaN equals nothing) and fmin/fmax are
IEEE minNum/maxNum with -0 < +0, a quieted result for a signalling NaN
and the other operand for a quiet one, all with integer ops so the
driver's float controls do not matter. The existing 32-bit fmin/fmax
kept the old value whenever a NaN or two zeros were involved; it now
uses the same rule.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:56:09 +02:00
Adrià Franch e8e75a8bc5 feat(shader): implement buffer_atomic_inc/dec and the 64-bit integer buffer atomics
buffer_atomic_inc, buffer_atomic_dec, buffer_atomic_cmpswap_x2 and
buffer_atomic_{add,sub,smin,umin,smax,umax,and,xor}_x2 threw in the decoder.
The 64-bit ones use native 64-bit SPIR-V atomics like the existing
swap_x2/or_x2; inc and dec wrap at the data operand through the existing
compare-exchange helpers.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:56:09 +02:00
Adrià Franch 6dd5a61541 feat(shader): accept the dlc cache bit on MIMG
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:54:05 +02:00
Adrià Franch ef84d7bfa7 feat(shader): implement image_store_pck and image_store_mip_pck
Write the raw texel bits: dmask bit i selects texel dword i, taken from the
next data register, and every other dword of the texel is written as 0; the
descriptor swizzle is ignored (measured on RDNA2 hardware). Only formats whose
bits go through the storage view unchanged are accepted (unsigned integer
components, raw 32-bit signed integer and 32-bit float); normalized, 16-bit
float, narrow signed and 96-bit formats throw.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:46:58 +02:00
Adrià Franch bb24017c45 test(shader): execute the untested LDS reads, writes and integer atomics against values measured on RDNA
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:35:58 +02:00
Adrià Franch e2ac1a6690 feat(shader): implement image_load_pck and image_load_mip_pck with signed variants
Return the raw texel bits: dmask bit i selects texel dword i, dwords past the
texel read 0 and the _sgn forms sign-extend texels narrower than 32 bits
(measured on RDNA2 hardware). Only formats whose bits are exactly recoverable
from the sampled view are accepted (unsigned/signed integer, unorm up to 16
bits, 32-bit float components), on a direct sampled image with identity
swizzle; anything else throws.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:32:13 +02:00
Adrià Franch d4d045f73e test(shader): execute flat and global loads against hardware results
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 19:09:54 +02:00
Adrià Franch e1a99077d1 test(shader): execute the untested buffer byte/short/dwordx2/x3 loads and stores and the 32-bit integer buffer atomics against values measured on RDNA
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 18:37:45 +02:00
Adrià Franch dc878c9c5c test(shader): execute every non-f64 VOPC compare against values measured on RDNA
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 18:12:35 +02:00
DotDebian e2dd34f360 test(shader): cover the SOPK s_waitcnt counters and count them as decoded
The decoder maps SOPK opcodes 0x17 to 0x1a to SWaitcnt, but no test encoded them and tools/progress.py only counted S_WAITCNT_VSCNT. The test runs the four waits with a null and a live register field and checks that SCC and the register are left unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:13:18 +02:00
DotDebian a701cfb08d feat(shader): implement global_load_dword_addtid
Decode FLAT opcode 0x16 in the global segment and load one dword per
active lane from the SGPR pair base plus the signed offset plus four
times the lane id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:09:25 +02:00
DotDebian 9754103cc4 fix(shader): keep decoding past an s_endpgm while a branch targets later code
The decoder stopped at an s_endpgm unless the next word was a known branch
target. When an earlier branch jumps further than that word, the block right
after the s_endpgm is entered only from later code, so the program was cut
short and the graph builder rejected the branch as targeting an invalid
program counter. Stop only when no decoded branch targets a word at or past
the one after the s_endpgm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:03:31 +02:00
DotDebian a590841f19 test(shader): cover the VOP3 carry-out add and subtracts and count v_sub_co_u32 as decoded
v_add_co_u32, v_sub_co_u32 and v_subrev_co_u32 (VOP3 0x30f, 0x310, 0x319)
decode to VAddI32, VSubI32 and VSubrevI32 and had no execution test.
tools/progress.py listed the first and the last as variants of those
opcodes but not v_sub_co_u32, which it reported as missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:01:01 +02:00
Adrià Franch 89eb938803 fix(shader): VOP3P integer clamp on v_pk_mad/add/sub_{i16,u16}
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 12:33:38 +02:00
Adrià Franch 1a5507698b fix(shader): choose v_div_scale_f32/v_div_fmas_f32 NaNs on the bits and refuse s_denorm_mode
v_div_scale_f32 returns a NaN source unchanged instead of scaling it,
and v_div_fmas_f32 quiets the first NaN input or returns the default
NaN 0xffc00000, so results no longer depend on the driver's NaNs. The
test compares NaN results bit for bit. s_denorm_mode throws: the
recompiler does not pin a denormal mode, so no value matches what it
models.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 12:05:33 +02:00
Adrià Franch 11bc279945 feat(shader): implement v_div_scale_f32, v_div_fmas_f32, v_div_fixup_f32 and s_denorm_mode
These make up the precise f32 division macro compilers emit for a / b. No
reference emulator implements them and the ISA pseudocode disagrees with the
hardware, so the rules were measured on an RDNA2 GPU:
- div_scale decides from the exponent fields only: 2^64 or 2^-64 scaling
  and VCC for differences >= 96 or <= -96, a denormal or huge (>= 253)
  denominator and a numerator exponent <= 24; a zero input gives 0xffc00000.
- div_fmas scales by 2^64 when the exponent of S2 is >= 128, else 2^-64,
  before the single rounding (the ISA says a fixed 2^32).
- div_fixup follows the ISA, and a NaN quotient with finite inputs becomes
  +-inf.
s_denorm_mode is accepted and ignored; listed in TechnicalDebt.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 12:05:33 +02:00
Adrià Franch 7f291b7658 feat(shader): implement the float and 64-bit inc/dec buffer atomics
buffer_atomic_fcmpswap, fcmpswap_x2, fmin_x2, fmax_x2, inc_x2 and
dec_x2 are compare-and-swap loops on the dword or qword. fcmpswap
compares as floats (-0 equals +0, NaN equals nothing) and fmin/fmax are
IEEE minNum/maxNum with -0 < +0, a quieted result for a signalling NaN
and the other operand for a quiet one, all with integer ops so the
driver's float controls do not matter. The existing 32-bit fmin/fmax
kept the old value whenever a NaN or two zeros were involved; it now
uses the same rule.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 12:01:15 +02:00
Adrià Franch ae36aafcb2 feat(shader): implement buffer_atomic_inc/dec and the 64-bit integer buffer atomics
buffer_atomic_inc, buffer_atomic_dec, buffer_atomic_cmpswap_x2 and
buffer_atomic_{add,sub,smin,umin,smax,umax,and,xor}_x2 threw in the decoder.
The 64-bit ones use native 64-bit SPIR-V atomics like the existing
swap_x2/or_x2; inc and dec wrap at the data operand through the existing
compare-exchange helpers.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 11:59:54 +02:00
Dean 97822deb0b
Merge pull request #446 from adriadam10/feat/vop3-f64-basic
feat(shader): implement basic f64 VALU ops
2026-10-04 22:55:23 +13:00
Dean 6a4bbade0d
Merge pull request #435 from adriadam10/feat/vop3-mad-i64-i32
feat(shader): implement v_mad_i64_i32
2026-10-04 22:54:49 +13:00
Dean 13cbbfa7f7
Merge pull request #325 from adriadam10/feat/relative-indexing
feat(shader): implement v_movrelsd_b32, v_movrelsd_2_b32, v_swap_b32 and v_swaprel_b32
2026-10-04 22:54:32 +13:00
Dean f4071f2469
Merge pull request #331 from adriadam10/feat/format-d16-stores
feat(shader): implement the D16 format buffer stores
2026-10-04 22:54:11 +13:00
Dean 1f4e030374
Merge pull request #330 from adriadam10/fix/formatted-store-conversion
fix(shader): convert formatted buffer stores to the element format
2026-10-04 22:53:54 +13:00
Dean 598833214b
Merge pull request #329 from adriadam10/feat/format-d16
feat(shader): implement the D16 format buffer loads
2026-10-04 22:53:37 +13:00
Dean 5ce9600d87
Merge pull request #319 from adriadam10/feat/d16-memory
feat(shader): implement the D16 byte/short loads and high-half stores
2026-10-04 22:53:20 +13:00
Michon 527c8e46a8 fix(shader): v_mov_b32 SDWA writes byte destinations
v_mov_b32 accepted SDWA destination selectors for the words only; a byte
destination (dst_sel BYTE_0..3) threw 'VOP1 SDWA destination selector is not
supported'. The write itself already handles bytes and every dst_unused mode
(TranslationContext::writeRawU32). GTA V aborted during boot on such a move
(dst_sel BYTE_0, dst_unused UNUSED_PRESERVE) in one of its eboot compute
shaders. The error now names the selector, opcode and pc. The SDWA destination
execution test covers BYTE_0 and BYTE_2 with UNUSED_PRESERVE and BYTE_1 with
UNUSED_PAD.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 11:44:10 +02:00
Adrià Franch e1b7ecc1c5 feat(shader): implement v_mad_i64_i32
Decode VOP3b 0x177 and translate it next to v_mad_u64_u32: the high half of
the product comes from SMulHi, and the carry-out is the sign of the exact
sum (bit 64 of the sign-extended product plus the sign-extended addend), as
measured on RDNA2 hardware.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 09:17:12 +02:00
Dean a75b2c9550
Merge pull request #316 from adriadam10/fix/wave32-subgroup-size
fix(agc): run wave32 compute programs on 32-wide subgroups
2026-10-04 20:09:16 +13:00
Adrià Franch fe26911cbb fix(shader): build f32/f64 conversion NaNs from the bits
OpFConvert leaves NaN payloads to the driver; NVIDIA returns its own.
v_cvt_f64_f32 now shifts the f32 payload left by 29 and v_cvt_f32_f64
keeps the top 23 payload bits, both quieted, as RDNA does (60/60 NaN
conversions measured on RDNA2). F64NanConversions covers both with the
hardware rows.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 08:52:14 +02:00
Adrià Franch b0afa04c77 feat(shader): implement basic f64 VALU ops
Decode and translate v_add/mul/fma/min/max/ldexp_f64, v_trunc/ceil/floor/
rndne/fract_f64, v_frexp_mant/exp_i32_f64 and the f64 <-> f32/i32/u32
conversions. f64 values stay as their raw bits (U64) in the IR and are
bitcast to double in SPIR-V, which needs the Float64 capability: the
device enables shaderFloat64 when it also preserves signed zero, inf and
NaN for 64-bit floats, and the shader declares SignedZeroInfNanPreserve 64.

Semantics measured on RDNA2 hardware (8209 inputs per op): literals are
the high dword, the 1/(2*pi) inline constant is the exact double,
omod is ignored, clamp maps NaN to +0, min/max quiet a
signaling NaN and drop a quiet one, NaN results are quiet, and the
integer conversions saturate with NaN -> 0. Truncation, rounding and
ldexp are done on the bits so they do not depend on the driver: lavapipe
returned wrong results for f64 RoundEven and Trunc, and GLSL Ldexp is
undefined past +-1024. Fma is NoContraction so RADV keeps it fused.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 08:52:14 +02:00
Dean b0a4a991cb
Merge pull request #334 from adriadam10/feat/ds-permute
feat(shader): implement ds_permute_b32
2026-10-04 19:42:21 +13:00
Adrià Franch eff7af93d4 fix(shader): translate s_setreg_imm32_b32 only for round to nearest even in MODE
Any other field or value throws. The existing s_setreg_b32 no-op is
recorded under Functional technical debt instead of silent stubs.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 08:28:52 +02:00