Skip to content

AGC: 4x DCC refill resolve loses watched color after an adjacent aligned import (Windows RTX5080) #8103

Description

@Amoenus

2026-10-19 UTC recheck: rebuilt the fixture/runtime on literal main 903cbbd5ba, after #7432. One RTX5080 4x process reproduces the same watched-color refusal; requested device and loaded Khronos verified, zero VUID/errors/warnings, skip or timeout. The repeated window controls below retain their bf2 source pin.

Observed failure

Literal main bf2c63f853, rebuilt libraries/relinker and agc_driver_alpha_to_coverage_tests: agc_driver_msaa_dcc_clear_4 fails 3/3 fresh processes on Windows / RTX5080:

AGC graphics: multisampled DCC target reuse requires watched guest memory (color range 0x2002b0000+0x100000, 4 samples)

The same build passes 2x/8x 3/3 each. This is separate from #7936: literal-main AMD stops earlier at its existing resolve-value assertion and does not reach this refill case.

Narrowed location and control

Local test-only print probes locate the failure in DccRefillTests, mode1 without CMASK (CPU full DCC fill). Its second draw completes. Immediately before resolve, the full color range is watched. Existing APS5_TRACE_HOST_IMPORT=1 then prints:

step=after-draw color=1 address=0x2002b0000
step=before-resolve color=1 address=0x2002b0000 resolved=0x2003c0000
[gpu] host import of 0x200000000+0x400000 ok ... by access
AGC graphics: multisampled DCC target reuse requires watched guest memory (color range 0x2002b0000+0x100000, 4 samples)

The 4MiB import spans the resolve destination and the live native color source. One diagnostic change at entry to DccRefillTests, AgcDriver::Graphics::SetHostImportWindow(BlockBytes); (BlockBytes=0x10000), prevents adjacent allocations being grouped here. 4x then passes3/3. Restoring the exact default-window probe and rebuilding returns the same failure3/3. Production code is unchanged throughout. This is an isolation control, not a proposed global window reduction or removal of the resident-memory guard.

Relevant code: aligned block selection/import, refill fixture. #6457 and #7250 are relevant context; no introducing commit has been established. The mode5 Windows GPU-fill/rewatch case discussed in #7250 is later than this mode1 stop. #6308 concerns running the unwatch hook; #4448 concerns storage-surface comparisons on unwatching imports, rather than this native-DCC resolve refusal.

Reproduce

cmake --build build --target libs relinker agc_driver_alpha_to_coverage_tests
ctest --test-dir build -V -j1 --timeout 30 --no-tests=error -R '^agc_driver_msaa_dcc_clear_4$'

Run three separate processes, serially. Child environment: ANYPS5_GPU=NVIDIA GeForce RTX 5080, ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1, APS5_NO_PIPELINE_JOURNAL=1, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, installed SDK VK_LAYER_PATH, VK_LOADER_DEBUG=error,warn,info,layer,driver, and VK_LOADER_LAYERS_DISABLE=~implicit~. Other AnyPS5/Vulkan overrides removed. Driver caches uncontrolled.

Windows11 Enterprise26200, WinLibs GCC15.2r7/UCRT Release; RTX5080 10de:2c02, driver610.62 /32.0.16.1062; Khronos SDK/layer1.4.363.0. Actual device and loaded layer verified, zero VUID/errors/warnings, skips or timeouts in the controls. Later maina700 changes libkernel/tooling, not this graphics source/fixture; it has not been rerun here.

Found while qualifying the PPSA99902 integration; no new title stop, gameplay/FPS, console, Linux or AMD-refill result is claimed. Preserve the refusal until the import/tracking interaction has a general correction. AI-assisted investigation/report: yes (Codex).

