Commit Graph

4254 Commits

Author SHA1 Message Date
Dean bf6e25a1dd
Merge pull request #2830 from SleglJan/feat/libscessl-ca-list
feat(libSceSsl): implement sceSslGetCaList, sceSslFreeCaList and sceSslUnloadCert
2026-10-11 07:12:36 +13:00
Dean ec6383f9ab
Merge pull request #2824 from MarcZX100/codex/signal-sema-zero-count-2748
fix(libkernel): accept zero-count semaphore signals
2026-10-11 07:12:27 +13:00
Dean 077075d6c7
Merge pull request #2821 from MarcZX100/fix/relinker-windows-tls-reads-2761
fix(relinker): patch TLS reads after zero alignment padding
2026-10-11 07:12:19 +13:00
Lexroid 45a561aea5 fix(libkernel): accept a zero count in sceKernelSignalSema
sceKernelSignalSema threw invalid_argument for a count of 0. Marvel's
Wolverine (PPSA03671) signals with a count computed as min(a, b) - c,
which can be 0, and ignores the result, so the throw ended the title a
few minutes in. A zero count now adds no tokens and returns SCE_OK, as
in shadPS4 and Kyty. A null semaphore and a negative count still throw.

guest_kernel_errors signals 0 on a full and on an empty semaphore and
checks that the count is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 7191d34c4d79622ba71087f0da2b75eb81ad2c23)
2026-10-10 16:12:43 +00:00
AlxcBTW fccfbee72b fix(relinker): convert Windows guest TLS reads after zero alignment padding
The Windows TLS rewriter only patches FS-relative instructions that
CodeInstructionCollector decodes. Code that no symbol, unwind range or
root reaches is covered by a linear sweep that starts after int3 padding
and stops at the first instruction beginning with two zero bytes, so
zero-filled bytes are not read as code.

The .NET NativeAOT homebrew titles pad between functions with zero bytes
instead of int3 and have unwind entries for only part of their code. In
Prospero Vibrate (PPSA99920) the sweep ended at the padding after the
first function. Functions reached only through switch jump tables, which
the control-flow graph does not follow, or through pointers it cannot
resolve kept 105 of 670 FS loads unpatched: 84 `mov reg, fs:[0x28]`
stack-guard reads (65 into rax, 19 into rcx) and 21 `mov rax, fs:[0]`
thread-pointer reads. The title faulted reading address 0x28 within a
second of start.

The sweep now treats a zero run that follows a jump, call, return or
trap and ends at the next 16-byte boundary as alignment padding, and
continues at that boundary. A call counts because a function can end in
a call to a noreturn function. Zero fill after straight-line code, or a
whole zero 16-byte block, still ends the sweep as before.

All 670 FS loads in PPSA99920 are now patched, as are the 102 of 685 in
Prospero Explorer (PPSA99109) and the 103 of 718 in Prospero Multi Tools
(PPSA99110). New tls_function_coverage padding cases: loads behind zero
padding after a return, a call and a jump, with 13, 2, 1 and 5 zero
bytes, are patched; a load behind zero fill after a nop is left
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 0306c677784b6c4272990ce65f6daf9fb2dbc3ca)
2026-10-10 16:08:54 +00:00
Jan Šlégl 33184a1b33 feat(libSceSsl): implement sceSslGetCaList, sceSslFreeCaList and sceSslUnloadCert
PPSA11386 imports sceSslGetCaList and sceSslFreeCaList and PPSA15508
imports sceSslUnloadCert; on main all three are missing and the loaders of
both titles stop on them. No root certificate bundle is shipped and no
loaded certificate is kept, so an SSL context holds no certificates:
sceSslGetCaList clears the list and returns NOT_FOUND, as sceSslGetCaCerts
does; sceSslFreeCaList accepts only that cleared list; sceSslUnloadCert has
nothing to drop and is assumed to return 0. A null list returns the
invalid-argument code that sceSslGetCaCerts and KytyPS5 return. An unknown
context and a list sceSslGetCaList did not return throw, as their codes are
not confirmed. Signatures and the SceSslCaList layout follow SharpProspero
and shadPS4.

