Repository navigation
perf(agc): present and keep pending only the drawn slice of an array color target - #4935
Conversation
|
Me volvi loco con esta mierda, horas de laburo espero sirva de algo |
|
Windows test (MinGW GCC 15.2, Release, Windows 10, RTX 4080 SUPER). Built on 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). |
|
Please also add the |
|
@oneandonlydean you are right, thank you.
AI-assisted: yes (Claude Code). |
|
Thanks, slice 1 finds its image now. If more than one pending array image contains the range, |
|
@oneandonlydean done in AI-assisted: yes (Claude Code). |
… image Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent presentation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rget Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g array image Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ay images Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e7d9ff8 to
3ddfc23
Compare
|
Rebased onto main after #5311: its one-pass present now takes the drawn slice, so a display buffer in slice 1 or later presents through it too. |
|
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.
|
What
A title whose color target is one slice of an array image (
CB_COLOR_VIEWslice of a surface with several slices) now presents from that image and keeps only the slice it drew pending. Before, the whole array image was treated as one unit in two places:ResidentPresentablerefused any pending image with more than one layer, so every flip of such a display buffer went through guest memory: the frame's results were stored, 33 MB were read back and uploaded again, with the GPU mutex held.ResidentPresentSlicenow finds the slice whose bytes are the display buffer, and the blit, the converted path (GpuColorTransfer::DetileImage) and the frame dump read that layer. The pending image is looked up withStorageTexture::FindPendingSlice, which also finds an array image that contains the display buffer past its first slice;FindPendingonly matches an image that starts at the display buffer's address, so alone it served slice 0 only. Only an image the range is exactly one slice of counts, and a range that is a slice of more than one pending array image throws (is a slice of the pending array images ...: which one holds its results is not modeled).StorageTexture::MarkDirtymarked every tracked layer or 64 KiB unit of the target pending. Memory under slices no draw rendered then counted as holding GPU results: any buffer or shader capture over it stored those units back and the next draw waited for the GPU.MarkSliceDirtymarks the units of the rendered slice only. It falls back toMarkDirtyfor volumes, single-layer images and DCC-compressed targets.No change for single-layer targets.
Tested
Windows 11, NVIDIA RTX 4070 Laptop GPU, WinLibs GCC 15.2.0 r7, Release,
ANYPS5_ENABLE_SPIRV_TOOLS=ON. Tests ate7d9ff8ffonmain7e181fcc3; the title runs and traces are from9d53a588f, before the lookup by containment was added, and were not repeated.agc_slice_dirty: clears the two slices of a linear and of a tiled 128x128 array image to different colors, marks slice 0 and stores; slice 0 holds its color and the memory of slice 1 is untouched; after marking slice 1 it is stored too. With the whole image marked instead, the test fails. With slice 0 pending it also checks the lookup presentation uses: a display buffer that is slice 0 or slice 1 finds the image throughFindPendingSliceandResidentPresentSlicenames that layer,FindPendingdoes not find slice 1, and a range past the last slice finds nothing. With two images over the same memory pending, the lookup of slice 1 throws.agc_resident_present(the existing resident presentation tests, which no CTest entry ran): the slice decision (ResidentPresentSlice) and the converted path reading layers 1 and 2 of an array image; with the layer ignored inDetileImageit fails.ctest -j 8: 1037 passed, 8 skipped, 0 failed, out of 1045.VulkanDevice::PresentDisplayBuffer. No test presents to a swapchain (nothing undertestscalls it, and thevideo_out_flip_*tests are skipped here), and this title's display buffers start at their image's address, so its runs exercise slice 0 only.main7e181fcc3. Performance traces (APS5_TRACE_FRAMES=300:600), menu screen, 45 draws per frame:buffer descriptor uses an unsupported typeOn the older
maine51428bf2, where #4820 alone did run, two traces of 200 presents had a p50 of 39.2 and 48.1 ms, with 9.6 to 10 ms per frame inVulkan.Present.pixel_uploadand 7.4 to 8 ms of draws waiting for the GPU mutex; with only the presentation change the p50 was 18.9 ms and the p90 42 ms.Summary lines (
aps5-summary.jsonl). There is none formainitself: the title does not draw without #4820. Before, #4820 ate7cf856f0onmaine51428bf2,APS5_TRACE_FRAMES=150:200:After, #4820 and
9d53a588fmerged locally withmain7e181fcc3(commitab8f91d0e6cb),APS5_TRACE_FRAMES=300:600:The two sets are not the same window or the same
main, so they compare the order of magnitude, not exact numbers.APS5_DUMP_FRAMESafter both changes shows the title's menu with its game thumbnails.maindacd78525, three 60 s runs per build of the same title: with feat(agc): sample a multisampled color target through its 2D MSAA texture #4820 alone the title's own mean frame time over frames 1 to 600 is 83.41 to 85.76 ms; with this change as well it is 41.46 to 45.43 ms, and 38.81 to 40.05 ms over frames 601 to 1200 (max 84 ms). So the frame time halves there but stays near 40 ms, not 16.7 ms; what limits it on that GPU was not investigated. feat(agc): sample a multisampled color target through its 2D MSAA texture #4820 alone did not stop in those runs.Not tested here: Linux, AMD and Intel GPUs, lavapipe, other titles, and why #4820 alone stops here on
main7e181fcc3(not investigated; it does not stop with this change, and it did not stop on the Radeon 860M on a latermain). The AMD result above is the reporter's own.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)🤖 Generated with Claude Code