Repository navigation
perf(agc): sync only the source for DMA_DATA copies into host-only memory - #1157
Conversation
|
Native Windows run, since no Windows results were posted. Setup: Windows 10 (19045), RTX 3060 Laptop (NVIDIA 616.92), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head
No title was run. 🤖 Addressed by Claude Code |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks. The idea is sound, but one case changes behaviour compared with the drain it replaces:
PacketMemory.cpp:148-153: the new branch runs for everyCopyBufferoutcome other than path 1/3 and never looks atoutcome.reason. For a host-only destination the GPU can't read or write it, butCopyBufferalso refuses withLabel(PendingLabelIncoverslabels, wide labels andqueuedLabels) andDestinationUnsettled(VulkanDevice.cpp:1670-1677): CPU stores that are still pending over the destination. The drain let them land before the CPU copy; now they can land after it and overwrite the copied bytes. Please either keep the drain when the reason isLabel/DestinationUnsettled/DestinationPending/Reader/Shadow, or show that none of them can happen with a non-registered destination.- The branch is also taken for path 0, where the copy was already done on the CPU; the flush +
SyncThroughthere is wasted work. Restricting it to path 2/8 would keep it to the case the PR describes. - There is no test. A guest/driver test that writes a deferred label (or a completion store) over the destination range before a >64 KiB DMA_DATA into host-only memory, and checks the final bytes, would pin the ordering. It should fail on the unguarded version.
|
Windows run of this PR alone on current
No title was run. Tested with AI assistance (Claude Code). |
9653aa9 to
dbbc1ba
Compare
|
Thanks. Rebased onto current
One caveat on the test: I couldn't make it fail on the unguarded version, because no reachable state leaves a store pending over a destination without an import when
So the guard is defensive. It costs a few range lookups, and it keeps the branch correct if either of those paths changes. The test pins the ordering for both cases you named. It also turned out the CPU copy's own read of the source would see the GPU result even without the explicit
|
dbbc1ba to
481c27b
Compare
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the rework; the StoresPendingOver guard and the path 2 restriction address the earlier points. Two things left:
core/libs/prx/libSceAgcDriver/tests/Submit.cpp:445-471:testCopyIntoHostMemorylives inagc_driver_tests, which isEXCLUDE_FROM_ALLand not registered in ctest (core/libs/prx/libSceAgcDriver/CMakeLists.txt:267), so it never runs in CI. New tests must be registered in ctest. Please put it in a target that is (e.g. one of theagc_driver_*_testsexecution targets that useVulkanTestDevice), with a skip (exit 77) when there is no Vulkan device.- The branch conflicts with
main:VulkanDevice.hpp/VulkanDevice.cppnext to the newRecordedWritesSettled. I rebased it locally by keeping both functions; the scoped libSceAgcDriver ctest (319 tests) andagc_driver_testspass on the result.
Once the test is registered and the branch is rebased this is good to merge.
…mory A DMA_DATA copy larger than the store limit runs as a transfer between host imports. When the destination is not registered guest memory (the GPU can neither read nor write it, so no import exists), the transfer was refused and the packet drained the device: every batch recorded so far was submitted and waited for, then the CPU copied. Such a copy only has to see the source's results. When CopyBuffer refused for want of an import (path 2) and nothing can still store over the destination (VulkanDevice::StoresPendingOver: a recorded write, a label, a copied write-back, a storage image's pending write-back or a unit shadow), the packet now flushes storage results pending over the source and waits for the batches that write it (Recorder::SyncThrough), then copies on the CPU without a drain. Anything else still drains as before. The [sync] line counts these copies. agc_driver_tests copies a buffer the GPU just wrote into host memory, once directly and once behind a label into the destination, and checks the bytes and that the copy did not drain. PPSA14632 (LEGO Horizon Adventures) copies 256 KiB of GPU results into host memory this way, about 50 times per 10 s: device drains drop from about 50 to none per 10 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
481c27b to
14c2eca
Compare
|
@adriadam10 Thanks. I rebased onto On the test registration:
Full |
|
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.
|
|
On the two remaining points, checked on
AI-assisted: yes (Claude Code Fable 5.1 xhigh) |
adriadam10
left a comment
There was a problem hiding this comment.
Checked on the PR merged onto current main: scoped build + ctest of libSceAgcDriver 713/713 (agc_driver runs the new test, also repeated 10x), and the test fails to build without the change (copiesToHostMemory), so it pins the new path, including the pending-label-over-destination case. The StoresPendingOver guard and the path 2 restriction cover the earlier review points; agc_driver_tests is registered in ctest through the loop in CMakeLists.txt:911. Merging.
What
A DMA_DATA copy larger than the store limit (64 KiB) runs as a transfer between host imports. When its destination is not registered guest memory, there's no import for it (the GPU can neither read nor write that memory), so the transfer was refused. The packet then drained the device: every batch recorded so far was submitted and waited for, and then the CPU copied.
Such a copy only has to see the source's results:
Recorder::SyncThrough). Then it copies on the CPU without a drain.[sync]line counts these copies (copies into host memory synced on their source).Tested
Linux 7.2.9 (Arch), Mesa 26.2.4 RADV, RX 9070 XT.
ctest: 396 of 396 pass.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code