Commit Graph
4862 Commits
Author SHA1 Message Date
raghav314andClaude Opus 5.5 70a6dde689 perf(agc): continue render passes across draws with only a fault buffer
A recorded draw counted as reading and writing any guest memory when its
resources needed completion work, which a fault buffer alone (guarded
descriptor slots, rect lists) also needs. Such a draw reaches no guest
memory through it: the buffer is the draw's own, written only on a fault.
Its pass hazards now come from its known ranges and images like any other
draw; address-based draws, draws through the BDA table and draws with
copied writes still count as touching any guest memory.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 07:53:23 +05:30
DavidandClaude Fable 5.1 1671179c4f feat(libc): implement random, srandom, initstate and setstate
Port FreeBSD 11 lib/libc/stdlib/random.c (freebsd-src 4ab2e064): the
additive feedback generator with the default 128-byte TYPE_3 table,
good_rand seeding, state sizes rounded down to 8, 32, 64, 128 or 256
bytes, setstate returning the previous state, and initstate returning
null below 8 bytes without setting errno. Calls are serialised by one
lock; a null state throws.

The import audit of the homebrew catalog on main 262c0316 lists them as
absent libSceLibcInternal imports:
- random: PPSA74126 Stremio Plus, PPSA85300 VLC, PPSA99169 RetroArch,
  PPSA99177 PS5VR, PPSA99420 PS5MC, PPSA99505 Jelly5, PPSA99515 Emby5,
  PPSA99810 PSBox Cloud Gaming
- srandom: PPSA85300, PPSA99169, PPSA99420, PPSA99810
- initstate, setstate: PPSA99177, PPSA99420, PPSA99505, PPSA99515

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-11 04:07:38 +02:00
XairRrR ba0b042925 feat(agc-driver): blend into COLOR_8_8 SWAP_ALT targets with a separate alpha equation
An 8_8 target with SWAP_ALT keeps the x export in its first channel and
the alpha export in its second, and the color block blends that second
channel with the alpha equation. Blending into such a target threw.

With one equation for color and alpha the draw blends as before. With a
separate alpha equation the pipeline draws twice: the first pass writes
the first channel with the color equation, the second writes the second
channel with the alpha factors and operation moved into its color
equation. The split is refused, by throwing, for draws that write depth
or stencil, use per-face depth bias, or whose pixel shader writes memory,
since those would repeat; factors of the destination alpha throw since
the target keeps it in its second channel. Pipeline libraries are not
used for split pipelines.
2026-10-11 04:00:44 +02:00
Adrià FranchandClaude 3cd36b0135 feat(libc): implement acosl and frexpl
Co-Authored-By: Claude <[email protected]>
2026-10-11 03:58:47 +02:00
krishnarayaandClaude Opus 5.5 1ce9790481 fix(agc): pick float or integer sampler border colours from the paired images
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-10 21:57:09 -04:00
fma-rc eb2c43a2eb fix(shader): sample a 1D T# through a 2D implicit-LOD image_sample
A plain image_sample that says DIM 2D on a 1D T# takes its texel and its LOD
from the first coordinate alone, measured on RDNA2 (gfx1036) with the
hardware oracle. Astro's Playroom draws with such a pair.
2026-10-11 03:54:50 +02:00
Gustavo Ariel Gamarra Rojas 50e84c7cf7 test(agc): pin alpha-to-coverage coverage measured on RDNA2
The expected rows were measured with Vulkan alpha-to-coverage on a Radeon 660M (gfx1035) under RADV_DEBUG=noatocdithering, which programs DB_ALPHA_TO_MASK 0xaa01: an alpha of at least one half, 2 and +inf keep the pixel; below one half, -0, negatives, -inf and NaN drop it.
2026-10-10 22:50:46 -03:00
Gustavo Ariel Gamarra Rojas 869d73e4d8 test(libSceSysmodule): compare sceSysmoduleGetModuleInfoForUnwind with /proc/self/maps
Covers code, stack and an anonymous page, and an unmapped address. On Linux the test runs again with APS5_NO_PROCMAP_QUERY so the line scan stays covered.
2026-10-10 22:50:46 -03:00
Gustavo Ariel Gamarra Rojas 7d92bf70f9 feat(agc): decode undithered alpha-to-coverage
DB_ALPHA_TO_MASK 0xaa01, the enable bit with the four offsets at 2 and no OFFSET_ROUND, reaches the pixel stage, which keeps a pixel when its MRT0 alpha is at least one half. Dithered or rounded settings, and an MRT0 that is missing, swizzled, packed or exported without a floating-point alpha, still throw. God of War Sons of Sparta (PPSA28997) stopped on it a few minutes into play.
2026-10-10 22:50:46 -03:00
Gustavo Ariel Gamarra Rojas ad4add2b1a perf(libSceSysmodule): look up the mapping with PROCMAP_QUERY in sceSysmoduleGetModuleInfoForUnwind
It carried its own copy of the /proc/self/maps line scan and is called on the same Unity stack walks as sceKernelGetModuleInfoForUnwind. It now uses the shared HostMapping lookup.
2026-10-10 22:50:46 -03:00
Gustavo Ariel Gamarra Rojas d152ff833c feat(shader): turn the MRT0 alpha into a sample mask for alpha-to-coverage
A pixel shader whose stage info asks for alpha-to-coverage declares SampleMask, starts with every sample covered and, at its MRT0 export, clears the mask when the alpha is below one half or NaN, running with late fragment tests. The shader keeps running, as a zero coverage mask does on the GPU. The flag is part of the static shader identity and of the request serialization, now version 16.
2026-10-10 22:50:46 -03:00
Gustavo Ariel Gamarra Rojas 15ae919325 perf(libkernel): look up the mapping with PROCMAP_QUERY in sceKernelGetModuleInfoForUnwind
On Linux every call opened /proc/self/maps and scanned it line by line with sscanf. Unity titles call it on each stack walk, and with about 900 mappings God of War Sons of Sparta (PPSA28997) spent most of its main thread there. The covering mapping is now asked of the kernel with PROCMAP_QUERY (Linux 6.11), on one descriptor opened once, as GuestMemory does; older kernels and APS5_NO_PROCMAP_QUERY keep the line scan.
2026-10-10 22:50:46 -03:00
Adrià FranchandClaude 9fe5d90cbe test(agc): split agc_driver_flat_apertures into six parts
Co-Authored-By: Claude <[email protected]>
2026-10-11 03:47:10 +02:00
Adrià FranchandClaude d4b9808705 fix(libkernel_sys): keep umask bits up to 07777 like FreeBSD
Co-Authored-By: Claude <[email protected]>
2026-10-11 03:36:40 +02:00
Hannah Lyons 967de40393 feat(libkernel_sys): export fork and implement setsid and umask 2026-10-11 03:36:32 +02:00
Claude 7c4f9381d4 Merge upstream main into fix-shader-f16-directed-rounding
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01K9MzdVqDf6wHUKzNymQSze
2026-10-11 01:33:16 +00:00
raghav314andClaude Opus 5.5 aa013f59ac fix(libc): register guest heap blocks without GPU access
AnyPS5's libc heap registered every block with GPU access, so every
address-based build imported or mirrored each malloc block the title had
made. The console's libc.prx maps its heap with protection 3 (CPU read
and write, no GPU bits), so the GPU never sees it there either.

Heap blocks are now registered without GPU access; reallocating keeps the
block's access. The AvPlayer fallback for a title that passes no texture
allocator stands in for that allocator, which hands out memory the GPU
reads, so it allocates through a new GuestHeapAlignForGpu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 07:02:30 +05:30
fma-rc ab0babdc9b fix(libs): bind the system libraries eagerly on Linux
A title calls our exports on stacks it sized for the console. With lazy
binding the first call through a PLT slot runs the dynamic linker's symbol
lookup on that stack: on the 2 KiB fiber context Astro's Playroom uses it
wrote below the context into the neighbouring heap chunks.
2026-10-11 03:31:37 +02:00
Scramblrrrr 4fd6192d5c fix(agc): enforce retained-byte budget before buffer-only work 2026-10-10 22:25:59 -03:00
MarcZX100 eb9efe109e fix(libkernel): preserve vector socket error codes 2026-10-11 01:17:37 +00:00
MarcZX100 d78af2c710 fix(libkernel): route vector I/O on guest sockets 2026-10-11 01:16:58 +00:00
Dean Galvin 60f12c888d fix(agc): compare host imports when device writes reach the write watch
The import probe only checked whether a GPU read of an imported range
reports its pages as written. lavapipe runs command buffers on CPU
threads, so its writes into an import go through the page tables and
are collected as CPU stores. In agc_unit_shadow the whole publish's
copy into the import is then collected as a CPU store over unit 3, and
the next partial publish drops the slab's newer bytes as stale: "the
partial publish did not copy exactly the partly covered unit".

The probe now also fills the scratch range on the GPU and collects
again. When the read or the fill reports pages as written, host and
dma-buf imports are compared. lavapipe reports 0 of 4 pages after the
read and 4 of 4 after the fill; NVIDIA reports 0 after the fill.

