Commit Graph
6138 Commits
Author SHA1 Message Date
Liav Mordouch e6eb64aa58 fix(shader): reduce v_sin_f32 and v_cos_f32 inputs exactly
v_sin_f32 and v_cos_f32 take their input in cycles, and the SPIR-V
backend reduced it with GLSL Fract before scaling by 2*pi. For x in
(-0.5, 0), fract(x) = 1 + x is rounded to a multiple of 2^-24, which
drops the low bits of x, and for |x| <= 2^-25 it rounds to 1.0, which
RADV's v_fract_f32 clamps to 0x3f7fffff. On RADV, v_sin_f32(-2^-30)
returned 0xb4c90fde (-3.7e-7) where RDNA3 returns 0xb1c90fd5 (-5.9e-9).

The cycle is now x - roundEven(x). It lies in [-0.5, 0.5] and is exact
for every finite x: it is x when roundEven(x) is 0, and Sterbenz's
lemma applies otherwise. Finite inputs of magnitude 2^23 or more still
reduce to +0, so the select that forced them to 0 is removed. Infinite
and NaN inputs are unaffected: the translation selects their results
on the input bits.

Measured on RDNA3 (gfx1101) with the hardware oracle, with the same
results in all 16 combinations of IEEE, DX10_CLAMP and the f32 and f16
denormal modes: over 544 inputs, v_sin_f32(x - v_rndne_f32(x)) returns
the bits of v_sin_f32(x) for 519 and is at most 11 ulp off, while
v_sin_f32(v_fract_f32(x)) matches 403 and is more than 16 ulp off for
80, all of them in (-0.5, 0). For v_cos_f32 the counts are 523 (at
most 7 ulp off) and 484 (6 more than 16 ulp off). On RADV the
recompiled shader returns the bits of the v_fract_f32 sequence before
this change and of the v_rndne_f32 sequence after it, for all 544.

v_sin_f16 and v_cos_f16 share the reduction. On RADV, with f16
denormals kept, v_sin_f16 now returns the RDNA3 bits for all 65536
inputs, where it was 1 ulp off for 6 small negative ones, and
v_cos_f16 matches for all of them before and after.
2026-10-09 06:34:59 +03:00
AlexandClaude Opus 5.5 33603bf8a9 fix(shader): keep runtime image mode switches inside continue targets
An image with several runtime modes is emitted as a switch whose default
and disabled modes end in OpUnreachable. In a loop latch that exit breaks
the continue construct, and spirv-val rejected the shader. Inside a
continue target those cases now join the merge with an undefined result.

Fixes #1921

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 23:05:07 -04:00
AlexandClaude Opus 5.5 dc902b2eae fix(hw-oracle): assemble wave64 bodies in wave64 mode
clang assembled every body as wave32, so a --wave64 body that used vcc
or an SGPR pair as a condition failed with "operands are not valid for
this GPU or mode". Pass -mwavefrontsize64 on wave64 runs.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 23:03:22 -04:00
Liav Mordouch 7ba9807147 fix(shader): read v_ldexp_f16 src1 float inline constants as f16
v_ldexp_f16 read src1 with readU32, so a float inline constant gave
the low 16 bits of its f32 pattern: 0 for 0.5, 1.0, 2.0, 4.0 and
their negatives, which returned src0 unchanged, and 0xf983 for
1/(2*pi), which clamped to -64 and returned a signed zero. The
hardware treats src1 as an f16 operand, as LLVM's
LDEXP_F16_VOPProfile in VOP2Instructions.td records, so it receives
the f16 encoding: 0.5 is 0x3800, an exponent of 14336. Measured on
gfx1101, ldexp(1.0, 0.5) is +inf and ldexp(1.0, -0.5) is +0.

