Repository navigation
Conversation
… memory A fast clear of an unwatched surface copied its whole guest memory so Refresh could compare it later, even when the copy it already kept still matched; the copy also dropped the compare memo, so the next Refresh read the whole surface again. In DAVE THE DIVER (PPSA19115) that was ~790 copies of 8 MiB per 10 s, every one identical to the last. The clear now checks the kept copy with the memoized compare first and copies only when a block changed, a unit is kept at unwatch, or a write-back's saved bytes are still pending (as before). GuestSnapshots() counts the copies for the regression test.
0717f6f to
a69c307
Compare
|
Traces of the two captures in the description (base, then this change). aps5-trace-9a14a74bd275-105296.json.gz |
|
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.
|
|
Checked build and the AgcDriver ctest scope on the PR merged onto main: |
What
A fast clear of a storage image over unwatched memory (
upload,IsDccClear(uploadedKeys)) callscaptureGuestBytes(nullptr)so that a laterRefreshcan compare the texels. It did so on every clear, even when the bytes it already kept still matched the memory, andcaptureGuestBytesresetscomparedGuestBytes, so the nextRefreshcompared the whole surface again instead of answering from the memo.The clear now checks the kept copy with the memoized
compareUntrackedfirst. It copies again only when a block changed, as before, and also, conservatively, when a unit kept at unwatch would read as written or a write-back's saved bytes are still pending (savedTicket). In those cases the old copy (which cancels the pending save) still runs. The state after the clear is the same as before: the same bytes inoriginal, the samelayerOriginal. The memo now survives.GuestSnapshots()countscaptureGuestBytescalls, likeUntrackedCompares(), for the regression testRunClearKeepsSnapshotinDccKeysFirstWrite.cpp(unwatched block):mainwith "copied its guest bytes 1 times");Refreshdoes not upload again (the copy holds the CPU store).Tested
GPU tests. Linux (Intel Alder Lake-P iGPU, Mesa 26.2.4), on ba3ffba: every
agc_driver*and multisample test passes exceptagc_driver_multisample_fill_host_only, which fails the same way without this change (vkWaitSemaphoresKHR-4). Underctest -j8,agc_driver_gated_dispatch_capturefailed once after the last rebase andagc_driver_oversized_descriptor_setsonce before it; both pass alone and in 3 repeats. Windows 11 (RTX 5060, 596.36):agc_driver_dcc_keys_first_writepasses, the new case included (only that test was built there).DAVE THE DIVER (PPSA19115), underwater scene, Windows 11, RTX 5060 (596.36), Ryzen 7 5800X. This title needs the MSAA stack listed in #5963 to render, so it does not run on
mainalone. The base ismain956269a plus that stack, measured with and without this change; that base predates 69702ef, so the measured change has nosavedTicketcheck.Captured as the Performance report form describes:
APS5_TRACE_SECONDS=180:30and no otherAPS5_*variable, log not redirected, warm caches (the scene ran, then the title was restarted), same underwater scene, same machine and session; onlylibs/changed between the two captures.tools/performance_compare.py: frame p50 -22.6 %, p99 -25.3 %,Driver.Draw.draw_and_resource_release-33.8 %; the only recorded configuration difference iswindow.first_present. The GPU time per present is unchanged; the queue worker is busy about 99 % of the window in both.{"commit":"9a14a74bd275","dirty":false,"env":{"APS5_TRACE_SECONDS":"180:30"},"gpu":"NVIDIA GeForce RTX 5060","driver":"NVIDIA 596.36","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 180:30","first_present":5225,"ms":30008.092},"presents":821,"frame_ms":{"p50":35.928,"p90":40.175,"p99":49.084,"max":57.341},"gpu_busy_ms_per_present":9.384,"worker_busy_pct":{"queue worker 0x0":99.045},"top_phases_ms_per_frame":{"Driver.Packet":35.298,"Driver.Packet.draw":32.502,"Driver.Draw":32.323,"Driver.Draw.draw_and_resource_release":25.214,"Graphics.Draw":24.932,"Graphics.Draw.draw_and_resource_release":21.428,"Driver.Draw.shader_compile_and_link":4.382,"Graphics.Draw.validate":3.325},"trace_dropped":true,"trace":"aps5-trace-9a14a74bd275-105296.json.gz"} {"commit":"cc690190b21a","dirty":false,"env":{"APS5_TRACE_SECONDS":"180:30"},"gpu":"NVIDIA GeForce RTX 5060","driver":"NVIDIA 596.36","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 180:30","first_present":6683,"ms":30016.633},"presents":1062,"frame_ms":{"p50":27.826,"p90":30.790,"p99":36.663,"max":44.595},"gpu_busy_ms_per_present":9.272,"worker_busy_pct":{"queue worker 0x0":98.772},"top_phases_ms_per_frame":{"Driver.Packet":26.853,"Driver.Packet.draw":24.344,"Driver.Draw":24.169,"Driver.Draw.draw_and_resource_release":16.682,"Graphics.Draw":16.420,"Graphics.Draw.draw_and_resource_release":12.829,"Driver.Draw.shader_compile_and_link":4.845,"Graphics.Draw.validate":3.409},"trace_dropped":true,"trace":"aps5-trace-cc690190b21a-88920.json.gz"}Traces, attached in the comment below:
aps5-trace-9a14a74bd275-105296.json.gz(base) andaps5-trace-cc690190b21a-88920.json.gz(change). Both reporttrace_dropped: the queue worker's default event buffer filled after about 4.6 s (base) and 3.5 s (change) of the window, so the event tracks of that thread cover only those first seconds. The summary lines come from the per-thread totals and cover the whole window. I kept the default buffer because the form asks for no otherAPS5_TRACE_*switch.A local counter in that path (not part of this PR), per 10 s, in an earlier run:
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)agc_driver_dcc_keys_first_write)