Commit Graph
4862 Commits
Author SHA1 Message Date
Adrià FranchandClaude f132f16155 feat(shader): flush f32 denormals in the float modes that flush them
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:59:24 +02:00
LeandroLP23andClaude Opus 5.5 f054374661 test(libSceNet): pin the resolver info layout and check the buffer on errors
The layout offsets the titles read are static_asserts, and guest_sce_net now
checks a canary past byte 384, distinct records, and an untouched buffer on the
EINVAL, RESOLVER_ENODNS and EBADF paths, as #1845's test did.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:58:18 +02:00
Adrià FranchandClaude d3f2611384 fix(shader): apply the output modifier only in the float modes where the hardware does
Co-Authored-By: Claude <[email protected]>
2026-10-08 23:58:08 +02:00
Adrià ae91d9780b Merge pull request #697 from queeeef/feat/interp-f16
feat(shader): implement v_interp_p1ll_f16, v_interp_p1lv_f16 and v_interp_p2_f16
2026-10-08 23:56:17 +02:00
LeandroLP23andClaude Opus 5.5 427fd92591 feat(libSceNet): implement sceNetResolverStartNtoaMultipleRecordsEx
PS5VR (PPSA99177) stops at start-up on the unresolved import sT4nBQKUPqM;
Jelly5, Emby5 and Nuvio import it too. The call fills the 384-byte resolver
info with up to ten IPv4 records (32 bytes each, family at +16) and the record
counts at +320 and +324, from the same host lookup sceNetResolverStartNtoa
uses, now shared. Only flags 0 is implemented; other flags throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:52:02 +02:00
LeandroLP23andClaude Opus 5.5 7449e51483 feat(libc): implement __inet_aton
PICO-8 for PS5 (PPSA99808) stops at start-up on the unresolved import
a7ToDPsIQrc from libSceLibcInternal. The parser follows FreeBSD's inet_aton
(lib/libc/inet/inet_addr.c): one to four parts in decimal, octal or hex, the
last part filling the remaining bytes, input ending at a NUL or whitespace,
and a null address only validating.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:48:48 +02:00
Gerard L.andClaude Opus 5.5 1d6968225f test(agc): run agc_driver_mesh_tests under ctest
The mesh test was built only on request and never registered, so the
translation of NGG geometry programs to mesh shaders ran in no test
run. On an RTX 4060 it passes. Register it with the other AGC driver
tests.

Three cases would fail or mislead under ctest. Without a Vulkan device
the test failed, and the Windows job has none. A device without
VK_EXT_mesh_shader exited 0, so ctest reported a pass for a test that
drew nothing. On llvmpipe, with the Linux job's Mesa 25.2.8 and Ubuntu
24.04's LLVM 20.1.2, every draw that builds a mesh pipeline stops the
process with "LLVM ERROR: Cannot emit physreg copy instruction"; Mesa
26.2.4 with LLVM 23.1 segfaults in LLVM's code generation instead. The
SPIR-V of all 18 modules the test builds passes spirv-val. Mesa #14376
reports the same error for lavapipe mesh shaders that index shared
memory per invocation; that the cause is the same is not established.

The test now opens its device with OpenVulkanTestDevice and exits 77
without a device, without VK_EXT_mesh_shader and on llvmpipe, saying
why. ANYPS5_REQUIRE_VULKAN still turns a missing device into a
failure. The Linux job therefore skips the test; it runs on hosts with
a GPU.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:44:46 +02:00
Joey Fisher 24623021cd fix(ajm): decode multichannel ATRAC9 streams
Config 0x30 (the ambisonic layout, 4 to 16 channels) was rejected at instance init, so Demon's Souls asserted in
its audio player and crashed entering the tutorial level. Each channel is decoded as a mono stream and the
blocks are interleaved.
2026-10-08 15:44:01 -06:00
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
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 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
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à 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
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
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
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
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
clem-gbandClaude Opus 5.5 c91b306157 feat(http): accept sceHttpSetAuthInfoCallback
PPSA13427 imports sceHttpSetAuthInfoCallback (jf4TB2nUO40), which no
library exported, so the relinked title failed to load. No request
reaches the network, so no server asks for authentication: the
callback is accepted and never called. The signature and callback
type follow shadPS4.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HeC9bA3n74TzJRYv9AgBE8
2026-10-08 20:42:24 +02:00
Adrià FranchandClaude 028bea7818 test(shader): use raw buffer bounds in the packed horizontal gather test
Co-Authored-By: Claude <[email protected]>
2026-10-08 20:42:14 +02:00
Adrià FranchandClaude 7f25d49fb8 fix(shader): fetch packed horizontal gather texels and cover edge coordinates
Co-Authored-By: Claude <[email protected]>
2026-10-08 20:42:14 +02:00
Mark Kuebel d0551d381b feat(shader): implement image_gather4h_pck end to end
Decodes IMAGE_GATHER4H_PCK (MIMG opcode 98) and IMAGE_GATHER8H_PCK
(opcode 99), implements gather4h_pck through translation, the SPIR-V
backend and a GPU execution test, and documents gather8h_pck as a
desktop null-op.