Read VOP3 src1 through readF16SourceBits, which maps the float inline
constants to their f16 bits and reads other operands as before.
Registers, integer inline constants and literals already matched the
sign-extended low 16 bits the hardware uses. SDWA src1 keeps its old
read, as gfx11 has no SDWA to measure it on.
2026-10-09 05:53:32 +03:00
Renan Pires 851f3b7a10 feat(libkernel): implement getrlimit for RLIMIT_DATA 2026-10-08 23:52:33 -03:00
Renan Pires 942a105c39 feat(libkernel): implement pthread_getcpuclockid and per-thread CPU clocks 2026-10-08 23:50:03 -03:00
Liav Mordouch ccef16b4da fix(shader): return +0 when v_div_fmas_f32 cancels with |src2| >= 2^64
With VCC set and a src2 exponent field of 128 or more (scale 2^64),
v_div_fmas_f32 recomputed an fma result with exponent field 0 as an
fma of the smaller multiplicand times 2^64, the other multiplicand and
src2 * 2^64. For |src2| >= 2^64, src2 * 2^64 overflows to infinity, so
an fma that cancels exactly returned -inf or +inf. The hardware
returns +0: measured on gfx1101 for (1.0, FLT_MAX, -FLT_MAX) and
(1.0, -2^100, 2^100) in all 16 combinations of IEEE mode, f32 and
f16/f64 denormal mode and DX10_CLAMP.

Only exact cancellations reach that path. With |src2| >= 2, a nonzero
sum below 2^-126 needs a product above 1, which is a multiple of
2^-47, while src2 is a multiple of 2^-22, so a nonzero sum is at least
2^-47 and the fma result is normal. The scaled result is then the fma
result times 2^64, +0 for a cancellation. The recomputation is now
done only for the 2^-64 scale, when the fma result overflows.
2026-10-09 05:49:01 +03:00
SK Arin 567b1f923f chore(oracle): resolve upstream test registration conflict 2026-10-09 07:55:35 +05:30
Liav Mordouch df5c0ec35c test(shader): check v_fma_mix_f32 in FmaRounding
FmaRounding checks v_fma_f32, v_fmac_f32, v_fmaak_f32 and v_fmamk_f32
against the fused result on the GPU, but not v_fma_mix_f32. It now
also runs v_fma_mix_f32 v20, v4, v5, v6 with all sources f32 on its 64
rows and expects the fused value, in the group that is skipped when the
device splits fma.
2026-10-09 05:20:42 +03:00
Raihan Abdul MajidandClaude Opus 5.5 c8c2079e56 fix(agc): sample resident depth surfaces when a stage-A texture record hits
fastTexture took the Textures() cache entry of a stage-A image record
without asking whether a depth surface is resident at the address. The
full lookup in cachedTexture returns DepthSurfaceTexture first; the fast
path skipped it, so once a guest-memory entry existed for a depth
target's descriptor, every later sampled read got that entry and saw
the guest memory under the target, which a depth target never writes.
The fast path now returns nothing while a depth surface is resident
there, and the lookup falls back to cachedTexture.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UTjpbMX7BUFMZZaxJE98zV
2026-10-09 09:15:28 +07:00
arcwiser 2051436d4c test(shader): cover high MIMG opcode bit 2026-10-09 13:06:21 +11:00
arcwiser 3058b5193b fix(shader): name unsupported MIMG opcodes 2026-10-09 12:43:37 +11:00
TacoCat055 9a6667cb4c docs: explain relinker Python test discovery 2026-10-08 19:27:23 -06:00
Joey Fisher 21612855b3 fix(agc): skip registration-time preparation for unsupported shader types 2026-10-08 19:16:19 -06:00
Zinebyte 2381e7fc64 fix(relinker): reject prefixed system-call instructions
Use the decoded opcode offset when checking forbidden system calls.
Add synthetic regressions for prefixed forms, immediate decoys, and the skip option.

