Commit Graph
12196 Commits
Author SHA1 Message Date
Gjon Gojcevic 7c19c66def fix(shader): fold texel offsets into base-level unnormalized samples
An implicit-LOD or gradient sample with a texel offset through an
unnormalized S# was refused at bind time with "unnormalized guest sampler
is used by an implicit-LOD sample". PPSA01317 aborts on boot on such a
pixel image_sample_o. The base-level path already samples these through
OpImageSampleExplicitLod with LOD 0, which Vulkan allows for unnormalized
samplers, but it dropped the offset. It now adds the offset to the
coordinates in that branch, as the explicit-LOD offset fold does, so a
sampler whose uses also include offsets takes the base-level path. A
normalized S# keeps the offset operand.

AI-assisted: yes
2026-10-17 14:43:23 -04:00
milescovielloandClaude Opus 5.5 24ec391c06 fix(relinker): keep a segment's zero-filled tail zero when the next PT_LOAD starts on its page
On Linux the kernel maps each PT_LOAD from the start of its first page.
When a segment begins inside the page that holds the end of the previous
segment's zero-filled memory, that page is mapped again from the file, and
the bss tail reads whatever bytes precede the segment in the file. Nuvio
Max'd 0.5.27 (PPSA99288) keeps a mutex there and crashes at launch.

A segment whose page would read wrong bytes is now appended to the output
with that page prefix rebuilt from the segments below it. Outputs whose
pages already read right are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:41:25 +00:00
milescovielloandClaude Opus 5.5 7e061035b9 perf(shader): declare the read-only descriptor tables NonWritable
The flattened SRT, the BDA page table and the image table map are filled
by the host and only loaded by the shader, but they were declared as
writable storage buffers. A program that also stores through device
addresses then gives the driver no way to know those loads are not
aliased by its stores, so every descriptor read stays a separate load.
Crimson Desert's largest compute program reads the flattened SRT 12,362
times; with the decoration NVIDIA 595.99 creates its pipeline in 90 s
with a 4.3 GiB peak, against 200 s and 10.6 GiB.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:41:24 +00:00
Nithishvelan M aaba312e6d feat(libSceNetCtl): support NET_CTL_INFO_HTTP_PROXY_PORT and validate null in sceNetCtlGetNatInfo 2026-10-18 00:06:43 +05:30
milescovielloandClaude Opus 5.5 3d44f17eca fix(agc): treat an inverted scissor rectangle as empty
A scissor whose top-left corner lies past its bottom-right corner passes
no pixels; RADV writes such a viewport scissor whenever a viewport lies
outside the application's scissor, and radeonsi encodes its empty GFX12
scissor that way. PSSwanStation (PPSA99248) draws through one and
stopped on the throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:33:19 +00:00
milescovielloandClaude Opus 5.5 8b81fa09bf fix(libSceNet): close a libkernel socket through sceNetSocketClose
MXGP 26 (PPSA30839) opens TCP sockets with libkernel's socket() and
later closes them with sceNetSocketClose. libSceNet only looked in its
own socket table, so every one of those closes failed with
SCE_NET_ERROR_EBADF and the host socket stayed open. On the console both
calls work on the same kernel sockets.

A descriptor libSceNet does not own but libkernel has open as a socket
is now closed through libkernel's close(). Anything else still fails
with EBADF. The fallback runs after g_mutex is released, because
libkernel's close() first asks libSceNet's socket closer, which takes it.

guest_sce_net closes a libkernel TCP socket with sceNetSocketClose,
checks that libkernel no longer has it open, and checks that a second
close fails with EBADF.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:31:38 +00:00
milescovielloandClaude Opus 5.5 a7c68a3919 fix(libSceLibcInternal): fail posix_spawn with ENOENT when the program is not there
Dusklight (PPSA99305) aborts on main as soon as its Select disc image
item is chosen: SDL's file dialog probes "zenity --version" through
posix_spawnp, and posix_spawnp throws "process creation not implemented".

