Repository navigation
fix(shader): take lane-mask arms and a merged high word in a pointer-keyed record pointer - #8939
EagleBearerYS wants to merge 58 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.
|
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.
|
|
@EagleBearerYS thanks for #8939. We ran PPSA01474 on The IR shows which check refuses it, and why that arm isn't a pointer:
So on the one path where the high word comes from the second buffer, the "pointer" is (a lane mask, a T#-table dword). That's the SGPR pair being reused by the waterfall loop, not an address. Tamalero's dump on #6191 (issuecomment-6255548496) agrees: the record's high word is Could the walk pair the two words by incoming edge? Concretely:
This decides it at plan time from the IR alone, with no run-time fault path and no new plan field. If you'd rather keep the walks separate, a run-time fault for pointers built from that arm (as lane-mask pointers already do) would also work for us. We can share the IR excerpt around 0x9a30, and we're happy to run the title on the result. |
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.
|
@oneandonlydean, thank you for reading the IR this closely. The edge-by-edge pairing is the better fix, so I've written it as you describe, with both cases: |
…walk red/green and Linux CI mirror
|
@oneandonlydean, thank you for the IR dump and the steps. a7d1e62 on this branch pairs the two words as you describe:
There's no new plan field and no new run-time path. Tested on GitHub's runners, on
One shape that planned before is now refused. Both Phis are in one block, one edge carries the record's low word with an immediate high word, and the other carries a lane mask with the record's high word. No edge carries a whole record pointer, so the old plan could only fault at run time there. If you'd rather keep it planned, falling back to the old separate high-word walk when the paired walk finds no high read keeps it as before. Could you run Ratchet & Clank: Rift Apart (PPSA01474) on a7d1e62? If it stops again, the IR excerpt around the new stop would help. |
|
Retail check of a7d1e62 on Ratchet & Clank: Rift Apart (PPSA01474, 01.005.003), Linux, RTX 4090 (NVIDIA 615.78.08), cold shader cache, one unattended run per build:
The new chain has the same overall shape one level deeper. The low word is a Phi of the record read at So a7d1e62 fixes the 0x9a30 stop on the retail title. No regression up to the new stop. I can dump this shader's IR or the runtime values of the Tested and written by Claude (AI assistant) on a contributor's machine. |
|
@Tamalero, thank you for the retail run. It's now in the description: this PR gets Ratchet & Clank: Rift Apart (PPSA01474) past the 0x9a30 stop. We'd like to look at the 0x10b84 stop next. If you have time, the IR dump would help most:
If it's easy, the runtime values would help too: on the dispatch that stops, the dword the We'll read the dump before saying what the fix is. |
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.
✅ 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 (14, 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 (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)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (14, 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. |
BunnyFl
left a comment
There was a problem hiding this comment.
Reviewed this PR's own change on top of #7395's head (git diff of the two heads: ResourceTracker.cpp, the new agc_driver_pointer_phi_* cases, the cache format and the debt entry). #7395 itself I haven't re-reviewed here.
Reads right. PointerRecordPairs walks the low and high words together, pairing a Phi's arms by predecessor block (PhiIncoming) when both words are Phis in the same block. It skips an edge only when its low word is a constant or a lane mask, and, for paired Phis, refuses an edge where both words are immediates. A record word ANDed with a lane mask is unwrapped only when exactly one AND operand is a lane mask (MaskedRecordWord), and every accepted read must keep the same offset and record column (PointerRecordRead). The skipped edges can't bind a wrong resource silently: per the debt entry (docs/dev/debt/shader.md), the snapshot holds the captured records' pointers and the GPU looks up the actual 64-bit pointer, so a lane-mask value that reaches the lookup faults instead.
Tested on Windows 11, WinLibs GCC 15.2.0, with this head merged onto current main: 21 tests (agc_driver_pointer_*, agc_driver_image_table*, agc_shader_memory*, agc_shader_disk_cache*) pass, nothing skipped. Negative control: with #7395's ResourceTracker.cpp in the same merged tree, the four new cases (..._lane_and_table, ..._high_table, ..._high_second_lane_table, ..._lane_not_table) fail and #7395's three pass. agc_driver_pointer_phi_lane_and_table fails with GetImageResource dword 0 is not a valid runtime value; chain: ... BitwiseAnd32(Phi(CompositeExtractU32x4(Ballot(... (the shape the titles stop on).
XairRrR
left a comment
There was a problem hiding this comment.
Reviewed — approved
The edge-paired walk of a pointer-keyed record pointer's two words is sound. It merges and builds on current main, the focused tests pass with no new VUIDs, and four of the five new tests fail without this PR's ResourceTracker.cpp.
What I ran
Head afb123a49ec3f7555c274c769abfa5bbd4f87b81, main 9090972b7e91fd266819cbd77a8b058e177b5682, merged tree 811a3c5c010226d737ab32ee801a80c9d77bb65d (Release, GCC 14.2.0, Ninja, lavapipe Mesa 26.1.6 / LLVM 19, Debian 13 VM).
git diff --check 9090972b7e91fd266819cbd77a8b058e177b5682...afb123a49ec3f7555c274c769abfa5bbd4f87b81
python3 tools/check_conventions.py --base 9090972b7e91fd266819cbd77a8b058e177b5682
ctest --test-dir build -j8 --test-load 32 --output-on-failure -R "^(agc_driver_pointer_|agc_driver_nested_|agc_driver_image_table|agc_shader_disk_cache|agc_shader_nested|agc_shader_memory$|agc_shader_bindless$)"
# negative control
git show 6cb37cc9eda523074d5fd844537c28ce2bbe6907:core/shader/recompiler/Optimization/src/ResourceTracker.cpp > core/shader/recompiler/Optimization/src/ResourceTracker.cpp
ninja -C build -j32 -l32
ctest --test-dir build -j8 --test-load 32 --output-on-failure -R "^agc_driver_pointer_"
git show 811a3c5c010226d737ab32ee801a80c9d77bb65d:core/shader/recompiler/Optimization/src/ResourceTracker.cpp > core/shader/recompiler/Optimization/src/ResourceTracker.cpp
ninja -C build -j32 -l32
ctest --test-dir build -j8 --test-load 32 -R "^agc_driver_pointer_"
git status --porcelain
Results
| Check | Result |
|---|---|
git diff --check |
clean |
check_conventions.py |
All conventions checks passed |
| Configure / build / libs (script) | ok |
| Selected tests (script) | 2113 ran, 0 new failures, 0 timeouts. 7 known failures also fail on main (agc_driver_division, the denormal-mode tests, unwrap_self, vector_constant_factor_tininess) |
| Validation layer (script) | 769 tests, layer loaded in 768, none missing, 0 tests with new VUIDs against main |
Focused set (26 tests: 8 agc_driver_pointer_*, nested, image-table, disk-cache, nested snapshot retry, agc_shader_memory, agc_shader_bindless) |
26/26 pass. The slowest is agc_driver_image_table at 9.8 s |
| Negative control | 4 of 5 new tests fail. vsharp_select passes, as the description says it would |
| Worktree after restore | clean (git status --porcelain empty), 8/8 agc_driver_pointer_* pass again |
Negative control output (truncated)
1/8 Test #1657: agc_driver_pointer_phi_lane_not_table ...........***Failed 0.12 sec
ShaderRecompiler::Recompile: GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x000000c0(GetAddressResource(Phi(Immediate, Phi(ReadConstBuffer@pc=0x00000074(...
2/8 Test #1656: agc_driver_pointer_phi_high_second_lane_table ...***Failed 0.12 sec
ShaderRecompiler::Recompile: GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x00000108(GetAddressResource(Phi(Phi(ReadConstBuffer@pc=0x0000007c(...
3/8 Test #1655: agc_driver_pointer_phi_high_table ...............***Failed 0.12 sec
ShaderRecompiler::Recompile: GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x000000e0(GetAddressResource(Phi(ReadConstBuffer@pc=0x0000007c(...
4/8 Test #1654: agc_driver_pointer_phi_lane_and_table ...........***Failed 0.12 sec
ShaderRecompiler::Recompile: GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x000000ec(GetAddressResource(Phi(Immediate, Phi(BitwiseAnd32(Phi(CompositeExtractU32x4(Ballot(LogicalAnd), Immediate), ...
5/8 Test #1652: agc_driver_pointer_phi_ballot_table ............. Passed 0.36 sec
6/8 Test #1658: agc_driver_pointer_vsharp_select_table .......... Passed 0.29 sec
7/8 Test #1653: agc_driver_pointer_phi_copies_table ............. Passed 0.41 sec
8/8 Test #1651: agc_driver_pointer_phi_sampler_table ............ Passed 0.94 sec
50% tests passed, 4 tests failed out of 8
Negative control
This PR's own production change over #7395 is ResourceTracker.cpp. It is identical at the head and in the merged tree, and main has not changed it since #7395's head 6cb37cc9ed. So I replaced only that file with #7395's version (6cb37cc9eda523074d5fd844537c28ce2bbe6907) in the merged tree, kept the tests, and rebuilt.
lane_and,high,high_second_laneandlane_notfail with theGetImageResource dword 0refusal the titles stop on.- #7395's three pointer-Phi tests still pass.
agc_driver_pointer_vsharp_select_tablepasses without the change, as the description says (it is coverage of #7395's chain).
This matches BunnyFl's Windows negative control. I then restored the merged file, rebuilt, and confirmed the worktree is clean.
Findings
Blocking
None.
Non-blocking
-
Dead test mode left behind by 4750c85. The commit removed the
agc_driver_pointer_phi_high_second_tableregistration and its--pointer-phi-high-seconddispatch. The test code for it is still there:PointerHighSecondCode(80 words, ImageTable.cpp#L395)PointerMask::HighSecond(L2072)- its fall-through arm in the
code/nameselection (L2090-L2091)
Nothing can reach them. Suggest deleting the array and the enum value, and making the last arm of each ternary explicit.
-
The rule that refuses an edge where both words are immediates is inconsistent with how other non-record edges are handled. See ResourceTracker.cpp#L1035-L1043.
- When both words are Phis of one block, an edge on which both are immediates refuses the whole column.
- An edge with a lane-mask low word is skipped instead. So is an immediate low word whose high word is a record read. In both cases the run-time lookup faults on a pointer that was not captured.
- A null pointer also faults at run time ("unmapped", per #7395's commit). Skipping that edge would therefore be just as safe.
- Refusing it may block the common shape where a loop header merges an SGPR pair zeroed before the loop with the record pointer.
This is not a correctness problem, because the refusal throws. If the refusal is intended, the debt entry could say so. Otherwise, consider skipping the edge like the other pointer-free edges. Since 4750c85 removed the assertion, no test covers this branch.
-
Stale description items.
- Under "What" (item 1) and "Tested",
agc_driver_pointer_phi_high_second_tableis still described as a test that "must refuse". 4750c85 removed that test. - The checklist's "Based on … merged with #7395's head e04a705" is out of date (the head now merges #7395's
6cb37cc9ed).
Reviewers who read the description to see what the tests cover will be misled.
- Under "What" (item 1) and "Tested",
-
The merge brings the whole stack. Merging this PR before #7395 (and #7223) lands would bring them in with it: about 1,500 of the 1,695 added lines are theirs (
ResourceMaterializer.cpp,SpirvImageEmitter.cpp, the ABI to 4,ShaderDiskCache66). TheDepends on: #7395line covers this. I reviewed this PR's own change over #7395 in detail, and their parts only as far as this change uses them.
Not verified
- The title claims (Ratchet & Clank: Rift Apart, Little Nightmares Enhanced Edition, Ghostrunner). I launched no titles.
- Hardware other than lavapipe. The NVIDIA RTX 2000 Ada results come from TechLevelZero's bot, not from me.
- Windows behaviour, including the libc PATH lines for the nested retry tests.
- How the pair walk performs on very large shaders.
seenholds (low, high) pairs, which grows quadratically when the two words' Phis are not paired. I have no shader large enough to measure it. - I did not re-review #7223's and #7395's materializer, SPIR-V emitter and disk-cache changes as a whole.
✅ 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 (12, not counted against this PR)Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)Validated but not compared (15, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 510 tests)Skipped (54)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
The only new commit is 58ebe4b, a clean merge of main 4f41f4c (it brings #10000's sampler limits, among others). This PR's own change is the same apart from context lines. Checks and the focused tests pass. The one new VUID the script reports comes from a main test that this PR does not reach.
What changed since my last review
- One new commit, 58ebe4b ("Merge main into fix/shader-pointer-key-lane-masks"). Its parents are afb123a, which I reviewed last time, and
main4f41f4c. The commit message lists no conflicts. The range-diff in delta.patch only reorders the cherry-picked commits; the patches are the same. - The PR's own diff is the same as before, apart from context lines. I compared
git diff 9090972b7e...afb123a49ewithgit diff 4f41f4c375...58ebe4b440, ignoring index and hunk lines. Three things differ, and all three are context that comes frommain:main'sFormatVersionis now 52, and this PR still replaces it with 66, which is still abovemain's.- A
set_tests_propertiescontext line now includesagc_shader_sampler_limits. - The
docs/dev/debt/shader.mdcontext now has #10000's sampler-limit entry.
- No new author comments or replies. The description is unchanged.
What I ran
Head 58ebe4b44099cd04f81411a07d2c4d25d95a7a87, main 4f41f4c375f5abb487dbd184fbc150f31994d762, merged tree bad6f1b67d11d12ed7ed1d1a76b7dbba23e6eee1. Release build with GCC 14.2.0 and Ninja, on lavapipe (Mesa 26.1.6, LLVM 19), in a Debian 13 VM.
git diff 9090972b7e91fd266819cbd77a8b058e177b5682...afb123a49ec3f7555c274c769abfa5bbd4f87b81 # compared with the next diff
git diff 4f41f4c375f5abb487dbd184fbc150f31994d762...58ebe4b44099cd04f81411a07d2c4d25d95a7a87
git diff --check 4f41f4c375f5abb487dbd184fbc150f31994d762...58ebe4b44099cd04f81411a07d2c4d25d95a7a87
python3 tools/check_conventions.py --base 4f41f4c375f5abb487dbd184fbc150f31994d762
ctest --test-dir build -j8 --test-load 32 --output-on-failure -R "^(agc_driver_pointer_|agc_driver_nested_|agc_driver_image_table|agc_shader_disk_cache|agc_shader_nested|agc_shader_memory$|agc_shader_bindless$|agc_shader_sampler_limits$)"
env VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ANYPS5_NO_SHADER_CACHE=1 ANYPS5_REQUIRE_VULKAN=1 VK_LOADER_DEBUG=error,warn,layer ctest --test-dir build -V -R "^agc_driver_native_depth_uniform_planes$"
git log -S native_depth_uniform_planes 4f41f4c375 -- core/libs/prx/libSceAgcDriver
git merge-base --is-ancestor c9987271e3 d1ae628bc2f62459cce1e9872ba5632c938c71f2
| Check | Result |
|---|---|
git diff --check |
clean |
check_conventions.py |
All conventions checks passed |
| Configure, build and libs (run by the script) | ok |
| Selected tests (run by the script) | 2244 ran: 0 new failures, 0 timeouts. 7 known failures also fail on main. |
Focused set, 27 tests (the 7 agc_driver_pointer_* tests, the nested, image-table, disk-cache and nested snapshot retry tests, agc_shader_memory, agc_shader_bindless and main's new agc_shader_sampler_limits) |
27/27 pass. The slowest is agc_shader_sampler_limits at 14.6 s. |
| Validation (run by the script) | 782 tests, layer loaded in 781, missing in none. One test has new VUIDs: agc_driver_native_depth_uniform_planes (see below). |
The new VUID comes from main, not from this PR.
- The VUID is
VUID-vkCmdDispatch-groupCountX-00386inagc_driver_native_depth_uniform_planes. The script marks that test "(test not run on main)". - The test comes from
main's c998727 (2026-10-31). That commit is not in the validation baseline d1ae628, so the baseline has no run of it to compare with. - The test exercises
Graphics/src/DepthSurface.cpp's import of a native multisample D32S8 target. This PR changes nolibSceAgcDriverproduction file. - I reran the test with the layer in the merged tree. It reports
groupCountX (69144) exceeds device limit maxComputeWorkGroupCount[0] (65535), which belongs to that depth-import dispatch, not to an image-table path. I did not run the test on amain-only build.
Validation excerpt
Validation Error: [ VUID-vkCmdDispatch-groupCountX-00386 ] | MessageID = 0x8e927036
vkCmdDispatch(): groupCountX (69144) exceeds device limit maxComputeWorkGroupCount[0] (65535).
Negative control: not rerun. The tests and this PR's ResourceTracker.cpp lines are the same as at afb123a, where four of the five new tests failed without the change. Rerunning it here would also be harder: main has since changed ResourceTracker.cpp (#10000, #12132), so dropping in #7395's version of the file would also revert main's changes.
Previous findings
- Dead test mode (
PointerHighSecondCode,PointerMask::HighSecond). Still open, and unchanged:PointerHighSecondCodeis still at ImageTable.cpp#L395.PointerMask::HighSecondis still at L2072.- Nothing can reach either of them.
- An edge where both words are immediates refuses the whole column, while other pointer-free edges are skipped. Still open, and unchanged. It is now at ResourceTracker.cpp#L1039-L1047. It is not a correctness problem, because the refusal throws.
- Stale description items. Still open:
- The merge brings in the whole stack (#7395, #7223). Still applies, and is covered by
Depends on: #7395.
New findings
Blocking
None.
Non-blocking
None.
Not verified
- The title claims (Ratchet & Clank: Rift Apart, Little Nightmares Enhanced Edition, Ghostrunner). I launched no titles.
- Hardware other than lavapipe, and Windows.
agc_driver_native_depth_uniform_planeswith the validation layer on amain-only build. I attribute its VUID tomainfrom where the test comes from and from the code it exercises.- I did not reread how #10000's sampler limits, now on
main, interact with the stack's nested S# budget beyond the passing tests.agc_shader_sampler_limitsand the nested sampler tests pass together.
✅ 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 524 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.
✅ 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 547 tests)Skipped (49)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. |
4769d4a is boykopovar#8939 with boykopovar#7395's merge of main after boykopovar#7223. The one conflict is this branch's FormatVersion 67.
What
Depends on: #7395. #7223, which #7395 was stacked on, has merged. Until #7395 merges, this PR's diff shows its commits too.
#7395 lets a T# or S# be read through a pointer that a scalar-buffer record holds, with the pointer's low word merged by Phis with constants, lone
Ballotwords and copies of the record word. Two titles' chains still refuse on the pointer's words:Ballotmask ANDed with theNOTof the loop's lane bit, thes_andn2that clears the current lane.main82f0c9a plus open PRs and feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's earlier commits:Ballotword is ANDed into the low word, and the high word is merged through a Phi. One arm of that Phi reads a second buffer, and on that edge the low word is a lane mask: the waterfall loop reusing the SGPR pair, as oneandonlydean read it from the IR (comment).The change, in
ResourceTracker.cpp, for pointer-keyed columns only:fix(shader): take lane-mask ANDs and a high-word Phi in a pointer-keyed record pointer.Ballotword, or an AND or Phi made only of those and immediates. The other operand is walked on, so a record read in it must still match the column. An AND with no lane-mask operand still refuses.fix(shader): skip lane-mask arms built from a waterfall's lane bit in a pointer-keyed record pointer.ShiftLeftLogical32(1, index), and ORs and NOTs of lane-mask operands.FindILsb32,FindUMsb32orReadFirstLane, throughBitwiseAnd32,IAdd32,ISub32, immediates and the arms ofSelectU32.s_ff1_i32_b32,s_ff1_i32_b64,s_bitset0_b32and the shift's ownAND 31.docs(shader): the image-table debt entry lists the new arms and the merged high word, and says that a high word read from a second buffer stays refused.fix(shader): pair a pointer-keyed record pointer's two words by Phi edge, from oneandonlydean's reading of Ratchet & Clank: Rift Apart's IR (comment).docs(shader): the debt entry says the two words are walked edge by edge, and that a second-buffer high word stays refused on an edge whose low word is the record word.fix(shader): refuse a pointer-keyed record arm whose two words are both immediates(9e50a74). Where the pointer's two words are Phis of one block, an edge on which both are immediates is a constant pointer that no record holds, such as a null pointer, so the walk refuses the column there instead of planning it.At run time, a pointer built from a lane mask faults as outside the snapshot, as #7395's lane-mask arms do.
Disk cache: no plan field changes, but so that a cache written by #7395's recompiler isn't read as this one's, this PR has its own format, 66 (see Tested).
mainis at 56 since #7223. Ours take one number each: #10489 57, #7642 62, #7395 63, #8939 66, #9457 67, #9633 70, #9790 71, #9749 72 and #9969 73. The other open PRs seen changing it hold 51 (#14944), 53 (#12944), 56 (#9508, the same asmain), 65 (#14032), 68 (#14636), 69 (#14871) and 74 (#14853). Whichever lands second on a number takes the next free one.Marvel's Spider-Man 2 (PPSA08338), run by spiff637 (comment), stops on a record → pointer → V# → T# chain keyed by
ReadFirstLane(SelectU32(LogicalAnd, IAdd32, Phi)). The second commit'sagc_driver_pointer_vsharp_select_tablebuilds a record → pointer → V# → T# chain with the T# read under a second key, and it passes without this PR's tracker changes. The title doesn't take it yet: hugodearaujo's run of the US release, Marvel's Spider-Man 2 (PPSA03016), still stops on the #6191 chain with this PR and #7679 (comment). There the T# is read at a fixed offset of the pointer-loaded V#, with no second key, and the same shader then reads its next block through a linked pointer. The test stays as coverage of the keyed form.Tested
tests/execution/ImageTable.cpp, on lavapipe. They are synthetic wave64 waterfall loops, assembled withllvm-mc -mcpu=gfx1030 -mattr=+wavefrontsize64. The fourth commit's is the second-buffer shader with one instruction added (s_mov_b32 s44, exec_lo,0xbeac037e) and its three crossing branch offsets adjusted, checked by disassembly.agc_driver_pointer_phi_lane_and_table(lane-mask ANDs),agc_driver_pointer_phi_high_table(a merged high word) andagc_driver_pointer_phi_high_second_table(the second-buffer arm, which refused; 4750c85 later removed this test, see below).agc_driver_pointer_phi_lane_not_table(Little Nightmares'BitwiseNot32ands_andn2arms) andagc_driver_pointer_vsharp_select_table(Spider-Man 2's chain).agc_driver_pointer_phi_high_second_lane_table(Rift Apart's edge: the second-buffer high word with a lane-mask low word, which must plan).ResourceTracker.cppreverted and the tests kept, on Linux with CI's configuration:lane_andandhighfail with the dword-0 refusal, andhigh_secondpasses (refused). Each half of the commit fixes only its own test.lane_notfails:GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x000000c0(GetAddressResource(Phi(Immediate, Phi(ReadConstBuffer@pc=0x00000074(…), Phi(BitwiseAnd32(CompositeExtractU32x4(Ballot(LogicalAnd), Immediate), BitwiseNot32(ShiftLeftLogical32(Immediate, BitwiseAnd32))), ….vsharp_selectpasses (coverage).high_second_lanefails:GetImageResource dword 0 is not a valid runtime value; chain: LoadAddressU32@pc=0x00000108(GetAddressResource(Phi(Phi(ReadConstBuffer@pc=0x0000007c(…. The other 10 image-table cases pass,high_secondamong them (refused).agc_shader_disk_cache.agc_shader_disk_cachepass 5 runs in a row on Linux. On Windows the GPU ones skip and the rest pass. The libc and libkernel suites pass on both.agc_shader_disk_cache_large_filepass 5 runs each. Windows: builds; the Vulkan cases skip on the runner.^agc(run): 813 of 874 pass, 60 skip and 1 fails. The one failure isagc_driver_sgpr_pattern_fill_keys, a timing test, which passed in the worker's full run of the same head.GetImageResource dword 0,LoadAddressU32@pc=0x9a30.GetImageResource dword 0,LoadAddressU32@pc=0x10b84.pc=0xfd94and aBallotlane-mask word. The high word's other arm isReadConstBuffer@pc=0x10350, through a V# whose four dwords are loaded atpc=0x10338from another pointer.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 (22 tests) pass 10 runs in a row on Linux. On Windows the set has 24, with two Windows-only disk-cache tests: they build, 5 pass 10 runs in a row, and the other 19, 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_shader_replay --preparewithANYPS5_NO_SHADER_CACHE=1on the request the driver dumped, RTX 4090, Windows 11; replay only, no title run. Onmain513ca7e with fix(shader): link table callees that together exceed s_call_b64 range #9068, fix(shader): link a table call whose V# is a slice of an s_load_dwordx8 or s_load_dwordx16 #8070 and fix(shader): find strongly connected components without recursion #9701 to refactor(shader): walk each construct when checking the structured constructs #9703, it stops on Shader recompiler: non-invariant descriptor Phi causes GetImageResource validation abort #7459'sGetImageResource dword 0 is not a valid runtime value: a T# behind areadfirstlane-keyed record in a waterfall loop whose pointer Phis carryBallotAND-NOT words. With this PR (9162d9d) it gets past that and stops onsampler resource limit exceeded, which feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000 raises.agc_shader_replay --prepareon the title's dumped request withANYPS5_NO_SHADER_CACHE=1, Windows 10 22H2, WinLibs GCC, Release; replay only, no title or GPU run. The base ismain0db47b2 with fix(shader): link table callees that together exceed s_call_b64 range #9068, fix(shader): link a table call whose V# is a slice of an s_load_dwordx8 or s_load_dwordx16 #8070 and refactor(shader): walk each construct when checking the structured constructs #9703.GetImageResource dword 0 is not a valid runtime valueatLoadAddressU32@pc=0x000517dc, and so does the base with fix(shader): plan an image table for a T# read at a first-lane offset #10228.sampler resource limit exceeded.LoadAddressU32@pc=0x0002ef78. Its pointer Phi has, besides the record reads with lane-mask arms, an arm read at a fixed offset of a buffer whose V# is loaded from memory. fix(shader): follow pointer hops and fixed-offset V# reads behind a record pointer #9457 with feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000 stops at the same 0x2ef78.main379b1dc), on top of the new commit 9e50a74 (6. above). The conflict inResourceTracker.cppis between this PR's paired walk and fix(shader): resolve table column pointers through Phi nodes #7880's unwrap of the pointer's words: pointer-keyed columns keep the paired walk, the others take fix(shader): resolve table column pointers through Phi nodes #7880'sUnwrapTableRead.FormatVersionstays at feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's 47.agc_shader_memoryandagc_shader_bindlesson both runners withGetImageResource dword 0 is not a valid runtime value(run). And 9e50a74 refuses a pointer-keyed Phi edge whose two words are both immediates (a constant pointer no record holds, such as a null pointer), where the walk planned it before.agc_driver_pointer_phi_high_tablefails 3 of 3 on Linux with "a record pointer arm whose two words are both immediates was planned". With the commit, ×10: Linux 24 run, 24 pass, 0 skip, 0 fail; Windows 26 run, 7 pass, 19 skip, 0 fail.agc_shader_bindless,agc_shader_memoryand the^agc_driver_pointer_,^agc_driver_nested_,^agc_driver_image_tableand^agc_shader_disk_cachetests. Linux: 24 run, 24 pass, 0 skip, 0 fail. Windows: 26 run, 7 pass, 19 skip (Vulkan device tests; the runner has none), 0 fail.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners. The full^agcset at fix(shader): read a chased pointer's high word at its own offset #9749's and fix(shader): plan several T#s read through one pointer-loaded V#, keeping the V# real for their other uses #9790's heads, which carry this merge, shows onlymain's three known failures (see those PRs).main5d3ab77 with fix(shader): structurize a 4,750-block graph before Unreal's render thread watchdog fires #9702 merged in, so compute shader 0x200c520000 gets past structurization.GetImageResource dword 0 is not a valid runtime value(LoadAddressU32@pc=0x00051884andpc=0x0005192c).storing storage image results pending over memory outside the write watch without the guest bytes saved before them is not implemented, the check fix(agc): save the guest bytes of results that become pending over a surface that is no longer fully write-watched #7048 addresses.sampler resource limit exceeded, the replays' next stop, doesn't appear in these runs.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: 24 run, 24 pass, 0 skip, 0 fail. Windows: 26 run, 7 pass, 19 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: 24 run, 24 pass, 0 skip, 0 fail. Windows: 26 run, 7 pass, 19 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.agc_shader_replay --preparewithANYPS5_NO_SHADER_CACHE=1on a freshshader_200c520000.prepare.reqfrom a run onmain74acfad.main74acfad with this PR (e2af03b): a title run on an RTX 3080 (617.42) stops after about 152 s onsampler resource limit exceededin compute shader 0x200c520000, and the replay stops the same way. feat(shader): raise the sampler and sampled-pair limits past the 32-bit sampler masks #10000 raises that limit.LoadAddressU32@pc=0x0002ef78(GetImageResource dword 0 is not a valid runtime value). The IR shows the T# pointer is a Phi of the record pointer and a pointer read at offset 0 through a V# loaded from the record at +0x30, with that V#'s words edited before use (& 0xffffon the base's high word,<< 4on the record count,| 0x30000000on word 3). No PR in this stack plans that arm; it's the title's next stop.main0cd07dc (run).main0d62324, which moves feat(shader): resolve nested image tables through runtime pointers #7223 toFormatVersion49) and feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's test-only commit. Clean, and this PR's own diff is unchanged.not a valid runtime value, two of the assertions @oneandonlydean listed on fix(shader): index a pointer-loaded V#'s T# array by a word read from the same buffer #9969, under the rule that tests don't assert that a shape the code doesn't support yet throws: a high-word arm read from a buffer whose V# is loaded through a pointer, and a record-pointer arm whose two words are both immediates. The first was the whole ofagc_driver_pointer_phi_high_second_table's mode, so that test and its registration go; the lane-mask, high-word and second-lane cases stay.main0cd07dc. The one conflict wasResourceTracker.cpp's include list, where mrfelek's fix(shader): plan an image table for a T# read at a first-lane offset #10228 adds<numeric>beside this PR's<set>; both stay. This PR's changed lines are the same.guest_raise_exceptionfailed after "address waking round 47: the handler did not run within 5 s", asmain9fc181d does in the same verify setup (run); that is libkernel (Windows): guest_raise_exception slowed about 3x and sometimes aborts at "address waking" since 540364a24 (#10666) #11813, and this PR doesn't touch libkernel.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.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 51 (see What), and this PR's diff over feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 is the same. The pointer-Phi, V#-select, SGPR-fill and nested-sampler 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: 12 run, 12 pass, 0 skip, 0 fail. Windows: 14 run, 6 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), and 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, which moves feat(shader): resolve nested image tables through runtime pointers #7223 toFormatVersion50). Clean.agc_shader_bindlessandagc_shader_memoryran 10 times with no failure. Linux: 24 run, 24 pass, 0 skip, 0 fail. Windows: 26 run, 8 pass, 18 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.main0836dfd. Compute shader 0x2010fa0000 gets past its stop, andagc_shader_replay --prepareon its dumped request prepares it (481,271 SPIR-V words). Onmain, and onmainwith feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 alone, it fails at pc 0x3300 withGetImageResource dword 0 is not a valid runtime value. The title then stops at compute shader 0x200c340000 with the same message, a pointer chase that fix(shader): follow a conditional pointer chase through a V# behind a pointer-keyed record pointer #9633 and fix(shader): read a chased pointer's high word at its own offset #9749, stacked on this PR, plan when the chase isn't a loop (from reading the code, not run).main0836dfd (1f158eb) (run).CMakeLists.txtconflicted from build(agc): register each AGC test executable in its own CMake fragment #12862's split.tools/agc_test_split.py resolvemoves this PR's registrations intotests/cmake/agc_driver_image_table_tests.cmake: +7 −2 against feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge, the 5 newadd_testlines and feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's twoset_tests_propertieslines extended with this PR's names.ShaderDiskCache::FormatVersionconflicted too, since feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge brings 63. This PR's own format moves from 53 to 66, the lowest number above 63 that no open PR uses, so its recompiler change keeps a disk cache format of its own.main, left as he made it, so the stack's numbers are uneven until one of them merges again.-DBUILD_TESTING=ON,ctest -Ngives 3089 tests:main's 3075, feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's 9 and this PR's 5, 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),main0836dfd against this merge, for the same tests. The loader inserted the layer 1 time onmainand 13 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.agc_shader_nested_snapshot_retry, which this PR now carries through feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's merge. As on feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395 and fix(agc): span table-reading wave64 programs by default on Intel drivers that share handles across fused threads #10846, it exits with 0xc0000135 before it starts, because its registration doesn't put libc's directory on PATH on Windows. df80d9b, below, fixes it.main, and 2 are unstable onmain.VK_LAYER_KHRONOS_validation, there are no new validation IDs againstmain, over 939 tests on the GPU.agc_shader_nested_snapshot_retrylibc's directory on PATH on Windows, beside feat(shader): read samplers through nested and pointer-keyed descriptor tables #7395's sampler retry, as oneandonlydean asked on fix(agc): span table-reading wave64 programs by default on Intel drivers that share handles across fused threads #10846 (comment). It brings in only that line, so the upstream Windows failure noted above is gone.APS5_SKIP_TIMING_TESTS=1, which relaxesprecise_wait's median bounds on GitHub's hosted runners.maind262000: 39 tests, 39 passed, 0 skipped, 0 failed, both retry tests included.maine6f5730, driver 595.99.02, Ubuntu 26.04.1, 2,548 of 3,148 tests selected.main, and 3 are unstable onmain.VK_LAYER_KHRONOS_validation, there are no new validation IDs againstmain, over 946 tests on the GPU. 14 tests ran with the layer but aren't inmain's baseline, so they weren't compared. Both nested snapshot retry tests passed on the GPU.main88e804b (run). Clean:FormatVersionstays 66, and this PR's own diff is unchanged; the plan-encoder numbers come 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 shader-memory, nested, pointer, image-table, disk-cache and bindless tests, with fix(shader): split scalar-address descriptor phis #7694'sagc_shader_descriptor_phis, pass 10 runs in a row. Linux: 27 run, 27 pass, 0 skip, 0 fail. Windows: 29 run, 11 pass, 18 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,563 passed, 7 failed, none new (3 also fail onmain, 4 unstable onmain), 45 skipped, with no new validation IDs (985 tests on the GPU).main4f64f81 (run). Clean:FormatVersionstays 66, 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 shader-memory, nested, pointer, image-table, disk-cache and bindless tests, with fix(shader): split scalar-address descriptor phis #7694'sagc_shader_descriptor_phis, pass 10 runs in a row. Linux: 27 run, 27 pass, 0 skip, 0 fail. Windows: 29 run, 11 pass, 18 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, complete ×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 66; anddocs/dev/debt/shader.md, where this PR's pointer lane-mask entry andmain's new sampler-limit entry 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_cacheor^agc_shader_sampler_limits. Linux: 7 run, 7 pass, 0 skip, 0 fail. Windows: 9 run, 7 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_,^agc_driver_nested_,^agc_shader_nestedand^agc_shader_tabletest, so every test in this PR's diff overmainruns. Linux: 22 run, 22 pass, 0 skip, 0 fail. Windows: 24 run, 10 pass, 14 skip (no Vulkan device), 0 fail.windowscheck is red at this head on one test,avplayer_http_patched_modules, atAvPlayerHttpModules.cmake:155, where the owner executableavplayer_http_patched_modules_tests.exewasn't built for the selected test (job). fix(ci): build owners of wrappers around selected guest tests #15375 is the open fix. This PR changes no avplayer or HTTP file, and the check passed at afb123a.mainc2eafe4 with yabanana's feat(shader): resolve nested image tables through runtime pointers #7223 (×10).ShaderDiskCache.hpp'sFormatVersion, which stays 66 (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 image-table 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: 27 run, 27 pass, 0 skip, 0 fail. Windows: 29 run, 10 pass, 19 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
main4f64f81) and then withmain4f41f4c; 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)