image_store with D16 data to a storage image of a SINT format threw
"stores 16-bit data to an image of a SINT format", both when the
descriptor is decoded and in the SPIR-V image emitter, and the runtime
image modes left out the SINT conversions for such images. God of War
Ragnarok (PPSA08330) stops on it in compute shader 0x1052a17900 right
after its MFSR setup.
Each 16-bit half is now converted like the D16 format buffer stores
(EmitD16StoreComponent): sign-extended, then saturated to the
component width as for 32-bit data. The buffer form was measured on
RDNA2 in #331; the image form is not measured (TechnicalDebt).
agc_driver_image_store_sint now stores D16 data with DMASK 0xf and 0x5
to all eight SINT formats and after an image_atomic_add on 32_SINT,
instead of expecting the refusal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The relative vector addressing entry still said every window register
lives in one function-scope array. It now describes the array of the
bounded slots, the per-slot variables, the OpSwitch fallback and
APS5_NO_WINDOW_NARROWING, with the RTX 3060 measurement.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uzy15wqYTt6iWyxYXEzUWo
A 2D image_sample_l through a 1D T# now takes the 1D runtime mode, as
image_sample_lz already does, instead of failing the runtime image
interface. Measured on RDNA2 (gfx1036) with tools/hw-oracle against the
same sample with DIM 1D: u inside, on and past the edges, v of 0, 0.5, 1,
-0.25 and 3, LOD -1 to 6 on a 5-level R32_FLOAT texture, point, linear and
linear-mip filtering, wrap, clamp and border addressing, and HEIGHT or
DEPTH 3. All 4725 rows matched: the 1D T# decides the addressing and v is
ignored.
The execution test samples a 5-level 1D T# with distinct mip contents at
LODs -1 to 6, fractional ones included, with u inside, on and past the
edges, under point filtering with wrap and clamp and linear filtering with
linear mips and wrap, clamp and border addressing. Every result must match
the same image_sample_l with DIM 1D bit for bit; point-filtered results
must also be the expected texel of the expected level, and linear-mip
results the blend of the two levels the LOD selects.
ds_add_f32 and ds_add_rtn_f32 now follow the measured hardware: both
operands are flushed to a signed zero when bit 0 of the f32 denormal field
is clear and the result when bit 1 is clear, the sum is rounded to nearest
even, a NaN data operand is stored quieted, else a NaN old value is stored
quieted, and +inf + -inf stores 0xffc00000. Measured on gfx1010 and, in
#5492, on gfx1031.
The new MemoryInfo field is stored in the shader disk cache (field count
31, minimum record 79 bytes, FormatVersion 34). The parts that depend only
on the data operand are computed once, before the CAS loop.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The front-face VGPR was always +1.0 / -1.0, which is its form only while
FRONT_FACE_ALL_BITS is clear (current Mesa reads it with fgt 0 / fsign).
With the bit set, as Mesa 22.0 RADV programs it, a back face reads 0 and
a front face non-zero: ACO then tests it with v_cmp_lg_u32 0. Uncharted:
Legacy of Thieves Collection (PPSA05684) sets the bit and its two-sided
cloth shaders test v_cmp_lt_u32 0, so -1.0 (0xbf800000) made every back
face a front face: the insides of the menu skeleton's rags kept their
front normals and were lit white by the spot light behind them.
The pixel stage info now carries the bit (request version 26, cache and
draw keys), the decode reads SPI_BARYC_CNTL when FRONT_FACE is an active
input, and the translator turns the builtin into 0xffffffff / 0. The
exact front value is not measured (docs/dev/debt/shader.md).
AI-assisted: yes
On ds_ordered_count M0 holds the ordered wave ID, not a GDS address as
for ds_append: radeonsi and ACO pass the wave ID as the intrinsic's
pointer and keep the counter address in offset0. Reading M0 as the base
and size skipped the add whenever M0[15:0] was 0, so every wave got the
same range. The test now runs the ordered pass with M0 = 0 and M0 = 7.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ds_ordered_count adds the first active lane's value to a GDS counter and
returns the previous value, like ds_append adds the lane count. Waves are
not serialized in launch order: each still gets its own range. Ordered
swap and multi-dword counts stay refused. DISPATCH_DIRECT and
DISPATCH_INDIRECT accept ORDERED_APPEND_ENBL (bit 3) of the initiator.
Compute shaders of MXGP 26 (PPSA30839) use both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VGT_TF_PARAM.PARTITIONING 3 now compiles to Vulkan's fractional-even
spacing, which radeonsi programs as PART_FRAC_EVEN. Its factors are
bounded at 64 like integer partitioning; Vulkan raises the remaining
ones to at least 2, the D3D11 range for this mode.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mode 1 keeps subnormal inputs and flushes a result below 2^-126 to a
zero of its sign; mode 2 flushes subnormal inputs and rounds a subnormal
result in the f32 round mode, as measured on RDNA2 (gfx1030) in every
f32 round mode at IEEE=0 and IEEE=1. Both modes threw before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v_cmp_X_f32 and v_cmpx_X_f32 flush their denormal inputs by bit 0 of the
FLOAT_MODE f32 denormal field, as measured on RDNA2 (gfx1030): mode 1
keeps them and mode 2 flushes them. Both modes threw before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An s_swappc_b64 whose target is not resolved compiles to a faulting call
only at the fallback the table-call linker emits; the linker lists those
calls in the request (GuestContext::linkedCallFallbacks), and every other
computed call is refused at compile time again, as on main. The new
agc_driver_compute_table_calls test runs a linked two-record table on
Vulkan in wave32 and wave64, with SCC 0 and 1 reaching the callee, and a
record past the table reporting the UnlinkedCall fault.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An s_swappc_b64 whose target pair comes from an s_buffer_load of a buffer
whose descriptor is loaded from user data now calls the targets that buffer
holds: at dispatch the driver reads the buffer, links one copy of each
distinct callee after the caller and rewrites the call into a compare chain
that s_call_b64s the matching copy. A target that matches no copy, and any
other computed call, records an UnlinkedCall fault that the driver reports,
instead of failing the shader at compile time.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A 3D image access bound to a 1D T# matched no runtime image mode and threw
"image descriptor is incompatible with the static runtime image interface"
(SONIC SUPERSTARS, PPSA06888, which reads a 1x1 1D T# as 3D with a plain
image_sample and an image_load). Add a 1D mode for 3D accesses whose only
uses are image_sample_lz, plain image_sample or mip-less image_load.
Measured on RDNA1 (RX 5700 XT, gfx1010) with the hardware oracle:
image_sample_lz reads the texel u selects and ignores v and r with every
addressing mode; a plain image_sample takes its texel and LOD from u alone;
image_load reads the x texel for any y when z is 0 and returns zero for any
other z, as the 3D-on-2D load measured in #2023 does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQNVXyqeecpyneonkYL6H1
Plan runtime-indexed T# and S# columns read through a 64-bit pointer.
Preserve the console offset alignment, signed immediate and key bounds.
Track the descriptor dwords consumed by each table in its invocation.
Reject table reads when a writable buffer or storage image overlaps them.
Cover the overlapping-storage fault and isolated second-table behavior.
Materialize runtime-indexed image and sampler records into descriptor
tables while keeping descriptor selection in the shader. Report invalid
active entries through the existing deferred fault buffer.
Bind fragment tables in the fragment set when pipeline libraries split it,
and reserve a physical descriptor for empty tables. Reject unsupported
sampler, border, cube and anisotropic pairings per entry. Keep one column
per heap access shape, one T# shared by several image operations included
(milescoviello's #5550 case), and narrow it to the union of its keys'
domains when every key has one (SleglJan's key-domain changes). Plan
columns read at (key << n) & mask over their whole domain (tibzejoker's
fix). Read records in runs through SleglJan's bulk reader, and reject
entries whose surface has no mapped byte, as Tamalero proposed. Store
table columns in disk plans; update the runtime ABI and disk format. Bound
table-sized entries in the resource cache (65,536 table elements) and the
dispatch cache (256 MiB of captured words), evicting LRU.