Skip to content

fix(win): windows host import texture reuploads - #2096

Merged
boykopovar merged 3 commits into
mainfrom
fix/windows-host-import-texture-reuploads
Oct 9, 2026
Merged

boykopovar merged 3 commits into
mainfrom
fix/windows-host-import-texture-reuploads

Conversation

@boykopovar

@boykopovar boykopovar commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

What

Preserve CPU write tracking for Windows shared memory imported through a separate Vulkan alias. Avoid redundant texture uploads and write-backs. Retain byte comparisons for imports without reliable tracking.

The regression appeared presumably in 838d02a - fix(agc): compare Windows host imports after late driver writes

Tested

Windows, NVIDIA GeForce GTX 1050 Ti Dreaming Sarah: 12fps -> 60 fps

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
#1847 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp L1228-1229
core/libs/prx/libSceAgcDriver/Graphics/src/GuestBufferMemory.cpp L292, L413-414
docs/dev/TechnicalDebt.md L249
#1860 docs/dev/TechnicalDebt.md L249
#1960 core/libs/prx/libSceAgcDriver/Execution/src/GuestMemory.cpp L1263
#1994 core/libs/prx/libSceAgcDriver/Graphics/src/GuestBufferMemory.cpp L292
docs/dev/TechnicalDebt.md L249
#1995 docs/dev/TechnicalDebt.md L248-249

@github-actions github-actions Bot added docs agc libSceAgc* labels Oct 9, 2026
@github-actions github-actions Bot added the build label Oct 9, 2026
@popcoder565

popcoder565 commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Corrected: the device loss below also happens without this PR, though less often. Only the refresh store failure comes from it (commit 0e1d25a). Measurements are in #2155.

Windows run on the driver that shows #1434's late marking. Setup: Windows 10 (19045), RTX 3060 Laptop (NVIDIA 616.92), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head 3ed0d036 merged onto main b7218b3.

  • agc_driver_dcc_keys_first_write and agc_driver_srgb8_color_target pass 30/30 each, so AGC: on Windows (NVIDIA) a new host import's pages are marked written after ImportWatched's window, so write-backs drop GPU results #1434 stays fixed here.
  • Full ctest: 494/494, twice.
  • agc_driver_recorder_tests (not in ctest; built with --target) fails 5 of 5.
    • In 2 runs it fails with the refresh's store of the results did not reach guest memory (Recorder.cpp:1672, storageRefreshTests). After a draw and image->Refresh(), the image holds the draw's texels but guest memory doesn't.
    • In 3 runs it fails at the start of the same function with vkQueueSubmit recorder: Vulkan result -4 (VK_ERROR_DEVICE_LOST). main b7218b3 also hits this, in 1 of 18 runs.

No title was run.

🤖 Addressed by Claude Code

@boykopovar
boykopovar merged commit 43972e6 into main Oct 9, 2026
20 checks passed
aryanrawatispro-ship-it added a commit to aryanrawatispro-ship-it/AnyPS5 that referenced this pull request Oct 9, 2026
… memory

0e1d25a (boykopovar#2096) compares an untracked import's bytes with the image's
snapshot. When they still match, a refresh keeps the image's own
results pending instead of storing them, as it already does over
watched memory. storageRefreshTests (unwatched case) and
staleGenerationTests read the guest bytes directly, so they expected
the refresh itself to store the results, and stopped at "the refresh's
store of the results did not reach guest memory" and "(s) results
pending when their memory left the watch did not reach it".

Both now read the memory through GuestMemory::Read, as the watched
storage refresh case already does; its flush hook stores the pending
results first. Results that were dropped still fail both checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adriadam10 pushed a commit that referenced this pull request Oct 10, 2026
…port is compared

#2096 keeps a copy of a storage image's guest bytes so that Refresh can
compare memory the write watch does not cover. The host-import upload
path takes that copy only when the range is unwatched, but the DCC
fast-clear path took it on every upload. Reading the whole surface goes
through the flush hook, so each 64 KiB block of a surface that a unit
shadow covers recorded a publish and waited for the GPU.

The clear path now resolves the surface's host import first (the import
can unwatch the range, as a compared host-pointer import does) and takes
the copy only when the range is then unwatched, like the import path.
Write-watched memory, such as direct memory behind a dma-buf import,
skips it; a range that is unwatched later re-uploads instead of
comparing, as before #2096.

agc_driver_dcc_keys_first_write checks that a fast-cleared upload keeps
the copy exactly when its range is unwatched at that point.

PPSA14632 (LEGO Horizon Adventures) on Linux, RX 9070 XT: the flush hook
waited ~60,000 times per 10 s for these publishes (6.4 s), now ~3,500,
and presents rise from ~24 to ~100 per 10 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants