Repository navigation
perf(agc): copy small draw snapshots into a per-recorder upload chunk - #6082
Conversation
6ef1382 to
e9bcecb
Compare
|
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.
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 the diff against |
e9bcecb to
3518eb8
Compare
What
ShaderResources::PrepareDrawBindingssnapshots each guest buffer that a draw reads in place. Since #5906, a snapshot that nothing wrote since the last draw is reused from a per-recorder map (Recorder::UnwrittenDrawSnapshot). On a miss, the draw still collects the range's writes, looks for a kept copy (Recorder::ReusableDrawSnapshot), and otherwise creates a buffer for the copy and keeps it. Most of these ranges are small.On the S2 page of Sonic Origins Plus's main menu, with #5906,
PrepareDrawBindingscosts the queue worker 5.22 samples per frame (APS5 sampler, 15 s). Of that, 0.78 goes toBuffer::Buffer, 0.56 toReusableDrawSnapshot, 0.35 toKeepDrawSnapshotand 0.29 toCollectWrites.A miss of at most 4 KiB is now copied into a per-recorder upload chunk (
Recorder::DrawUpload) and bound at its offset. The chunk is 1 MiB, bump-allocated at the storage buffer offset alignment. The copy skips the collect, the lookup and a buffer of its own.DrawBindings::Snapshotgains the offset and size of its bytes inbuffer. The descriptor write and the capture inputs use them.CollectEpoch() != 0), where the queue worker's collects are memoized the same way. A thread without one copies again on every draw.APS5_DRAW_UPLOAD_MAXchanges the limit, and 0 turns this off.With the chunk,
PrepareDrawBindingsfell from 5.22 to 3.20 samples per frame:Buffer::Buffer0.78 to 0.31ReusableDrawSnapshot0.56 to 0.03KeepDrawSnapshot0.35 to 0.01CollectWrites0.29 to 0.11Tested
Windows 11 (10.0.26300), WinLibs GCC 15.2.0 (UCRT), Release, NVIDIA GeForce RTX 2080 Ti, driver 617.14.
agc_draw_snapshot_capnow also runsdrawSnapshotUploadTests. It checks that inputs up to the limit share the chunk at aligned offsets with their guest bytes, and that a larger one gets its own buffer. A copy made after a CPU store gets a new slice without touching the slice an earlier draw reads, and a full chunk is replaced.unwrittenSnapshotTestschecks that the map keeps the offset.agc_driver_recorder_tests's unregistered default path read a snapshot through its offset now:resourceReadTests,misalignedRegionTestsandmisalignedSnapshotTests.drawSnapshotReuseTestscovers the kept-copy path, so its input is now 8 KiB, above the limit. No ctest entry runs that path; run through a local flag, its snapshot tests pass on that main with this change. On Windows,drawSnapshotReuseTests,drawSnapshotPatchTestsand the kept-indices part ofdrawInputInPlaceTestsstop early: host imports are compared there, not watched.APS5_TRACE_SECONDS=200:15on the same machine in one session, caches warm. Traces attached.APS5_DRAW_UPLOAD_MAX=0; this change uses the default limit:The FPS shown in the title went from 7.35 to 7.84 (median of six readings). The sampled runs agree: 7.28 to 7.72.
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)Traces, summary lines and the measuring patch (one build; baseline
APS5_DRAW_UPLOAD_MAX=0, this change the default):snapshot-5906-traces.zip