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.
When another readable allocation starts right after the buffer's allocation,
the bound range still ends at the first allocation: the bytes past it are
outside the buffer the descriptor's records describe, and binding into the
neighbour would send the range back to a copy on every draw.
AI-assisted (Claude Code).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
RADV rounds a strided buffer descriptor's record count up, so stride * records
can run up to one stride past the end of the buffer's allocation. The guest
buffer region then no longer fits inside the allocation's host import and is
copied on the CPU, whole, for every draw that binds it.
When a strided descriptor ends less than one stride past the end of the
readable registered allocation that contains its base, the range is bound up
to the allocation's end. RetroArch's Dolphin core binds a 48 MiB stream buffer
with stride 20 (records 0x266667, 12 bytes past the allocation) on every draw.
With this change the buffer is bound in place from its import.
AI-assisted (Claude Code).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The window offset register is already required to be zero, so the enable bit has no effect on a draw that gets this far.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Background registration preparations (#2583) copy the device's
SpirvTarget, whose capability and extension spans point into the
device's shader profile. Driver::stop reset the device without waiting
for the detached pool, so a preparation still queued or running read
freed extension names and agc_driver crashed at exit on RADV.
Driver::stop now closes the pool after joining the queue workers: it
stops queueing and waits until no task is queued or running. A
preparation submitted after that runs on the caller's thread, which
holds its own reference to the device, like the existing fallback for
a pool without threads.
Fixes#2891
Co-Authored-By: Claude Opus 5.5 <[email protected]>
v_log_f16 is lowered through the same f32 log2, so the entry names both
and states the f16 effect measured over every f16 input (one NVIDIA
result moves onto the hardware's bits, none on RADV). The series is
chosen with OpSelect, so its cost applies to every v_log.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fnrk5Dazjb2tLooVSpdRQq
The driver's Log2 has an absolute error that does not shrink with the
result, so near 1.0 the relative error explodes: on an RTX 3080, v_log_f32
of 1 - 2^-24 is 23,947,836 ULP off. Measured on RDNA2 (gfx1036), the
hardware's log2 is within 1 ULP of the correctly rounded value, and an
eight-term series in x - 1 is within 2 ULP of both for |x - 1| <= 1/8.
The lowering keeps the driver's Log2 and takes the series only inside that
band when the two differ by more than 4 ULP, so RADV's native result stays
bit-exact and NVIDIA's is within 6 ULP inside the band.
agc_driver_log_near_one pins 64 inputs per type from the oracle with
per-lane tolerances.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_012GLfKH7Sqe51wX254k1XsV
Enable the existing input-only f32 flush policy for division scaling.
RDNA2 measurements pin all three sources and signed zeros; keep the
scaling rules unchanged and retain their separate technical debt.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>