Repository navigation
Description
Observed failure
Unmodified main 5d9dcc42d2ec5401aebd089028b8d4d7410a77b4, Windows/NVIDIA, the public agc_driver_store_over_untracked fixture:
AGC graphics: store over untracked: the sampled surface has no live storage image
This occurred once in 20 unrestricted fresh NVIDIA processes, on process 13 (1.038 seconds). The other 19 processes passed. The fixture source and executable hashes were unchanged throughout that composition's campaign. This is a synthetic test failure, not a game failure, device loss or access violation.
The assertion is in Run, Kind::UntrackedRepeat, before its MarkDirty and intervening CPU-write checks. The case settles its initial store, allocates the output surface, queues ReadImage, and then requires an exact live storage-image lookup to succeed. FindLive only returns a cached, unreleased image with the exact base and footprint. The original observation did not identify the cause; the subsequent test-side diagnosis and regression are recorded below.
Reproduce
Windows 11 Enterprise 10.0.26200, Ryzen 9 9950X3D, NVIDIA GeForce RTX 5080 (10de:2c02), driver 610.62 / 32.0.16.1062. WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, bundled dependencies, SPIRV-Tools enabled, BUILD_TESTING=ON. The target and its dependencies were rebuilt on the pinned main. No test or production diagnostics were added to this source.
cmake --build build --target agc_driver_store_over_untracked_tests
$env:ANYPS5_REQUIRE_VULKAN = '1'
$env:ANYPS5_NO_SHADER_CACHE = '1'
$env:ANYPS5_GPU = 'RTX 5080'
ctest --test-dir build -R '^agc_driver_store_over_untracked$' --repeat until-fail:50 --parallel 1 --timeout 30 -VUse the normal full process affinity, not the single-CPU constraint used for #6383. Our captured failure has verified child mask 0xffffffff; the requested and actually selected GPU match. The campaign cleared inherited APS5_*/ANYPS5_* runtime overrides before setting the three options above. Driver caches were not controlled. The suggested repeat command is for reproducing an intermittent assertion, not a guarantee of this exact failure rate; other existing assertions can stop it first.
Comparisons and existing work
The same four-way current-main campaign ran 20 fresh processes per GPU and scheduling profile for main, #6359, #6385, and both together: 320 total. Compositions are #6359 only, #6385 only, and both. Every process verifies physical GPU selection and affinity. This particular assertion appeared only in the main/NVIDIA/unrestricted cell. Many constrained main/#6359 processes stop earlier at #6383; they do not establish coverage of this later case. Neither of the two PRs changes UntrackedRepeat or the shared HoldPending/Settle helpers. Their passing compositions alone do not establish a fix for this intermittent assertion.
- test(agc): cover repeated untracked storage writes after sampling #5708 added this case and is merged. Main includes its output-lifetime correction
9c765fa0fand the case-table correctiond17895ed8; this report is not against their earlier versions. I checked that PR's discussion before filing. - Windows: StoreOverUntracked fails at "the first result was not stored" #6347/test(agc): wait for the actual image in repeated untracked stores #6359 concern
RunSecondStore's first-result wait; AGC: StoreOverUntracked's NeighbourCopied case intermittently misses its pending result on Windows / RTX 4080 #6383/test(agc): keep waiting for the neighbour copy case's result #6385 concernNeighbourCopied's pending-result wait. Those are different assertions and call sites. - Searches for this exact error,
UntrackedRepeat, and StoreOverUntracked issue reports did not find an existing report of this assertion. The known lifetime issue Windows NVIDIA: StoreOverUntracked can free surfaces before queued work completes #5789 was an access violation, not this caught assertion.
Four preexisting internal watch-transition cases still report not run, the surface is not write-watched; no successful coverage is claimed for those transitions. AMD Radeon Graphics (1002:13c0, driver 32.0.21036.18) was included in the matrix, but did not reproduce this assertion. That original campaign did not include Linux or establish a cause. The subsequent isolated regression is described below; no capability fix, title startup or FPS result is claimed.
AI-assisted investigation and report: Codex; locally observed source-pinned failure, no private game assets or shader captures involved.
Follow-up: shared wait correction and deterministic regression
#6744 by Ondra97 fixes the shared HoldPending helper: it requires the exact surface's pending image to be the same live image. The author reproduced this assertion on unchanged main and reports a temporary diagnostic in which 37/44 accepted waits had neither a live nor pending image for the requested surface. Those results belong to that author's campaign. MarcZX100 independently identified the overlapping diagnosis in #6745 and closed it in favor of #6744.
Our independent validation and test proposal provides a deterministic control: with another surface pending, the old helper incorrectly accepts an already-completed surface with no image. Main + test only failed at the intended assertion 5/5 times on each of RTX 5080, Radeon Graphics and Linux lavapipe. The unchanged #6744 head plus our test-only commit passed 5/5 on each, with actual device selection verified. This establishes the helper contract independently; it is not a second reproduction of the author's causal diagnostic. No duplicate fix PR is planned.
Activity
MarcZX10 commentedon Oct 16, 2026
I found a test-side race consistent with the report and opened #6745.
HoldPendingused globalStorageTexture::AnyPending(), so a pending image from an earlier case could satisfy the wait before this surface’s asynchronousStorereached the worker. The test then submittedReadImageand checkedFindLivewithout proving this surface’s image had been created. The change waits for pending writes overlapping this surface. This is a code-path diagnosis, not a reproduction on the reported RTX 5080; the focused Linux binary built, but this host’s CPU guard prevented the fixture from running.