Repository navigation
fix(agc): store small pending storage results at each flip - #4841
Conversation
|
An Intel run, and the full suite. Setup: Windows 11 (26200), WinLibs GCC 15.2.0 r7, Release, CI configure flags, an RTX 4070 Laptop GPU and an Intel Raptor Lake-S iGPU. The head fb388af merged into
No negative control here: with the production files as on Written with AI assistance. |
|
Windows test (MinGW GCC 15.2, Release, Windows 10, RTX 4080 SUPER). Built on current main
Not tested: no game run. The batch was built once, not per PR; nothing failed, so no bisect was needed. AI-assisted (Claude Code). |
fb388af to
0b5a4aa
Compare
|
Rebased onto Thanks @kr4y4 and @xXPBSXx for the runs. AI-assisted: yes |
|
A game run: Kena: Bridge of Spirits (PPSA01802) shows this on its title screen, and this PR fixes it. Setup: Linux (Arch, kernel 7.2.9), GCC, Release, RX 9070 XT (RADV, Mesa 26.2.4). Kena does not reach its title on plain
The 3-frame cycle and the fix fit the exposure readback described above (small GPU-written results read by the CPU a frame later, here apparently rotating through three images). With queue 0 kept busy by the pipelined committer, the queue-idle store does not cover it. Before finding this PR I had a narrower local version (images of at most 4x4 texels, stored through AI-assisted (Claude Code). |
|
Checked on Linux (merged onto current |
What
A storage image result stays on the GPU until something stores it to guest memory: a driver-observed use of its range (
FlushPendingthrough the flush hook, a packet that reads the range), the queue-idle store (#3777), orAPS5_STORE_AT_FLIP=1atPresentDisplayBuffer. A guest CPU that reads the result with plain loads gets none of the first, the second only runs when queue 0 drains, and the third is off by default. While a title keeps queue 0 busy, such a result never reaches guest memory.PPSA01317 needs a guarantee here. Its CPU auto-exposure reads 16x16 R32F and RGBA16F images that the GPU writes in host-imported memory, a frame or more after they are written. On an older local tree without #3777, those images were marked written 50 to 80 times and stored 0 times, and a guard-page probe on them caught guest CPU loads. The exposure multiplier computed from them collapsed to 2^-32 and the garage car view went black within seconds of each camera cut.
On current
main, #3777 covers this whenever queue 0 drains between frames. This change makes the store not depend on the queue going idle. That matters if the idle store is delayed, as #4410 proposes (50 ms): this title's gap between a flip and its next submit is about 5 to 13 ms. I have not run the title on currentmain; the test below shows the failure onmainwhen the queue stays busy.Change: when queue 0 reaches a flip packet, before the flip's batch is submitted,
StorageTexture::StoreSmallPendingstores every pending image of at mostSmallStoreBytes(64 KiB) whose memory is host-imported. The stores are recorded on the GPU behind the frame's work and submitted in the flip's batch, so neither the queue worker nor the title waits for the GPU. A flip ends the title's frame, so a result it reads a frame later has been stored by then.The bounds:
APS5_STORE_AT_FLIP=1does, and its cost is why that switch is off by default (feat(agc): store pending storage-image results at each flip with APS5_STORE_AT_FLIP #1995).APS5_STORE_AT_FLIP=1is unchanged.Related: #4794 (open) stores every image result at draw time instead; this PR stores only small imported results, once per frame.
Tested
mainat 90c6839.agc_driver_flip_stores_small_results: on queue 0, a dispatch writes a 16x16 R32 storage image in imported guest memory, then a flip, then aWAIT_REG_MEMon a dword only the test writes, which keeps queue 0 busy so the queue-idle store cannot run. The test polls the image with plain CPU loads for 2 s. Without the change it fails ("a small image written before a flip did not reach guest memory while the queue kept working"); with it, it passes.ctest -R agc_driver: 347 tests, all passed (1 skipped as onmain:agc_driver_stencil_ref_export).python tools/check_conventions.py --base origin/mainpasses.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)