Fill takes either info struct, so sceKernelGetModuleInfo reports the
name and segments sceKernelGetModuleInfoFromAddr reports for the same
image, on Linux and Windows.
A sampler with FORCE_DEGAMMA (S# word 0 bit 20) threw at decode, so
every dispatch or draw sampling through one was skipped.
DecodeSamplerResource now records the bit, but accepts it only for a
caller that pairs the sampler with its images. The direct sampler
binding does, and RequireDegammaFormat checks each sampled image
against its paired samplers: only already sRGB formats (8, 8_8 and
8_8_8_8 SRGB, BC1, BC2, BC3 and BC7 SRGB) pass, decoded once, as
shadPS4 (PS4) models it. Other textures and unpaired decodes still
throw; gfx10 behaviour is not measured.
On Windows, nanosleep and this_thread::sleep_for/sleep_until go
through winpthreads, which ends a wait on a 15.6 ms GetTickCount64
step. Blocking sceAudioOutOutput and sceAudioOut2ContextPush calls
returned in bursts about every 16 ms, a blocking sceAudio3dPortPush
ran at about 68 % of real time, and sceAudioInInput without a device
woke anywhere from 1 ms to 31 ms apart. They now sleep with
PreciseSleepUs or the new PreciseSleepUntil.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
sigprocmask keeps the first word of the title's set as it is, where
FreeBSD keeps signal n at bit n - 1 (_SIG_BIT), but Dispatch tested bit
n. A title that blocked SIGTERM with a FreeBSD-built set (bit 14) was
not protected, and a set with bit 15 blocked SIGTERM instead of SIGURG.
Dispatch now tests bit n - 1; the stored mask and the set returned by
sigprocmask are unchanged.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The AMD Windows driver returns 1 for a NaN operand when any float form
of ordered not-equal feeds a ballot on a 32-wide subgroup, which is how
e32 compares are read in wave32. FPOrdNotEqual32 is now emitted as an
unordered not-equal with both operands checked for NaN on their bits,
which gives the same result for every input.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
When every dst_sel of a sampled view selects constant 0 or 1, a sample
or gather returns that constant whatever the texel, filter, LOD or
coordinates. Such placeholder views can have a dimension the static
runtime image interface has no mode for (a 3D view under a 2D sample,
a 1D view under a 2D gather), and a 3D one paired with an unnormalized
sampler fails the unnormalized proof.
A direct sampled image whose accesses are all non-compare samples or
gathers gets three constant runtime modes (float, uint, sint). The mode
is selected when all four dst_sel are 0 or 1, unless the view is FMASK,
depth bits, converted or sRGB-decoded. In it the emitter returns each
channel's constant (the dmask channel's, in all four texels, for a
gather) from the image's swizzle specialization constants, and the
image is left unbound. ProveUnnormalized skips the mode after the
run-time-selected check, so table roots still throw.
Untracked host imports may retain pending image results on the GPU after an unchanged refresh. Assert that behavior and verify that an explicit FlushPending makes the results visible in guest memory, while watched memory still checks refresh write-back.
Fixes#2155
Keep serialized lookup scratch under the existing pipeline cache mutex and use the standard byte-string hash for indexing. Preserve exact key comparison and private handling of unidentified shaders. Add a real-device cache lifetime fixture and warmed lookup benchmark.
Written with AI assistance.
The machine check compared against 'x86-64' (uname reports 'x86_64'), so the
native execution was always skipped. With it enabled the fixture itself was
wrong: the initialiser's rip-relative call used the wrong displacement, and
the pending block was set on a different copy of the host library than the
one the module binds to.
Co-Authored-By: Claude <[email protected]>
The DT_RELA tags were still guarded on the input module's relocation table, while the
new accessor relocations were appended to a copy of it. A module with an initialiser and
no imports therefore kept the argument stub but lost both relocations that fill its GOT
slots, so the stub called through a null pointer at load time.
Guard on the extended table instead, and drop the unused start parameter from the
displacement helper. The test now converts a module whose DT_RELASZ is zero and asserts
that the output carries both accessor imports and a 48-byte relocation table.
Add a hand-built guest module with an explicit DT_INIT that forwards rdi and rsi to a
host recorder without touching them and returns a known value. The test sets a known
argument count and argument pointer, loads the converted module, and asserts that the
initialiser received both values and that the stub forwarded its return value.
The host recorder also provides the two accessor symbols, so the test resolves them
without loading libkernel. The converted module must import both accessors, which is
what distinguishes the new behaviour from the previous stub that zeroed the arguments.
sceKernelLoadStartModule discarded its arguments, and the relinker's Linux guest writer
synthesized an initialisation trampoline that also cleared the argument registers before
jumping to the module entry point, so a converted module always reached its own start-up
code with args = 0 and argp = NULL.
On PPSA28997 two of the title's own modules validate that parameter block as their first
act and dereference it unconditionally: SaveData faults on `mov (%rsi),%eax` with rsi = 0
beside its `cmp $0x10` size checks, and PSN faults the same way at PSN+0x3ee7 with rbx = 0.
The Windows branch delivers the block, so identical code reports its parameter-version
error and continues instead of faulting.
sceKernelLoadStartModule now records the pair before dlopen and clears it afterwards, and
the emitted DT_INIT stub reads it through two accessors exported by libkernel. The
initialiser is called rather than tail-jumped so its return value can be reported through
*res as the PS5 API specifies. The state is thread_local, which makes the handoff per-call:
ld.so runs a module's initialiser on the thread that called dlopen. DT_FINI keeps a plain
call-through, so unloading neither reads stale arguments nor reports a result.
The accessor names use the _nid_no_patch suffix so the NID resolver leaves them alone and a
guest import can name them exactly.
Retain host backing views for emulator writes and completion labels. Validate full spans, preserve write versions and GPU ordering, and keep the fallback for other mappings. Test remaps, aliases, access checks, partial failures, tracking, view lifetime, and completion ordering.
Written with AI assistance.