Commit Graph
6138 Commits
Author SHA1 Message Date
Adrià 94b1eecb59 Merge pull request #533 from adriadam10/test/vop3p-packed
fix(shader): choose packed f16 NaN results on the bits, as RDNA does
2026-10-08 23:41:34 +02:00
sarohyandClaude Opus 4.8 f765b27cc0 test(relinker): cover CLI argument parsing
Cli::ParseArgs had no test coverage: its only sibling test
(AutorunExitTests) exercises the autorun launcher, not the parser.

Add cli_args_tests covering every option and its side effects, the
--rpath and --exclude-sce-module value consumption (including that the
following token is taken verbatim rather than re-parsed as a flag), the
unused-filter value and single-specification validation, the
--exclude-sce-module/--skip-sce-module conflict in both orders, the
order-independent --windows-diagnostics/--windows-gui requirement on
--windows, unknown-option and extra-positional rejection, and the usage
message when an input or output path is missing.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-10-09 02:40:19 +05:00
Adrià dc79e9b1d6 Merge pull request #938 from CnRJay/feat/ds-src2-b32
feat(shader): implement the 32-bit DS src2 operations
2026-10-08 23:36:33 +02:00
Nahuel Genchi 81d86aa523 fix(libc): call the new handler when operator new fails to allocate 2026-10-08 18:36:31 -03:00
Adrià FranchandClaude 8f663d0123 feat(shader): follow the float mode in 16-bit interpolation
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:36:04 +02:00
Daan DehingandClaude Opus 5.5 425836e73f fix(shader): give 16-bit interpolation NaNs the hardware priority
Measured on RDNA2 in #697: an invalid product or sum (inf * 0, inf - inf)
gives the negative default NaN, 0xffc00000 or 0xfe00, and beats a NaN
addend. A NaN delta, then a NaN coordinate, still wins, quieted; a NaN
addend is returned quieted only when the product is valid.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:36:04 +02:00
Daan DehingandClaude Opus 5.5 7f53a48131 fix(shader): round each 16-bit interpolation step once, as on hardware
Measured on RDNA2 in #697: v_interp_p1ll_f16 and v_interp_p1lv_f16 are a
fused multiply-add rounded once to f32, and v_interp_p2_f16 rounds the exact
P20 * J + S2 once to f16. The separate multiply and add matched about 85% and
4% of the measured rows.