AI-assisted: Codex. The submitting author is responsible for every changed line.
2026-10-08 20:34:40 -04:00
john.maiaandClaude Opus 5.5 f5293b64d2 feat(libSceVideodec2): decode HEVC and VP9
EVO-PLAYER (PPSA99039) creates resident AVC, HEVC and VP9 decoders at
start-up, and stopped at "Videodec2: unsupported codec" on the HEVC one.
Codec types 974921 (HEVC) and 2382845 (VP9) now open FFmpeg's HEVC and
VP9 decoders. HEVC input goes through the same Annex B conversion as
H.264 and VP9 frames are passed through; output stays 8-bit NV12, and a
frame deeper than 8 bits throws. Picture info throws for HEVC and VP9,
whose layouts differ from the AVC one.

Assisted by Claude Code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DwFnKjMxmwGDWiuYYf1v4D
2026-10-09 01:27:15 +01:00
Joey Fisher def0be1085 fix(agc): prepare a rect-list draw's missing rectangle at draw from its prepared stages 2026-10-08 18:06:04 -06:00
Joey Fisher a2dc28aa6a refactor(agc): look up a rect-list draw's rectangle through DrawRectangle 2026-10-08 18:01:42 -06:00
Scott SchusterandClaude Opus 5.5 88cc2ea477 fix(agc): accept RADV's disabled conservative rasterization state
With conservative rasterization disabled, RADV programs
PA_SC_CONSERVATIVE_RASTERIZATION_CNTL to NULL_SQUAD_AA_MASK_ENABLE alone,
where libSceAgc writes the two INNER_TO_NORMAL overrides (0x6000). A value
made of only those bits now decodes as disabled; overestimation (0x6001) keeps
its checks, and every other mode is still rejected.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:24:47 -05:00
Scott SchusterandClaude Opus 5.5 6c5b181b68 fix(agc): accept PA_SC_MODE_CNTL_1's out-of-order watermark
RADV sets OUT_OF_ORDER_WATER_MARK to 7 on every GFX10 draw, also when
OUT_OF_ORDER_PRIMITIVE_ENABLE is off. The watermark only tunes out-of-order
rasterization, which stays rejected, so the field is accepted alone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:24:47 -05:00
Scott SchusterandClaude Opus 5.5 1e20b4ec50 feat(agc): blend against an opaque destination for CB_COLOR_ATTRIB FORCE_DST_ALPHA_1
FORCE_DST_ALPHA_1 makes blending read a target's destination alpha as 1, as
for an RGBX surface; RADV sets it for formats without alpha. The target's
blend factors are rewritten to what they become with Ad = 1: DST_ALPHA is
ONE and ONE_MINUS_DST_ALPHA is ZERO, SRC_ALPHA_SATURATE is ZERO in the color
equation, and DST_COLOR and ONE_MINUS_DST_COLOR are ONE and ZERO in the
alpha equation. Other CB_COLOR_ATTRIB bits stay rejected.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:24:46 -05:00
Scott SchusterandClaude Opus 5.5 4bc84d6b44 fix(relinker): convert stack-guard and thread-pointer reads with an empty PT_TLS
A title built with -fstack-protector reads its guard from fs:0x28 even when
it has no thread-local data and its linker emits an empty PT_TLS. The
Windows TLS builder refused any guest TLS access in that case. The guard and
the thread pointer live in the thread control block, which the builder
already emits, so an empty PT_TLS now takes the normal path, where a
zero-sized TLS block still rejects every other displacement.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:08:06 -05:00
Scott SchusterandClaude Opus 5.5 7c8dae0b33 fix(pad): accept the compatible vibration mode
scePadSetVibrationMode rejected mode 2 (compatible, per SharpProspero's
ScePadVibrationMode). The PS5 SDL joystick driver requests it on every
open and closes the pad when it fails, so SDL titles lost their controller.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:08:05 -05:00
Joey Fisher 1f0060d72d fix(shader): saturate VOP3 v_add/sub_nc_u32 and 16-bit add/sub on clamp 2026-10-08 16:55:06 -06:00
Joey Fisher 485387ef2f test(shader): pin VOP3 integer add/sub clamp results measured on RDNA2 2026-10-08 16:55:06 -06:00
Adrià f145139676 Merge pull request #1878 from adriadam10/fix/shader-fma-mix-fused
fix(shader): translate v_fma_mix_f32 as a fused multiply-add
2026-10-09 00:46:52 +02:00
Adrià 42e9148636 Merge pull request #1867 from adriadam10/fix/shader-unary-nan-ieee
fix(shader): quiet signaling NaNs only in IEEE mode
2026-10-09 00:42:27 +02:00
Adrià FranchandClaude 6833b0ed55 fix(shader): translate v_fma_mix_f32 as a fused multiply-add
Co-Authored-By: Claude <[email protected]>
2026-10-09 00:40:13 +02:00
Adrià db1391dc5a Merge pull request #1863 from adriadam10/fix/libc-arena-reserve-race
fix(libc): retry the guest arena reservation when the range was mapped meanwhile
2026-10-09 00:40:13 +02:00
Adrià FranchandClaude ef4dca9a54 fix(shader): quiet signaling NaNs only in IEEE mode
Co-Authored-By: Claude <[email protected]>
2026-10-09 00:33:02 +02:00
Adrià d64134f09e Merge pull request #1866 from adriadam10/feat/shader-dx10-clamp
feat(shader): follow DX10_CLAMP in the clamp modifier
2026-10-09 00:31:40 +02:00
krishnarayaandClaude Opus 5.5 17f1a2e59a test(agc): pin the 64-bit atomics emission failures
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 18:28:50 -04:00
krishnarayaandClaude Opus 5.5 e5da5fd2a3 fix(agc): lay out 3D SW_64KB_D_X textures as thick volumes
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 18:28:19 -04:00
krishnarayaandClaude Opus 5.5 b719eedaa5 fix(agc): round linear volume mip extents up as addrlib does
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 18:28:18 -04:00
krishnarayaandClaude Opus 5.5 96569aac30 fix(shader): refuse the MUBUF lds modifier instead of decoding a VGPR load
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 18:28:16 -04:00
Adrià FranchandClaude f04ce007b6 feat(shader): follow DX10_CLAMP in the clamp modifier
Co-Authored-By: Claude <[email protected]>
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à FranchandClaude b9fa0c941d fix(libc): retry the guest arena reservation when the range was mapped meanwhile
Co-Authored-By: Claude <[email protected]>
2026-10-09 00:22:52 +02:00
Celegans12 d3a66dbbbe feat(agc): implement deferred faults for descriptors read through null SRT pointers
Capturing a shader evaluates every V#, T# and S# the program uses,
including those behind a branch the wave does not take. When such a
descriptor was loaded through a pointer read from memory that is null
or unmapped, the capture threw "guest memory is not readable", while
the console faults only if a wave executes that s_load. The descriptor
now reads as zero words, and the flat SRT walk records the s_load's
dwords as it does for flat reads, so their guarded ReadConst raises
the BDA fault where the wave runs the s_load. A zero V# is an absent
buffer and a zero T# binds a null descriptor, as for any zero word
read from memory, so nothing new enters a key. A zeroed descriptor
whose read no flat slot records still throws, as do branch conditions,
uniform fills, table bases and user-data pointers.
2026-10-09 00:21:00 +02:00
Celegans12 56f8a62428 feat(agc): implement deferred faults for reads through null SRT pointers
Capturing a shader threw "null or misaligned address" when the flat
SRT walk read through a pointer loaded from memory that is null or
unmapped, even when the program skips that s_load. Such a read now
yields zero and a record with its pc and address, as does a slot whose
address needs it. The registered artifact checks one flag word per
guarded slot at each ReadConst; the capture appends the flags and the
records to the flattened SRT, and a set flag raises an Unmapped BDA
fault through the fault buffer and stops the invocation as a BDA read
does. Nothing per capture enters a key: poisoned and clean captures
share one variant and specialization. Descriptors, branch conditions,
uniform fills, table bases and user-data pointers that need such a
value still throw, and poisoned results stay out of the dispatch and
draw caches. The shader disk cache format becomes 21.
2026-10-09 00:20:59 +02:00
Adrià 1be6f9f1c5 Merge pull request #1851 from adriadam10/feat/shader-omod-float-mode
fix(shader): apply the output modifier only in the float modes where the hardware does
2026-10-09 00:18:27 +02:00
overlordxrz-source 8f09ec3616 feat(libkernel): implement system 2026-10-08 18:15:49 -04:00
Adrià FranchandClaude f132f16155 feat(shader): flush f32 denormals in the float modes that flush them
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:59:24 +02:00
LeandroLP23andClaude Opus 5.5 f054374661 test(libSceNet): pin the resolver info layout and check the buffer on errors
The layout offsets the titles read are static_asserts, and guest_sce_net now
checks a canary past byte 384, distinct records, and an untouched buffer on the
EINVAL, RESOLVER_ENODNS and EBADF paths, as #1845's test did.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:58:18 +02:00
Adrià FranchandClaude d3f2611384 fix(shader): apply the output modifier only in the float modes where the hardware does
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:58:08 +02:00
Adrià ae91d9780b Merge pull request #697 from queeeef/feat/interp-f16
feat(shader): implement v_interp_p1ll_f16, v_interp_p1lv_f16 and v_interp_p2_f16
2026-10-08 23:56:17 +02:00
LeandroLP23andClaude Opus 5.5 427fd92591 feat(libSceNet): implement sceNetResolverStartNtoaMultipleRecordsEx
PS5VR (PPSA99177) stops at start-up on the unresolved import sT4nBQKUPqM;
Jelly5, Emby5 and Nuvio import it too. The call fills the 384-byte resolver
info with up to ten IPv4 records (32 bytes each, family at +16) and the record
counts at +320 and +324, from the same host lookup sceNetResolverStartNtoa
uses, now shared. Only flags 0 is implemented; other flags throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:52:02 +02:00
LeandroLP23andClaude Opus 5.5 7449e51483 feat(libc): implement __inet_aton
PICO-8 for PS5 (PPSA99808) stops at start-up on the unresolved import
a7ToDPsIQrc from libSceLibcInternal. The parser follows FreeBSD's inet_aton
(lib/libc/inet/inet_addr.c): one to four parts in decimal, octal or hex, the
last part filling the remaining bytes, input ending at a NUL or whitespace,
and a null address only validating.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:48:48 +02:00
Gerard L.andClaude Opus 5.5 1d6968225f test(agc): run agc_driver_mesh_tests under ctest
The mesh test was built only on request and never registered, so the
translation of NGG geometry programs to mesh shaders ran in no test
run. On an RTX 4060 it passes. Register it with the other AGC driver
tests.