guest_ssl_tests now links libc, as guest_http2_tests does, so an exception
thrown from libSceSsl unwinds with the same unwinder that resumes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:01:23 +02:00
boykopovar 57f96fd2b3
Merge pull request #2808 from boykopovar/ci/pr-intake-min-10
ci(pr): set min intake pr count to 10
2026-10-10 18:40:02 +03:00
boykopovar f4b6e1011d ci(pr): set min intake pr count to 10 2026-10-10 18:37:56 +03:00
Dean ca349535f5
Merge pull request #2681 from oneandonlydean/up2/swept-buffer-staging
perf(agc): stage read and written buffer elements a dispatch sweeps
2026-10-11 04:36:15 +13:00
Dean de5e541d8f
Merge pull request #2673 from oneandonlydean/up2/image-dedupe
perf(agc): resolve a sampled element repeating the one before it to the same texture
2026-10-11 04:07:26 +13:00
Dean eb94c554da
Merge pull request #2672 from oneandonlydean/up2/image-memo
perf(agc): memoize decoded image descriptors and their texture cache entries
2026-10-11 04:07:17 +13:00
Dean Galvin 63fb5779b3 perf(agc): resolve a sampled element repeating the one before it to the same texture
A build's sampled image elements often repeat the element just before them
in plan order (the same eight descriptor words). Each still took its own
stage-A record (decode, collect, DCC key read, cache entry) and its own
stage-B lookup.

The lookups run in plan order and nothing runs between two consecutive ones,
so a repeated element's lookup would find the state the previous lookup just
left: the entry it validated or made, current against the same collect. Such
an element now binds the previous element's texture (when the depth-compare
flag matches too, which is part of the cache key), and stage A gives it a
record of the decoded descriptor only. An element repeating an earlier but
not the immediately preceding one still takes its own lookup, as does any
element after a storage image lookup.
2026-10-11 03:35:08 +13:00
Dean Galvin 0209c64245 perf(agc): memoize decoded image descriptors and their texture cache entries
A resource build decodes every image element's eight descriptor words,
describes the surface (a mip layout with a vector of levels) and finds the
sampled texture's cache entry by hashing its key, once in stage A and again
in stage B. Most elements repeat a small set of descriptors from build to
build.

Each worker now keeps a small direct-mapped memo by descriptor words of the
decoded resource, its guest size and view component mapping (pure functions
of the words) and of the cache entry the words last found. The entry is
reused only while the sampled texture cache has erased no entry since it
was found (an erase counter bumped by eraseTexture), so the list iterator is
still valid and still holds the same key; anything else takes the hash
lookup.
2026-10-11 03:35:08 +13:00
Dean 5edae35361
Merge pull request #2657 from oneandonlydean/up2/address-draw-key
perf(agc): skip the resource-cache key and lookup for address-based draws
2026-10-11 03:15:31 +13:00
Dean db343a934c
Merge pull request #2656 from oneandonlydean/up2/buffer-slabs
perf(agc): sub-allocate small host buffers from shared memory blocks
2026-10-11 02:59:36 +13:00
Dean 8b812318b4
Merge pull request #2683 from oneandonlydean/up2/refresh-proof
perf(agc): keep a storage image's refresh proof while nothing it read moved
2026-10-11 02:37:50 +13:00
Dean 808d8dc43a
Merge pull request #2691 from oneandonlydean/up2/parallel-snapshot-compare
perf(agc): compare large stale draw snapshots on helper threads
2026-10-11 02:35:16 +13:00
Dean 9526f0d739
Merge pull request #2685 from oneandonlydean/up2/stale-snapshot-patch
perf(agc): patch a stale storage snapshot's changed blocks in place
2026-10-11 02:34:59 +13:00
Dean e668748ce2
Merge pull request #2664 from oneandonlydean/up2/stale-snapshot-reuse
perf(agc): reuse a stale storage snapshot whose bytes are unchanged
2026-10-11 02:34:43 +13:00
boykopovar ba2a0a31ff
Merge pull request #2750 from rohankmr414/fix/videoout-output-status-with-vrr
fix(videoout): add throwing GetOutputStatusWithVrr export
2026-10-10 16:13:38 +03:00
boykopovar 78aedb40e2
Merge pull request #2708 from boykopovar/feat/strict-sce-module-search
feat(relinker): strict sce module search
2026-10-10 16:01:29 +03:00
Dean Galvin e8b43459a6 perf(agc): keep a storage image's refresh proof while nothing it read moved
Every draw into a resident target refreshes the target's storage image
(StorageTexture::Refresh): a pending-registry scan for an alias,
FlushPending over the surface, the collect, the key proof, a
whole-surface UnchangedSince, four vectors and a generation update over
every 64 KiB unit, nearly always finding the image current.

A refresh that finds the image current now keeps a proof: the image's
generation and uploaded keys, its key proof's generation and the pending
registry serial. The next refresh is answered from it when the image's
own state is still that, the surface and its key range are unstamped
since those generations (CollectWrites over both, then one
UnchangedSinceAll), and no other image has results pending over the
surface: the registry serial is unchanged, or the registry is scanned and
holds none (a newly pending image, a flush in progress). The proof is
taken only under GuestMemory::GpuMutex, without a pending alias, with
stable keys and when no other pending image overlaps the surface; any
full refresh drops it. A CPU write, a driver or GPU store, a key store,
another image's pending results or a different image therefore always
refresh in full, and the image's own pending results (a draw into it)
keep the proof.

