Commit Graph
12196 Commits
Author SHA1 Message Date
JAB-devandClaude Sonnet 5.5 a63e77e9fc fix(libSceSysmodule): report the region of the queried page from a cached unwind region
VirtualQuery describes the pages from the queried address to the end of the run of equal pages, so the reported seg0 begins at the queried page. The cached entry returned the first lookup's page for every later address in the run. It now returns the queried page and the bytes up to the end of the cached run, which is what VirtualQuery returns.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-15 22:08:20 +02:00
Ori ShamirandClaude Opus 5.5 f6fd60c6ca fix(libSceSaveData.native): write only the changed bytes of save-data memory
sceSaveDataSetSaveDataMemory2 read the whole slot file, patched it and
replaced it through a temporary file on every call, so each call cost a
full rewrite of the slot (up to 32 MiB). The changed ranges now go to a
small journal that is staged through the slot's temporary file and
renamed into place, then written into the slot file in place, and the
journal is removed. A journal left by an interrupted call is replayed by
the next setup, get, set or sync of that slot.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 22:43:50 +03:00
Jota a4e6e8b3b2 fix(tests): keep generic category vtable entries castable to functions 2026-10-15 16:42:52 -03:00
billybobpicklioandClaude Opus 5.5 a0347cfed5 feat(agc): draw line-strip output of NGG geometry programs as mesh lines
A geometry program with VGT_GS_OUT_PRIM_TYPE 1 was refused as an
unsupported output assembly. Each primitive export of an NGG line-strip
program is one line whose indices are packed like a triangle's, so the
mesh module now declares OutputLinesEXT with PrimitiveLineIndicesEXT for
it. A subgroup gets VGT_GS_MAX_VERT_OUT - 1 lines per input primitive and
at least GE_MAX_OUTPUT_PER_SUBGROUP line slots; fast launch keeps using
PRIM_AMP_FACTOR. The output size is part of the cache, draw, validation
and pipeline keys, and the request serialization version becomes 31.
Triangle-strip geometry is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 15:39:35 -04:00
JJenkx 7777219ee1 feat(libkernel): support cpuset affinity by guest thread ID 2026-10-15 15:25:34 -04:00
Get-fix 284fc6fd8c fix(relinker): treat DT_INIT_ARRAY without DT_INIT_ARRAYSZ as empty
The OpenOrbis create-fself drops a DT_INIT_ARRAYSZ of 0, so a PS4
program without constructors, such as the ClassiCube PS4 port, has
DT_INIT_ARRAY and no size. Code analysis rejected it with "incomplete
initializer array". FreeBSD 11.4's rtld takes the number of
initializers only from DT_INIT_ARRAYSZ and starts it at 0, so such an
array calls nothing; code analysis now adds no roots for it. A size
without an array still fails.
2026-10-15 22:21:28 +03:00
Yunus Shaikh 9c4bb70741 Merge branch 'perf/agc-host-import-aligned-blocks' into perf/agc-host-import-blocks 2026-10-15 12:12:29 -07:00
Muhammad Wasif Ali WasifandClaude Opus 5.5 7d9a308044 fix(nid): reject ELF exports that patch to different symbols under one name
Two defined ELF exports that are renamed to the same name, such as foo
and foo_nid_disambig1, were both written as one name and the patcher
exited 0, leaving a lookup that can reach only one of them. The PE and
Mach-O back ends already reject this.

The ELF patcher now remembers the address (st_value and st_shndx) of
each patched export name and throws "duplicate patched export name"
only when the name comes from a symbol at a different address. Aliases
of one address are kept: the Linux libc defines __cxa_throw and
__cxa_throw_nid_no_patch_cut as aliases of __cxa_throw_nid_postfix, so
both become __cxa_throw, and any lookup of that name resolves to the
same code.

The Linux libc also exported __gxx_personality_v0 twice at different
addresses: the forwarding function in Personality.cpp and the
__gxx_personality_v0_nid_no_patch_cut alias of the guest personality.
Drop that alias, so the name keeps only the forwarding function, as
in the PE build.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 00:08:27 +05:00
Scott SchusterandClaude Fable 5.1 244f41ed24 fix(agc): a relocation trial counts the hits the verification captured again
With APS5_VERIFY_DRAW_ENTRIES=1 every hit is captured again, so drawHit is false and no relocated hit counted for its shader set's trial, which judged every set unproductive and turned the relocation off under the very mode meant to check it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-15 14:06:44 -05:00
Yunus Shaikh 9c308c739b fix(agc): drop the expand import requester that no path uses
Expand named a DB expand's store, but nothing passes it: main has no DB
expand, and the open DB expand change stores its planes only where host
imports already hold them, through HostImportOverlaps and the storage
write-back, without making or retiring an import. The requester could
never count, so the shutdown line always ended with expand 0/0/0.

agc_driver_graphics checks the requester names and the shutdown report
without it.
2026-10-15 11:45:59 -07:00
AlxcBTW b82d688ed8 fix(agc): flush the log queue, bounded, where the process ends without exit handlers
Lines queued behind the logger were lost when the process ended through
abort(), std::terminate, the Windows crash report or a guest _Exit,
because only driver failure, Driver::stop and a normal exit flushed the
queue.

libc keeps one end flush (LibcSetEndFlush_nid_no_patch) and runs it from
those paths. Its first registration chains a SIGABRT handler in front of
the previous one, so every abort() and std::terminate in the process is
covered, on Linux as well; with the default disposition the handler
restores it and raises again, so raise(SIGABRT) still ends the process.
Guest abort() and _Exit, and ReportCrash for the first fatal exception,
run the flush directly. AsyncLog registers a bounded flush (FlushFor, 2 s)
that polls two counters and takes no lock, so a dying process cannot hang
on a blocked stream or on the queue lock; after its first timeout it
returns at once. Flush counts queued and finished entries instead of
watching the queue and the writer flag, so it waits for the lines queued
before the call and not for a moment in which no thread is logging.

agc_async_log_fatal runs the test executable as a child that queues lines
behind a held stream and ends in abort(), std::terminate(), raise(SIGABRT)
(POSIX) or an access violation (Windows), and once more with the stream
never released. The lines of the first four must arrive in order, the last
child must end after the bound, and every child has a watchdog.
agc_async_log gains the bounded flush case.
2026-10-15 20:42:16 +02:00
AlxcBTW 99ada24cc5 test(agc): Flush waits for a held stream and a full queue blocks the caller
Flush must not return while the logger still waits for a stream that
another thread holds (the regression reported on the pull request: it gave
up after two seconds), and a full queue must block its caller instead of
dropping a line. AsyncLog::Capacity becomes public so the test sizes its
load from it.
2026-10-15 20:42:16 +02:00
AlxcBTW 4e26472603 fix(agc): Flush waits until the logger has written every queued line 2026-10-15 20:42:16 +02:00
AlxcBTW ad85ed13ac perf(agc): format and write steady-state log lines off the queue worker
Texture creation logged one stdout line per texture and per mip through
WriteLogLine, which formatted with the mingw printf and flushed every
line on the queue worker (about 786k lines in a 25 minute cave run).

AsyncLog keeps a bounded queue and a logger thread. AGC_LOG_DEFERRED
captures numeric arguments on the caller and formats them on the logger
thread; WriteLogLine hands finished lines to a per-module sink in
libc/LogMacros.hpp that AgcDriver installs, so all AgcDriver stdout
lines keep their order and are written one flush per batch. A full queue
blocks the caller, so no line is dropped. Flush runs on driver failure,
shutdown and at exit. APS5_LOG_SYNC=1 restores the synchronous path.

Identical "deferred write-back failed" notes are printed three times per
10 s and then counted into one "repeated N more times" line. A
"[log] 10 s" line reports lines, bytes, caller time and logger time
(APS5_LOG_STATS=0 hides it).
2026-10-15 20:42:16 +02:00
javierUDP 6f100d3f61 test(relinker): execute the AMD64-only conversion stubs on macOS
The execution part of the AMD64-only converter tests was compiled for
Linux x86-64 only, so the SSE4A, SHA-1, SHA-256, CLZERO and reciprocal
stubs were never run on a macOS x86-64 build, unlike the ANDN lowering
tests. Rosetta maps no memory below 4 GiB, so the CLZERO case that needs
a 32-bit address is left out when that mapping is unavailable.
2026-10-15 15:40:26 -03:00
Codex ced0305455 fix(libkernel): return EINVAL for invalid mutex priority attributes 2026-10-15 21:34:35 +03:00
Adrià 44df216321 Merge pull request #5834 from xXPBSXx/fix/agc-register-default-owner-v2
fix(libSceAgcDriver): return 0 from sceAgcDriverRegisterDefaultOwner
2026-10-15 20:34:25 +02:00
Adrià e6134fd0d9 Merge pull request #5827 from hamb3r/perf/precise-wait-spin-tail
perf(libc): add sub-tick spin tail to PreciseSleepUs and PreciseSleepUntil
2026-10-15 20:34:20 +02:00
Adrià 048e61b897 Merge pull request #5815 from EagleBearerYS/fix/agc-space-owner-overlap
fix(agc): bind a read-only V# over the cached address space through the region that holds it
2026-10-15 20:34:16 +02:00
Adrià 15a60e1455 Merge pull request #5762 from AlexOfTheForest/fix/rosetta-legacy-compare
fix(relinker): move legacy CMPSS and CMPSD out of line for Rosetta
2026-10-15 20:34:12 +02:00
Adrià dee15e2ec6 Merge pull request #5810 from mohammad-alosta/fix/libSceNgs2-listener-transform
fix(libSceNgs2): support listener transforms in sceNgs2GeomCalcListener
2026-10-15 20:34:07 +02:00
Adrià c503db8d87 Merge pull request #5800 from fdfawef324/codex/frame-dump-io-best-effort
fix(agc): disable optional BMP dumps after host I/O failures
2026-10-15 20:32:15 +02:00
Anthony 2b567cda34 fix(libc): count wide collate string elements 2026-10-15 15:30:40 -03:00
ArjenS-LA 725ad5649c feat(libc): implement getopt_long_only 2026-10-15 11:27:50 -07:00
ArjenS-LA af691b717a feat(libc): implement overlap-safe bcopy 2026-10-15 11:27:49 -07:00
Sam c8bedff055 test(agc): check that lazy registration defers preparation
The lazy mode of agc_driver_prepared_shaders only checked dispatch output and failure reporting, which eager preparation also produces. Read the registered snapshot through Driver::RegisteredShaders: registration leaves it deferred with no prepared artifact, and the first dispatch prepares it.
2026-10-15 19:26:59 +01:00
Sam 96070188b9 perf(agc): allow shader preparation on first use
APS5_LAZY_SHADER_PREPARE=1 keeps registration validation and decoding but skips queueing the preparation. Draws and dispatches prepare a deferred snapshot on first use and cache it; explicit ABI resolution still prepares its stages. Titles that register thousands of shaders at boot no longer hold every prepared shader in memory before the first frame.

Cover lazy dispatch, metadata and failure cases in both asynchronous and synchronous modes.
2026-10-15 19:26:20 +01:00
Adrià b7cedd900d Merge pull request #5803 from YossiYad/fix/videodec2-avc-parameter-sets
fix(libSceVideodec2): hold an AVC unit of parameter sets for the next slice
2026-10-15 20:18:10 +02:00
JJenkx 4c2b12439f fix(audio-propagation): preserve existing destination mixes 2026-10-15 14:17:17 -04:00
ee6aba54 d6fe6551b2 fix(agc-driver): keep storage images with pending results out of the memory release
Storing a storage image's pending results needs a staging buffer, and under memory pressure that buffer comes from the heap whose allocation just failed. The release turned to dirty images once the clean ones did not cover the request, so with the device and shared heaps full it failed on a 4 MiB write-back buffer at every call (PPSA26344 on Windows). StorageTexture::Flush clears the pending state before it stores, so each failed store also dropped that image's results. The release now takes only sampled entries and storage images without pending results, and its line reports how many images with pending results it kept.
2026-10-15 20:13:28 +02:00
AlxcBTW c0588d2747 fix(agc): write copied buffers back before reporting an unaligned BDA access
WriteBackBuffers threw the fault before guestMemory.WriteBack(), so a
dispatch that recorded an unaligned BDA access lost the stores of its
other invocations, although the shader only skips that access. The
write-back now happens first and the report follows. A fault of any
other kind still fails the command before anything is published.
2026-10-15 20:06:02 +02:00
AlxcBTW 0f0197c16d fix(agc): rate-limit the deferred report of an unaligned BDA access
A shader that records an unaligned BDA access on every dispatch formatted
and printed one line per completion. CheckFault now throws
BdaUnalignedAccess for that fault, and the recorder prints the first 8
deferred reports of it whole, then every 1024th with the count. Every
other deferred failure is still printed each time.
2026-10-15 20:02:38 +02:00
Get-fix 8c34587598 fix(relinker): search libc.prx for libkernel-only Windows executables
AnyPS5 exports some libkernel functions, such as __error, from
libc.prx, which libkernel.prx links. On Linux they resolve through that
dependency. On Windows, the import stubs search only the listed
modules, and libc.prx was listed only when libSceLibcInternal.prx was
needed. A PS4 homebrew that needs libkernel.prx but no C library (the
OpenOrbis graphics sample) failed with "unresolved ELF import
9BcDykPmo1I". libc.prx is now also listed when libkernel.prx is needed.
PS5 executables need libSceLibcInternal.prx and convert unchanged.
2026-10-15 21:02:31 +03:00
Yunus Shaikh f036140f3a Merge branch 'perf/agc-host-import-aligned-blocks' into perf/agc-host-import-blocks 2026-10-15 10:57:55 -07:00
Yunus Shaikh 57ceb9e370 fix(agc): keep the guest's sample order where pixel (0,0)'s locations stand in for a 2x2 grid
Village's 2x checkerboard puts its two samples at x = +4/16 and -4/16
and swaps their indices on odd rows. On a device without a 2x2 sample
location grid every pixel takes pixel (0,0)'s locations, so the odd
rows hold the console's sample 1 in sample 0 and the reverse: a pass
that reads the samples by index, as checkerboard reconstruction does,
exchanges the two half-pixels of every odd row, and SampleID, sample
masks and exported coverage name the wrong samples there.

Such a pattern holds one set of positions in every pixel, so drawing
with pixel (0,0)'s locations is exact up to the order of each pixel's
samples. The draw now keeps the guest's order: the pixel shader reads
SampleID, applies the sample mask and exports coverage through each
pixel's order, and every render pass drawing with the stand-in puts the
samples of its multisampled attachments in the stand-in's order before
it and back in the guest's after it. Color targets do that through a
storage view of their texels as unsigned integers, depth through a copy
and a per-sample pass writing FragDepth, and stencil through
VK_EXT_shader_stencil_export or one pass per bit.

It needs shaderStorageImageMultisample with a storage view of the color
format, sampleRateShading, and a depth format FragDepth writes back
exactly (16-bit or 32-bit float); otherwise, and for patterns whose
pixels hold different positions, the stand-in alone is used, and the
log line says why. Devices with the grid are unchanged.

Recompile requests carry the order as serialization version 32 (#6470
takes 31), and the shader cache format becomes 40 (open pull requests
take 37 and 39).
2026-10-15 17:53:11 +00:00
RickandClaude Opus 5.5 6c5686d7ea feat(libSceImeDialog): take the dialog's text from the host keyboard
sceImeDialogInit wrote "Slayer" into an empty text buffer and the
dialog finished on the second status poll, so a title never got text
from the user: ProsperoRadio's search typed "Slayer" by itself and
found no station.

The dialog now runs until the user answers on the host keyboard, the
way #4756 made sceImeOpen's panel-less IME take it. While no IME panel
is open, libSceIme hands the game window's text and editing keys to
a sink that the dialog registers. Typing edits the text up to
maxTextLength without splitting a surrogate pair, Enter writes it to
the title's buffer and finishes with end status 0, and Escape finishes
with 1. Abort still finishes with 2. A second Init reports busy, and a
null parameter or buffer or a maximum length outside 1 to 2048 is
refused, as in shadPS4.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 19:52:28 +02:00
winstrexandClaude Opus 5.5 f81fb317dd perf(agc): match the dword pattern-fill kernel with its two compares in either order
MatchDwordPatternFill took the 69-word pattern-fill kernel only word for
word. Hades (PPSA03355) runs the same kernel with words 27 to 29 in the
other order: the SDWA v_cmp that writes s12 (0x7d8c02f9 0x06068c02)
comes before the v_cmp that writes vcc_lo (0x7d860609). Neither compare
reads what the other writes, so both orders compute the same fill.
The matcher now takes either order; every other word and every
user-data and packet condition is unchanged.

The test runs both orders through the matcher and through Submit, flips
each word of the swapped kernel, refuses the other orders of those three
words, and is registered a second time with
APS5_NO_FILL_HLE=1 so the translated kernel must give the same bytes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 14:40:16 -03:00
Yunus Shaikh b8a33ab7ff test(agc): register the write-back block test apart from the split write-back test
Its registration and its command-line option followed the split write-back test's, where another open pull request adds its own. They now follow the copied-direct ordering and CMASK tests. No test changes.
2026-10-15 10:36:21 -07:00
Ondra97 1fee29b6ad fix(libSceNet): inherit nonblocking mode on accepted sockets 2026-10-15 19:29:41 +02:00
Yunus Shaikh 3ba5574dc4 Merge upstream main into perf/shader-image-table-reuse-v3-pr 2026-10-15 10:29:25 -07:00
Zinebyte 5c378ece37 fix(relinker): preserve weak imports in macOS guest modules 2026-10-15 13:25:46 -04:00
Adrià 03c4cb5e78 Merge pull request #5791 from Ondra97/codex/fix-draw-mesh-index-cache
fix(agc): validate mesh index descriptors on cached draws
2026-10-15 19:25:11 +02:00
Adrià 3bb409b603 Merge pull request #5784 from gguerra26/fix/macos-m1-andn
fix(relinker): lower ANDN in Rosetta conversion
2026-10-15 19:25:06 +02:00
notaxeltvandCursor 511db2e8ff feat(libc): export locale::classic for the C locale
Absent PPSA34015 import; return a stable facade over the classic _Locimp.

Co-authored-by: Cursor <[email protected]>
2026-10-15 18:57:39 +02:00
Alex ColliniandClaude Opus 5.5 49919d7f32 fix(agc): drop resource-cache entries that hold released sampled textures
A resource-cache entry keeps every sampled texture of its descriptor sets alive. The sampled texture cache passes over textures something else holds and, past its ceiling, drops them anyway; textures it makes without caching are never in it. Entries holding either kept them alive with no budget counting them, bounded only by the 1,024-entry and 65,536-element counts, until device memory ran out.

The texture cache now marks such textures released. ResourceCache::Insert refuses descriptor sets holding one and hands the entries that hold one back to the caller, like RemoveImage does for evicted storage images.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 18:56:30 +02:00
milescovielloandClaude Opus 5.5 92f170c673 fix(agc): treat a view past a depth surface's first level as memory
A depth surface is one level: the driver rejects draws that render a
depth mip. A sampled or storage view at the surface's address and extent
that starts at a later level, or a storage access to a later level, does
not touch that level, so it is not the depth plane. DepthSurfaceTexture
and DepthSurfaceStorage still sent such views to the surface, which
rejected the level. Forspoken (PPSA03984) builds a depth pyramid from its
1984x1116 D32 depth surface with a compute shader that samples one level
of a five-level R32F view and stores the next, and stopped there.

Both now leave such views to the texture and storage caches, as they
already do for a view of another extent or format.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 16:55:31 +00:00
milescovielloandClaude Opus 5.5 4cdd2f4834 fix(agc): accept a copy's sample selection on a draw that copies nothing
DB_RENDER_CONTROL.COPY_CENTROID and COPY_SAMPLE select the sample that
DEPTH_COPY or STENCIL_COPY copies. Forspoken (PPSA03984) draws with
DB_RENDER_CONTROL 0xc0, DEPTH_COMPRESS_DISABLE and COPY_CENTROID with
neither copy bit set, and stopped at 43 s because both
DepthMaintenanceRejection and decodeDepth took the selection for a copy.

Accept the selection fields when no copy is enabled; draws that copy are
still rejected.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 16:54:42 +00:00
Adrià fa9365ca74 Merge pull request #5781 from moong15/fix/agc-sample-stencil-as-unorm
fix(agc): sample a depth surface's stencil plane through an R8_UNORM view
2026-10-15 18:50:41 +02:00
Adrià 2cefed5499 Merge pull request #5778 from meh7an/fix/agc-buffer-range-limit-by-mapped-memory
fix(agc): bind a V# past the range limit by the memory behind it
2026-10-15 18:50:36 +02:00
Adrià e2bcee655d Merge pull request #5776 from simonbronk/fix/convert-keycode-state-bit
fix(libSceConvertKeycode): ignore the state bit 0x4000000 RE Engine titles pass
2026-10-15 18:50:01 +02:00