Repository navigation
fix(shader): plan several T#s read through one pointer-loaded V#, keeping the V# real for their other uses - #9790
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.
…andles as nested children Marvel's Spider-Man 2 (PPSA03016) stops at 131 s on boykopovar#9457 in a compute shader whose record pointer, at dwords 2-3 of a waterfall-keyed record with its low word merged by a Phi with a constant, leads to a V# that two GetBufferResource handles read: a T# at offset 0 and a T# at 0x4c0, each sampled. The nested branch of TryMakeTableColumn refused the first T# because the V#'s words also fed the second handle, whose reads belong to the other T#. A parent V# whose word reads feed several GetBufferResource handles is now accepted when every other handle has the same words and its uses are only reads whose users are T# or S# descriptor handles. Each descriptor plans its child column from its own handle; both walks reach the same reads, so the parent interns to one source, the materializer reads its records once (NestedColumn takes them from Column()), and each child keeps its own offset. A handle with any other use still refuses, and a sibling descriptor that cannot be planned still refuses the shader, as its words are not runtime values. T# or S# words that have other users stay refused. Planning keeps those reads in the program: PlanTableColumnPass marks a read planning-only only when every user is a planned handle (ResourceTracker.cpp:1770-1781). But they read through the V# handle, whose arguments Run() replaces with the column offset and the parent pointer words (:154-160), and whose own word loads become planning-only once every handle over them is planned, so LoadAddress emits nothing for them (SpirvMemoryInstructions.cpp:599-601). The kept read would address a V# that only the snapshot holds. Allowing those uses in this shape, where the second T#'s dwords 0 and 1 reach the pointer registers on one edge before a later s_load, crashes lavapipe in the dispatch. Taking it needs that V# kept alive for those reads: an unrewritten copy of the handle and real loads of its words through the record pointer. Shape from hugodearaujo's IR on boykopovar#8939 (issuecomment-6340144242).
…d other instructions Marvel's Spider-Man 2 (PPSA03016) still stops at pc 0x8fa0 with the shared-V# planning alone: its shader moves dwords 0 and 1 of the second T# read through the pointer-loaded V# into the record pointer's registers, so those reads have Phi users. The nested branch of TryMakeTableColumn refused that T#, and the first T# with it, because the sibling handle's reads were not only descriptor words. d132754 added the refusal after such a read crashed lavapipe: the read stayed in the program but went through the V# handle that Run() rewrites to the column offset and parent pointer words, while the V#'s own word loads became planning-only and were not emitted, so it read a garbage address. A planned nested child's T# or S# read with other users now goes through an unrewritten copy of the V# GetBufferResource. PlanTableColumnPass keeps a read real while any planned handle using it has a use that stays real, so the V#'s four loads through the record pointer are emitted for the copy, and the descriptor handles still take the snapshot. No kept read goes through a rewritten handle, so the other users read the guest's V# and descriptor words at dispatch. The copy needs the V#'s words to be loads through the record pointer that the program emits. Any other V#, and a data read through a handle on the V#'s words, remain refused. The shared-V# reuse test now checks both T#s per group and the word the later s_load reads behind T#2's dwords 0 and 1, which the test backs with a snapshot at that address. The T# and S# consumer cases that d132754 refused now check the real descriptor word. A data read through a third handle and a T# consumer whose V# comes from a keyed table record stay refused. Shape from hugodearaujo's IR on boykopovar#8939 (issuecomment-6340144242).
|
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.
|
|
@hugodearaujo this is the follow-up for the next stop in your Marvel's Spider-Man 2 (PPSA03016) run on #9457 (comment), |
MarcZX10
left a comment
There was a problem hiding this comment.
The change is carefully scoped to the declared #9457 stack. The current-main conventions check and git diff --check pass. I inspected the nested-column capture/materialization paths and the PR’s reported pointer-shared T#/V# tests and validation-layer comparison. I did not build or execute the shader/Vulkan tests locally in this review. Hosted PR checks currently cover eligibility, conventions, intake, labels and report; product and relinker builds are skipped. The reported Linux validation-layer comparison uses #9457’s head as the baseline, which is appropriate for this stacked delta.
The exact head is 69 commits behind live main (8499ea52e571b0edfc1feecfd3f6b9944012b359), while #9457 is still open. CONTRIBUTING.md says to keep branches up to date with main. Please refresh the stack against current main as the prerequisite progresses, then rerun the focused image-table/Vulkan tests and validation-layer comparison on the final merge base before merge. I confirmed Git can auto-merge the current head with main, so this is a synchronization and final verification request, not a reported textual conflict.
MarcZX10
left a comment
There was a problem hiding this comment.
I refreshed the exact head 53523163d22faf335ff71418b74fd0c672473122 against current main (11f976b27c16ed91633f00039dba5dfd97dd7cc1). Current-main conventions, git diff --check, and merge-tree checks pass. The reported Linux llvmpipe shader, validation-layer and negative-control results are contributor-reported; the hosted product jobs are skipped. This VM has no Vulkan device suitable for the required paired validation run, so I did not claim a local shader test. The branch is 82 commits ahead and 24 behind its merge-base relation; it includes the declared #9457 stack. Please keep the dependent stack current and rerun the required same-GPU main/change validation comparison after rebasing before merge.
|
@EagleBearerYS I ran
That block after So two things meet at 0x9a50:
Linux 7.2.11, RX 9070 XT, RADV Mesa 26.2.5, Release, |
✅ 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 (19, 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. |
|
Measurement of this change on current Without the series: in 2 of 2 runs (600 s requested) the title ended early, after 121 s and after 97 s, on an uncaught What was applied: for each pull request of the series, its diff against
So from #8939 on, the chain that failed on Diagnostic only, local and not checked in: with this pull request's change and Not judged or not done: the picture, other titles, Linux, the tests of these pull requests (left out), and any game run with the series applied. AI-assisted (Claude Code). |
|
@xXPBSXx thanks for the replays, and for applying each PR of the chain alone. From #8939 on, your table shows the descriptor behind the waterfall loop resolving, and the shader moving on to the sampler limit. That limit has its own PR: #10000 raises With |
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (8, 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 537 tests)Skipped (58)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
XairRrR
left a comment
There was a problem hiding this comment.
Re-checked — approved
This push (6b38153) merges main into the branch. The merged tree builds, the focused table, BDA-anchor and shader-memory tests pass, the validation layer reports no new VUID-, and both negative controls (the tracker change, and the scalar-base low-bits change) fail exactly as the description says.
What changed since my last review
I had no text from my earlier review, so this re-check covers the whole change again. The new commit, 6b38153, is a merge of main. It changes no product line of this PR's own delta over #9457's head 0a4f7cd, except where main touched the same files (ResourceTracker.cpp and SpirvEmitterState.hpp). FormatVersion is 71, above main's 52.
Scope: the diff against main also carries the open stack below this PR (#7223, #7395, #8939, #9457). I reviewed this PR's own delta in detail: the diff from 0a4f7cd to a12bac5, made of the shared-V# planning, the unrewritten V# copy, the planning-only fixpoint, the SMEM base masking and its tests. I read the stack's code only far enough to follow it, since those parts are reviewed on their own PRs.
What I ran
Head 6b38153c074944c7aca01b4d66d0a241c34ec646, main 4f41f4c375f5abb487dbd184fbc150f31994d762, merged tree 1b423f740b78b8d6a4d88183b2a0b7cbf67ba11a. Debian 13 VM, GCC 14.2.0, Release, lavapipe (Mesa 26.1.6, LLVM 19).
git diff --check 4f41f4c375f5abb487dbd184fbc150f31994d762...6b38153c074944c7aca01b4d66d0a241c34ec646
python3 tools/check_conventions.py --base 4f41f4c375f5abb487dbd184fbc150f31994d762
ctest --test-dir build -j8 --test-load 32 --output-on-failure -R "^agc_driver_(pointer_|nested_|bda_anchor)|^agc_shader_memory$|^agc_shader_bindless$|^agc_shader_nested"
# control 1: git diff 0a4f7cdbed a12bac51d6 -- ResourceTracker.cpp, reverse-applied
ninja -C build -j32 -l32 agc_driver_image_table_tests agc_shader_memory_tests
ctest --test-dir build -j8 --test-load 32 -R "^agc_driver_(pointer_|nested_)"
# control 2: the same delta of ImageTableAbi.hpp, SpirvBdaRead.cpp, SpirvMemoryInstructions.cpp, SpirvEmitterState.hpp, reverse-applied
ninja -C build -j32 -l32 agc_driver_image_table_tests agc_shader_memory_tests agc_driver_bda_anchor_reads_tests
ctest --test-dir build -j8 --test-load 32 -R "^agc_driver_(pointer_|nested_|bda_anchor)|^agc_shader_memory$|^agc_shader_bindless$"
# merged files restored with git show 1b423f740b:<path>, rebuilt
VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ctest --test-dir build -j8 --test-load 32 -V -R "^agc_driver_(pointer_vsharp_shared|nested_(image|sampler)_table$|bda_anchor)"
git status --porcelain
| Check | Result |
|---|---|
git diff --check |
clean |
check_conventions.py |
All conventions checks passed |
| Build (script) | configure, build and libs OK |
| Selected tests (script) | 2233 ran, 0 new failures, 0 timeouts; 7 known failures that fail on main too |
Validation (script, main against merge) |
787 tests, layer loaded in 786, none missing, 0 tests with a new VUID- |
| Focused set, merged tree | 22 of 22 pass |
| Focused validation run, merged tree | 5 of 5 pass, no VUID- lines, no was not found |
| Worktree after the controls | git status --porcelain empty |
Negative control
- The tracker delta (
ResourceTracker.cppat #9457's level):agc_driver_nested_image_table,agc_driver_nested_sampler_table,agc_driver_pointer_vsharp_shared_tableand_shared_reuse_tablefail withGetImageResource dword 0 is not a valid runtime value. The other 13 pointer and nested tests pass. This matches the description and wachi35676's run. - The low-bits product side (47a4e59):
agc_driver_pointer_vsharp_shared_reuse_tablesegfaults in llvmpipe, andagc_driver_bda_anchor_reads,agc_shader_memoryandagc_shader_bindlessfail. The other 16 pass, which also matches the description.
Previous findings
No previous review text was available, so there are no earlier findings to track.
I checked the other reviewers' points:
- The test-policy pin (oneandonlydean, MarcZX10): stays resolved. No test in this delta asserts the
not a valid runtime valuerefusal. - The macOS low-bits bug (jotitadev): resolved. The test now forces a T# dword 0 ending in
01and11, and my control 2 reproduces the crash on Linux without the fix. - The paired validation comparison (MarcZX10): on this machine,
main4f41f4c against the current merge, the layer loaded in every compared test but one, none reported it missing, and no newVUID-appeared.
New findings
Blocking
None.
Non-blocking
- The SMEM base-alignment rule has no cited source. At
core/shader/recompiler/SpirvBackend/src/SpirvMemory/SpirvMemoryInstructions.cpp:194andcore/shader/recompiler/ImageTableAbi.hpp:133, the 64-bit base of ans_loadthrough an SGPR pair now drops its low two bits.- This changes shader instruction semantics. CONTRIBUTING asks such a change to name its source: an ISA section, or a hardware measurement with the GPU.
- The description and 47a4e59 say only "as SMEM does". The
V# bases off a DWORD boundaryentry indocs/dev/debt/shader.mdrecords a console measurement fors_buffer_load, not fors_loadthrough a pointer. - Suggested fix: cite the RDNA2 ISA section on scalar memory addressing in the description, or add an
s_loadcase to that debt entry, unverified on hardware until measured.
- Kept descriptor words can differ from the snapshot. Under
core/shader/recompiler/Optimization/src/ResourceTracker.cpp:159-172, a T# or S# word that has other users is now read from the guest's V# at dispatch, while its descriptor handle takes the snapshot. A guest write between snapshot and dispatch can make the two differ. This is disclosed in the debt line (docs/dev/debt/shader.md:61), so I note it for reviewers rather than as a defect.
Not verified
- Real GPUs: not run here. NVIDIA, AMD (RADV and Windows) and MoltenVK results are as reported in the description and comments.
- The Marvel's Spider-Man 2 (PPSA03016) run: author-reported (hugodearaujo), not run here.
- The stack's own code (#7223, #7395, #8939, #9457): not reviewed in depth in this re-check. This PR can only merge after those land.
- Windows and macOS builds: not built here.
✅ 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 (2, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 529 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. |
✅ AMD 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 (8, 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 529 tests)Skipped (58)ReproduceAutomated build and test on a contributor's AMD 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.
…sharp-reuse 6e403b4 is boykopovar#9457 with the stack's merges of boykopovar#7395's main merge after boykopovar#7223. FormatVersion stays this branch's 71. In the debt file, boykopovar#7395 adds a sentence on nested children's registered views to "Nested image tables", which this branch rewrites. The entry keeps this branch's wording, and the sentence moves into its own entry after it, since both together are over the debt files' 1000 characters.
✅ 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 (1, not in the main baseline's validation pass)Validation IDs already present on main (13 IDs in 553 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. |
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (7, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (8 IDs in 552 tests)Skipped (60)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
b41beed is boykopovar#9790 with the stack's merges of boykopovar#7395's main merge after boykopovar#7223. FormatVersion stays this branch's 73, and the debt file keeps this branch's three entries, with boykopovar#7395's "Nested image table children" entry added after "Nested image tables".
What
This is stacked on #9457.
With #9457, Marvel's Spider-Man 2 (PPSA03016) gets past
ReadConstBuffer@pc=0x8560. It then stops at 131 s in compute 0x11e2b38300 (hugodearaujo's run):hugodearaujo's IR (comment) shows the shape:
#9457's nested tables refuse both parts:
The change, three commits and a test-only one:
S_LOADaddress asSGPR[base] + inst_offset + { M0 or SGPR[offset] or zero }and says of every component, the base included, that "the two LSBs are ignored and treated as if they were zero" (AMD, "RDNA 2" Instruction Set Architecture: Reference Guide, 2020-11-30, §7.2.1S_LOAD_DWORD, Scalar Memory Addressing, page 52 of 283; PDF). @jotitadev found it on macOS (review): a T# whose dword 0 ends in01made the read through its words start one byte past the snapshot and fault.~3, and so does the anchored direct read.ScalarAddressDwordstarts from the cleared base, so the records behind such a pointer are read instead of being leftUnmapped.01and11on every platform, as it did in that macOS build.Overlap:
CMakeLists.txtconflict, the same lines fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's own registrations touch. Keeping both resolves it. The product files auto-merge.git merge-treeconflicts are the same as fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's head's, so it adds none. That covers fix(shader): keep a v_writelane lane known across computed-index window stores #8881, feat(agc): merge partial writes into 4_4_4_4 UNORM color targets #8564, fix(shader): resolve table column pointers through Phi nodes #7880, feat(agc): blend into 10_11_11 unorm color targets in the pixel shader #9748, 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 and fix(shader): split descriptor webs whose paths fold or hold invalid arms #8077. feat(recompiler): read I/J from barycentric built-ins on MoltenVK #9193, docs(shader): drop the stale lavapipe skip from the 16-bit interpolation entry #8406, feat(agc): emulate barycentrics in rect-list draws #8339, docs(debt): correct stale f64 denormal and RSRC1 float mode statements #8281 and fix(shader): read a 2D MSAA T# through DIM 2D as its sample 0 #7803 merge cleanly with both.FormatVersion: 71, this PR's own number on the stack's ladder (see Tested), so a cache written by fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's recompiler isn't read as this one's. No serialized structure changes.Tested
ImageTable.cpp, in hand-written RDNA.agc_driver_pointer_vsharp_shared_table: the record pointer at dwords 2/3 of a waterfall-keyed record, its low word merged with 0xea, a V# at the pointer, and two buffer handles reading T#s at 0x0 and 0x4c0.GetBufferResources over the same fourLoadAddressU32s.agc_driver_pointer_vsharp_shared_reuse_table: the same, plus T#2's dwords 0/1 moved into the pointer registers on one edge before a laters_loadthrough them.agc_driver_nested_image_tableandagc_driver_nested_sampler_table:ResourceTracker.cppat fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's head, those four tests fail with "GetImageResource dword 0 is not a valid runtime value" (the sampler test with "GetSamplerResource ..."), the title's text.precise_wait: "PreciseSleepUs(50) median overslept target bound" (116147 and 115847 ns, against its 90 µs bound).agc_driver_sgpr_pattern_fill_keystiming flake under--parallel 4(it passes alone).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_validation6 times on fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's tree and 8 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.test/sm2-9790-on-c00cb0f875(aeb0b65) with his fix(agc): resolve indexed indirect draws on a queue that never set INDEX_BUFFER_SIZE #9424 merged in, on Linux 7.2.11, AMD Radeon RX 9070 XT, RADV Mesa 26.2.5, Release, a cold shader cache, one run. That branch is this PR's two commits on c00cb0f, patch-identical to 0e78959 and 5352316, without the latermainmerges. The title gets pastReadConstBuffer@pc=0x8fa0and stops at 135 s later in the same shader, atReadConstBuffer@pc=0x9a50, with "GetImageResource dword 0 is not a valid runtime value".agc_shader_replayrefuses the new request at the same place. That stop is a different shape: a T# in an array inside the pointer-loaded V#'s buffer, at an offset of(word >> 16) * 32where the word is read through the same V#. This PR still refuses that as a data read through the V#, and it's a follow-up.main499b1cf merged in (clean; the PR's own diff is unchanged), on GitHub's runners (run):mainhas (agc_driver_image_table_vouched_lookupsandagc_driver_image_table_vouch_queued_draws) and the shader disk cache test pass 10 of 10, none skipped.mainagainst this head, in the same run:main's tree ran the three of these tests it has. The loader insertedVK_LAYER_KHRONOS_validation3 times onmainand 110 times with this PR, and neither log haswas not found. Both logs report onlyVUID-VkDeviceCreateInfo-pNext-pNext, so this PR adds noVUID-message.guest_raise_in_system_callfailed in the first attempt with this head, and the rerun of that job passed both suites. The libc and libkernel suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.mainon lavapipe, with an unmapped record pointer:mainand fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 refuse these shapes at planning, at compile time. With this PR they compile, and the loads the second commit keeps real miss the BDA table, so llvmpipe crashes instead of reporting the fault.StopBdaInvocationIfends the invocation before that load, but llvmpipe still performs the uniform load from address 0.s_load_dwordthrough an unmapped pointer read from a buffer, also crashes on a load from address 0. It ran on this PR's first commit, but it has no image table, which is what this PR changes, and the files that emit these loads (SpirvBdaRead.cpp,SpirvBdaFault.cpp,SpirvRuntimeBuffer.cppandSpirvMemoryInstructions.cpp) are identical tomain's.test/9790-unmapped-record(4dd9a25), this PR's head plus an unmapped record pointer in the two shared-V# tests.BDA access failed: address=0x7f12345000 instruction=0x90 bytes=1 stage=4 reason=1.selected the descriptor at 0x7f12345000: unmapped, as on llvmpipe.main0db47b2. The only conflict wasShaderDiskCache.hpp'sFormatVersionline:mainmoved to 45 (fix(shader): normalize offset perspective barycentrics after interpolation #7831), and this branch keeps its 46. On GitHub's runners (run), the pointer, nested, image-table and disk-cache sets (27 tests) pass 10 runs in a row on Linux. On Windows the set has 29, with two Windows-only disk-cache tests: they build, 5 pass 10 runs in a row, and the other 24, 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.agc_driver_pointer_vsharp_shared_reuse_tablecrashes llvmpipe,agc_driver_bda_anchor_readsfails "scalar loads from a base with low bits 1 byte 32784 is 0x87618183, expected 0x61818380", andagc_shader_memoryandagc_shader_bindlessfail "scalar address rule: a base with low bits 1 is not dword-aligned"; the other 14 pass. On Windows,agc_shader_memoryandagc_shader_bindlessfail with the same rule line.agc_driver_bda_anchor_reads,agc_driver_pointer_vsharp_shared_tableand_reuse_table) skip; none 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.VUID-VkDeviceCreateInfo-pNext-pNext, so the change adds noVUID-message.main379b1dc). It's clean, and this PR's own diff is unchanged. The planner behaviour changes underneath it: It brings the planner changes of 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: a record pointer counts as merged only when its Phi isn't a single record read; an unmerged pointer's low word is unwrapped as fix(shader): resolve table column pointers through Phi nodes #7880 does, and refused when it isn't a table read; and fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939's new commit refuses a pointer-keyed Phi edge whose two words are both immediates.agc_shader_bindless,agc_shader_memoryand the^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_tableand^agc_shader_disk_cachetests. Linux: 42 run, 42 pass, 0 skip, 0 fail. Windows: 44 run, 20 pass, 24 skip (Vulkan device tests; the runner has none), 0 fail.^agcset once (run): Linux 984 run, 919 pass, 64 skip, 1 fail; Windows 1003 run, 272 pass, 729 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.main379b1dc against cfd61b7 (run), on one GitHub Linux runner (llvmpipe, LLVM 20.1.2) with the setup above and the focused set:main's tree ran the 24 of these tests it has, 24 pass. This head ran 42: 42 pass, 0 skip, 0 fail.VK_LAYER_KHRONOS_validation8 times onmainand 26 times with this head, and neither log haswas not found.VUID-VkDeviceCreateInfo-pNext-pNext, so the refreshed head adds noVUID-message.mainc9b2660). Clean:FormatVersionfollows feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's 50, and this PR's own diff is 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: 42 run, 42 pass, 0 skip, 0 fail. Windows: 44 run, 20 pass, 24 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.mainc8d34aa). Clean:FormatVersionfollows feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's 50, and this PR's own diff is unchanged: the merge brings in exactly what feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395'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: 42 run, 42 pass, 0 skip, 0 fail. Windows: 44 run, 20 pass, 24 skip (no Vulkan device), 0 fail.guest_raise_in_system_calltimed out at 30 s, 220th of 222; this PR changes nothing in libkernel. Run alone on this head 20 times in a row (run), it andguest_raise_exceptionpass on Windows, and both suites pass on both runners. The suites ran withAPS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.mainaeff26b, WinLibs GCC 15.2.0, Release,ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1, no validation layer.pointer_andnested_table tests,image_table,vouch,disk_cacheand theagc_shader_tests, 68 entries, pass on both GPUs,agc_driver_pointer_vsharp_shared_tableand_shared_reuse_tableamong them.ResourceTracker.cppat fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 and the rest of this PR kept, exactly the four tests this description names fail on both GPUs withGetImageResource dword 0 is not a valid runtime value:agc_driver_nested_image_table,agc_driver_nested_sampler_table,agc_driver_pointer_vsharp_shared_tableand_shared_reuse_table. The other 19 table tests pass.agc_entries, the same ones fail with and without the stack, none of them table tests.main, by @hugodearaujo (comment): this head merged intomainf95acfc (clean;mainhas fix(agc): resolve indexed indirect draws on a queue that never set INDEX_BUFFER_SIZE #9424), Linux 7.2.11, RX 9070 XT, RADV Mesa 26.2.5, Release, a fresh shader cache in each run, X pressed every 30 s, 480 s limit.mainf95acfc alone stops at 211 s, at the first dispatch of the compute shader whoses_swappc_b64at pc 0x1fe0 calls a computed target, withGetImageResource dword 0 is not a valid runtime value(chain fromReadConstBuffer@pc=0x000084bc).APS5_DUMP_SHADERS=1, that shader is first dispatched at 206 s and prepares: no.prepare.reqor_failed.reqis written for it.agc_shader_replayon this tree still refuses the four.prepare.reqfiles saved at the earlier stops, atReadConstBuffer@pc=0x9a50. They came from trees withoutmain's table-call linking changes (0a4027d, ef2b164, 01e7d15); he reads the program linked at dispatch as probably different now, which can't be shown, since a.prepare.reqis written only when preparation fails.mainb986c11 with the macOS port changes (FormatVersionresolved to a new number). MoltenVK 1.4.2 (Vulkan SDK 1.4.363.0) and MoltenVKmainwith SPIRV-Cross Ratchet & Clank: Rift Apart: SIGSEGV since #861, an address-less 64 GiB reservation now takes the addresses the title hints next #2704,ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1.^agc_driver_(pointer_|nested_|bda_anchor)tests pass 3 of 3 runs on each driver,_shared_reuse_tableandbda_anchor_readsincluded._shared_reuse_tablefails withBDA access failed: ... instruction=0xd8 bytes=1 stage=4 reason=1andbda_anchor_readswithscalar loads from a base with low bits 1 byte 32784 is 0x87618183, expected 0x61818380, on both drivers; the other 17 pass.VUID-vkCreateDescriptorSetLayout-support-09582come from the image table layout on MoltenVK (ThevkGetDescriptorSetLayoutSupportimplementation makes using bindless impossible KhronosGroup/MoltenVK#2573), as on the base; the 20VUID-VkSamplerCreateInfo-samplerMipLodBias-04467innested_sampler_tablecome from MoltenVK's portability subset.^agcsuite (SDK driver): the same 41 failures as the base; with MoltenVKmain+ Ratchet & Clank: Rift Apart: SIGSEGV since #861, an address-less 64 GiB reservation now takes the addresses the title hints next #2704, the base's 40 lesscross_workgroup_flag, nothing new.main0cd07dc (run).not a valid runtime value, from the assertions @oneandonlydean listed on fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969: a T# with another consumer whose V# only the table snapshot holds, and a data read through a third handle on a pointer-loaded V#'s words. The two summary lines no longer name refusals, and the sampled results stay.main0cd07dc, with fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's resolution of mrfelek's fix(shader): plan an image table for a T# read at a first-lane offset #10228. Clean here, and this PR's changed lines are the same.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.agc_driver_nested_sampler_table: this PR plans the S# and checks its sampled result (5352316), so the merge keeps that check and drops only therefusedhelper, which nothing uses any more. This PR's diff now adds the S# case with its sampled-result check, where it used to replace feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's refusal; the test at the head differs from 5b81551 only by the helper. The shared-V#, BDA anchor, nested, vouch and SGPR-fill tests with the disk-cache, bindless and shader-memory tests ran 10 times with no failure. Linux: 28 run, 28 pass, 0 skip, 0 fail. Windows: 30 run, 23 pass, 7 skip (the Vulkan device tests), 0 fail. 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.main38ccd50 and with it fix(agc): sample cube descriptors with fewer than six slices as six faces #11507'sFormatVersion49 (run). Clean:FormatVersionstays 57, and this PR's diff over fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 is the same. The ladder is now:mainis at 49 since fix(agc): sample cube descriptors with fewer than six slices as six faces #11507 (hugodearaujo), and feat(shader): resolve nested image tables through runtime pointers #7223, perf(agc): GPU descriptor heap on VK_EXT_descriptor_heap (APS5_GPU_HEAP) #9508, feat(agc): blend into 10_11_11 unorm color targets in the pixel shader #9748 and other open PRs use 49 too. Ours take one number each: feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 50, fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939 51, feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000 52, fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 53, feat(shader): raise the image limit to 128 and name the counts in its refusals #10489 54, fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 55, fix(shader): read a chased pointer's high word at its own offset #9749 56, fix(shader): plan several T#s read through one pointer-loaded V#, keeping the V# real for their other uses #9790 57, fix(agc): span table-reading wave64 programs by default on Intel drivers that share handles across fused threads #10846 59 and fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969 60. 58 is held by our draft feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642 and by feat(agc): serve lane-keyed, pointer and runtime image-table columns #10193 (Celegans12), which carries feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642's commits; feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642 moves above 60 at its next update. The shared-V#, BDA anchor, nested, vouch and SGPR-fill 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_cuberan 10 times with no failure. Linux: 29 run, 29 pass, 0 skip, 0 fail. Windows: 31 run, 23 pass, 8 skip (the Vulkan device tests), 0 fail. 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.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) and the format commits below this PR. Two conflicts:FormatVersion, which stays this PR's until the next commit, andtests/execution/ImageTable.cpp, where d908758 removes the shared-V# refusal check and its helper next to this PR's T#-with-another-consumer case; the merge takes the removal and keeps this PR's case, which plans that T# and checks its sampled words. This PR's diff no longer removes the T# refusal check itself, since feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 now does.mainis at 49 since fix(agc): sample cube descriptors with fewer than six slices as six faces #11507 (hugodearaujo), and perf(agc): GPU descriptor heap on VK_EXT_descriptor_heap (APS5_GPU_HEAP) #9508, feat(agc): blend into 10_11_11 unorm color targets in the pixel shader #9748 and other open PRs use 49 too; feat(shader): resolve nested image tables through runtime pointers #7223 is at 50 since yabanana's 0dbf547. Ours take one number each: feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 51, feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000 52, fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer #8939 53, feat(shader): raise the image limit to 128 and name the counts in its refusals #10489 54, fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 55, fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 56, fix(shader): read a chased pointer's high word at its own offset #9749 57, fix(shader): plan several T#s read through one pointer-loaded V#, keeping the V# real for their other uses #9790 59, fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969 60 and fix(agc): span table-reading wave64 programs by default on Intel drivers that share handles across fused threads #10846 61. 58 is held by feat(agc): serve lane-keyed, pointer and runtime image-table columns #10193 (Celegans12), which carries the commits of our draft feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642, and feat(agc): look up table images at run time through a device image table on the GPU heap (APS5_GPU_PATH) #7642 takes 62 at its next update.agc_shader_bindless,agc_shader_memoryand 17 otheragc_shader_tests (table snapshots, selected records, memo budgets and pair layouts) ran 10 times with no failure. Linux: 46 run, 46 pass, 0 skip, 0 fail. Windows: 48 run, 25 pass, 23 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.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.mainb08c539 into fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 (run).CMakeLists.txt, from build(agc): register each AGC test executable in its own CMake fragment #12862's split, resolved withtools/agc_test_split.py resolve. It moves this PR's registrations intotests/cmake/agc_driver_image_table_tests.cmake, next to the stack's (+4 −2 against 4eaf19b).FormatVersionmerged cleanly and stays this PR's own. Apart from the move, this PR's diff is unchanged.-DBUILD_TESTING=ON,ctest -Ngives 3098 tests:mainb08c539's 3081 plus the stack's 17 tests (fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's 15 and this PR's 2), each listed once.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.VK_LAYER_KHRONOS_validationon GitHub's Linux runner (run),mainb08c539 against this merge, for the same tests. The loader inserted the layer 2 times on main and 19 with this merge. The only VUID in either arm isVUID-VkDeviceCreateInfo-pNext-pNext, so this merge adds none.agc_driver_image_tablefails in that mode in both arms, because the mode treats thatmainmessage as a failure.main3741ca9, 2,540 of 3,121 tests selected.main, and 2 are unstable onmain.VK_LAYER_KHRONOS_validation, over 947 tests on the GPU, there are no new validation IDs againstmain. 17 of the stack's nested and pointer table tests ran with the layer but aren't inmain's baseline, so they weren't compared.FormatVersion, which the format commit moves from 59 to 71, above fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457's 67 and fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633's 70. 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: 32 run, 32 pass, 0 skip, 0 fail. Windows: 34 run, 10 pass, 24 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,569 passed, 6 failed, none new (3 also fail onmain, 3 unstable onmain), 45 skipped, with no new validation IDs (990 tests on the GPU).main4f64f81 (run). Clean:FormatVersionstays 71, 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: 32 run, 32 pass, 0 skip, 0 fail. Windows: 34 run, 10 pass, 24 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.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 71; 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: 17 run, 17 pass, 0 skip, 0 fail. Windows: 17 run, 0 pass, 17 skip (no Vulkan device), 0 fail.mainc2eafe4 with yabanana's feat(shader): resolve nested image tables through runtime pointers #7223 through 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 71 (mainis at 56 since feat(shader): resolve nested image tables through runtime pointers #7223), anddocs/dev/debt/shader.md. There feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 adds a sentence on a nested child's T# to "Nested image tables", which this PR rewrites. The entry keeps this PR's wording, and the sentence moves into its own entry after it, "Nested image table children", since the two together are over the debt files' 1,000 characters. This PR's other 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: 32 run, 32 pass, 0 skip, 0 fail. Windows: 34 run, 10 pass, 24 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)ReadConstBuffer@pc=0x8fa0(hugodearaujo's run, with fix(agc): resolve indexed indirect draws on a queue that never set INDEX_BUFFER_SIZE #9424); its next stop isReadConstBuffer@pc=0x9a50in the same shader, a follow-up