Semantics were measured on gfx1031 hardware with hand-encoded MIMG
words (LLVM rejects the PCK gather mnemonics on every RDNA1/RDNA2
target). The measured rule for gather4h_pck: the four-texel horizontal
window is floor(u*width-0.5)+{-1,0,+1,+2} clamped to the width, the row
is floor(v*height) clamped, the raw bits of the window texels are
concatenated into a little-endian bitstream (texel k at bit offset
k*texelBits), and output register j - the j-th set DMASK bit in
ascending order - receives stream word j, zero past the end of the
stream. Exactly popcount(dmask) consecutive VGPRs are written from vdst
ascending; texels wider than 32 bits write zeros (hardware limit); rows
past the height read zeros; negative coordinates clamp to zero. The
window anchor matches the repo's existing PS5-validated HorizontalOffsets
rule, so this reuses the established convention.

The decoder accepts multi-bit DMASKs for these two opcodes only and
sizes their data span as popcount(dmask) (measured), unlike gather4h
which always writes four components. Translation carries the packed
flag through imageMemoryInfoFromInstruction; the SPIR-V emitter
reassembles the bitstream per lane with per-texel OpImageFetch and
byte assembly. D16 data throws until measured.

gather8h_pck never returns texel data on this hardware: across dmasks
0x1-0xFF including the upper nibble, RGBA8/RGBA16/RGBA32 formats, 1D/2D
and 3D descriptors, normalized and unnormalized sampling, sentinel-
prefilled destination registers confirm it only ever zero-fills
popcount(dmask) registers. It decodes but throws at translation.

The measured semantics and the gather8h_pck null-op are recorded in
docs/dev/TechnicalDebt.md.
2026-10-08 20:42:03 +02:00
emirplus a8c2100f59 fix(savedata): ensure metadata precedes blob commit and handle rollback recovery
Write initial SaveDataParam metadata before replacing the memory blob so metadata failure cannot leave a prematurely grown blob. Handle blob write failure with metadata rollback, and allow retries to recover slots with missing metadata. Expand tests with nonzero data, blob failure, and fresh readback.
2026-10-08 21:41:09 +03:00
ArjenS-LA 74e1a6f5c4 fix(libc): convert wcsrtombs using guest characters 2026-10-08 11:32:21 -07:00
Celegans12 97b9439d4f perf(agc): size the storage and sampled texture caches to the device
The storage image and sampled texture caches each let go of their least
recently used entries past a fixed 2 GiB, and a sampled view of a
storage image counted that image a second time.

The storage image cache keeps a quarter of the largest device-local
heap, at least the 2 GiB of before (TextureCacheBudget). The sampled
cache gets what VK_EXT_memory_budget leaves on that heap after the
memory in use outside sampled textures and cached storage images, the
storage cache's budget and an eighth of the heap budget, read at most
once a second and at least 2 GiB; without the extension it keeps the
storage cache's rule. A snapshot counts its image allocation, a texture
still bound after leaving the cache counts as sampled memory, and a
change of more than 10% is logged at most every 10 s. A nonzero
APS5_TEXTURE_CACHE_MIB sets both budgets; a view of a cached storage
image counts nothing and leaves the cache when its image does.
2026-10-08 20:24:03 +02:00