FreeBSD 11.4's posix_spawn returns the error of the child's exec, and
an exec of a program that is in no directory of PATH (_PATH_DEFPATH
when PATH is unset) fails with ENOENT. Both calls now return ENOENT
without writing the process ID when the program is not in the guest
file system, and keep throwing when it is. SDL then reports the file
dialog as unsupported and the title stays on its menu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:31:37 +00:00
milescovielloandClaude Opus 5.5 6025f00504 feat(libc): implement telldir and seekdir
Link's Awakening for PS5 (PPSA99670) imports both and does not load
without them. They wrap the host directory stream that opendir
already holds, under the stream's lock.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:31:37 +00:00
milescovielloandClaude Opus 5.5 18cf27aaba fix(libc): allocate the getifaddrs list on the application heap
FreeBSD's freeifaddrs is a plain free of the list, and Doom 3 BFG
(PPSA99313) releases the list with free. The list came from host malloc,
so the guest free stopped on an unregistered allocation; it now comes
from the application heap, and freeifaddrs returns it there.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 18:31:36 +00:00
Nithishvelan M 39c430bd48 fix(libSceSystemGesture): validate gesture handle and recognizer in sceSystemGestureGetTouchEventByIndex 2026-10-18 00:01:22 +05:30
Gjon Gojcevic 448ccee76a perf(agc): read DCC keys behind a pattern fill kernel's fast clear without a wait
A 64-thread compute kernel (23 dwords) stores pattern[i % 4], the pattern
in s4..s7, to dword i of a 4-byte-stride buffer for every i below
min(launched threads, s8, num_records), with the group id in s9.
PPSA01317 fast-clears its render-target DCC keys with it every frame. As a
plain dispatch its writes had no known value, so every key read of those
targets waited for the GPU under the GPU mutex.

The dispatch still runs as before. When it stores one repeated key code,
its keys are noted in the key-store memo right after the dispatch is
recorded, as a buffer fill of keys already is; the memo answers only while
the dispatch's own write note is the newest over the range, so any later
writer still makes the read wait. The key codes come from KeysFillMemo, as
for the memory-value fill kernel.

AI-assisted: yes
2026-10-17 14:28:47 -04:00
Nithishvelan M 9518b73656 fix(libSceSaveDataDialog.native): return NOT_RUNNING from progress bar updates when not running 2026-10-17 23:56:59 +05:30
Romans Pokrovskis bf8556f8e7 test(agc): classify native clear import skips 2026-10-17 21:25:34 +03:00
Romans Pokrovskis 9efdc59ef1 test(agc): exercise a full native depth clear through BDA 2026-10-17 21:24:39 +03:00
Eli Yarson 90fbcba2c4 test(libc): take the overcommit skip only under mode 1 2026-10-17 15:22:36 -03:00
Nithishvelan M 5a1039bbc1 feat(libSceVoiceQoS): implement sceVoiceQoSSetRemoteEndpointAttribute 2026-10-17 23:51:50 +05:30
Gjon Gojcevic 4aaf276999 fix(recompiler): give a dynamic-mip storage image a slot for every level
A dynamic-mip storage image reserved four mip slots, so a compute shader
whose T# spans more levels failed with "runtime storage image mip capacity
exceeded". PPSA01317 hits it on boot with a 512x512 surface of ten levels
and aborts. An RDNA T# addresses at most sixteen levels (4-bit BASE_LEVEL
and LAST_LEVEL), so a dynamic-mip image now reserves sixteen slots, and a
typed storage heap holds 64 elements so four such images still share one
class. Heap arrays keep their compact length. The runtime ABI goes to 14,
so existing shader caches are invalidated.

AI-assisted: yes
2026-10-17 14:14:22 -04:00
Nicolas FalesyandClaude Opus 5.5 1ffffc318d feat(libkernel): export nmount
Prospero Themes (PPSA90210) imports nmount (3YnXspQNyw8) from libkernel
and fails to load without it:
"./app.elf: symbol lookup error: ./app.elf: undefined symbol: 3YnXspQNyw8".