The probe change is the first commit of #1046.
2026-10-11 14:15:27 +13:00
Adrià FranchandClaude bbe26912dc fix(agc): view 4_4_4_4 textures as B4G4R4A4, which every Vulkan device can sample
Co-Authored-By: Claude <[email protected]>
2026-10-11 03:13:40 +02:00
Hannah Lyons 0e88f3014d fix(libkernel): name pthread_kill's errors and test the signal range edge 2026-10-10 21:11:29 -04:00
Hannah Lyons d8af71c0ca feat(libkernel): implement pthread_kill 2026-10-10 21:11:29 -04:00
Scott SchusterandClaude Opus 5.5 3f32c12fd8 fix(libkernel): read sceKernelGetAppInfo's title id through AppMetadata
The title id now comes from GetAppTitleId, so param.json has one parser and
its validation (a missing file or titleId throws). Another pid returns EPERM
and a null info returns 0 without writing, as shadPS4 does. app_id stays 1,
the running title's id in libSceSystemService, which is inferred, not
measured.

guest_app_info runs the call without param.json in a child process and
checks that the field between app_id and the title id is left alone.

AI-assisted (Claude Code).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 03:11:18 +02:00
Scott SchusterandClaude Opus 5.5 a6520d0c8b feat(libkernel): implement sceKernelGetAppInfo
sceKernelGetAppInfo fills the app id and the title id of the calling
process: app id 1, the running title's id in libSceSystemService, and the
titleId of /app0/sce_sys/param.json at offset 0x10, up to 9 characters and a
terminator. Only those fields are written, since callers declare the
structure with different sizes. Another pid returns ESRCH and a null info
EFAULT.

AI-assisted (Claude Code).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 03:11:18 +02:00
Adrià 77bd928a3c Merge pull request #3201 from adriadam10/feat/libc-ctime
feat(libc): implement ctime
2026-10-11 03:06:01 +02:00
Adrià FranchandClaude ef2d56eb9c feat(libc): implement ctime
Co-Authored-By: Claude <[email protected]>
2026-10-11 02:58:30 +02:00
Dean Galvin 5543c73b37 fix(libkernel): reserve the AMM virtual address ranges at the top of the guest arena
The AMM ranges were reserved address-less on first use, so they took the
lowest free address of the arena, directly after the title's last mapping,
where the title's next hinted maps go. They are now reserved at a fixed
place, the last 64 GiB of the guest arena, which maps without MAP_FIXED and
the hints derived from them do not reach; a reservation that cannot be made
there throws.

Fixes #3146
2026-10-11 13:56:11 +13:00
Adrià FranchandClaude e7605c8fd6 feat(libc): implement rewind
Co-Authored-By: Claude <[email protected]>
2026-10-11 02:54:24 +02:00
Achraf ReyaniandClaude Opus 5.5 0f480c6acc feat(libc): implement strsep
Split at the first delimiter like FreeBSD's strsep: empty fields are
returned, and the cursor becomes null after the last token.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 09:48:07 +09:00
Achraf ReyaniandClaude Opus 5.5 86db61ca30 feat(libc): implement rand_r
Share rand's generator step with rand_r, which advances the caller's
state instead of the global one, as FreeBSD's rand and rand_r share
do_rand.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 09:48:07 +09:00
hugodearaujoandClaude Opus 5.5 4c4e789a33 fix(libSceRudp): match the console's init and status checks
Measured on a PS5 (firmware 13.60):
- sceRudpInit rejects a null pool or a size of 0 or less with
  INVALID_ARGUMENT, and a pool under 0xC58 bytes or not 8-byte aligned
  with MEMORY (0x80770007).
- sceRudpGetStatus rejects a null pointer or a byte count of 0 or above
  0xF8 with INVALID_ARGUMENT and reports the live context count at 0x64.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 21:40:27 -03:00
Achraf ReyaniandClaude Opus 5.5 1191ed3eaa feat(libc): implement the hyperbolic functions
Export sinh, cosh, coshf, asinh, asinhf, acosh, acoshf and atanh,
forwarding to the C++ standard library like tanh and tanhf.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 09:38:33 +09:00
gookie 23a8b8b3d0 perf(agc): build the initial context registers once
InitialContextRegisters built the clear-state context registers on every
call: about 200 emplace calls from its list and loops, with the register
vectors growing several times on the way to offset 0x3b8. Each
QueueState starts from it, so it ran for every CLEAR_STATE, and
ResolveShaderAbi and ResolveGraphicsStagesAbi construct a QueueState on
each call, which sceAgcLinkShaders, sceAgcCreatePrimState and
sceAgcCreateInterpolantMapping make while a title draws.

The registers are now built once into a table that is never destroyed,
so a queue cleared while the process exits still finds it, and each call
returns a copy of the table.

A call takes 71 ns instead of 746 ns, and constructing a QueueState 885
ns instead of 1378 ns (200000 calls each, GCC 13 -O2). On the title
screen of PPSA21402 (Balatro) the two functions took 44 to 47 of about
2300 CPU samples per 10 s and no longer appear in the profile.
2026-10-11 02:33:14 +02:00
gookie 132715e4e2 perf(libSceNgs2.native): parse waveform files without reading their samples
sceNgs2ParseWaveformFile read everything from the offset to the end of
the file into a zero-filled buffer and parsed that, although parsing
uses only the RIFF chunk headers and the fmt, fact and smpl payloads.
A waveform at an offset in a sound bank cost a read of the rest of the
bank on each call.