agc_driver_recorder_tests refreshProofTests: an unchanged image and one
holding its own pending results are proved; a CPU write, a driver store
into the surface, a key store, another image's pending results, a new
image of the surface and a fast clear of the keys each refresh in full.
2026-10-11 01:57:32 +13:00
Dean bc2f128ea4
Merge pull request #2655 from oneandonlydean/up2/target-key-proof
perf(agc): prove a render target's register clear keys instead of scanning them every draw
2026-10-11 01:55:58 +13:00
Rohan K 179c9b6014 fix(videoout): add throwing output status with VRR export 2026-10-10 18:14:49 +05:30
Adrià b69270dd95
Merge pull request #2713 from adriadam10/feat/gpl-background-lto
perf(agc): relink library pipelines with link-time optimization in the background
2026-10-10 14:36:43 +02:00
Dean da7429f684
Merge pull request #2678 from oneandonlydean/up2/single-pass-storage
perf(agc): move storage texels between the image and its tiled bytes in one pass
2026-10-11 01:36:32 +13:00
boykopovar 0bd2e4cb90 test(relinker): align module tests with nonrecursive discovery 2026-10-10 15:31:17 +03:00
Adrià Franch 8e73f6e73e perf(agc): relink library pipelines with link-time optimization in the background
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-10 14:24:45 +02:00
Dean cf8b129e27
Merge pull request #2670 from oneandonlydean/up2/pass-hazards
perf(agc): continue render passes across draws without hazards
2026-10-11 01:18:14 +13:00
Adrià 197ffac972
Merge pull request #2661 from adriadam10/feat/fixed-push-slots
perf(agc): give each graphics stage a fixed push constant slot with pipeline libraries
2026-10-10 13:50:19 +02:00
boykopovar f756225f09 docs(usage): add sce-module-path optional flag 2026-10-10 14:38:04 +03:00
boykopovar 336d481bff fix(relinker): default module path to input elf directory 2026-10-10 14:12:04 +03:00
boykopovar bec6d62b29 feat(relinker): add explicit guest module parent path option 2026-10-10 14:10:13 +03:00
boykopovar 776f7738d4 fix(relinker): stop requiring host dependencies in guest module directories 2026-10-10 14:04:37 +03:00
boykopovar 400a496792 refactor(relinker): unify guest module diagnostics 2026-10-10 14:02:00 +03:00
Dean b5f5362d3d
Merge pull request #2647 from oneandonlydean/fix/guest-stack-host-margin
fix(libkernel): keep host stack room below guest thread stacks
2026-10-10 23:59:23 +13:00
boykopovar 41126bfa5b fix(relinker): restrict guest module discovery to adjacent directories 2026-10-10 13:59:11 +03:00
Dean Galvin db2cd3559e perf(agc): compare large stale draw snapshots on helper threads
A stale storage snapshot is revalidated by comparing every tracker block
stamped since it was taken. A title that binds buffers a dispatch writes
in place every frame (the whole declared range stamped, few pages really
changed) makes the graphics worker compare gigabytes per second.

Compares of 1 MiB or more are now split by block across a small pool of
helper threads (hardware threads / 8, from 1 to 4). The compare is memory
bound, so the worker's share roughly halves rather than dividing by the
thread count. A caller that finds the pool busy compares on its own
thread. Results and the patch-in-place rules are unchanged.

agc_driver_graphics_tests parallelCompareTests: per-span results on the
pool and serial paths, and two threads comparing at once.
2026-10-10 23:55:38 +13:00
Dean b0cccf20a0
Merge pull request #861 from jeffrey12cali/fix/linux-guest-arena
fix(guest-arena): place guest address space in the PS5 window on Linux
2026-10-10 23:55:28 +13:00
Dean Galvin 7c1b60c544 perf(agc): patch a stale storage snapshot's changed blocks in place
A stale storage snapshot was compared whole with the guest bytes and, on
any difference, copied whole into a new buffer, although few of the
tracker blocks stamped since the copy usually hold different bytes.

Only the 64 KiB tracker blocks stamped since the snapshot's generation
are compared now. When some differ and the cache holds the only
reference (no recorded draw binds the buffer), those blocks are copied
into it in place; otherwise the range is copied again as before.

agc_driver_recorder_tests drawSnapshotPatchTests: changed bytes in
several blocks and a whole changed block patch the snapshot nothing else
holds, an unchanged one is reused, and one a recorded draw still holds is
copied again with its bytes untouched.
2026-10-10 23:52:58 +13:00
Dean 2ba993a873
Merge pull request #1745 from AymanFE/fix/agc-hold-flip-behind-worker
Fix/agc hold flip behind worker
2026-10-10 23:52:07 +13:00
Dean Galvin 2688b76463 perf(agc): stage read and written buffer elements a dispatch sweeps
A written V# element bound in place in a host import makes every load a
PCIe round trip. A particle update that loads and stores a 10 MiB pool
(2048x64 threads over 131072 records of 80 bytes), above the 2 MiB written
window, took about 4.8 ms of GPU per frame.