Three cases would fail or mislead under ctest. Without a Vulkan device
the test failed, and the Windows job has none. A device without
VK_EXT_mesh_shader exited 0, so ctest reported a pass for a test that
drew nothing. On llvmpipe, with the Linux job's Mesa 25.2.8 and Ubuntu
24.04's LLVM 20.1.2, every draw that builds a mesh pipeline stops the
process with "LLVM ERROR: Cannot emit physreg copy instruction"; Mesa
26.2.4 with LLVM 23.1 segfaults in LLVM's code generation instead. The
SPIR-V of all 18 modules the test builds passes spirv-val. Mesa #14376
reports the same error for lavapipe mesh shaders that index shared
memory per invocation; that the cause is the same is not established.

The test now opens its device with OpenVulkanTestDevice and exits 77
without a device, without VK_EXT_mesh_shader and on llvmpipe, saying
why. ANYPS5_REQUIRE_VULKAN still turns a missing device into a
failure. The Linux job therefore skips the test; it runs on hosts with
a GPU.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:44:46 +02:00
Joey Fisher 24623021cd fix(ajm): decode multichannel ATRAC9 streams
Config 0x30 (the ambisonic layout, 4 to 16 channels) was rejected at instance init, so Demon's Souls asserted in
its audio player and crashed entering the tutorial level. Each channel is decoded as a mono stream and the
blocks are interleaved.
2026-10-08 15:44:01 -06:00