Commit Graph
14017 Commits
Author SHA1 Message Date
NikoandClaude Opus 5.5 83787e692a perf(agc): compare Windows direct imports only after a write-watch mark
On Windows every direct host import leaves the write watch, and a storage
image over it compares its whole surface with its guest-byte copy at every
collect epoch. #4432 measured 7-8.6 s of every 10 s in those compares on a
GTA V scene, with 98% of the compared surfaces unchanged.

Tracker blocks that leave the watch now keep their write-watch marks as a
hint. Leaving the watch gives a block a fresh hint stamp, and
UntrackedHint walks a range of such blocks, at most once per collect epoch
and thread, stamping the blocks whose pages a CPU store marked; it
returns the newest stamp of the range. compareUntracked puts that stamp in
its memo key in place of the collect epoch, so an image is compared again
after a mark in its range, a driver store, a mapping change or a recorded
GPU write. The byte compare still decides whether anything changed: a mark
the driver makes without a CPU store costs one compare and drops nothing.
Nothing else reads the hint. Collects, Watched, UnchangedSince,
ChangedBlocks and NewestStamp still treat those blocks as untracked, and
Linux is unchanged.

agc_driver_dcc_keys_first_write refreshes an imported storage image over
50 collect epochs with no store: it compared the image 50 times before and
0 times now. A CPU store is still uploaded on the next refresh, and a store
of the bytes already there costs one compare and keeps the pending
results. agc_write_tracking checks the hint itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 18:56:27 +13:00
Ondra97 46b96329e3 fix(relinker): reject invalid PNG icon chunk types 2026-10-14 07:53:01 +02:00
fogydes d41a3e65f6 test(relinker): suppress Windows error dialog in occupied base collision check 2026-10-14 11:18:46 +05:30
john.maiaandClaude Opus 5.5 9a1ac6a23d test(agc): run the queued write group tests in ctest
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 18:45:10 +13:00
john.maiaandClaude Opus 5.5 fce8aa8c7f fix(agc): keep stores after occlusion dumps after them in a queued run
A queued store run records each group's plain stores first and its
occlusion counter dumps after them. A store started a new group only
when it overlapped an earlier dump, so a label the title writes after
its dumps was recorded before them. A title that polls that label then
reads counters from before the dumps land. Any store after a dump now
starts a new group.

Epic Mickey: Rebrushed (PPSA15657) read stale or zero occlusion results
every other frame and left visible geometry undrawn on alternate frames.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 18:44:55 +13:00
fogydes 9dc2ce8acf fix(relinker): prevent address overflow and signed UB in CFG, GOT access, and entry point analysis 2026-10-14 11:14:34 +05:30
Dean f74ec639c4 Merge pull request #5428 from alfalfa-star/perf/agc-keep-address-space-read-overlap
perf(agc): keep the cached address space for a read-only V# across two imports
2026-10-14 18:42:58 +13:00
JAB-devandClaude Sonnet 5.5 19c55dc804 fix(libkernel): drop the unwind cache's freshness check and let a failed forget throw
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-14 07:41:54 +02:00
Sanxchep Sharma 94ae3f1bfe perf(relinker): stream scans and reuse executable buffers 2026-10-14 07:40:54 +02:00
NikoandClaude Opus 5.5 49de394787 test(agc): compare the copied compiled information with the moved one
The reused program hands out its compiled information through
IrProgram::CompiledInfo() const&, while compileVariant still moves it out
with TakeCompiledInfo(). The layout-pair fixtures are pixel shaders whose
user-data base, scratch size and parameter export mask are all zero, so
the comparison with isolated compiles could not tell whether the copy
kept those fields: a copy that zeroed them still passed.