Both steps now use FPInterpolateF32 and FPInterpolateF16: the f16 delta times
the f32 coordinate is exact in f64, the sum is rounded to odd and then once to
nearest even at the target precision, so no driver can split or reround it.
Infinite and NaN operands take the unbounded f64 result.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:36:04 +02:00
Daan DehingandClaude Opus 5.5 daa6bee7cf feat(shader): implement v_interp_p1ll_f16, v_interp_p1lv_f16 and v_interp_p2_f16
Decode the three VOP3 16-bit interpolation instructions (attribute, channel
and high-half select in the src0 field, the I/J VGPR in src1, P0 or the first
step's result in src2) and translate them with a new
GetInterpolationParameterF16 IR value. It reads the selected 16-bit half of
each vertex's parameter through VK_KHR_fragment_shader_barycentric, so P10 and
P20 are vertex differences rounded to f16; both steps are a multiply and an
add, as in the f32 forms.

An input in FP16_INTERP_MODE whose low half is defaulted is still declared at
its slot when its high half is read, and the high half takes its default from
USE_DEFAULT_ATTR1 and DEFAULT_VAL_ATTR1. Without barycentrics, on an input
without FP16_INTERP_MODE or on a pass-through input the instructions throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:36:04 +02:00
Adrià FranchandClaude a000305181 fix(shader): choose packed f16 NaN results on the bits, as RDNA does
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:34:18 +02:00
Adrià aa258760dc Merge pull request #1826 from adriadam10/feat/shader-ieee-minmax
feat(shader): follow IEEE_MODE in f32 min, max, min3, max3 and med3
2026-10-08 23:33:59 +02:00
journaltraces e411282b80 feat(libc): implement stpcpy
PICO-8 for PS5 (PPSA99808) imports stpcpy from libSceLibcInternal, one
of the absent imports #1578 lists for it. POSIX defines it as strcpy
that returns a pointer to the terminating null of the copy.
2026-10-09 00:22:57 +03:00
journaltraces 668a1e6f72 feat(libc): implement ldiv
RetroArch (PPSA99169) imports ldiv from libSceLibcInternal, one of the
absent imports #1578 lists for it. The guest long is 64-bit, so the
export takes std::int64_t and returns lldiv_t, which has the guest
ldiv_t layout; std::ldiv would truncate on Windows, where long is 32-bit.
2026-10-09 00:22:57 +03:00
ps54allandClaude Sonnet 5.5 1bd0ef8c96 refactor(libkernel): share one rename implementation with libc
The repo allows one implementation per export. Move libc's rename into
libc/src/Rename.cpp, compile that file into both libc and libkernel, and
drop the second copy from libkernel's Stdio.cpp. FilesystemError moves to a
header so the shared source can use it.

The test now checks that the symbol it resolves belongs to libkernel (module
handle on Windows, dladdr on Linux) so it fails when the export is removed.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-08 23:17:04 +02:00
ps54allandClaude Sonnet 5.5 1f580c8dde test(libkernel): use a relative directory in the rename test
The guest VFS on Linux does not map absolute host paths, so the test failed
at the first rename there. Match GuestFilesystem.cpp and build the directory
relative to the working directory.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-08 23:17:04 +02:00
ps54allandClaude Sonnet 5.5 372e2d4267 test(libkernel): cover the libkernel rename export directly
guest_filesystem_tests links libkernel and libc, both of which define
rename_nid_postfix, so which one it binds to depends on the loader and the
suite passes either way. Resolve the symbol from libkernel.prx explicitly so
the export added for titles that ship their own libc.prx is actually tested.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-08 23:17:03 +02:00
ps54allandClaude Opus 5.5 fc457760a8 feat(libkernel): export the POSIX rename
Titles that ship their own libc in sce_module import rename from
libkernel (NID NN01qLRhiqU), where it was missing, so PPSA12544 failed
to start. It checks both paths like unlink and maps sceKernelRename's
result to errno.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:17:03 +02:00
Adrià 364a56b681 Merge pull request #1816 from adriadam10/feat/shader-float-mode-carry
feat(shader): carry the shader float mode into the recompile request
2026-10-08 23:16:04 +02:00
Adrià FranchandClaude be3bd9fbd7 fix(shader): refuse the f32 DS src2 operations until LDS float denormals are modelled
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:13:23 +02:00
Adrià FranchandClaude fe1f7b38af feat(shader): follow IEEE_MODE in f32 min, max, min3, max3 and med3
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:09:31 +02:00
Prophet069 05e1cf9d67 fix(libc): bridge guest exception vtable callbacks
Give guest exception what, non-deleting destructor and deleting destructor slots explicit APS5_VABI types and register guest adapters. Preserve native helpers, object layouts, native exception routing and existing malloc/free ownership.

Add mismatched and cleared RCX regressions for plain and message vtables, observing actual libc free calls to reject foreign or duplicate frees. Retain typed guest catch/rethrow and native exception coverage. All 27 targeted CTests pass three repetitions on Windows Release; Linux execution remains unvalidated.
2026-10-08 23:06:47 +02:00
Prophet069 a961ad35e5 fix(libc): bridge guest message exception destructors
Guest message throws registered native Windows callbacks even though Release invokes guest callbacks using System V. Register an APS5_VABI adapter in the standard and regex message throw paths and retain the native DestroyMessage helper and legacy callback storage type.

Add MinGW CTest regressions with distinct or zero RCX, shared and final-release messages, typed guest catches, rethrow and normal Release. All ten new cases plus Windows exception and thread callback regressions pass three repetitions. Linux execution remains unvalidated; guest vtables and host exception paths are unchanged.
2026-10-08 23:06:47 +02:00
Claude c0519cc814 feat(shader): implement the 32-bit DS src2 operations
The decoder threw on the GFX10.1 DS src2 opcodes 0x80-0x8b, 0x8d,
0x92, 0x93 and 0x95. Each reads DS[B], where B is the address plus
four times the 15-bit signed offset in offset1[6:0]:offset0, and
applies the matching operation to DS[A]: add, sub, rsub, inc, dec,
signed and unsigned min and max, and, or, xor, f32 min, max and add
through the 32-bit LDS atomics, and a plain write for
ds_write_src2_b32. The form that takes the offset from the address
bits (offset1[7]), the 64-bit forms and GDS still throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:06:15 +02:00
Adrià 0447793216 Merge pull request #1809 from adriadam10/feat/image-pck2-pck4
feat(shader): implement MIMG PCK2/PCK4 loads as measured on hardware
2026-10-08 23:05:02 +02:00
TideOPL 39463913c7 fix(libScePad): fuse queued pad states at the read time
Keeping lastFuseTime at its maximum never let it recover from a process time that wrapped on the first call (fixed separately in #1501), so tilt correction stopped and guest_pad failed. Queued states keep their own timestamp; the orientation is fused once at the time of the read, as scePadReadState does.
2026-10-08 21:56:33 +01:00
hugodearaujoandClaude Opus 5.5 b7b281678b fix(audioout2): match measured MAIN port format validation
Measured on a PS5 (firmware 13.60) through dlopen of libSceAudioOut.sprx:
a MAIN (type 0) port accepts 1, 2, 8 or 12 channels (bits 8-11) with
sample type 0 or 1 (bits 0-6). Bit 7 without 8 channels returns
0x80268001, any other unsupported format returns 0x8026800E, and both
write UINT64_MAX to the output handle. Bits 12-31 do not affect the
result. Other port types keep their current validation.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 17:41:02 -03:00
Adrià aa277b3818 Merge pull request #1821 from adriadam10/ci/repeat-on-main
ci: repeat the tests three times on main only
2026-10-08 22:35:30 +02:00
Adrià FranchandClaude 8adb7db88e ci: repeat the tests three times on main only
Co-Authored-By: Claude <[email protected]>
2026-10-08 22:31:54 +02:00
eliasbruno124-dev ac2b0f5deb fix(relinker): rebase guest runpaths from their output directories 2026-10-08 22:31:03 +02:00
Adrià FranchandClaude 0cbc9586bc feat(shader): carry the shader float mode into the recompile request
Co-Authored-By: Claude <[email protected]>
2026-10-08 22:17:07 +02:00
Adrià FranchandClaude 57d4be33bb feat(shader): implement MIMG PCK2/PCK4 loads as measured on hardware
Co-Authored-By: Claude <[email protected]>
2026-10-08 21:54:10 +02:00
Jan ŠléglandClaude Fable 5.1 8f31696450 feat(libkernel): implement socketpair
AF_UNIX pairs as FreeBSD 11 makes them: SOCK_STREAM, SOCK_DGRAM and
SOCK_SEQPACKET with protocol 0, SOCK_NONBLOCK applied to both ends and
SOCK_CLOEXEC accepted, EAFNOSUPPORT for an unknown family, EOPNOTSUPP
for AF_INET and AF_INET6, EPROTONOSUPPORT for type 0 or a protocol,
EPROTOTYPE for another type, EFAULT for a null output, and nothing
written on failure. The ends are guest sockets, so send, recv,
shutdown, fcntl, poll and close work on them; getsockname and
getpeername report the unnamed AF_UNIX address, recvfrom and recvmsg
no address for a stream and the unnamed one for a datagram. On Linux
the pair is the host's socketpair; on Windows a loopback TCP connection
or two connected UDP sockets, and SOCK_SEQPACKET throws. The remaining
differences from the console are recorded in TechnicalDebt.

OpenSSL's QUIC notifier in 15 catalog titles creates such a pair.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-08 21:51:00 +02:00
st44rplatinum 3599d41941 docs(libSceSystemService): record PPSA01521 as the MediaPlay caller 2026-10-08 22:45:43 +03:00
Adrià 4b6ab6bb73 Merge pull request #1797 from adriadam10/ci/keep-main-cache
ci: save the compiler cache before the tests
2026-10-08 21:40:48 +02:00
Jan ŠléglandClaude Fable 5.1 7785933807 feat(libkernel): implement sceKernelGetFsSandboxRandomWord
Returns the name of the directory under which a title's sandbox exposes
system files, which homebrew SDKs splice into paths such as
/<name>/common/cert/CA_LIST.cer and /<name>/common/lib/libc.sprx. The
name is fixed here; recorded in TechnicalDebt together with the fact
that nothing is mounted under it.

Registers guest_sandbox_random_word.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-08 21:39:11 +02:00
Adrià 2cc7f09d1d Merge pull request #1793 from adriadam10/feat/image-by-measured
feat(shader): implement MIMG BY2/BY4 loads as measured on hardware
2026-10-08 21:37:24 +02:00
Adrià FranchandClaude fe7e0e6098 ci: save the compiler cache before the tests
Co-Authored-By: Claude <[email protected]>
2026-10-08 21:35:13 +02:00
SilentOne 1b5d406a2f fix(relinker): add regression test for fall-through after zero padding and tighten reset condition 2026-10-09 01:02:14 +05:30
Scott SchusterandClaude Opus 5.5 8eb2c3d504 feat(agc): detile XOR-swizzled textures whose base carries a pipe/bank XOR
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:30:52 -05:00
SilentOne f8031f7c9e fix(relinker): keep fall-through edge after trailing zero padding in StrictReachability 2026-10-09 00:58:57 +05:30
SilentOne e55209d274 perf(relinker): replace O(n²) zero-padding scan in StrictReachability
addGap and buildEdges each called isZeroPadding(address, end) at every
instruction boundary. isZeroPadding scanned from the current address to
the region end, so the total work for a region with N instructions and a
trailing-zero suffix of length Z was O(N*Z), quadratic in the worst case.

Replace with trailingZeroStart, which scans backwards from the region end
once to find the start of the trailing-zero suffix. The loop then stops at
that position, eliminating the per-instruction zero check entirely.
2026-10-09 00:58:57 +05:30
Adrià FranchandClaude d5a3a4321c fix(shader): follow measured hardware for MIMG BY2/BY4 loads
Co-Authored-By: Claude <[email protected]>
2026-10-08 21:28:22 +02:00
ChadandClaude Opus 5.5 cd43c270d6 Merge upstream/main into fix/recompiler-descriptor-phi-web
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:17:07 -05:00
gdr-98 21d21da385 fix(libc): format guest wide printf arguments on Linux 2026-10-08 21:15:04 +02:00
Petre 88f7a5e0e4 feat(shader): lower full-width MIMG BY2 and BY4 transfers 2026-10-08 21:10:51 +02:00
Adrià b858fdc48e Merge pull request #1701 from pandather/feat/shader-decode-gather-h-pck
feat(shader): implement image_gather4h_pck end to end
2026-10-08 21:05:27 +02:00
ChadandClaude Opus 5.5 f5ba4e9c68 fix(recompiler): throw for descriptor web leaves that are not SRT descriptors
A path whose T# or S# dwords hold a program-counter, EXEC or compare-mask
value is no longer folded onto the first descriptor: the web split gives up
and the read throws as on main. Cache the invariant-Phi resolution per web,
lower the state limit to 512 and test the program-counter, EXEC and
compare-mask rows, unwritten registers, and the arm and state limits.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 14:02:49 -05:00
MathiasDevelopesandClaude Opus 5.5 485eb1aedd fix(libSceHttp): sceHttpWaitRequest reports no ready requests
It returned the network error, which titles that poll their epoll treat
as fatal. No request is ever pending, since sending fails at once, so the
wait now times out with no events; an infinite wait throws.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 20:48:20 +02:00
TideOPL c9685e47e4 fix(savedata): report a CREATE2 mount of an existing save as not created
sceSaveDataMount3 with SCE_SAVE_DATA_MOUNT_MODE_CREATE2 opens a save that
already exists, so its mount status is 0 rather than CREATED, as shadPS4's
savedata.cpp reports. A CREATE mount still reports CREATED.
2026-10-08 19:46:23 +01:00
TideOPL c17c5ebd4d fix(agc): apply the raw OOB_SELECT range rules to zero-stride vertex buffers
With stride 0, OOB_SELECT 2 puts a fetch out of range only when NUM_RECORDS
is 0, and OOB_SELECT 3 only when the offset is not below NUM_RECORDS (GFX10
table in Mesa ac_descriptors.c). A one-record descriptor therefore returns
its whole element: Unreal's per-draw PrimitiveId stream is such a descriptor,
and refusing it skipped the draw. A wholly out-of-range fetch reads a zero
buffer.
2026-10-08 19:46:22 +01:00
husari.orozco 4d13e99a0d test(relinker): execute the guest Intel trampolines end to end 2026-10-08 12:46:05 -06:00