ReadChunks now takes the bytes through an accessor. Waveform data passes
its buffer; a waveform file seeks to and reads the headers and those
payloads alone, with the same checks against the length from the offset
to the end of the file. The format dispatch both use moves to
ParseWaveform.

ngs2_parse adds a bank of two waveforms in one file, the second with a
chunk after its samples, and parses each at its offset.

PPSA21402 (Balatro) parses its five 33 MB music tracks at start: one
call took 8.3 to 26.7 ms and allocated 33 MB, and now takes 0.01 to
0.04 ms with the same result.
2026-10-11 02:29:13 +02:00
Adrià 06da117642 Merge pull request #3176 from adriadam10/carry/pthread-attr-setsolosched-np
feat(libkernel): implement pthread_attr_setsolosched_np
2026-10-11 02:24:45 +02:00
Adrià 343163a0c1 Merge pull request #3174 from adriadam10/carry/system-gesture-no-touch
fix(libSceSystemGesture): report no touch events for the primitive and recognizer calls
2026-10-11 02:22:43 +02:00
Adrià f1ae427b66 Merge pull request #1337 from TibixDev/pr/cmask-fast-clears
fix(agc): keep CMASK clears resident without host imports
2026-10-11 02:13:34 +02:00
Scott SchusterandClaude Opus 5.5 39fdc48b5f fix(agc): read unregistered graphics programs only while no shader is registered
An unregistered graphics program is read raw only while the shader registry
is empty; with shaders registered it throws, as before. A draw that uses a
raw program is noted, and RegisterShader throws once that has happened,
since a title that registers shaders after drawing unregistered programs is
not understood. The draw cache revalidates a raw program by reading it raw.

AI-assisted (Claude Code).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 19:12:14 -05:00
DavidandClaude Fable 5.1 064f5ca825 feat(libkernel): implement pthread_attr_setsolosched_np
The POSIX alias takes (attr, int), returns EINVAL (22) for a null or
uninitialized attribute like the other pthread_attr setters, and
stores the value through scePthreadAttrSetsolosched, returning its
result in errno form. The signature and the stored int follow the SCE
twin in KytyPS5 and sharpemu; PS5PCEM implements the alias the same
way. The value is not applied to scheduling, recorded in TechnicalDebt.

Returnal (PPSA01285 v03.000.005) stops on it after eager binding
(#2872, #1155):

    what(): pthread_attr_setsolosched_np_nid_postfix not implemented

LEGO Horizon Adventures (PPSA14632, #734) and Palworld (PPSA23126,
#2598) import it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-11 02:06:30 +02:00
Adrià FranchandClaude 894ef6db09 test(libSceSystemGesture): cover the handle and null checks of every recognizer call
Moves the no-touch line to "Silent stubs" and records the error-code disagreement with KytyPS5.

Co-Authored-By: Claude <[email protected]>
2026-10-11 02:04:04 +02:00
Adrià e8d6de4ae7 Merge pull request #1091 from kjhq/feat/libkernel-socket-events
feat(libkernel): implement read and write events for guest sockets
2026-10-11 02:02:31 +02:00
xXPBSXxandClaude Sonnet 5.5 4bf608565f fix(libSceSystemGesture): report no touch events for the primitive and recognizer calls
WIP: the TechnicalDebt entry for the silently successful calls is still missing.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-11 02:01:32 +02:00
Scott SchusterandClaude Opus 5.5 d1d1681bae fix(agc): drop a cached draw whose unregistered program was rewritten
The register draw key identifies an unregistered program only by its
address, and a key hit reuses the entry's decode without reading the
program again. A different program uploaded to the same address with
the same registers would run the old compiled shader. A hit now checks
the decode's unregistered programs against guest memory and drops the
entry when one changed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 19:00:20 -05:00
Scott SchusterandClaude Opus 5.5 7373ee1311 feat(agc): prepare unregistered graphics programs at first use
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 19:00:19 -05:00
Scott SchusterandClaude Opus 5.5 dddd9f29c2 test(agc): cover raw program snapshots and headerless vertex decode
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 18:59:28 -05:00
Scott SchusterandClaude Opus 5.5 767b8f83a2 feat(agc): accept graphics programs without an AGC shader header
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 18:59:28 -05:00
Adrià 2a38c0bd91 Merge pull request #3011 from MarcZX100/codex/prbatch-2988-cond-wait
fix(libkernel): return errors for waits with an unowned mutex
2026-10-11 01:59:12 +02:00