Mounting file systems is not supported, so it throws if called, like
execvp does for executable replacement. The title opens its theme
library without calling it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Sovthwyu4H63RMbRVha2Sy
2026-10-17 14:08:53 -04:00
JJenkx b17406a33a fix(ngs2): return PS5 errors for invalid voice handles 2026-10-17 14:07:44 -04:00
Nicolas FalesyandClaude Opus 5.5 05b457d49a feat(libkernel): implement pthread_condattr_setpshared
PSFlyCast (PPSA99247) imports pthread_condattr_setpshared (3BpP850hBT4)
from libkernel and fails to load without it:
"./app.elf: symbol lookup error: ./app.elf: undefined symbol: 3BpP850hBT4".

The attribute stores PTHREAD_PROCESS_PRIVATE (0) or
PTHREAD_PROCESS_SHARED (1); a null or uninitialized attribute and any
other value return EINVAL without changing it, following FreeBSD 11
libthr thr_condattr.c and pthread_mutexattr_setpshared here. Sharing
across processes is not modeled, as for mutexes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Sovthwyu4H63RMbRVha2Sy
2026-10-17 14:06:11 -04:00
hugodearaujo 52c4589f83 test(agc): check the unaligned import's lead only for a dma-buf import
A device that imports shared memory through host pointers, such as lavapipe, imports the unaligned range that way, and a host-pointer import has no lead.
2026-10-17 15:03:33 -03:00
hugodearaujo 9eb7e2444f fix(agc): publish unit shadows at an import's lead
A unit shadow published its units into the import's buffer at the guest offset from the import's
base, without the import's lead, so a sparse import that starts below its range (HostImport::lead)
got the units lead bytes before their place. The shadow keeps the lead with the import's base and
buffer, and the shadow verify reads the guest bytes at the same place.

agc_driver_sparse_dma_buf_import publishes a unit shadow of its unaligned import and checks the
unit's guest bytes and the bytes around it; without the lead it fails there.
2026-10-17 15:03:33 -03:00
hugodearaujo ef622e2f8f feat(agc): import shared ranges whose backing offset is not 64 KiB aligned
A sparse import binds whole 64 KiB blocks, so a range whose memfd offset
is not a multiple of 64 KiB fell back to one UDMABUF_CREATE and, above
udmabuf's size limit, to copies. The sparse buffer now starts at the
block below the range: HostImport::lead holds that distance, the
import's device address points at the range itself, and every offset
into the import's buffer goes through HostImportOffset.
2026-10-17 15:03:33 -03:00
Adrià 07b4651142 Merge pull request #6104 from fma-rc/fix/libc-host-libstdcxx-exceptions
fix(libc): catch exceptions that libstdc++ throws inside the prx libraries on Linux
2026-10-17 19:59:41 +02:00
jagrat Singh 586028c991 feat(libSceVoice): implement sceVoiceGetResourceInfo 2026-10-17 23:26:26 +05:30
AlxcBTW 5da6de62ad fix(agc): count stage-A drops of a dispatch move as refusals
The [dispmove] line printed refused 0 next to a rebuild count that came mostly from PrepareDispatch dropping the hit. The line now reports the refusals at stage A and at record separately, each with its reasons.
2026-10-17 19:32:05 +02:00
Gjon Gojcevic 88642b874f fix(shader): declare the 64-bit integer type only for programs with BDA anchors
EmitBdaAnchors declared the u64 type before checking for anchors, so every
program got a 64-bit integer type, and programs without the Int64 capability
failed SPIR-V validation. It now returns before declaring anything when the
program has no anchors. A compute program without BDA reads is checked to
declare no 64-bit integer type and no Int64 capability.

AI-assisted: yes
2026-10-17 13:05:25 -04:00
milescovielloandClaude Opus 5.5 227d1e44a1 perf(shader): fold a select nested in a select on the same condition
select(c, a, select(c, b, d)) is select(c, a, d), and
select(c, select(c, a, b), d) is select(c, a, d). The recompiler leaves
these behind when a register is written more than once under the same
lane mask and when the f32 NaN selection tests the same source twice,
and nothing folded them. The constant folder now takes the inner arm
the outer condition already decides, then folds a select whose arms
became equal.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 17:03:09 +00:00
thuanquangandClaude Opus 5.5 20502c0022 feat(agc): render 5_6_5 UNORM color targets
Goosebumps Terror in Little Creek (PPSA27305) aborts in gameplay with
"unsupported color format 16 number type 0 component swap 2": it renders
into a COLOR_5_6_5 UNORM target. The target now renders into
R5G6B5_UNORM_PACK16. AMD keeps X in bits 0-4 and Z in bits 11-15, and
Mesa's ac_translate_colorswap programs SWAP_STD_REV for a surface with
red in bits 11-15, so with SWAP_STD_REV the exports are written as they
are and with SWAP_STD they are written with X and Z exchanged, as for
1_5_5_5. The alternate swaps and other number types keep throwing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 23:59:26 +07:00
Dextroid17 9d12efa1c6 test(libkernel): stagger the leaving-thread raise by the clock, not by yields 2026-10-17 12:53:05 -04:00
SandstromPLandClaude Opus 5.5 3dadf77121 fix(agc): draw a one-sample depth target under a multisampled rasterizer without MSAA_ENABLE as one sample
With #6014 merged, the first draw of METAL GEAR SOLID: Peace Walker's
(PPSA18216) opening movie stops on "the depth target's sample count
differs from the rasterizer's" (mrfelek on #6196). The state he reported
is a 4x PA_SC_AA_CONFIG, MSAA_ENABLE clear, a one-sample 1440x810 depth
target and no color target; on main alone it throws earlier, on "a depth
target". Like the one-sample color targets of bb877791a, such
a depth target, with or without one-sample color targets, is now drawn
as a one-sample draw at the pixel center, before the multisampled-target
check and instead of the sample-0 path, which needs MSAA_ENABLE.

Points, lines, alpha-to-coverage, a sample-mask export and DB_EQAA Z
interpolation or overrasterization throw on this path, and so do
PS_ITER_SAMPLE and ANCILLARY or SAMPLE_COVERAGE pixel inputs when the
pixel program runs. A skipped pixel program is replaced by the null
program, which uses neither.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 22:18:56 +05:30
simonbronk f0d68fb436 fix(libc): reject null secure scan destinations
Prevent reached null conversion destinations from crashing sscanf_s and vsscanf_s. Return EOF before writes and retain earlier assignments. Add regression coverage through both guest ABI entry points.

AI-assisted: yes (OpenAI Codex). Windows WinLibs GCC 15.2 Release: production baseline crashes with the new regression; fixed shared libc passes guest_scan_count, guest_formatting, guest_wide_formatting and guest_strings (4/4). Conventions pass. Full all-target build was deliberately stopped after 83s with 3691 pending targets, not completed. No title or console run; constraint-handler invocation remains unimplemented as documented. No performance or coverage-percentage claim.
2026-10-17 18:46:36 +02:00
unknown 7c71fc603a fix(libSceHttp): make URI escaping independent of host locale 2026-10-17 18:46:12 +02:00
alosta 14db22d458 test(libSceRudp): add GuestRudpContextLifecycle behavioral tests
Adds tests for nine implemented libSceRudp functions that previously
lacked coverage:

- sceRudpActivate (returns 0 always)
- sceRudpEnableInternalIOThread (NOT_INITIALIZED before init, 0 after)
- sceRudpSetEventHandler (returns 0)
- sceRudpBind (NOT_INITIALIZED, INVALID_CONTEXT_ID, 0 on success)
- sceRudpSetOption (NOT_INITIALIZED, INVALID_CONTEXT_ID, 0 on success)
- sceRudpInitiate (NOT_INITIALIZED, INVALID_CONTEXT_ID, CONN_REFUSED)
- sceRudpGetContextStatus (NOT_INITIALIZED, INVALID_CONTEXT_ID, fills
  status with 0, null status allowed)
- sceRudpWrite (NOT_INITIALIZED, INVALID_CONTEXT_ID, CONN_RESET)
- sceRudpRead (NOT_INITIALIZED, INVALID_CONTEXT_ID, CONN_RESET)

