FillClearColor refused half and B10G11R11 patterns with a denormal code,
since an implementation may flush them in a clear, so such fills over a
resident image took the CPU path: PPSA01325 fast-clears its 3840x2160
R16G16_SFLOAT target 0x515390000 with a denormal half every frame, a
33 MiB guest write and re-upload (about 85 ms).
ClearKeepsDenormals probes the device once per format: a 1x1 image
cleared with denormal codes (half 0x0001, 0x83ff, 0x0200, 0x8001;
11/10-bit 0x001) and read back. When the bits survive, FillClear takes
the refused pattern again with SmallFloat decoding denormals exactly.
NaNs, float32 denormals and the SNORM minimum stay refused.
agc_driver_recorder_tests clears an R16G16_SFLOAT resident image with a
normal, a denormal and a NaN pattern: the denormal is cleared exactly
when the probe says the device keeps it, and the NaN is refused.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UTjpbMX7BUFMZZaxJE98zV
eb06284c7 made a read-only 2D image_load through a 1D T# valid, so the
test no longer pins a refusal. The TechnicalDebt line now says storage
loads still throw.
#1629 makes sceAgcDcbResetQueue throw 'unsupported op bit 0x40' (and for
0x200/0x400). Dreaming Sarah and Astro Bot call it with op bit 0x40 at
start-up, so both abort before the first frame. Main with only #1629
reverted runs Dreaming Sarah normally again (59.9/59.9 fps, no skipped
draws, no flashes).
Measured on RDNA2 (gfx1035) in review: image_store with DIM 2D through a
1D T# writes texel x for every y, including y = 0xffffffff. The T# type
decides the addressing and DIM only how many address VGPRs are read. The
store no longer drops y != 0.
The test now pins the second store at y = 1 with dmask 0x5: texel x holds
its components 0 and 2, components 1 and 3 are 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A compute program of PPSA26344 writes a 1D storage image with image_store
DIM 2D, and no runtime image mode matched its T#. A write-only 2D storage
access now also gets a 1D mode. A store through it is dropped when y is not
0, as a one-texel-high image bounds it; this mirrors the measured 3D loads
through 2D T#s of #2023 and is listed in TechnicalDebt as unmeasured.
Loads, atomics and image_store_mip through such a pair still throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A flip packet names a buffer index; the buffer was looked up when the
command buffer was submitted, so a title that registers its buffers
after submitting the first frame failed with "flip buffer is not
registered". The buffer is now resolved when the GPU reaches the flip,
as the hardware does. A flip whose buffer is still unregistered then
presents black and completes (see TechnicalDebt).
Uncharted: Legacy of Thieves Collection (PPSA05684) submits its first flip before registering its buffers and stopped with "flip buffer is not registered".
AI-assisted: yes. Match the firmware 13.60 probe in PR #1798: names of 32 bytes or more return guest ENAMETOOLONG=63 and preserve the prior name. The complete final change passed a full Windows build and eight focused runtime tests.
AI-assisted: yes. Validated with the final library change on Windows; full build and eight focused runtime tests pass. Expected rename behavior comes from the public firmware 13.60 probe in PR #1798.
In SCE_AVPLAYER_AV_SYNC_MODE_NONE every decoded frame was handed out in
order, so a title that requests video slower than the film's frame rate
fell behind its audio (about 52 s by the end of the PPSA12544 intro).
While the title pulls audio, frames the audio clock has already passed are
now skipped; frames that are not late are handed out as before.
Fixes#1635
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On RDNA2 (gfx1036) ds_min/max/cmpst(_rtn)_f32 and _f64 flush both operands
when bit 0 of the type's denormal field is clear: field 2 flushes like field
0, field 1 keeps like field 3, in IEEE 0 and 1. The flush decision now tests
that bit. agc_driver_lds_float_atomic_modes adds FLOAT_MODE 0x50 (both fields
1) and 0xa0 (both fields 2), and the TechnicalDebt entry records the measured
fields.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GLfKH7Sqe51wX254k1XsV
ds_min/max/cmpst_f32 and ds_min/max/cmpst_f64 with their _rtn forms follow the
rule measured on RDNA2 (gfx1036): both operands are flushed to a signed zero
when the type's denormal field flushes, a signalling-NaN data operand is stored
quieted, else a signalling-NaN old value, else a quiet NaN loses, else the
ordered compare decides, and the flushed value is written. The shared f32
path used the host's float compares, so its NaN and denormal results were the
driver's; the shared f64 path lacked the signalling-NaN rules the buffer path
has. Both now use AtomicFloatBits. The translation marks the shared float
atomics with the mode's flush in MemoryInfo.
The new agc_driver_lds_float_atomic_modes pins 32 operand pairs per type in
the titles' mode, with both fields kept and with both flushed. The 64-bit
test's model gets the signalling-NaN rule and one lane kind now feeds the
signalling NaN of its table into min/max.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GLfKH7Sqe51wX254k1XsV
The f64 unary instructions, v_ldexp_f64, v_div_fixup_f64 and
v_cvt_f64_f32 always quieted a signaling NaN. The hardware does that
only with IEEE_MODE=1, as #1867 measured for the f32 and f16 forms;
with IEEE=0 the NaN comes out unchanged, measured on gfx1036.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The ±6.1e-5 lanes take the driver's cosine of a tiny angle, where RADV
returns the hardware's 0x3f7ffffe, NVIDIA 0x3f7ffffd and Intel ANV
0x3f800000 (reported by Kikoarl on #2380), so the lanes tolerate 2 ULP
instead of 1.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GLfKH7Sqe51wX254k1XsV
After #1979 the cycle is exact, but the driver's sine of the radians loses
tiny results to its absolute error, and near the zeros of sine at k + 0.5
and of cosine at k ± 0.25 the f32 radians drop the low bits of the cycle.
Measured on RDNA2 (gfx1036), the hardware returns the input times 6.2831826
for every input below 2^-12 of a turn and stays within 7 ULP of the f32 2π
times the distance at the half and quarter turns.
Within 2^-12 of a turn from a zero the lowering now returns the linear term
of the exact distance to that zero, with the hardware's constant at the
integers and the f32 2π elsewhere; everywhere else it keeps the driver's
sine or cosine of the radians. agc_driver_sin_cos_near_zero pins 32 inputs
per type from the oracle with per-lane tolerances.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GLfKH7Sqe51wX254k1XsV
A context without a device, such as the graphics test's mock, leaves state.device equal to context.device, so refreshImports never loaded destroyBuffer and freeMemory and retiring an import called a null pointer.
The pin waiter now receives the mutation range, drains GPU work and retires every overlapping host import before the unmap callback releases the pages. Deferred import retirement keeps only the device handle and the Vulkan destroy functions, so the static import registry no longer owns a Context or its BufferPool past the device.
A compute shader in Astro Bot samples an image as 2D while the bound
T# is 1D, and the recompiler refused it. Offer a 1D runtime mode for
sampled images used only by image_sample_lz and mip-less image_load,
which reads the texel the first coordinate selects, as measured on
RDNA2 in #2237.