Commit Graph

4249 Commits

Author SHA1 Message Date
MathiasDevelopes e8209307e9 feat(libSceAjm): implement sceAjmBatchJobDecodeSplit and sceAjmBatchJobSetResampleParametersEx
sceAjmBatchJobDecodeSplit queues a split run job with the stream
sideband, as sceAjmBatchJobDecode does for a single buffer pair.
sceAjmBatchJobSetResampleParametersEx with a zero ratio change per
sample sets the ratio as sceAjmBatchJobSetResampleParameters does; a
non-zero change throws, since its ramp is unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:24:54 +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
Dean Galvin fef67a4b21 perf(agc): prove a render target's register clear keys instead of scanning them every draw
materializeRegisterClear read the target's DCC keys with CurrentDccKeys on
every draw into a resident target with metadata: a full AllKeysEqual scan
of the key range (52 KiB for a 2432x1368 RGBA8 target), about 440k scans
per 10 s and 7.2% of the queue 0 worker's CPU time in one level.

ProvedCurrentDccKeys answers CurrentDccKeys from a proof kept with the
resident image (DccRangeProof: the key range, the keys and the write
generation collected before the scan), the rule ProvedClearKeys already
applies to a storage image's own keys: the proof holds while the key range
is unstamped since that generation (CollectWrites first, then
UnchangedSince), and a scan becomes the proof only when it read the bytes
(not the pending store memo) and no recorded work still writes them. Every
key writer stamps the range, so a store, a pending result or another key
range always scans again. The proof is used under GuestMemory::GpuMutex
only, and not with APS5_NO_KEY_FAST_PATH.

agc_driver_recorder_tests: an unchanged range is proved, and a key store
stamp, a CPU write, another range or address, and a pending key fill each
force a scan; the fill's result is proved once its batch finished.
2026-10-10 23:11:16 +13:00
Dean Galvin 765619a00b perf(agc): sub-allocate small host buffers from shared memory blocks
Every small host buffer (size classes below 1 MiB: draw and dispatch data,
copied regions, snapshots) had a VkDeviceMemory of its own. When the pool
missed, the worker paid a vkAllocateMemory and vkMapMemory, and the release
thread a vkUnmapMemory and vkFreeMemory, for each one. The frees also stall
the worker's vkQueueSubmit in the driver.

A host-visible buffer of a size class now gets its own VkBuffer bound into a
slot of a shared block (2 MiB, or 8 slots for the large classes) per memory
type, size class and device-address use, mapped once. Releasing it destroys
only the VkBuffer and returns the slot; a block is freed when it empties and
its slab already keeps an empty one. A slot is used only when the buffer's
alignment and the non-coherent atom divide its size class, so the slot
offset is valid for the bind and Invalidate covers exactly the slot. The
pool still retains released buffers by class as before; only what backs
them changed.
2026-10-10 23:05:21 +13:00
Dean Galvin 5d888abd75 fix(agc): wake the flip hold on worker progress
The hold no longer polls every millisecond and has no switch to turn it
off. A held submission waits on the driver's condition variable until no
flip is ahead of it, or until queue 0 waits for memory that only the
title can store. The queue 0 worker reports the second case from its
memory and rewind waits, and the worker that reaches a flip wakes the
holders.

agc_driver_flip_tests: a flip held behind a rendering wait is released
when the worker goes on to wait for a label only the title stores, with
no further submission.
2026-10-10 23:04:30 +13:00
Dean Galvin 2485915a03 perf(agc): skip the resource-cache key and lookup for address-based draws
A draw whose stages bind a BDA table or a fault buffer builds resources
that need completion work, so noteReusable never keeps them and the shared
resource cache never holds an entry such a draw could hit. Building the
content key and probing the cache for each of them was pure cost. Those
draws now skip both (ShaderResources::NeverReusable) and count as
uncacheable.
2026-10-10 23:02:52 +13:00
Adrià a29ef59219
Merge pull request #2645 from adriadam10/feat/gpl-dynamic-rendering
perf(agc): render with dynamic rendering when pipelines come from libraries
2026-10-10 12:00:40 +02:00