Repository navigation
fix(shader): read a chased pointer's high word at its own offset - #9749
EagleBearerYS wants to merge 135 commits into
Conversation
An S# read from a V# that a scalar record selects through a pointer was refused, so recompiling failed with "GetSamplerResource dword 0 is not a valid runtime value". The nested branch now takes sampler columns: they get child tables per distinct V# like nested T#s, share equal children, count against the nested key budget and the S# entry budget, and fault on an unmapped, non-buffer or uncaptured parent. The plan decoder accepts a nested sampler column; the plan encoding is unchanged.
An S# or T# loaded through a pointer that a scalar record holds was refused when a Phi merged the pointer's low word with constants, so recompiling failed with "GetSamplerResource dword 0 is not a valid runtime value". Such a column is now pointer-keyed: the snapshot captures every record's pointer and the descriptor behind it, the map holds boykopovar#7223's sorted pointer dictionary with descriptor records as its codes, and the GPU looks up the actual 64-bit pointer. A pointer that was not captured faults as outside the snapshot, and a null one as unmapped. The plan gains TableColumn::pointerKeyed and the snapshot gains ImageTableColumnSnapshot::pointerKeyed, so the disk-cache format moves to 43 and the image-table ABI to 4.
A T# loaded through a record pointer whose low word passes nested Phis was refused when one Phi arm held a word of a Ballot lane mask, as in a waterfall loop that reuses the pointer's SGPR for an s_and_saveexec or v_cmp mask, so recompiling failed with "GetImageResource dword 0 is not a valid runtime value". A pointer-keyed column now accepts such a word as an arm that is not a record pointer, as it does for constants, and still refuses any other foreign arm. At run time a pointer built from a lane mask is not a captured pointer and faults as outside the snapshot. A pointer-keyed column also accepts low-word reads, and a high-word read, of the same record word under different keys: same table, record offset, stride and addend. The GPU looks the pointer up by its value, so the key does not matter there. The column takes its table and record offset from the high-word read, which dominates the descriptor load. A shader that planned before plans the same way, so the disk-cache format stays at 43.
…ed record pointer A T# loaded through a record pointer was still refused with "GetImageResource dword 0 is not a valid runtime value" when the pointer's low word passed ANDs with lane masks, as a waterfall loop that copies EXEC into the pointer's SGPR builds them, or when its high word was a Phi of the record's high word read under several keys. For a pointer-keyed column, the walk of the low word now takes an AND with a lane-mask operand (a Ballot word, or an AND or Phi of only Ballot words and immediates) and keeps walking its other operand, so its record reads must still match the column and anything else still refuses. The high word is walked the same way: its record reads must be the record word at the low word's offset plus 4. A high word that is one read still gives the column its table and record offset, as before. Otherwise the table comes from a record read whose V# words are defined before the descriptor load, and the record offset from the high word, which the GPU does not read for a pointer-keyed column. A high-word arm read from another buffer, such as one whose V# is loaded through a pointer, stays refused. A shader that planned before plans the same way, so the disk-cache format does not change.
… a pointer-keyed record pointer A T# loaded through a record pointer was still refused with "GetImageResource dword 0 is not a valid runtime value" when a Phi of the pointer's low word merged the record read, a zero, and the waterfall's lane mask with the handled lane's bit cleared, BitwiseAnd32(CompositeExtractU32x4(Ballot(...), 0), BitwiseNot32(ShiftLeftLogical32(1, index))), as s_ff1, s_lshl and s_not with s_and, or s_andn2, build it in the SGPR the pointer reuses. The walk took only Ballot words and ANDs of them as lane masks, so it walked into the NOT and refused. A lane-mask operand is now a Ballot word or the loop's lane bit, a shift of 1 by an index from FindILsb32, FindUMsb32 or ReadFirstLane (through the AND, add, subtract and select that s_ff1_i32_b64, s_bitset0 and the shift's own mask put around it), or an AND, OR, NOT or Phi of only those and immediates. An arm of the pointer that is entirely such an operand is skipped. An AND with a record read in it still has the read matched against the column, and anything else still refuses. agc_driver_pointer_phi_lane_not_table builds that shape in a wave64 waterfall: the low word's Phis merge the record read at +0, a zero and the lane mask without the handled lane's bit, cleared by s_not and s_and and by s_andn2, and the high word is one read at +4. Each lane samples the T# of its record, and every masked word faults outside the snapshot. agc_driver_pointer_vsharp_select_table reads a record keyed by ReadFirstLane(SelectU32(LogicalAnd, IAdd32, Phi)), a pointer from it, a V# through the pointer and the T# through the V#; it passes without this change and keeps that chain checked, including a record pointer moved to the other V# without a recompile. Shaders that planned before plan the same way, and a refusal is never cached, so the disk-cache format does not change.
…keyed records A pointer-keyed record pointer now also takes lane-mask ANDs, the waterfall loop's lane bit and its OR and NOT forms, and a high word merged from the record's next word. A high word read from a second buffer stays refused.
The low and high words of a pointer-keyed record pointer were walked separately, so a high-word arm on a path whose low word is a lane mask refused the plan even though that pair is no pointer. Ratchet & Clank: Rift Apart (PPSA01474) stops this way at LoadAddressU32@pc=0x9a30: one high-word arm reads a second buffer, and on that edge the low word is a lane mask, the waterfall loop reusing the SGPR pair. Walk the two words together. Where both are Phis of one block, each low-word edge takes the high word of the same predecessor. An edge whose low word is a constant or a lane mask is skipped with its high word. A record low word still needs every high word it can meet to be a constant, a lane mask or the same record column at offset + 4, so a second-buffer high word paired with the record word stays refused. agc_driver_pointer_phi_high_second_lane_table adds the lane-mask low word to the second-buffer arm: it plans, each group samples the T# its record selects, and that arm faults outside the snapshot.
…nter The two words of the pointer are now walked edge by edge, and an edge whose low word is a constant or a lane mask is skipped with its high word. A high word read from a second buffer stays refused on an edge whose low word is the record word.
Brings boykopovar#8991 (match image-table T# halves offset before and after readfirstlane). ResourceTracker.cpp: main's FirstLaneOffset, ParseFirstLaneOffset and SameFirstLaneOffset go before TryMakeTableColumn, which keeps this branch's signature with the buffer parameter. Main's first-lane base check in the column loop merged on its own.
…ane-masks Brings boykopovar#7395's merge of main bd4d801, with boykopovar#8991. It merged without conflicts.
TryMakeIndirectColumn refused every pointer hop once the record's pointer words were merged, so a T# read through a pointer loaded from a pointer-keyed record pointer stayed unplanned (Gran Turismo 7's World Map compute shaders, issue boykopovar#6191). Only buffer handles still refuse hops: the materializer keys the records by the innermost pointer before it follows the hops, and the plan's parent pointer is that innermost one.
…one-key child From hugodearaujo's change on boykopovar#8939 (Marvel's Spider-Man 2, PPSA03016).
Spider-Man 2's shape: a record keyed by a first-lane read, its dwords 2-3 a pointer, a V# loaded at that pointer plus 0xa0, and the T# read at offset 0 or 0x40 of that V#'s buffer with no second key. Two records point at V#s of different T#s; a moved record pointer and a moved V# must change the result without recompiling.
… pointer-keyed record pointer A T# read at a pointer that a shader chases conditionally from a pointer-keyed record pointer, loading a V# at a fixed offset of the pointer and reading the next pointer from that buffer, stayed unplanned: the merged pointer's chase arms read another buffer at another offset than the record word, so PointerRecordRead refused them (Ratchet & Clank: Rift Apart stops at compute LoadAddressU32 with this shape). The walk now takes such an arm when its V# is read from a pointer that is the record pointer or another chase arm, records each distinct chase as a hop of the column, and refuses a chase that reaches itself or a depth over 4. The snapshot then also captures every record pointer's chase closure up to that depth as pointer-keyed entries, each with the T# at its own offset, so the GPU's lookup finds the pointer the shader reached.
PointerRecordPairs found an existing chase site by its V# alone. A second chase arm that reads its next pointer through the same V# at other words therefore kept the first arm's PointerChase, and the snapshot never followed the second arm: a T# behind a node whose V# holds two links (words 0 and 1, words 2 and 3), each taken in its own lanes, faulted as outside the snapshot when the second link was taken. Sites are now keyed by the V# and the whole PointerChase, so each word pair of one V# is its own chase in the column and in the snapshot's closure. This follows the chase work for Ratchet & Clank: Rift Apart (PPSA01474); its trace has not shown this shape yet.
A pointer chase arm whose next pointer is rebuilt from two words that are not adjacent stayed unplanned: ChaseHighRead took the high word only at the low word's immediate plus 4, so the walk refused the arm. Ratchet & Clank: Rift Apart (PPSA01474) stops this way at compute LoadAddressU32@pc=0x13bc0 with "GetImageResource dword 0 is not a valid runtime value": after two chase steps through a V# at the pointer plus 0x60, its third step loads a V# at the pointer plus 0x110, reads 16 dwords from 0x40 with one s_buffer_load_dwordx16 and rebuilds the next pointer from dword 5 (0x54) and dword 11 (0x6c). PointerChase now keeps the high word's own immediate, readHighImmediate. The walk takes a high read through the low read's V# (or an equivalent one) at the same buffer offset when its immediate is 4-aligned and differs from the low word's, and the snapshot reads the next pointer's high word at that immediate. The shader disk cache stores the field and refuses a plan whose high immediate is unaligned or equals the low one (format 48). Suggested by Tamalero's trace on boykopovar#9633 (issuecomment-6338256607), which also proposed the readHighImmediate field.
|
@Tamalero this is the follow-up for the third read you traced on #9633. |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
MarcZX10
left a comment
There was a problem hiding this comment.
I found no logic defect in the new high-word-immediate handling: the tracker records it, the snapshot reads it, the cache serializes/validates it, and the added positive/refusal tests cover the separate offsets. The PR report provides substantial repeated Linux test and VVL evidence. Current-base git diff --check and conventions pass, and merge-tree with current main is clean. I did not run the GPU suite locally; the workspace has no configured build and under 700 MB free.
Please update the integration checklist before approval. The PR says it is stacked on #9633, which is still open, but currently lists only Depends on: #9457; record #9633 as the prerequisite (the earlier stack is transitively included by it). Also this head is based on 3ca07d0, 19 commits behind current main b7d1d47. Rebase/refresh it and rerun the focused shader tests. The VVL evidence I see for this increment compares #9633 to this PR; after the refresh, include the required same-GPU main versus final-head ctest -V comparison with the prescribed environment, confirm the layer loaded, and compare VUID- output.
✅ NVIDIA GPU test: passedPR head
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (21, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 495 tests)Skipped (45)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
Main's 1D array layer rows add a loop to the table snapshot that records each table's registered image views, keyed by the table's index. This branch copies a column's records in a helper that also serves nested child columns, which have no table index, so the loop stays in the snapshot of the top-level table after the copy.
✅ NVIDIA GPU test: passedPR head
Unstable on main (2, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (21, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 510 tests)Skipped (45)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
…-arm Resolve the disk-cache format conflict at 74 and preserve the pointer-Phi bit-field fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XairRrR
left a comment
There was a problem hiding this comment.
Re-checked — approved
The three non-blocking findings from my review of c4f25ba are resolved. Since then the PR added a disk-cache round trip for readHighImmediate (babbb0e), the debt entry now names the two refusals (eac5dce), and the description is updated. The rest is stack and main merges plus disk-cache format bumps. The merged tree builds, the focused tests pass, the validation comparison with main shows no new VUID-, and dropping the field in the decoder makes the new check fail.
What changed since my last review
- babbb0e (test):
verifyPlanRoundTripbuilds a pointer-keyed column with onePointerChase{8, 16, 4, 24, 40, {}}, so the high word is read 16 bytes past the low word. It encodes and decodes the plan and requires the chases to come back equal (ShaderDiskCache.cpp#L2389-L2397). The value 40 is 4-aligned and differs fromreadImmediate24, so the decoder's validation accepts it. - eac5dce (docs): the chase entry (shader.md#L64) now starts with what stays refused. That includes a high word read at the low word's immediate, and a chased V# whose base leaves either word's address unaligned. It also says the console's behaviour at an unaligned base is not measured.
- 4769d5a and the commits brought in from #7395/#7223 (nested budget reset on retry, the epoch check for a lone nested sampler table, the Windows PATH fix): these belong to the base PRs. I built and ran them only as part of the merged tree.
FormatVersionis now 72 (ShaderDiskCache.hpp#L16), abovemain's 52.- The description's What and Tested sections were updated, along with the author's reply in the discussion.
What I ran
- Head
13e0df876dc226aedd498201c5f8725f2a664ccd,main4f41f4c375f5abb487dbd184fbc150f31994d762, merged treeef1441126d788e6d2417a6e90d976e431cfccf37(Debian 13 VM, GCC 14.2.0, lavapipe on Mesa 26.1.6).
git diff --check 4f41f4c375f5abb487dbd184fbc150f31994d762...13e0df876dc226aedd498201c5f8725f2a664ccd
python3 tools/check_conventions.py --base 4f41f4c375f5abb487dbd184fbc150f31994d762
# negative control: ShaderDiskCache.cpp decoder reads readHighImmediate into a discarded local
ninja -C build -j32 -l32 libs agc_shader_disk_cache_tests
ctest --test-dir build -R "^agc_shader_disk_cache$" --output-on-failure
# restore ShaderDiskCache.cpp from ef1441126d, rebuild
ninja -C build -j32 -l32 libs tests/agc_shader_disk_cache_tests agc_driver_image_table_tests
ctest --test-dir build -j8 --test-load 32 -R "^agc_shader_disk_cache$|agc_driver_pointer_|agc_driver_nested_|agc_driver_image_table"
git status --porcelain| Check | Result |
|---|---|
git diff --check |
Clean |
check_conventions.py |
All conventions checks passed. |
Build and libs (script) |
Pass |
| Selected tests (script) | 2,235 run, no new failures, no timeouts. 7 known failures that also fail on main |
| Validation layer comparison (script) | 789 tests; layer loaded in 788, layer_missing_in empty; 0 tests with a new VUID- |
| Focused tests, after restoring the merged file | 27 of 27 pass |
git status --porcelain afterwards |
Empty |
Negative control output
1/1 Test #2168: agc_shader_disk_cache ............***Failed 0.01 sec
a pointer chase whose high word has its own immediate changed in a disk-cache round trip
Previous findings
- The description didn't match the head (format number, refusal controls): resolved. The What bullet now gives #9633's 70 → 72, which matches
ShaderDiskCache.hpp:16. The refusal-control bullet now says c4f25ba removed those checks. - Nothing round-tripped
readHighImmediatethrough the disk cache: resolved. babbb0e adds the check. I made the decoder read the field into a discarded local (ShaderDiskCache.cpp:1365), andagc_shader_disk_cachethen fails with the new message. With the merged file restored it passes. This matches the author's reported negative control. - The debt line missed the unaligned-base and shared-immediate refusals: resolved. Both are now in the chase entry, along with the unmeasured question of whether the console reads the dword-aligned address. The entry passes the conventions check's length limit.
New findings
Blocking
None.
Non-blocking
- One detail in the description is out of date. The disk-cache bullet says "
mainis at 51 since #6959". Onmain4f41f4c,FormatVersionis 52. The PR's 72 is still above it, so nothing breaks, but the ladder in the description should say 52 formain.
Not verified
- The base PRs' code (#9633 and below, including the #7395 commits brought in since my last review). I built and tested it only as part of the merged tree; this approval covers this PR's increment over #9633.
- No title run, by policy. The Rift Apart results are Tamalero's and oneandonlydean's.
- Windows build and tests, and any GPU other than lavapipe on this machine.
- A warm-cache run of the split-chase shader end to end. The new round-trip test covers the encoder and decoder only.
✅ NVIDIA GPU test: passedPR head
Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 531 tests)Skipped (48)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
boykopovar#7223 has merged. The conflicts are this branch's additions on top of it: its tests in the image-table test lists, pointerKeyed in the image-table column and its equality check, the plan encoder's field count and list version, and FormatVersion 63. agc_shader_memory_tests.cmake merged without a conflict but registered agc_shader_nested_snapshot_retry twice: boykopovar#7223's block after agc_shader_descriptor_phis and this branch's before it. The merge keeps this branch's block, which adds agc_shader_nested_sampler_snapshot_retry, at boykopovar#7223's place.
e94fb3f is boykopovar#7395 with its merge of main after boykopovar#7223. The two conflicts are this branch's own changes over boykopovar#7395: FormatVersion 66, and its wording of the pointer-keyed image-table debt entry.
4769d4a is boykopovar#8939 with boykopovar#7395's merge of main after boykopovar#7223. The one conflict is this branch's FormatVersion 67.
6e403b4 is boykopovar#9457 with the stack's merges of boykopovar#7395's main merge after boykopovar#7223. The conflicts are this branch's own: FormatVersion 70 and its pointer-keyed chase debt entry.
…ords-on-c2 f498717 is boykopovar#9633 with the stack's merges of boykopovar#7395's main merge after boykopovar#7223. The conflicts are this branch's own: FormatVersion 72 and its wording of the pointer-keyed chase debt entry.
✅ NVIDIA GPU test: passedPR head
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (13 IDs in 555 tests)Skipped (50)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
…-arm Follow the stack onto main c2eafe4. The merge is clean: FormatVersion stays 74 and this PR's own diff is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019xuZ6A1q9uKgkTRkrHcoZb
What
This is stacked on #9633.
With #9633, Ratchet & Clank: Rift Apart (PPSA01474) gets past its 0x10b84 stop. It then stops at the next T# load, in compute 0x116bb67100 (Tamalero's run):
Tamalero's trace of the same shader (comment) shows a third chase step:
s_buffer_load_dwordx16from 0x40.#9633's chase arm required the high word at the low word's immediate + 4, so the walk refused this step. Its V# offset and its depth (3 of 4) were already covered. #9633's 2c1a650 already gives each word pair through a V# its own chase site, so the new high immediate becomes part of that site.
The change:
PointerChasegainsreadHighImmediate, the high word's own immediate. Tamalero's trace suggested the field.The tracker takes the edge's high-word read when it has:
The old rule, low + 4, is one case of this.
The snapshot reads each chased pointer's high word at that immediate.
The shader disk cache encodes the field.
FormatVersiongoes from fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 70 to 72.mainis at 56 since feat(shader): resolve nested image tables through runtime pointers #7223. Ours take one number each: feat(shader): raise the image limit to 128 and name the counts in its refusals #10489 57, feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642 62, feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 63, fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939 66, fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 67, fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 70, fix(shader): plan several T#s read through one pointer-loaded V#, keeping the V# real for their other uses #9790 71, fix(shader): read a chased pointer's high word at its own offset #9749 72 and fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969 73. The other open PRs seen changing it hold 51 (fix(agc): preserve proven base formatted buffer read extents #14944), 53 (fix(shader): serve ds_ordered_count in wave launch order #12944), 56 (perf(agc): GPU descriptor heap on VK_EXT_descriptor_heap (APS5_GPU_HEAP) #9508, the same asmain), 65 (perf(agc): bound instance-indexed guest buffers by the draw's instance range #14032), 68 (fix(shader): narrow a goto junction Phi to the arm its branch allows #14636), 69 (feat(shader): flatten oversized 1D image arrays to 2D #14871) and 74 (fix(shader): skip a bit-field low word in a pointer-keyed table's Phi #14853). A decoded chase with an unaligned high immediate, or one equal to the low immediate, is refused.Debt: fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's chase line now says each word is read at its own fixed immediate, through the arm's V# at the arm's buffer offset.
The chased V#'s base (52ae654): on a diagnostic build of this PR, Tamalero's run stopped after 781 s on
AGC driver: invalid shader memory read address(comment), on a V# read as4f81f1f 0 ffffffff 0.TableSnapshotter::Chase()checked the four words it reads as a V#, but not the alignment of the address it then reads through that V#, and the driver's shader memory reader throws on an unaligned address.Chase()now treats an unaligned base as unresolved, as the snapshot's other runtime-address reads do. That step isn't captured, so a dispatch that takes it faults as outside the snapshot, like a link to memory the snapshot can't read.Overlap:
git merge-treeconflicts are the same as fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's head's, so it adds none: perf(agc): GPU descriptor heap on VK_EXT_descriptor_heap (APS5_GPU_HEAP) #9508, fix(shader): keep a v_writelane lane known across computed-index window stores #8881, fix(shader): resolve table column pointers through Phi nodes #7880, feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642, feat(agc): draw alpha-tested packed-target merges that write depth as a depth pass and an EQUAL merge pass #9335, feat(agc): blend into 11_11_10 float color targets in the pixel shader #9020, fix(agc): round the color compare array layer half to even and compare NOT_EQUAL unordered (supersedes #907) #8625, feat(agc): merge partial writes into 4_4_4_4 UNORM color targets #8564, fix(shader): split descriptor webs whose paths fold or hold invalid arms #8077, fix(shader): defer guarded fragment V# type faults #7689 and fix(shader): bound image-table snapshots by table-key ranges #7684. fix(shader): write a GCN v_cmpx result to its VCC or SDST as well as EXEC #9671 and fix(runtime): isolate host worker MXCSR #7622 merge cleanly.Tested
Linux, Mesa llvmpipe: the new
agc_driver_pointer_chase_split_tablereproduces Rift Apart's shape in hand-written RDNA:It checks every taken and skipped step, including a node only the third step reaches, then a moved link, then a link outside the snapshot, which faults as outside the snapshot.
Refusal controls, refused on both trees until c4f25ba removed them, since they required valid shapes to be refused:
Red: with fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's tracker and materializer, the test fails with "GetImageResource dword 0 is not a valid runtime value", Rift Apart's text. A scratch build whose closure stops one step short makes the T# fault, so the test does prove the third step.
GitHub's runners (run):
CI's Linux job mirrored on a cloud Linux machine. The failures are the machine's three IPv6 tests, a timing test that passes alone (
agc_driver_sgpr_pattern_fill_keys), and two lavapipe JITIllegalfailures on a new host CPU, which also fail on an unrelated tree.Validation layer, fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 against this PR (CONTRIBUTING's shader rule), on one GitHub Linux runner (run):
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation,ANYPS5_NO_SHADER_CACHE=1,ANYPS5_REQUIRE_VULKAN=1andctest -V. The device was llvmpipe (LLVM 20.1.2) on Mesa 25.2.8, Ubuntu 24.04.5.VK_LAYER_KHRONOS_validation5 times on fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's tree and 7 with this PR. Neither log haswas not found but was requested by env var VK_INSTANCE_LAYERS.VUID-VkDeviceCreateInfo-pNext-pNext. This PR adds noVUID-message.check_conventions.py: passes, with no comment lines added.Ratchet & Clank: Rift Apart (PPSA01474), by @Tamalero (comment): content 01.005.003, Linux (CachyOS, kernel 7.2.9), GCC 16.2.1, Release, RTX 4090 (NVIDIA 615.78.08), the executable relinked once with this head's relinker, cold shader cache, no input.
LoadAddressU32@pc=0x13bc0, at the same sites as on fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633.ShaderRecompiler::Recompile: sampler resource limit exceeded.agc_shader_replay. The control refuses both at the T# load; with this PR both pass it and stop on the sampler limit,ShaderInfo::MaxSamplers = 32inAddSampler.After merging fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's refreshed head (820dc40; this PR's own diff is unchanged), on GitHub's runners (run):
VK_LAYER_KHRONOS_validation3 times onmain's tree (the three of these tests it has) and 100 times with this PR, and neither log haswas not found. Both logs report onlyVUID-VkDeviceCreateInfo-pNext-pNext, so this PR adds noVUID-message. The device was llvmpipe on Mesa 25.2.8, Ubuntu 24.04.5.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.6db7b36,
mainb7d1d47 merged in (clean; this PR's own diff is unchanged), on GitHub's runners (run):main's tree ran the three of them it has. The loader insertedVK_LAYER_KHRONOS_validation3 times onmainand 100 times with this PR, and neither log haswas not found. Both logs report onlyVUID-VkDeviceCreateInfo-pNext-pNext, so this PR adds noVUID-message.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.b2d4afc,
mainc55d7c8 merged in (clean; this PR's own diff is unchanged), on GitHub's runners (run):main's tree ran the three of them it has. The loader insertedVK_LAYER_KHRONOS_validation3 times onmainand 100 times with this PR, and neither log haswas not found. Both logs report onlyVUID-VkDeviceCreateInfo-pNext-pNext, so this PR adds noVUID-message.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.8abb8a4, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 6b64604, which merges
main0db47b2. The only conflict wasShaderDiskCache.hpp'sFormatVersionline:mainmoved to 45 (fix(shader): normalize offset perspective barycentrics after interpolation #7831), and this branch keeps its 48. On GitHub's runners (run), the pointer, nested, image-table and disk-cache sets (28 tests) pass 10 runs in a row on Linux. On Windows the set has 30, with two Windows-only disk-cache tests: they build, 5 pass 10 runs in a row, and the other 25, which need a Vulkan device, skip. The libc and libkernel suites pass on both, run withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners. An earlier run linked here didn't run this set, so it's replaced.a36e95b, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 5b6c96f (which carries feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's and fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939's merges of
main379b1dc). It's clean apart fromFormatVersion, which goes to 52: fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 is at 48 now, and feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000, fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969 and feat(shader): raise the image limit to 128 and name the counts in its refusals #10489 take 49 to 51. This PR's own diff is otherwise unchanged.agc_shader_bindless,agc_shader_memoryand the^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_tableand^agc_shader_disk_cachetests. Linux: 30 run, 30 pass, 0 skip, 0 fail. Windows: 32 run, 7 pass, 25 skip (Vulkan device tests; the runner has none), 0 fail.^agcset once (run): Linux 985 run, 920 pass, 64 skip, 1 fail; Windows 1004 run, 272 pass, 730 skip, 2 fail. The failures areagc_driver_sgpr_pattern_fill_keyson Linux ("the dispatch completed 17 times without a pending write over the keys") andagc_driver_pipelined_metadata_passand its_draw_pipelinevariant on Windows (vkCreateInstancereturns -9 on the device-less runner).main379b1dc shows the same three with the same messages (run);agc_driver_sgpr_pattern_fill_keysfailed 1 of 4 runs there.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.Ratchet & Clank: Rift Apart (PPSA01474) with feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000's limits, by @oneandonlydean (comment), on
test/9749-sampler-masks(b340d22, feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000's sampler limits on this PR's earlier head b2d4afc): one 600 s run from a cold shader cache withAPS5_DUMP_IR=all. Nosampler resource limit exceededline, nowhat()or terminate and no stop line: it ran the whole 600 s. 7840 IR blocks were dumped. The highest shader pc is 0x1f2c8, and 980 block lines are at or past 0x13bc0. This covers that branch, not this PR's current head.7bcb8f4, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 72f48b7 (which carries feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge of
mainc9b2660). The only conflict wasFormatVersion, which goes to 55. This PR's own diff is otherwise unchanged. On GitHub's runners, 10 runs (run) of the pointer, nested, image-table and disk-cache sets (agc_shader_bindless,agc_shader_memory,^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_table,^agc_shader_disk_cache): Linux: 30 run, 30 pass, 0 skip, 0 fail. Windows: 32 run, 7 pass, 25 skip (no Vulkan device), 0 fail. The libc and libkernel suites pass on both, run withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.67053a3, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 839cad8, which carries feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge of feat(shader): resolve nested image tables through runtime pointers #7223's f1cc524 (yabanana's merge of
mainc8d34aa). Clean:FormatVersionstays at 55, and this PR's own diff is unchanged: the merge brings in exactly what fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's merge did (249 files). On GitHub's runners, 10 runs (run) of the pointer, nested, image-table and disk-cache sets (agc_shader_bindless,agc_shader_memory,^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_table,^agc_shader_disk_cache): Linux: 30 run, 30 pass, 0 skip, 0 fail. Windows: 32 run, 7 pass, 25 skip (no Vulkan device), 0 fail. The libc and libkernel suites pass on both (143 and 206 tests on Linux, 170 and 222 on Windows), run withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.52ae654, the chased V#'s base, red/green against 67053a3 on GitHub's runners (run).
agc_driver_pointer_chase_tablegains a case where the V# at a chased pointer that no group's step goes through has an unaligned base, and requires that the snapshot records no range that starts unaligned.agc_shader_bindless,agc_shader_memory,^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_table,^agc_shader_disk_cache): Linux: 30 run, 30 pass, 0 skip, 0 fail. Windows: 32 run, 7 pass, 25 skip (no Vulkan device), 0 fail.agc_driver_pointer_chase_tableonce on Linux (llvmpipe) withVK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation,ANYPS5_NO_SHADER_CACHE=1andANYPS5_REQUIRE_VULKAN=1: the layer was inserted once on each tree, neither log haswas not found but was requested, and both report onlyVUID-VkDeviceCreateInfo-pNext-pNext, so the commit adds noVUID-message.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.7d6ab8a: 5e0d923, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 68d0464, the format commit fc0c03d, and 7d6ab8a, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's merge of
main0cd07dc (run).main0cd07dc. Clean here, and this PR's changed lines are the same.tests/execution,agc_driver_pipelined_metadata_passfails atvkCreateInstance(-9) on GitHub's device-less runner, before this PR's code;mainfails it the same way there (run), and upstream's Windows job builds it as a skipped stub.exec_arguments,guest_timed_join_import_libkernel_sysandguest_timed_join_import_libkernel_webfail at their setup in the verify's Windows build (FileNotFoundErrorstarting the title, or copying the libraries they load), and pass inmain's own Windows job at 1829def (job). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.ac64b90, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's b5a199b, which carries feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's test-only commit ca14648 (the nested-sampler test no longer asserts that an S# with another consumer is refused) (run). Clean, and this PR's changed lines are the same. The chase, split-chase, SGPR-fill, nested-sampler and pipelined metadata tests with the disk-cache, bindless and shader-memory tests. Linux ran them 10 times with no failure: 9 run, 9 pass, 0 skip, 0 fail. Windows: 11 run, 6 pass, 4 skip (the Vulkan device tests), 1 fail: on our verify's Windows build, which compiles
tests/execution,agc_driver_pipelined_metadata_passfails atvkCreateInstance(-9) on GitHub's device-less runner, before this PR's code;mainfails it the same way there (run), and upstream's Windows job builds it as a skipped stub. Suites: libc and libkernel pass on Linux (166 and 264). On Windows libc passes (194), and libkernel passes 283 of 286:exec_arguments,guest_timed_join_import_libkernel_sysandguest_timed_join_import_libkernel_webfail at their setup in the verify's Windows build (FileNotFoundErrorstarting the title, or copying the libraries they load), and pass inmain's own Windows job at 1829def (job). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.32ba4ec, a merge of 037f579, fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's merge of fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's 9a44f18, which carries
main38ccd50 and with it fix(agc): sample cube descriptors with fewer than six slices as six faces #11507'sFormatVersion49 (run). Clean:FormatVersionstays 56 (see What), and this PR's diff over fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 is the same. The chase, split-chase, SGPR-fill, nested-sampler and pipelined metadata tests with the disk-cache, bindless and shader-memory tests and fix(agc): sample cube descriptors with fewer than six slices as six faces #11507'sagc_driver_image_sample_short_cube. Linux ran them 10 times with no failure: 10 run, 10 pass, 0 skip, 0 fail. Windows: 12 run, 6 pass, 5 skip (the Vulkan device tests), 1 fail: on our verify's Windows build, which compilestests/execution,agc_driver_pipelined_metadata_passfails atvkCreateInstance(-9) on GitHub's device-less runner, before this PR's code;mainfails it the same way there (run), and upstream's Windows job builds it as a skipped stub. Suites: libc and libkernel pass on Linux (166 and 265). On Windows libc passes (194), and libkernel passes 284 of 287:exec_arguments,guest_timed_join_import_libkernel_sysandguest_timed_join_import_libkernel_webfail at their setup in the verify's Windows build (FileNotFoundErrorstarting the title, or copying the libraries they load), withmain's code too, and pass inmain's own Windows job at 1829def (job). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.f469f4d, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 6c13924, which adds the edited-V# chase (run). Four places conflicted, and the merge keeps both sides in each:
agc_driver_pointer_chase_split_tableand fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633'sagc_driver_pointer_chase_edited_table;PointerChasekeeps this PR'sreadHighImmediateand gains fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633'sedits;ShaderDiskCache.cppwrites and readsreadHighImmediateand then the edits, in the same order, and keeps both validation checks;docs/dev/debt/shader.mdstates both rules, this PR's two words at their own immediates and fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's edited V# words, worded to stay under the checker's 1000 characters.FormatVersionstays 56. The chase, split-chase, edited-chase, chase-words, SGPR-fill, nested-sampler and pipelined metadata tests with the disk-cache, bindless and shader-memory tests and fix(agc): sample cube descriptors with fewer than six slices as six faces #11507'sagc_driver_image_sample_short_cube. Linux ran them 10 times with no failure: 12 run, 12 pass, 0 skip, 0 fail. Windows: 14 run, 6 pass, 7 skip (the Vulkan device tests), 1 fail: on our verify's Windows build, which compilestests/execution,agc_driver_pipelined_metadata_passfails atvkCreateInstance(-9) on GitHub's device-less runner, before this PR's code;mainfails it the same way there (run), and upstream's Windows job builds it as a skipped stub. Suites: libc and libkernel pass on Linux (166 and 265). On Windows libc passes (194), and libkernel passes 284 of 287:exec_arguments,guest_timed_join_import_libkernel_sysandguest_timed_join_import_libkernel_webfail at their setup in the verify's Windows build (FileNotFoundErrorstarting the title, or copying the libraries they load), withmain's code too, and pass inmain's own Windows job at 1829def (job). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.c4f25ba: 85d0352, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's ee8767f, the format commit f6b5d58, and the test-only commit c4f25ba (run).
agc_driver_nested_image_table's two checks that a valid shader is refused (a V# with another buffer consumer and a T# with another consumer), feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge of feat(shader): resolve nested image tables through runtime pointers #7223's 0dbf547 (yabanana's merge ofmainf7e84c4), the format commits below this PR and fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's test-only commit ee8767f. The one conflict was intests/execution/ImageTable.cpp, in two places next to this PR's lines: the merge takes ee8767f's removal of the looped and five-step chase shaders and of their refusal checks, and keeps this PR's split-word shaders and the speculative keys it adds to the conditional chase test.agc_shader_bindlessandagc_shader_memoryran 10 times with no failure. Linux: 31 run, 31 pass, 0 skip, 0 fail. Windows: 33 run, 8 pass, 25 skip (the Vulkan device tests; the Windows runner has no Vulkan device), 0 fail. The libc and libkernel suites run 191 and 291 tests on Linux and 220 and 314 on Windows, with 0 failed. They ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.eac5dce and babbb0e, for XairRrR's review, on a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's a727b76 (×10 run, negative control run).
docs/dev/debt/shader.mdto lead with what stays refused, and adds this PR's two refusals: a high word read at the low word's own immediate, and a chased V# whose base leaves either word's address unaligned (52ae654), which ends the chase even inside the snapshot. Whether the console reads the dword-aligned address there instead is not measured. The entry is under the conventions check's 1,000 characters.agc_shader_disk_cache). The chase tests run withANYPS5_NO_SHADER_CACHE=1, so nothing coveredreadHighImmediatein the cache before. As a negative control, a decoder that reads the field into a throwaway makes the new check fail on both runners: "a pointer chase whose high word has its own immediate changed in a disk-cache round trip".APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.NVIDIA RTX 2000 Ada Generation at 99d77ab, from TechLevelZero's NVIDIA bot (report): driver 595.99.02, Ubuntu 26.04.1, this head merged onto
main3741ca9, 2,542 of 3,121 tests selected.main, and 1 is unstable onmain.VK_LAYER_KHRONOS_validation, over 949 tests on the GPU, there are no new validation IDs againstmain. 19 of the stack's nested and pointer table tests ran with the layer but aren't inmain's baseline, so they weren't compared.4699b25: d4ef08d, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 280d6d6, and the format commit 4699b25 (run). Two conflicts:
FormatVersion, which the format commit moves from 57 to 72, above fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 70, andagc_driver_image_table_tests.cmake, where this PR's split-chase registration is kept.ShaderDiskCache.cppmerged cleanly with fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's numbers, which this PR doesn't change. This PR's own diff is otherwise unchanged. The image-table, disk-cache, BDA anchor-read, shader-memory, nested and pointer tests, with fix(shader): split scalar-address descriptor phis #7694'sagc_shader_descriptor_phis, pass 10 runs in a row. Linux: 34 run, 34 pass, 0 skip, 0 fail. Windows: 36 run, 10 pass, 26 skip, 0 fail. Suites: libc and libkernel pass on Linux (210 and 310) and on Windows (237 and 331). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners. TechLevelZero's NVIDIA bot ran this head merged ontomain88e804b on an RTX 2000 Ada (report): 2,571 passed, 6 failed, none new (3 also fail onmain, 3 unstable onmain), 45 skipped, with no new validation IDs (992 tests on the GPU).8fa3da8, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's b9fab3f, which carries feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge of
main4f64f81 (run). Clean:FormatVersionstays 72, and this PR's own diff is unchanged. TheResourceMaterializer.cppresolution, with feat(agc): sample 1D arrays past maxImageArrayLayers as rows of a 2D image #12246's view loop moved back intoSnapshot, comes from feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge (see feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395). The image-table, disk-cache, BDA anchor-read, shader-memory, nested and pointer tests, with fix(shader): split scalar-address descriptor phis #7694'sagc_shader_descriptor_phis, pass 10 runs in a row. Linux: 34 run, 34 pass, 0 skip, 0 fail. Windows: 36 run, 10 pass, 26 skip (no Vulkan device), 0 fail. Suites: libc and libkernel pass on Linux (217 and 318) and on Windows (244 and 339). The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.agctest, once (run): Linux: 1,261 run, 1,182 pass, 78 skip, 1 fail. Windows: 1,297 run, 390 pass, 907 skip (no Vulkan device), 0 fail. The one failure isagc_driver_pipeline_journal's 120-second timeout, whichmain88e804b's own run of every test hits too (run).13e0df8, a merge of
main4f41f4c (×10, the PR's own tests ×10).ShaderDiskCache.hpp'sFormatVersion, wheremainis now at 52 (feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000) and this PR keeps its 72; anddocs/dev/debt/shader.md, where this PR's entries andmain's new entries are adjacent and both stay. This PR's own lines are unchanged apart from theFormatVersionline's old value.agc_driver_image_table,agc_driver_many_direct_samplersand every test matching^agc_shader_memory,^agc_shader_disk_cache,^agc_shader_sampler_limits,^agc_shader_nestedor^agc_shader_table. Linux: 11 run, 11 pass, 0 skip, 0 fail. Windows: 13 run, 11 pass, 2 skip (no Vulkan device), 0 fail. The libc and libkernel suites run 300 and 322 tests on Linux and 327 and 342 on Windows, with 0 failed. The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.^agc_driver_pointer_and^agc_driver_nested_test, the image-table tests in this PR's diff overmain, which the first run's names left out. Linux: 19 run, 19 pass, 0 skip, 0 fail. Windows: 19 run, 0 pass, 19 skip (no Vulkan device), 0 fail.18bc368, a merge of fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 6089e58, which carries
mainc2eafe4 with yabanana's feat(shader): resolve nested image tables through runtime pointers #7223 through fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457, fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939 and feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 (×10).ShaderDiskCache.hpp'sFormatVersion, which stays 72 (mainis at 56 since feat(shader): resolve nested image tables through runtime pointers #7223), anddocs/dev/debt/shader.md, where this PR's wording of the pointer-keyed chase entry stays. This PR's own lines are unchanged apart from theFormatVersionline's old value.agc_driver_many_direct_samplersand every test matching^agc_driver_pointer_,^agc_driver_nested_,^agc_shader_nested_,^agc_driver_image_table,^agc_shader_memory,^agc_shader_disk_cacheor^agc_shader_sampler_limits, which takes in every test in this PR's diff overmain. Linux: 34 run, 34 pass, 0 skip, 0 fail. Windows: 36 run, 10 pass, 26 skip (no Vulkan device), 0 fail. The libc and libkernel suites run 301 and 325 tests on Linux and 331 and 343 on Windows, with 0 failed. The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)sampler resource limit exceeded(MaxSamplers = 32). In Tamalero's later diagnostic runs, the stops after that areinvalid shader memory read address, which 52ae654 fixes (comment), and thenruntime image descriptor is invalidat a storage image that is written and never read, with a TYPE 0 T# (comment). That last stop has its own PR, fix(agc): bind a written TYPE 0 or 1 static image slot as a null storage image #10906, which binds such a slot as a null storage image: on gfx1030 a store through those words is dropped (Tamalero's measurement). A run past it is pending.