Commit Graph
408 Commits
Author SHA1 Message Date
Dean 0c4d871f18 Merge pull request #12253 from Michael-KD/fix/fma-f32-denormal-modes
fix(shader): translate the fused f32 fma forms in f32 denormal mode 2
2026-10-29 00:32:38 +13:00
Dean 7d223dd6da Merge pull request #12252 from Michael-KD/fix/f32-rounding-frexp-denormal-modes
fix(shader): translate f32 fract, floor, ceil and frexp_mant in f32 denormal modes 1 and 2
2026-10-29 00:32:22 +13:00
Dean 3a40945e62 Merge pull request #12298 from oneandonlydean/revert-11199-helper-lane-masks
revert(shader): restore pixel helper lanes in guest lane masks (#11199)
2026-10-28 22:57:31 +13:00
Dean 3917fa85ce Merge pull request #12188 from Gonic0/fix/shader-lds-lock-fences-moltenvk
fix(shader): fence the LDS lock's critical section on MoltenVK
2026-10-28 22:51:00 +13:00
Dean b332780eec revert(shader): restore pixel helper lanes in guest lane masks (#11199)
This reverts merge 7fc0ae6008. On NVIDIA, where helper lanes take part in ballots, clearing helper bits from every pixel ballot breaks derivatives along triangle edges (bright lines and specks on a cloud surface in PPSA21564). See the report on #11199.
2026-10-28 22:11:10 +13:00
Adrià 7fc0ae6008 Merge pull request #11199 from QRMOE/fix/shader-pixel-helper-lane-masks
fix(shader): keep pixel helper lanes out of guest lane masks
2026-10-28 08:54:16 +01:00
Michael Krumland-DunningandClaude Opus 5.5 254d7b416f fix(shader): translate the fused f32 fma forms in f32 denormal mode 2
v_fma_f32, v_fmac_f32, v_fmamk_f32 and v_fmaak_f32 threw "f32 denormal
mode 2 is not implemented" whenever FLOAT_MODE flushed f32 denormal
inputs but kept denormal results.

On RDNA2 (gfx1036) at round to nearest even, mode 2 flushes the inputs
and rounds the fused result once with gradual underflow, which the host's
Fma gives under DenormPreserve 32. The translation now matches all 5,596
measured triples for the four forms at IEEE 0 and 1. Mode 1 keeps
throwing: there the hardware flushes a result that is tiny after rounding
with an unbounded exponent even when the addend is nonzero.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 22:05:57 -07:00
Michael Krumland-DunningandClaude Opus 5.5 126b7b98a0 fix(shader): translate f32 fract, floor, ceil and frexp_mant in f32 denormal modes 1 and 2
All four threw "f32 denormal mode N is not implemented" whenever
FLOAT_MODE kept only one side of the f32 denormals.

On RDNA2 (gfx1036), in every f32 round mode and at IEEE 0 and 1, mode 2
gives the results of mode 0 and mode 1 those of mode 3 with a denormal
result flushed, which only v_fract_f32 of a positive denormal produces.
The translation now matches all 118 measured inputs in modes 1 and 2.
Mode 1 of the three that run host float operations on a kept denormal
needs DenormPreserve 32, as v_min_f32 does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 22:05:57 -07:00
Nicolas GonzalezandClaude Opus 5.5 2f25ab919f fix(shader): fence the LDS lock's critical section on MoltenVK
SPIRV-Cross emits the lock's acquire compare-exchange and release
exchange as relaxed Metal atomics, so the plain LDS loads and stores of
a locked 64-bit update were not ordered against the lock and contended
ds_add_u64 lost updates on an Apple M5 Pro. On MoltenVK the driver now sets
SpirvTarget::ldsLockFences, and the lock brackets its critical section
with workgroup-scope acquire and release OpMemoryBarriers, which become
threadgroup atomic_thread_fence with no execution barrier.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 23:37:56 -03:00
Adrià e0cd1259a9 Merge pull request #11254 from Michael-KD/fix/scalar-buffer-runtime-word3
fix(shader): ignore a runtime V#'s type for scalar buffer loads as RDNA2 does
2026-10-27 16:28:28 +01:00
Adrià 6f7cb75291 Merge pull request #9193 from imellag/feat/shader-barycentric-builtins-moltenvk
feat(recompiler): read I/J from barycentric built-ins on MoltenVK
2026-10-27 16:21:05 +01:00
Adrià 768e92f8b6 Merge pull request #9743 from frankea/fix/hull-reads-control-point-outputs
fix(shader): read other control points' off-chip outputs in hull programs
2026-10-27 12:00:31 +01:00
Adrià edabe9efa1 Merge pull request #11255 from Michael-KD/docs/vcc-descriptor-tuples-measured
docs(shader): record the VCC descriptor tuples measured on RDNA2
2026-10-27 08:28:15 +01:00
Adrià 42317c7f32 Merge pull request #11256 from Michael-KD/docs/array-comparison-through-2d-measured
docs(shader): record 2D-array comparison samples measured on RDNA2
2026-10-27 08:27:36 +01:00
Emanuele 03f7c1134f fix(shader): keep the position read of barycentric built-ins on MoltenVK
The I/J reads take the BaryCoordSmooth input, but gl_FragCoord was declared
only for the offset kinds, so its w was read as the constant 0 and the
fragment function never read [[position]]; Apple GPUs then return the
weights unnormalized. Declare it with the built-in, and select on
gl_FragCoord.w > 0, which a compiler cannot fold as it can
min(b, b + |w|).
2026-10-27 07:25:48 +01:00
Emanueleandyripper a95ced504c feat(recompiler): read I/J from barycentric built-ins on MoltenVK
MoltenVK exposes VK_KHR_fragment_shader_barycentric but its MSL step
rejects PerVertexKHR, so the extension is disabled there and a pixel
shader whose I/J VGPRs outlive their v_interp_p1/p2 pairs takes the
generated barycentric stages, which accept only triangle lists without
primitive restart on a device without geometry shaders.

A new target flag, fragmentBarycentricBuiltins, enables the extension
for its built-ins only. The host interpolation check then keeps the
leftover I/J reads (all perspective or all linear, at the fragment's
default position) and reads them from BaryCoordKHR or
BaryCoordNoPerspKHR, while the interpolated attributes stay hardware
varyings. Raw vertex parameters and I/J at an offset or a sample
position still take the generated stages. Apple GPUs return
unnormalized perspective weights unless the fragment function reads
[[position]], so each perspective read keeps a neutral use of
gl_FragCoord.w, loaded as a float. Devices with the full extension are
unaffected; the request serialization moves to version 45.

Co-authored-by: yripper <[email protected]>
2026-10-27 07:25:48 +01:00
Dean a453b29ebe Merge pull request #11434 from LeandroLP23/test/shader-cache-smb-posix-rename
test(shader): skip open-entry cache replacements where SMB has no POSIX rename
2026-10-27 18:38:46 +13:00
frankea 909a2f1f3b fix(shader): read other control points' off-chip outputs in hull programs 2026-10-27 03:47:24 +01:00
Dean d471a12b82 Merge pull request #11112 from Bram910/fix/shader-skip-unreachable-words
fix(shader): skip undecodable words that only follow s_branch or s_endpgm
2026-10-27 15:00:43 +13:00
Dean 37c6b4bc25 Merge pull request #8077 from 0xcrstn/ufc6/descriptor-web-fold
fix(shader): split descriptor webs whose paths fold or hold invalid arms
2026-10-27 14:56:47 +13:00
Dean d1de04f943 Merge pull request #7484 from AlxcBTW/pr/robust-loads
perf(recompiler): leave the descriptor-range comparison out of direct buffer loads when the device zeroes past the range
2026-10-27 14:56:32 +13:00
Dean 630211a866 Merge pull request #6612 from milescoviello/feat/tess-geometry
feat(agc): draw tessellation followed by an NGG geometry stage
2026-10-27 14:56:18 +13:00
Michael Krumland-DunningandClaude Opus 5.5 854be22d20 docs(shader): extend the 2D-array comparison measurement to every compare function
The 2D-array comparison results were measured with LESSEQUAL only. A
second gfx1036 run over all eight DEPTH_COMPARE_FUNC values (128
kernels) gives the same: a 2D-array address on a 2D T# ignores the
slice, and codes 1 and 56 return 0 under every function. Both entries
now say so.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 10:18:36 -07:00
Michael Krumland-DunningandClaude Opus 5.5 39f6f45487 docs(shader): record 2D-array comparison samples measured on RDNA2
A comparison or plain sample with a 2D-array address on a 2D T#
returns what the same sample with a 2D address returns, whatever the
slice, as measured with the hardware oracle on RDNA2 (gfx1036) for
formats 1, 7, 22 and 56 with point and bilinear filtering, while a
four-layer 2D-array T# over the same memory returns a different result
per slice. Codes 1 and 56 also compare to 0 with 2D-array addresses.
The three comparison debt entries keep gfx1013, cube comparisons and
the other formats' array comparisons as open.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 10:18:36 -07:00
Michael Krumland-DunningandClaude Opus 5.5 9c9c33821f docs(shader): record the VCC descriptor tuples measured on RDNA2
Buffer resources and MIMG samplers at register field 26 read s104,
s105, vcc_lo and vcc_hi, as measured with the hardware oracle on RDNA2
(gfx1036) in wave32 and wave64 with raw encodings, which LLVM's
assembler refuses. Loads, format conversion, bounds and stores through
the buffer tuple, and sampling through the sampler tuple, act as the
same words in ordinary SGPRs do, and a change to each of the four
words shows in the result. Both debt entries now keep gfx1013 as open.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 10:18:35 -07:00
Michael Krumland-DunningandClaude Opus 5.5 5abefb16ac fix(shader): ignore a runtime V#'s type for scalar buffer loads as RDNA2 does
A scalar buffer load through a V# read at run time recorded an
InvalidDescriptor fault when TYPE (word 3, bits 30-31) was nonzero, and
the dispatch wrote nothing. Measured with the hardware oracle on RDNA2
(gfx1036), s_buffer_load ignores the whole fourth word: OOB_SELECT,
TYPE, FORMAT, ADD_TID_ENABLE, INDEX_STRIDE, RESOURCE_LEVEL and DST_SEL
change no result, so the scalar path no longer checks TYPE. Vector
accesses keep the check. The debt entry now records the measurement
and keeps gfx1013 and a null base as open.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 10:18:33 -07:00
LeandroLP23andClaude Opus 5.5 b95b22cf16 test(shader): skip open-entry cache replacements where SMB has no POSIX rename
On Windows, WriteFileAtomically replaces a cache entry with a POSIX
rename so that readers and mappings of the old entry keep working.
Through an SMB share that rename fails with ERROR_INVALID_PARAMETER, and
the plain rename it falls back to is refused while the destination is
open or mapped, so agc_shader_disk_cache and shader_cache_file_read
failed with their temporary directory on such a share (#10833).

The POSIX rename moves into PosixReplaceByHandle, unchanged, and
PosixReplaceUnsupported probes it in a directory. Where it reports that
error, the tests skip only the replacements of an entry that a reader
holds open or the cache has mapped, and the disk cache test's cleanup
leaves its directory behind when the POSIX delete fails the same way;
any other failure still fails them. shader_cache_file_read also builds
its \?\ alias of a UNC path as \?\UNC\server\share. The limitation is
recorded in the shader debt file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 16:45:38 +01:00
0xcrstnandClaude Opus 5.5 ec06ba2973 fix(agc): read back descriptor faults of shaders that also use image tables
A shader with an image table map read its fault buffer back only when a
table record was poisoned, an SRT read was poisoned, it had window lane
guards or the loop guard was on. A DescriptorFault only set the fault
buffer, so with a valid table and no copied write nothing ran the fault
check, and a lane that took a folded descriptor web path or selected an
undefined arm read arm 0 or zeros with no report.

The compiled artifact now counts its DescriptorFault instructions
(descriptorFaults, stored in the shader disk cache, format 48), and the
readback gate requests the fault check when it is nonzero. The result a
capture materializes copies the count, and also windowLaneGuards, which
that copy had dropped, so the gate's window lane guard condition never
saw it. sizeof(CompiledShaderArtifact) is 288 and sizeof(RecompileResult)
552 with the new field.

agc_driver_descriptor_web_faults adds a wave32 shader that reads an image
table and then the descriptor web, storing only to LDS so no copied write
forces completion: it binds an image table and no BDA address table, a
valid arm and an unselected undefined arm stay clean, the folded path and
a selected undefined arm fault at the read, and nothing faults with EXEC
empty. Without the gate change the folded case does not fault.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 14:46:11 +02:00
0xcrstnandClaude Opus 5.5 ac0c125999 Merge upstream main into ufc6/descriptor-web-fold
Resolve the overlap with main's WindowLaneGuard and image-resource changes
by keeping both sides: DescriptorFault sits next to WindowLaneGuard in the
opcode list, metadata and side-effect switch, and its emitter next to
EmitWindowLaneGuard; optionalDescriptor is serialized after
remappedDepth1D; undefinedImageWords follows the new image helpers; the
descriptor web debt entry follows main's new entries.

The ImageResource field-count assertion is derived from the merged
structure (44 fields: main's 43 plus optionalDescriptor). sizeof
(ImageResource) stays 96 and sizeof(MemoryInfo) stays 80, so those
assertions are unchanged. The undefined-format test keeps its captured
regions in a variable, as MemoryRegionView no longer binds a temporary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 14:10:30 +02:00
Dean Galvin e0bd61fae2 Merge branch 'main' into pr/robust-loads 2026-10-26 23:10:10 +13:00
Bram910andClaude Opus 5.5 cece0ab167 fix(shader): report a skipped word's error on every decode exit
A branch into a skipped word was only reported when the sweep ended at
s_endpgm or s_code_end; a sweep that ran to the end of the code threw
the generic code-boundary error instead. Only the decoder's error types
are skipped now, so other exceptions propagate, and the debt entry
records the exception per skipped word and what a misaligned sweep
through an unreachable span puts in the program.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 11:08:51 +01:00
Bram910 433aa1dac9 Merge origin/main into fix/shader-skip-unreachable-words 2026-10-26 10:57:34 +01:00
Dean d9f5bf4d91 Merge pull request #11120 from shahulmubeen-a/fix/shader-1d-store-through-2d-array
fix(shader): write 1D storage images through 2D-array stores at slice 0
2026-10-26 21:58:24 +13:00
QRMOEandClaude Opus 5.5 5f10d0a229 fix(shader): keep pixel helper lanes out of guest lane masks
Pixel-stage ballots and EXEC reads count only lanes that are not helper
invocations, so a waterfall loop over a saved whole-quad EXEC picks and
clears live lanes only. In programs that execute s_wqm on EXEC, writing
EXEC from a value keeps a helper invocation active while a live lane of
its quad is, so implicit-LOD sampling after a save/restore still has its
helpers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 09:19:15 +01:00
Dean 701616674a Merge pull request #10708 from Michael-KD/test/sdwa-cvt-f32-ubyte-measured
test(shader): pin SDWA v_cvt_f32_ubyte source selects measured on RDNA2
2026-10-26 11:10:38 +13:00
Bram910andClaude Opus 5.5 df5555a905 docs(shader): move the unreachable-words debt entry next to the control-flow entries
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 19:40:23 +01:00
Shahul Mubeen AandClaude Opus 5.5 b9d00c5d80 fix(shader): write 1D storage images through 2D-array stores at slice 0
An image_store with DIM 2D_ARRAY through a 1D T# had no runtime image
mode, so the dispatch stopped with "image descriptor is incompatible
with the static runtime image interface". #2348 added a 1D mode for
DIM 2D stores only.

Write-only 2D-array storage images now get the same 1D mode as the 2D
case. On RDNA2 (gfx1036, hardware oracle) such a store writes texel x
and ignores y when the slice is 0, and writes nothing for any other
slice, with DEPTH 0 or 3, so the store is skipped unless the slice is 0.

New execution test agc_driver_image_store_line_through_plane_array.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 00:10:03 +05:30
Bram910andClaude Opus 5.5 e1213fd473 fix(shader): skip undecodable words that only follow s_branch or s_endpgm
The RDNA program decode sweeps linearly up to the last s_endpgm past the
furthest direct branch target, so it also decoded words that no path
reaches and threw on any it could not decode. A word directly after
s_branch, s_endpgm or s_code_end that fails to decode is now skipped;
the decode still throws that word's error when a direct branch or
s_call_b64 targets it, and a failure on a word reachable by fall-through
is unchanged. The control-flow graph starts the block after s_branch and
s_endpgm at the next decoded instruction instead of the next word.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 19:15:40 +01:00
Adrià e317f41d59 Merge pull request #10440 from SuarezPM/ai/atomic64-keyed-tables
feat(shader): support 64-bit image atomics through keyed image tables
2026-10-25 11:58:35 +01:00
Dean b91a6a60c5 Merge pull request #10595 from TechLevelZero/fix/f32-conversion-denormal-modes
fix(shader): translate f32 conversions in f32 denormal modes 1 and 2
2026-10-25 23:54:07 +13:00
Dean 10a41a0d50 Merge pull request #10612 from imellag/test/agc-skip-cull-distance-without-support
test(agc): skip cull distance cases on devices without shaderCullDistance
2026-10-25 21:52:25 +13:00
milescovielloandClaude Opus 5.5 cd5fc9e838 feat(agc): draw tessellation followed by an NGG geometry stage
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from #6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 08:32:37 +00:00
Dean Galvin eb3dd54501 Merge main into pr/robust-loads 2026-10-25 12:15:18 +13:00
Adrià c8d34aa8f4 Merge pull request #6009 from zmeizy/claude/minmax-f32-denormal-modes
fix(shader): translate f32 min and max in f32 denormal modes 1 and 2
2026-10-24 22:13:03 +02:00
Michael Krumland-DunningandClaude Opus 5.5 952cc18efa test(shader): pin SDWA v_cvt_f32_ubyte source selects measured on RDNA2
v_cvt_f32_ubyte0 to v_cvt_f32_ubyte3 take byte N of source 0 after
SRC0_SEL and SRC0_SEXT select and extend it, as measured with the
hardware oracle on RDNA2 (gfx1036) for all seven source selects with
and without SRC0_SEXT. The test checked four combinations derived from
the ISA guide; it now checks every combination against the measured
results, and the debt entry keeps only what is not measured: gfx1013.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 11:26:19 -07:00
Adrià d0e7fe7beb Merge pull request #5941 from zmeizy/claude/mullit-f32-denormal-modes
fix(shader): translate v_mullit_f32 in f32 denormal modes 1 and 2
2026-10-24 19:36:11 +02:00
Adrià e7e99adcc4 Merge pull request #6010 from zmeizy/claude/add-mul-f32-denormal-modes
fix(shader): translate f32 add and multiply in f32 denormal modes 1 a…
2026-10-24 18:20:07 +02:00
TechLevelZeroandClaude Opus 5.5 753767f86a fix(shader): translate f32 conversions in f32 denormal modes 1 and 2
The f32 conversions that only flush their inputs follow bit 0 of the
FLOAT_MODE f32 denormal field, as the f32 compares do: mode 1 keeps
denormal inputs like mode 3 and mode 2 flushes them like mode 0.
v_cvt_pk_u8_f32 also follows a round mode set at run time.

Measured on RDNA2 (gfx1036) with the hardware oracle.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 16:23:33 +01:00
Adrià 522e32e3b6 Merge pull request #7550 from gjonn/fix/shader-resinfo-any-descriptor-dimension
fix(shader): answer image_get_resinfo on any T# dimension
2026-10-24 15:30:15 +02:00
Adrià 18e85391b4 Merge pull request #9746 from imellag/fix/shader-empty-loop-continue
fix(shader): route a loop's back edge through an empty continue block when its latch holds instructions
2026-10-24 14:53:54 +02:00