An element the shader also reads (DescriptorBinding::bufferRead), written by
a direct dispatch whose threads times the V# stride cover at least half of
it, now takes device-local staging up to 16 MiB: that dispatch drops to
about 0.06 ms plus 0.9 ms of bulk copies. The coverage test keeps a kernel
that updates about 12k records of a 16 MiB pool in place, where staging all
of it would cost 1.3 ms of copies for a 0.08 ms kernel. Write-only
elements, indirect dispatches and raw (stride 0) buffers keep the 2 MiB
window.
2026-10-10 23:47:30 +13:00
Dean Galvin 25738ff67f perf(agc): move storage texels between the image and its tiled bytes in one pass
A storage write-back copied the image into a linear buffer and retiled
that buffer; an upload detiled into a linear buffer and copied it into
the image. With storage image access without a format, the retile now
reads each texel from the image through an unsigned integer view of the
element size, and the detile writes it there, so the linear buffer, its
copy and one barrier per move go away. The texels move bit for bit as
before, through the same tiling equations and windows.

This covers the block-unit windows of write-backs and uploads and the
whole-surface direct upload, for 2D, array and cube images.

agc_driver_recorder_tests singlePassTests: a first upload, a write-back
of new texels in every mip and a second upload over the stored memory
leave the images and guest memory byte for byte equal to the copies
through a linear buffer, in plain and write-watched memory.
2026-10-10 23:46:06 +13:00
Dean Galvin 2fb7a77acc feat(shader): note which guest buffer elements a shader loads from
DescriptorBinding gains bufferRead next to bufferWritten and bufferAtomic,
filled from the resource tracker's per-buffer read flag and kept in the
shader disk cache (format 24).
2026-10-10 23:45:38 +13:00
Dean 507f49fb33
Merge pull request #2669 from oneandonlydean/fix/windows-guest-read-refusal
fix(libkernel): read /dev/urandom through Windows pread again
2026-10-10 23:39:14 +13:00
Dean Galvin ecc14b0f66 perf(agc): continue render passes across draws without hazards
A recorded draw continued the open render pass only after a draw that
wrote no memory, so every draw with a storage write ended the pass and
paid two barriers. A draw now continues the open pass when its accesses
have no hazard (PassHazards) against those of the draws since the last
barrier. Address-based draws, draws through buffer device addresses and
draws with copied writes count as reading and writing any guest memory.

A draw of other attachments with no hazard ends the pass without a
barrier and begins its own without one, and a hazard break records the
begin barrier alone, towards every graphics stage, instead of the pass
end barrier plus the begin barrier. A pass with a depth attachment or
attachment proxies, or one followed by work after the pass, keeps both
barriers. APS5_FULL_BARRIERS keeps every barrier, as for the other merges.
2026-10-10 23:28:48 +13:00
Dean Galvin 0211ee7c73 feat(agc): render pass hazard tracker
PassHazards keeps the guest ranges, images and attachments the draws
since the last barrier read and wrote, and answers whether a new draw has
a RAW, WAW or WAR hazard against them. Address-based reads and unknown
writes count as touching any guest memory; attachments of the current
pass are ordered by rasterization and only conflict with other passes or
with sampled and storage uses. Unit tests in agc_pass_hazards.
2026-10-10 23:27:18 +13:00
Dean Galvin 766370108d fix(libkernel): read random devices in the Windows sceKernelPread
The Windows sceKernelPread stopped going through pread when it learned to
return errors, and with it lost the random device read, so a pread on
/dev/urandom reached ReadFile on a handle that is not a disk and failed
with ESPIPE. Read random devices first, as the Linux path does.

A pread into a read-only guest mapping now returns EFAULT instead of
throwing, matching Linux and the AIO read beside it, so the Windows
guest memory test checks for that return.
2026-10-10 23:26:37 +13:00
Adrià Franch 8c802e5eb1 perf(agc): give each graphics stage a fixed push constant slot with pipeline libraries
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-10 12:19:31 +02:00
Dean Galvin ce274b5c0a perf(agc): reuse a stale storage snapshot whose bytes are unchanged
A draw's storage snapshot was copied again whenever the write tracker
reported a store over its range, although most such stores leave the
bytes as they were: in one title screen about 10k of 14k stale lookups per
10 s held the same bytes (3.5 GiB of copies).

A stale storage snapshot is now compared with the guest bytes, after the
caller's collect of the range, before it is dropped. When they are equal
it takes that collect's generation and is reused; any store after the
collect is stamped newer and fails the next check, as for a fresh copy. A
registry change still drops it without reading, and vertex and index
snapshots are dropped as before.
2026-10-10 23:13:33 +13:00