Translate a compute program with a user-data base of 2 and 64 scratch
dwords and require the copied and the moved information to agree on
every field. Zeroing those fields in the copy now fails
agc_shader_layout_pair and agc_shader_layout_pair_off.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:44 +02:00
NikoandClaude Opus 5.5 60e564a31f test(agc): compare every artifact field of both registration layouts
The layout-pair check compared a subset of the prepared artifact: the
fragment parameters only by count, and not the barycentric emulation,
the runtime ABI version or the vertex interface fields. Its pixel fixture
also had no interpolated inputs, so the fragment parameter list was empty
on both sides.

Compare every artifact field except the variant id, the fragment
parameters element by element, and add a fifth configuration: registration
modules at the fragment slot offset with two interpolated inputs, which
must declare two fragment parameters in both layouts.

With this, flipping the barycentric emulation flag, a fragment parameter's
flat flag or the runtime ABI version on the reused path fails
agc_shader_layout_pair, where the previous check passed all three.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:44 +02:00
NikoandClaude Opus 5.5 010bfd7667 style(shader): name the emission-failure step's template parameter TStep
docs/dev/CONVENTIONS.md asks for C#-style template parameter names
(TKey, TValue). recordEmissionFailure, added with the split of variant
compilation, named its callable parameter Step; rename it to TStep and
write the template header the way the neighbouring recompiler sources do.

No behaviour change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:44 +02:00
NikoandClaude Opus 5.5 0d7b4b4bc6 test(agc): check both registration layouts against isolated compiles
Add a --layout-pair mode to agc_shader_memory_tests, registered as
agc_shader_layout_pair and agc_shader_layout_pair_off (the latter with
APS5_NO_PERF_LAYOUT_PAIR=1), next to the frontend-pair tests.

A pixel shader with a buffer load is prepared with a 128-byte push range
and with none through one context, in both orders: without registration
modules, with them at push offset 0 and at the fragment slot offset 128
that devices with graphics pipeline libraries use, and with a registration
word limit that forces the fallback to plain modules. Each pair must build
one program with reuse and two without, and each layout must match a
compile of the same code made on its own source without a context:
SPIR-V, binding layout, push range and push-data use, artifact fields and
compiled shader information. The materialized result must also match an
uncached Recompile.

The context must not reuse a program translated at another code address
or one built for another source at the same address, and it must release
the kept program when it builds another one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:44 +02:00
NikoandClaude Opus 5.5 558a8adfe9 perf(shader): emit both registration layouts of a pixel shader from one program
PrepareRegistered prepares every registered pixel shader twice: with the
plan's layout, then with pushConstantSizeBytes = 0. The layout is not part
of the source key, so both requests share one SourceEntry, but the first
variant consumes the entry's front-end program. On a cold cache the second
layout therefore ran PrepareResourceProgram again (translation, SSA, the
fold and eliminator passes, SrtWalker, ResourceTracker) and the interface
passes after it, although none of them reads the layout. Only decode, CFG
and structurization were shared through the context (#2526).

A ShaderPreparationContext now keeps the program it last emitted from,
after the interface step, together with its source entry. Another layout of
the same source at the same code address resets the binding allocation and
emits from that program, as the registration word-limit fallback already
does within one variant, and copies the compiled information out instead of
moving it. A different source or code address builds a program as before.
Building another program through the context releases the kept one first,
and the program dies with the context, so no program outlives the
registration that built it (the rule of #471). ResourcePrograms() counts
the programs built through a context.

Disk-cache loads and stores, the emission-failure memo and the variant
order are unchanged. APS5_NO_PERF_LAYOUT_PAIR=1 restores the previous path;
it is a neutral switch, so it does not change disk-cache keys.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:44 +02:00
NikoandClaude Opus 5.5 241ddda246 refactor(shader): split variant compilation into interface and emission steps
compileVariant ran the layout-independent interface passes
(ApplyStaticInterface, identity and dead-code removal, ShaderInfoCollector)
and the layout-dependent emission (binding allocation, SPIR-V emission, the
registration word-limit fallback, validation) as one step on a program it
consumed. Split it into prepareInterface and emitVariant, which take the
program by reference, and keep compileVariant as their composition with the
same emission-failure recording, so a later change can emit another layout
from a program whose interface is already prepared.

No behaviour change: compileVariant still runs both steps once per variant
and still moves the compiled information out of the program.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:35:20 +02:00
Rujul Talekar 7ef0931ffd fix(libkernel): answer pthread_getname_np for a joined thread with ESRCH 2026-10-14 10:59:48 +05:30
Dean 0b6d033b80 Merge pull request #5231 from fogydes/fix/relinker-call-site-address-bounds
fix(relinker): validate text section address bounds and avoid signed overflow in call-site targets
2026-10-14 18:27:21 +13:00
Dean fcd0ff8a21 Merge pull request #4935 from nicolasabosch/perf/agc-present-array-slice
perf(agc): present and keep pending only the drawn slice of an array color target
2026-10-14 18:27:08 +13:00
Rujul Talekar e41f7f292e fix(libkernel): answer a second scePthreadJoin with ESRCH 2026-10-14 10:57:05 +05:30
Dean 2958049b41 Merge pull request #4952 from Ondra97/codex/fix-relocation-symbol-bounds
fix(relinker): validate complete relocation symbol entries
2026-10-14 18:27:02 +13:00
JJenkx 48685f40e1 Merge remote-tracking branch 'origin/main' into fix/guest-declared-host-import-registry
# Conflicts:
#	docs/dev/debt/relinker.md
2026-10-14 01:25:14 -04:00
alfalfa-starandClaude Opus 5.5 040873f9dc feat(videoout): use native Wayland on Linux
Build SDL's Wayland backend next to X11 and ask SDL for "wayland,x11"
on Linux, so the window runs natively under a Wayland compositor instead
of through XWayland. SDL loads libwayland, xkbcommon and libdecor at run
time, so systems without them, or sessions without WAYLAND_DISPLAY, keep
using X11. SDL_VIDEODRIVER still overrides the choice.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:24:34 +02:00
alfalfa-starandClaude Opus 5.5 70389c09e9 test(npwebapi2): set a timeout on a created request
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:24:15 +02:00
alfalfa-starandClaude Opus 5.5 7505a8cf87 docs(npwebapi2): say why sceNpWebApi2SetRequestTimeout accepts any request id
shadPS4 looks the request up through its library and user contexts and
returns the matching NOT_FOUND error. This library keeps no request
table: CreateRequest hands out counter values and the other request calls
accept any id, so the checks wait for request tracking across all of
them. The entry moves to Silent stubs, as main's conventions check now
requires.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:24:03 +02:00
alfalfa-starandClaude Opus 5.5 c867b89a24 feat(npwebapi2): implement sceNpWebApi2SetRequestTimeout
The timeout setter takes (request id, timeout) and succeeds without
checking the request, like the other request setters: no request reaches
a service, so no timeout can expire. PPSA14632 imports it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 07:23:43 +02:00
Dean e46c695054 Merge pull request #5657 from oneandonlydean/fix/storage-save-at-unwatch
fix(agc): save the guest bytes of pending storage results when their range leaves the write watch
2026-10-14 18:23:11 +13:00
Rujul Talekar 39317d5b31 fix(tools): decode Ninja targets using its build-file encoding 2026-10-14 10:50:32 +05:30
Dean c9ee728a7c Merge pull request #3925 from eliasbruno124-dev/fix/http2-direct-wait
fix(http2): allow completion waits without an event queue
2026-10-14 18:19:42 +13:00
krishalivaibhav d50eed2df3 fix(memory): preserve process-owned services during exit 2026-10-14 07:18:19 +02:00
Dean e2cd213148 Merge pull request #5041 from mariobob/fix/param-json-number-libcxx
fix(kernel): build the param.json parser with libc++ before macOS 26
2026-10-14 18:17:25 +13:00
Dean Galvin fd2c300e46 fix(agc): drop the comments from the dissolve for a written V# over a copied read-only range 2026-10-14 18:16:22 +13:00
Dean Galvin 4e136dd323 fix(agc): decide the sparse dma-buf import before importing and throw after
A shared range larger than one chunk now takes the sparse path only when
the device binds sparse memory, udmabuf is open, the range's backing
offset is on the sparse block size, the sparse buffer accepts every
memory type a chunk import can have and the backing file covers the
last chunk. All of that is known before a chunk is imported. Once the
path is chosen, a failed chunk import, fence creation, bind, fence wait or device
address throws instead of going on to the whole-range udmabuf and copies.

agc_host_import_sparse checks the import against a mocked device with
the real udmabuf: a range above size_limit_mb becomes one sparse buffer
bound to one chunk import per 64 MiB, an unaligned backing offset
imports no chunk, and failures of UDMABUF_CREATE and vkQueueBindSparse
after the decision throw.
2026-10-14 18:16:17 +13:00
akkadbakkad89 975ed1213d feat(libkernel): count committed ranges in sceKernelGetPageTableStats
Charge each recorded protection ranges 2 MiB granules to the gpu
pool when the range has GPU-access protection bits and to the cpu
pool otherwise, so the available counts reflect committed usage
instead of staying at the 2048-entry budget. Follows KytyPS5s
counting model.
2026-10-14 05:14:20 +00:00
Dean ac35f596cc Merge pull request #5193 from 0xRickx/fix/libsceopusdec-narrowband
fix(libSceOpusDec): decode narrowband SILK packets
2026-10-14 18:12:32 +13:00
Dean d4efd33978 Merge pull request #4895 from fdfawef324/feat/agc-index-attributes-indirect
feat(agc): execute INDEX_ATTRIBUTES_INDIRECT (PM4 0x91)
2026-10-14 18:12:18 +13:00
Dean f5424b4db3 Merge pull request #4785 from krishalivaibhav/codex/netstat-with-memory
feat(net): implement memory-pool netstat diagnostic
2026-10-14 18:09:01 +13:00
Dean 9260767a06 Merge pull request #5471 from milescoviello/fix/shader-interp-p2-f16-high-half
fix(shader): decode the high-half result of v_interp_p2_f16
2026-10-14 18:05:04 +13:00
Dean 871f4ce8a0 Merge pull request #4693 from EagleBearerYS/fix/libc-windows-undeliverable-exception
fix(libc): report host C++ exceptions that Windows cannot deliver
2026-10-14 18:04:38 +13:00
Dean Galvin db4fd5f29c fix(agc): take the GPU lock when saving pending storage results before the range leaves the write watch
A draw made outside the GPU lock (agc_driver_recorded_kept_bytes) imports a target's memory and leaves the watch there; the hook threw instead of saving. It now takes the lock, as FlushPending does.
2026-10-14 18:04:20 +13:00
Dean 38b442dc6b Merge pull request #4652 from xXPBSXx/fix/avplayer-reset-clock-pause
fix(avplayer): resume the presentation clock when the source restarts after a pause
2026-10-14 18:04:10 +13:00
Evgeniy Kazarin 7ff22e76dc fix(tools): audit ELF modules with out-of-file section tables
Use program headers when the section table starts at or beyond EOF. Keep rejecting tables that start inside the file but are truncated.

Cover imports, exports, full module audits, and extended section counts.
2026-10-14 07:59:12 +03:00
Evgeniy Kazarin 7b6faf7dd2 fix(build): preserve UTF-8 shader cache source paths 2026-10-14 07:57:19 +03:00
MathiasDevelopes 8d89265c7a fix(agc): initialize stencil control and reference masks
(cherry picked from commit 85e0d98bba896002539365bb29a7a39a8e43f501)
2026-10-14 17:57:06 +13:00
codingreapermapsandClaude Opus 5.5 c8662b6bca fix(agc): accept alpha-to-coverage from a 32_AR MRT0 export without a color target
radeonsi exports MRT0 as 32_AR when alpha-to-coverage is on and no color
buffer is bound, so a depth-only draw can depend on that alpha. The
decoder now accepts 32_AR and an absent MRT0 target, and reads the MRT0
export format from SPI_SHADER_COL_FORMAT, which it masked to 0 for
draws without a color target.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 17:57:00 +13:00
NikoandClaude Opus 5.5 26a746a433 fix(shader): take the 32_AR export alpha from channel 1 as GFX10 does
A pixel export to an MRT whose SPI_SHADER_COL_FORMAT is 32_AR read its
alpha from export channel 3 (EN mask 0x9), the layout before GFX10. On
GFX10, which the PS5's gfx1013 is, the alpha is channel 1: Mesa's
emit_ps_color_export (ac_nir_lower_ps_late.c, index
gfx_level >= GFX10 ? 1 : 3), ACO and radeonsi in Mesa 22.0
(enabled_channels 0x3 with the alpha in channel 1) and LLPC's
FragmentColorExport.cpp (EXP_FORMAT_32_AR, exports[1]) all emit it
there. A console shader's `exp mrt0 v0, v1, off, off` therefore lost
its alpha: it stayed at the 1.0 default, so an alpha-only COLOR_32
ALT_REV target stored 1.0 and an R32 target blended with SRC_ALPHA
blended as if the alpha were 1. With channel 3 enabled, channel 3 was
taken instead.

ExportVector now reads channels 0 and 1 for 32_AR and puts channel 1
in the alpha component; channels 2 and 3 are ignored. The layout comes
from the compilers, not from a hardware measurement, and is recorded in
docs/dev/debt/shader.md.

agc_driver_pixel32_ar_export draws 32_AR exports with EN 0x3, 0xb and
0xf, as wave32 and wave64, into a COLOR_32 FLOAT ALT_REV target and a
COLOR_32 FLOAT target blended with SRC_ALPHA and ONE_MINUS_SRC_ALPHA,
and compares every stored value bit for bit. Without the fix every row
fails: the stored value uses an alpha of 1.0 or of channel 3.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 17:56:48 +13:00
Dean Galvin c58005374f fix(libkernel): name getdtablesize's throw with __func__ 2026-10-14 17:56:28 +13:00
hugodearaujoandClaude Opus 5.5 5894feff7e feat(agc): import shared ranges above 64 MiB as sparse buffers over udmabuf chunks
On Linux a shared-backed guest range is imported through one udmabuf
covering the whole range, and udmabuf refuses buffers above its
size_limit_mb (64 MiB by default). Larger ranges fell back to copies; an
address-based dispatch then synced its whole mirror, storing back every
pending storage image inside it each time.

Such a range is now one sparse buffer bound to the existing 64 MiB chunk
imports. The bind runs on a sparse binding queue of its own when the
device has one, so imports made at map time (without the GPU mutex) can
use it; otherwise only under the GPU mutex on the main queue.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 17:55:39 +13:00
Dean 75690a117e Merge pull request #4237 from MarcZX100/codex/carry-fixed-base-3043
fix(relinker): load Windows executables at a fixed low base
2026-10-14 17:49:45 +13:00
Dean Galvin e56a7c2351 fix(agc): save the guest bytes of pending storage results when their range leaves the write watch
On Windows, singly mapped direct memory is private since #5596, so its host
import is a direct import that leaves the write watch instead of a shared
alias that stays watched. A storage image whose results were pending when
its memory was imported had no saved guest bytes, and storing them threw.

GuestMemory now calls a hook before Unwatch and before an ImportWatched
that does not stay watched. Every image with results pending over the
range saves the guest bytes of its pending units that have none, then
collects and records the pieces the keep rule leaves to the CPU for the
writes the watch saw. The next store and Refresh leave those pieces to the
CPU and compare the rest with the saved bytes. A map-time import made
without the GPU lock is deferred to the locked retry when pending results
overlap the range.
2026-10-14 17:43:41 +13:00
Dean Galvin 3ddfc2395d test(agc): present slice 1 of an array image through the presentation pass 2026-10-14 17:41:55 +13:00