Activity

  1. wachi35676 commented on Oct 20, 2026

    @wachi35676
    Contributor

    Bisect: agc_driver_msaa_dcc_clear_4 starts failing at #6457 (5242599).

    I ran a first-parent git bisect between main 9127ea36d (good) and 0d8c51a54 (bad). That covers 19 merges. At each step I rebuilt the test and all unpatched/*.prx in one Release build dir and ran the test in 3 fresh ctest processes with ANYPS5_REQUIRE_VULKAN=1.

    Commit RTX 5070 Ti Radeon iGPU (ANYPS5_GPU=AMD)
    9127ea36d (parent of #6457) 3/3 pass 3/3 pass
    524259954 (merge of #6457) 3/3 fail 3/3 fail
    3756c72dc (#6479) 3/3 fail –
    a9970f75d 3/3 fail –
    a70080967 (before #7432) 3/3 fail –
    0d8c51a54 3/3 fail 3/3 fail

    Every failure is the same:

    AGC graphics: multisampled DCC target reuse requires watched guest memory (color range 0x2002b0000+0x100000, 4 samples)
    

    First bad commit: 524259954a3e85024560b2813df1eff410958f57, "Merge pull request #6457 from EagleBearerYS/perf/agc-host-import-aligned-blocks". #7432 is not the cause, because the test already fails at a70080967, the merge just before it.

    Why it fails. APS5_TRACE_HOST_IMPORT=1 plus a temporary print in GuestMemory::ImportWatched (local only, reverted) shows this at 0d8c51a54:

    [diag] ImportWatched 0x200110000+0x40000 staysWatched=0 covered=1 before=1
    [gpu] host import of 0x200110000+0x40000 ok ... by access
    [diag] ImportWatched 0x200270000+0x40000 staysWatched=0 covered=1 before=1
    [gpu] host import of 0x200270000+0x40000 ok ... by access
    [gpu] host import of 0x200110000+0x40000 retired: the range was mapped again
    [gpu] host import of 0x200270000+0x40000 retired: the range was mapped again
    [diag] ImportWatched 0x200000000+0x400000 staysWatched=1 covered=0 before=0
    [diag]   not watched before import: block 0x200110000 ... 0x200140000
    [diag]   not watched before import: block 0x200270000 ... 0x2002a0000
    [diag] ImportWatched unwatches 0x200000000+0x400000
    [gpu] host import of 0x200000000+0x400000 ok (1 live, 4.0 MiB live, 10.5 MiB ever) by access
    AGC graphics: multisampled DCC target reuse requires watched guest memory (color range 0x2002b0000+0x100000, 4 samples)
    
    1. Two earlier 256 KiB imports (0x200110000, 0x200270000) are under the settle floor, so they are made unwatched. They are later retired when their ranges are mapped again, and their blocks are still not watched afterwards.
    2. The default host import window is 8 MiB (SetHostImportWindow(8ull << 20u) in VulkanDevice.cpp). Before perf(agc): import adjacent host ranges as aligned blocks and stop re-trying budget refusals #6457, importRun grouped adjacent ranges only when they filled that whole aligned window; otherwise it imported the single range. perf(agc): import adjacent host ranges as aligned blocks and stop re-trying budget refusals #6457 (a24aafb, "import adjacent registered ranges as aligned power-of-two blocks") steps down through 4 MiB, 2 MiB and so on. Here it finds an exact 4 MiB aligned block, 0x200000000+0x400000. That block contains the resident 4x color target (0x2002b0000+0x100000), the resolve destination and the two blocks that are no longer watched.
    3. ImportWatched(base, bytes, ..., staysWatched=true) computes covered = tracker.covers(first, stop). If any part of the run is unwatched, before is false and it calls unwatchLocked over the whole run. That takes the resident color range out of the write watch. checkDccCurrent in MultisampleTarget.cpp then refuses the reuse.

    This matches the control in this issue, where SetHostImportWindow(BlockBytes) at the start of DccRefillTests makes 4x pass: it stops the multi-range block from forming.

    Possible directions; I haven't tried either:

    • Skip an aligned multi-range block when part of it is not watched but the requested range is.
    • Have ImportWatched unwatch only the blocks that were not covered or whose before/after walk fails, instead of the whole run.

    The first changes importRun, which sameRange also uses when imports are refreshed. If the result there depended on the watch state, imports could be retired repeatedly, so it needs care. I haven't written a fix.

    AMD iGPU. On this machine the AMD iGPU fails at the culprit and passes at its parent, the same as the NVIDIA GPU. It does not show the #7936 resolve-value assertion: at 0d8c51a54, _2 and _8 pass 3/3 on the iGPU too. So the AMD part of #7936 does not reproduce here with this driver version.

    Setup:

    • Windows 11 Home 26300; Ryzen 5 9600X; WinLibs GCC 15.2.0; Ninja; Release.
    • NVIDIA GeForce RTX 5070 Ti (10de:2c05), driver 32.0.16.1742.
    • AMD Radeon(TM) Graphics (1002:13c0), driver 32.0.21042.62.
    • ctest environment: ANYPS5_NO_SHADER_CACHE=1, APS5_NO_PIPELINE_JOURNAL=1, plus ANYPS5_REQUIRE_VULKAN=1. No validation layers.

    AI-assisted: yes (Claude Code); results above were run on this machine.

  2. simonbbby commented on Oct 20, 2026

    @simonbbby
    Contributor

    Linux control for the new bisect: I rebuilt agc_driver_alpha_to_coverage_tests and its runtime dependencies at each exact pin, then ran --dcc-fast-clear 4 in three fresh processes per device, serially:

    Pin RTX 3090 RADV gfx1036 lavapipe
    9127ea36d (parent) 3/3 pass 3/3 pass 3/3 pass
    524259954a3e85024560b2813df1eff410958f57 (#6457 merge) 3/3 pass 3/3 pass 3/3 pass
    34b1b77abfc013ffe740cf11cd76e02c6ccbafaf (current main) 3/3 pass 3/3 pass 3/3 pass

    All returned 0 with Multisampled DCC fast clear tests passed; no skip or timeout. Both DccFastClearTests and DccRefillTests run in this mode.

    To check whether a green run was missing the reported stage, I temporarily added prints immediately before/after the resolve in refill mode 1 without CMASK on that main pin. All nine additional processes reached it and reported the entire 1 MiB color source watched before and after resolve. For example, NVIDIA used source 0x7a1a30250000, destination 0x7a1a301e0000; RADV used 0x7da7a4050000 / 0x7da7a4000000. These are the Linux fixture's mmap addresses, rather than the Windows sequence at 0x200…. I restored the exact fixture, rebuilt, and repeated all nine runs successfully.

    Thus the stock Linux fixture does not reproduce the bisected failure here. This does not refute the mixed-watch-state explanation or establish Windows-only production behavior: the fixture allocation layout differs, and I have not constructed the same 4 MiB overlap on Linux. I have not tested a fix or changed the watch guard/import-window size.

    Ubuntu 24.04, kernel 7.0.0-38, Ryzen 9950X, GCC 13.3, Release; NVIDIA 595.99.02; AMD 1002:13c0 gfx1036, Mesa 25.2.8; lavapipe LLVM 20.1.2. ICD restricted separately, actual loaded device verified, ANYPS5_REQUIRE_VULKAN=1, shader cache and pipeline journal disabled, other AnyPS5/Vulkan overrides removed. No Khronos validation layer is installed, so these are execution results without validation-layer coverage. Raw logs and the temporary two-print patch are retained.

  3. added 2 commits that reference this issue on Oct 20, 2026
    b05e9aa
    58f0e89
  4. MarcZX10 commented on Oct 20, 2026

    @MarcZX10
    Contributor

    I opened PR #8169 with a Windows regression test and a focused fix. When write watching is active, an aligned grouped import now requires the full block to remain watched; otherwise it falls back to the requested range. The regression test and fix are separate commits.

    Convention and whitespace checks pass locally. I could not build or run the test in this Linux worktree because its submodules are unpopulated and CMake reports missing SDL/XRandR development support. I did not run the Windows RTX 5080 reproduction; that result and bisect are from the issue report. GitHub checks are running.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions