Commit Graph

38 Commits

Author SHA1 Message Date
Adrià b9d7fd6448
Merge pull request #1571 from Zheorgyan/fix/exp-f32-smallest-normal
fix(shader): keep v_exp_f32 at or above the smallest normal for inputs from -126
2026-10-10 03:11:42 +02:00
Adrià Franch 1910d1456d feat(shader): choose f32 arithmetic NaN results on the bits
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-09 09:14:44 +02:00
Adrià Franch ef4dca9a54 fix(shader): quiet signaling NaNs only in IEEE mode
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-09 00:33:02 +02:00
Adrià Franch f04ce007b6 feat(shader): follow DX10_CLAMP in the clamp modifier
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-09 00:25:07 +02:00
Adrià ce64d8eb36
Merge pull request #1850 from adriadam10/feat/shader-f32-denormal-flush
feat(shader): flush f32 denormals in the float modes that flush them
2026-10-09 00:24:54 +02:00
Adrià Franch f132f16155 feat(shader): flush f32 denormals in the float modes that flush them
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 23:59:24 +02:00
Adrià Franch d3f2611384 fix(shader): apply the output modifier only in the float modes where the hardware does
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 23:58:08 +02:00
Adrià Franch a000305181 fix(shader): choose packed f16 NaN results on the bits, as RDNA does
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 23:34:18 +02:00
Adrià Franch fe1f7b38af feat(shader): follow IEEE_MODE in f32 min, max, min3, max3 and med3
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 23:09:31 +02:00
Zheorgyan 847bd9f496 fix(shader): keep v_exp_f32 at or above the smallest normal for inputs from -126 2026-10-08 14:59:28 +02:00
Dean d2b23fb135
Merge pull request #664 from adriadam10/feat/f16-ternary-clamp
fix(shader): accept clamp and omod on every f16 VOP3 result op
2026-10-06 18:35:04 +13:00
Dean 964dd3c919
Merge pull request #669 from adriadam10/fix/dot2-f16-hw-rounding
fix(shader): match v_dot2_f32_f16 and v_dot2c_f32_f16 to hardware
2026-10-06 12:25:50 +13:00
Adrià Franch b8e1936783 fix(shader): accept clamp and omod on every f16 VOP3 result op
clamp (and omod, ignored while f16 denormals are enabled) were refused or
dropped per op: v_{add,sub,subrev,mul,min,max}_f16, v_ldexp_f16,
v_frexp_mant_f16, v_cvt_norm_{i,u}16_f16, v_{max3,min3,med3,div_fixup}_f16.
They now share one clamp on the f16 bits (clampF16Bits).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 20:30:47 +02:00
Dean 4c57426b51
Merge pull request #501 from adriadam10/fix/vop3-legacy-mods
fix(shader): v_mullit_f32 legacy rules, v_cvt_pk_u8_f32 rounding and VOP3 neg/abs
2026-10-06 02:32:06 +13:00
Adrià Franch b6c7f1c7e3 fix(shader): match v_dot2_f32_f16 and v_dot2c_f32_f16 to hardware
Single rounding of the whole sum, f32 accumulator denormals flushed, NaN
picked on the bits, clamp ignored and the v_dot2c accumulator read from
the lane itself under DPP, all as measured on hardware.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 15:20:01 +02:00
Adrià Franch f457d87bbd feat(shader): accept clamp on v_cube*_f32 and match their zero and subnormal results
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 10:57:27 +02:00
Adrià Franch 7bb6c59e83 fix(shader): v_mullit_f32 legacy rules, v_cvt_pk_u8_f32 rounding and VOP3 neg/abs
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 10:53:50 +02:00
Dean 1e37ed456a
Merge pull request #514 from adriadam10/fix/dpp16-movrels-pk-fmac
fix(shader): DPP16 operands of v_pk_fmac_f16 and the relative moves
2026-10-05 21:33:48 +13:00
Dean e90d2edf54
Merge pull request #596 from adriadam10/fix/vop3-pack-ldexp-bits
fix(shader): compute v_cvt_pknorm_*_f32, v_ldexp_f32 and v_pack_b32_f16 on the bits
2026-10-05 18:11:01 +13:00
Dean a84d759dd2
Merge pull request #498 from adriadam10/feat/vop2-dpp-sdwa-float-mods
feat(shader): accept float modifiers on v_cndmask_b32, v_mul_legacy_f32 and v_ldexp_f16
2026-10-05 18:08:04 +13:00
Dean dbfdcb1c79
Merge pull request #537 from adriadam10/test/vop1-float-unary
fix(shader): choose unary f32/f16 special results on the bits, as RDNA does
2026-10-05 18:06:40 +13:00
Dean 9f5fac08c8
Merge pull request #323 from adriadam10/fix/f16-result-clamp
fix(shader): apply clamp but not omod to f16 results, as RDNA does
2026-10-05 18:06:29 +13:00
Adrià Franch e58e2f0605 feat(shader): accept float modifiers on v_cndmask_b32, v_mul_legacy_f32 and v_ldexp_f16
- v_cndmask_b32: neg/abs on DPP; neg/abs applied on the bits, as the hardware does
- v_mul_legacy_f32: neg/abs on DPP and SDWA, clamp/omod on SDWA and VOP3
- v_ldexp_f16: neg/abs on src0 for VOP3, DPP and SDWA; NaN result chosen on the bits

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 04:59:40 +02:00
Adrià Franch a4482e0b71 fix(shader): compute v_cvt_pknorm_*_f32, v_ldexp_f32 and v_pack_b32_f16 on the bits
v_pack_b32_f16 applied neg/abs to bit 31 of the source dword instead of the
selected half. v_cvt_pknorm_{i16,u16}_f32 and v_ldexp_f32 used GLSL
PackSnorm2x16/PackUnorm2x16/Ldexp, which leave NaN, rounding ties and
denormals to the driver. Compute them on the bits as measured on RDNA2.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 03:42:08 +02:00
Adrià Franch f3b74e2cef fix(shader): choose unary f32/f16 special results on the bits, as RDNA does
v_ceil/floor/trunc/rndne/fract/sqrt/rsq/rcp/rcp_iflag/log/exp/sin/cos
(f32 and f16) and v_frexp_mant_f32 left NaN, invalid, zero and infinite
results to the driver: signalling NaNs came back unquieted, lavapipe lost
the NaN sign and payload, invalid results were +NaN instead of -NaN, f32
sin/cos at whole and half cycles returned tiny values instead of +0, and
v_fract_f16 of a tiny negative rounded up to 1.0.

Adds an execution test for the 27 opcodes with expected values from
hardware; approximate ops are compared with tolerances from the Vulkan
precision table.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 03:38:12 +02:00
Adrià Franch b94b1f96dc fix(shader): apply clamp but not omod to f16 results, as RDNA does
writeF16 dropped the clamp bit, so VOP3/SDWA f16 results with clamp
(v_rcp_f16, v_fma_f16, v_cvt_f16_f32, v_add_f16_sdwa, ...) were not
saturated. Clamp now limits to [0, 1] with NaN and -0 going to +0.
The f16 sqrt/rsq/log and sin/cos paths applied omod, which the
hardware ignores on f16 results in the default float mode, and
v_cvt_pkrtz_f16_f32 applied clamp and omod to its inputs, which the
hardware ignores as well.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-05 03:38:07 +02:00
Dean ebf29f8d91
Merge pull request #595 from NahuelGenchi/fix/fma-legacy-dx9-zero
fix(shader): apply the DX9 zero rule to v_fma_legacy_f32
2026-10-05 14:32:00 +13:00
Nahuel Genchi d32eb5d309 fix(shader): apply the DX9 zero rule to v_fma_legacy_f32
VOP3 0x140 was translated as a plain fma, so a zero source times an
infinity or a NaN gave NaN instead of the addend. A zero source now
gives +0 + src2, the same rule v_mul_legacy_f32 and v_mac_legacy_f32
already follow. The opcode also takes neg and abs on its sources.
2026-10-04 21:47:22 -03:00
Chad abbcb31e54 feat(shader): implement v_dot2_f32_f16
VOP3P 0x13 threw "VOP3P opcode is not implemented". It computes
src0.lo * src1.lo + src0.hi * src1.hi + src2 like v_dot2c_f32_f16, with
the VOP3P op_sel/op_sel_hi and neg_lo/neg_hi modifiers on the packed f16
sources, neg on the f32 accumulator and clamp. op_sel and neg_hi on the
accumulator throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 18:09:01 -05:00
Adrià Franch cebc1e8289 fix(shader): DPP16 operands of v_pk_fmac_f16 and the relative moves
v_pk_fmac_f16 read its accumulator through the permuted destination and
wrote without the DPP write mask. v_movrels/movrelsd/movrelsd_2 dropped
the source permute, and the relative writes dropped the DPP write mask.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-04 22:35:51 +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
Dean 837bb8fe96
Merge pull request #438 from adriadam10/feat/vop3-div-fixup-f16
feat(shader): implement v_div_fixup_f16
2026-10-04 15:41:11 +13:00
Adrià Franch c23ead6478 feat(shader): implement v_div_fixup_f16
Decode VOP3 opcode 0x35f and translate it on the raw half bits, matching
the RDNA2 hardware: NaN numerator or denominator is returned quieted,
0/0 and inf/inf give 0xfe00, a NaN quotient becomes a signed infinity,
and op_sel, abs and neg apply as for the other f16 ternary ops.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-03 09:19:46 +02:00
Adrià Franch 8fd19cda0e feat(shader): implement f16 ldexp/frexp/norm/class, v_sat_pk_u8_i16 and v_mul/mac_legacy_f32
v_ldexp_f16, v_frexp_mant_f16, v_frexp_exp_i16_f16, v_cvt_norm_i16/u16_f16,
v_cvt_pknorm_i16/u16_f16, v_cmp_class_f16, v_cmpx_class_f16,
v_sat_pk_u8_i16 and v_mul/mac_legacy_f32 threw in the decoder. The
behaviour was measured on an RDNA2 GPU: ldexp takes the exponent as an i16,
the norm conversions round to nearest even (done in integers, as x * 32767
does not fit f32 exactly), and a legacy multiply with a zero operand gives
+0 even for an infinite or NaN other operand. v_mac_legacy_f32 adds the
rounded product, like v_mac_f32.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-02 06:46:26 +02:00
STL1te d76ecfac06 fix(shader): DPP row and bank masks gate the instruction's VGPR write
The decoder puts an instruction's DPP fields on its source, and only a
destination carrying them has writeRawU32 keep the lanes the masks leave out
(and, without bound_ctrl, the lanes with no source lane). destinationOperand
copied them over, but no write used it, so every row was written: a wave64
scan adding the other row's total into the odd rows only (row_mask:0xa) added
it into every row, the prefix sums a key pass indexes primitives by came out
wrong, and the tree built from the keys held cycles its walkers looped on.

As in the Kyty recompiler (writes through DestinationOperand):
TranslateInstruction gives the destination its source's DPP fields once, and
a mac accumulator reads the destination without them (accumulatorOperand).
agc_dpp_write_tests checks a masked DPP add writes through DppUpdateU32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:22:21 +03:00
boykopovar c6dcc8bf6b feat(shader): translate float instructions functions 2026-09-16 13:24:40 +03:00
boykopovar d084eed394 feat(shader): rdna memory op decoder impl 2026-09-15 07:07:50 +03:00
Renamed from core/shader/recompilier/Translation/src/FloatInstructions.cpp (Browse further)