Each assertion mirrors the exact implementation in Export.cpp. Error
codes and return values are the constants hardcoded in the source.
No console measurement needed — these are pure offline behaviors.

AI-assisted: yes
2026-10-17 17:35:07 +01:00
milescovielloandClaude Opus 5.5 6e0886d76d perf(shader): drop the result flush of a product behind its tiny-product check
A v_mul_f32 in a FLOAT_MODE that flushes f32 denormals emits the
nearest-even tininess check, the NaN result selection and then a
result flush. The check already turns every product that rounds below
2^-126 into a zero of its sign, so the flush can't change what it
keeps. DenormalFlushEliminator now proves that: a select arm guarded
by the tiny-product check of the same denormal-free factors, an arm a
select takes only when its own bits are NaN, and an and with a mask
that has no significand bits are denormal-free.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 16:34:08 +00:00
MarcZX100 d71a1c5775 fix(libkernel): accept fractional nanosecond kevent periods 2026-10-17 16:28:55 +00:00
Muhammad Wasif Ali WasifandClaude Opus 5.5 78cabf5dcd fix(libc): keep a drive-letter component of a guest path under its mount on Windows
A guest path is resolved by appending its components to the host root or
to a mount alias directory through std::filesystem::path. On Windows a
component such as "C:" that came first in the appended part was parsed as
a root name, so operator/ replaced the host directory instead of
appending: "/savedata0/C:/Windows/win.ini" and "/app0/../C:/Windows/win.ini"
resolved to "C:\Windows\win.ini", and "/C:/x" lost the component and
resolved to "<root>\x". A colon is an ordinary character in a FreeBSD
file name, so those names belong under the mount.

Guest paths are now split into component names and joined to the host
directory as text. Explicit native drive paths are still passed through.
On NTFS a name containing ":" still opens an alternate data stream; the
libc debt list now records it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 21:22:08 +05:00
MarcZX100 28eaa5bdad fix(libkernel): preserve extended paths in stat metadata 2026-10-17 16:15:54 +00:00
MarcZX100 c0a6caeed3 test(libkernel): preserve directory stat on long paths 2026-10-17 16:15:54 +00:00
MarcZX100 2644234a24 test(libkernel): keep missing long stat paths as ENOENT 2026-10-17 16:15:54 +00:00
MarcZX100 ee5ff02e7a fix(libkernel): stat files under long Windows paths 2026-10-17 16:15:54 +00:00
Romans Pokrovskis cf84fc44a8 fix(libc): preserve existing Windows path namespaces 2026-10-17 19:13:32 +03:00
Romans Pokrovskis fd8a008277 test(libc): cover an existing Windows path namespace 2026-10-17 19:13:02 +03:00
hossiendehghan989 b4786ad4bc fix(input): avoid pad wheel bindings while title reads mouse 2026-10-17 16:11:42 +00:00
ThatsLeo e14a4e5138 fix(shader): stop first-lane reads that reach themselves from recursing
MayEvaluate and the evaluator track the first-lane reads they are inside, so a read reached again through a loop-carried phi or a constant slot is not evaluable instead of recursing.
2026-10-17 18:11:28 +02:00
Ondra97 3bf3253650 fix(libc): replace Windows directories without pre-deleting targets 2026-10-17 18:08:19 +02:00
Ondra97 de2e12148e fix(libkernel): share guest rename semantics with sceKernelRename 2026-10-17 18:08:19 +02:00
Ondra97 57f353df3e fix(libkernel): preserve semaphore wakeups across cancellation 2026-10-17 18:06:21 +02:00
ThatsLeo 745cdb5bf7 perf(shader): judge first-lane and constant reads by what they read
MayEvaluate took ReadFirstLane and ReadConst as evaluable without looking at
their sources, so plans kept conditions behind per-lane values.
2026-10-17 18:03:33 +02:00
Romans Pokrovskis a44455b740 test(libc): keep relative long-path fixture on one drive 2026-10-17 18:58:08 +03:00