An unregistered graphics program is read raw only while the shader registry
is empty; with shaders registered it throws, as before. A draw that uses a
raw program is noted, and RegisterShader throws once that has happened,
since a title that registers shaders after drawing unregistered programs is
not understood. The draw cache revalidates a raw program by reading it raw.
AI-assisted (Claude Code).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The POSIX alias takes (attr, int), returns EINVAL (22) for a null or
uninitialized attribute like the other pthread_attr setters, and
stores the value through scePthreadAttrSetsolosched, returning its
result in errno form. The signature and the stored int follow the SCE
twin in KytyPS5 and sharpemu; PS5PCEM implements the alias the same
way. The value is not applied to scheduling, recorded in TechnicalDebt.
Returnal (PPSA01285 v03.000.005) stops on it after eager binding
(#2872, #1155):
what(): pthread_attr_setsolosched_np_nid_postfix not implemented
LEGO Horizon Adventures (PPSA14632, #734) and Palworld (PPSA23126,
#2598) import it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
The register draw key identifies an unregistered program only by its
address, and a key hit reuses the entry's decode without reading the
program again. A different program uploaded to the same address with
the same registers would run the old compiled shader. A hit now checks
the decode's unregistered programs against guest memory and drops the
entry when one changed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Use the upstream CMASK implementation and remove the import requirement from image clears. Propagate storage-image creation failures. Test repeated clears, copied write-back, and failure without changing guest data.
AI-assisted: yes.
guest_filesystem creates symbolic links for the Windows lstat checks.
Without administrator rights or Developer Mode, CreateSymbolicLinkW
fails with ERROR_PRIVILEGE_NOT_HELD even with
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE, and the test aborted there
(reported as a stale guest errno). Skip those checks with a note in that
case; any other failure to create the first link still fails the test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
#2839 decides f32 product tininess after rounding, in all four f32
round modes, from the exponents and a UMulHi and IMul of the
significands, and builds the flushed value from them. To nearest even,
the mode of shaders without a known float mode and of the 0xc0 most
titles use, one multiply decides it: one factor times 2^64, which is
exact below 2^64, times the other factor rounds the exact product once
to 24 bits in the normal range, and 0 < |that| < 2^-62 is tininess
after rounding. A product that rounds up to 2^-126 is then not tiny and
keeps the emitted product, which is 2^-126 there, so nothing has to be
built from the significands.
The flush of v_mul_f32 v5, v6, v7 takes 12 IR instructions instead of
34, counted as the instructions the flush select needs beyond the
product. vector_constant_factor_tininess pins 12 to nearest and 36 for
the directed path of the same instruction, and checks that the
directed modes and v_mad_legacy_f32 (before rounding) keep #2839's
check. Its round-to-nearest branches are removed as unreachable.
The f32 denormals entry says which rounding the check inherits: the
multiply is a plain OpFMul like the product, with no f32 rounding mode
requested, so it relies on the driver rounding f32 to nearest even, as
the products do. F32ConstantFactorTininess names the row a check before
rounding flushes, 0x3f7ffffe * 0x00800001, which keeps the emitted
0x00800000.
Against #2839 to nearest even, a model of both checks agrees on
1,074,977,546 operand pairs (every 24-bit significand at both rounding
thresholds, random pairs, specials) with each other and with an exact
reference. On an RTX 5070 the outputs of #2839's own tininess and
mixed-source shaders are bit-identical with either lowering over
165,298 and 164,008 generated rows in all six float modes tested.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A wait on an equeue that holds socket events now blocks in poll/WSAPoll on
those sockets plus a per-thread loopback wake socket, instead of rechecking
every millisecond. Adding, triggering or deleting an event and closing the
equeue wake the blocked waiters. Closing a socket removes its read and write
events, as on FreeBSD. A read event also reports EV_EOF once the peer has
shut down its sending side.
sceKernelAddReadEvent/DeleteReadEvent and sceKernelAddWriteEvent/
DeleteWriteEvent register EVFILT_READ and EVFILT_WRITE events on guest
sockets. The equeue polls the host socket for readiness on each wait
and reports the readable byte count or the send buffer size in data,
with EV_EOF on hang-up or error.
pthread_cond_wait and pthread_cond_timedwait, and their sce counterparts, threw a
host exception when the mutex was unlocked, locked by another thread, or not yet
initialized, and dereferenced the adaptive static initializer. FreeBSD returns
EPERM for these (EINVAL for a destroyed mutex) before touching the condition.
(cherry picked from commit a78bb8a855)
The elected lane's inner spin loop never ended on Mesa ANV with the LDS in
a storage buffer. It now tries once and the outer loop elects again; the
update is unchanged.
(cherry picked from commit e894f90923)
sceVideoOutVrrPegToFixedRate and sceVideoOutVrrUnpegFromFixedRate were
NotImplemented without arguments. Both take the output handle; the peg
also takes two further arguments whose meaning is unknown. VRR is not
modelled and the output always runs at a fixed rate, so both validate
the handle and return 0; non-zero peg arguments throw. Recorded in
TechnicalDebt.
Uncharted: Legacy of Thieves Collection (PPSA05684) stops on main with
"sceVideoOutVrrUnpegFromFixedRate not implemented"; it passes its
output handle to both (and zeros to the peg) and ignores the results.
Since #2133, a 3D image_sample_lz or image_load bound to a 2D-array T#
decodes as 2D and matches the new 2D mode, so it reads layer 0 for any
r and returns zero for z != 0. adriadam10 measured on RDNA2 (gfx1035)
that dim 3D on a 2D-array T# behaves exactly like dim 2D-array, with r
or z as the layer. Decode a 2D-array T# bound to a 3D access as 2D-array
and add a 2D-array mode next to the 2D one.
The same measurement covers image_load_mip on both T# types and
image_get_resinfo, which returns (w, h, 1, levels) on a 2D T# and
(w, h, layers, levels) on a 2D-array T#. Allow those accesses and return
1 as the third resinfo component through the 2D mode. image_get_lod is
not measured and keeps throwing.
Pipeline destroyed its shader modules right after LinkPipelineFromLibraries returned, while the pre-rasterization and fragment shader library parts built from them stay cached and are relinked later with VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT. On AMD's Windows driver (RX 6700 XT, Adrenalin 25.10.45.05) that link faults inside amdvlk64.dll at varying offsets, reading freed heap memory, in 22 agc tests on a cold driver cache; all of them pass with APS5_NO_PIPELINE_LTO=1. Running the optimized link synchronously or without a pipeline cache did not help, keeping the modules alive did.
When the optimized link is enabled, the library store takes over the modules of each newly built shader part and destroys them in ClearPipelineLibraries after the pending links have finished. Modules of a pipeline whose parts were all cached are destroyed as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Key 0x10 (GFX9_DCC_CLEAR_SINGLE in Mesa) marks a 256-byte block whose texels all equal its first texel. A CB DCC decompress pass over uniform comp-to-single keys now writes that texel over its block and stores uncompressed keys; a fast-clear eliminate over them throws.