vk: render targets' images in VMA blocks of their own; dead targets swept every 10 presents (follow-up to #1416) #1436
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1436
Loading…
Reference in a new issue
No description provided.
Delete branch "perf/target-image-blocks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up to #1416. Only the second commit,
7a9151b, is new. The first commit,c34f350, is #1416 as it landed in the v2.0.12 branch, with the same hash, so this applies there as it is. Againstmainthe diff shows both commits until v2.0.12 reaches it.What
#1416 took away the once-a-second burst of destroyed images. A longer play session (18 minutes on an RTX 5070) then showed the next layer, which is VRAM.
Change
gpu/vk/vk_vma.cpp: a second VMA pool,target_images_pool(), with the same memory type and block size, for render targets' images.create_image(..., target)takes its images from there.RX_VK_TARGET_BLOCKS=0puts them in the textures' blocks, as before.gpu/vk/vk_texture.cpp:create()knows whentexture_getasked for a target (!for_sampling). Only those images go to the targets' blocks and to the target pool.RX_VK_DEAD_EVERY(it was 60). The choice is cheap: 1930 textures ordered in 0.3 ms, 251 chosen in 0.2 ms.vma_log_image_blockssays what each image pool's blocks hold, and the largest free range in them.Measured
RX_VK_TARGET_BLOCKS=0 RX_VK_DEAD_EVERY=60 RX_VK_TARGET_POOL_MB=1024, which is #1416 as it is.Not covered
Tests
tests/test_target_image_pool.py, 9 cases, adds:RX_VK_TARGET_BLOCKS);RX_VK_DEAD_EVERY(10) presents;tests/run_all.pyon every test that readsvk_texture.cpp,vk_texture.horvk_vma.cpp: 9 passed, 2 skipped. The 2 skipped ones need the Vulkan headers, and both pass when run with them:test_vulkan_clear_mip.pyandtest_parallel_init_order.py.🤖 Generated with Claude Code
This landed in the v2.0.12 branch (merged there for testing; it reaches
mainwith that release), so closing. Thanks!Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.
Looked at
7a9151bonly (c34f350is #1416). This looks good to me. Splitting the transient targets into their own blocks is the right fix for the holes the log shows, and the A/B numbers back it up.What I checked:
targetonly goes tocreate_imagefor non-BC/ASTC images made with!for_sampling. The BC/ASTC storage retry still goes to the textures' blocks, which is right. If the targets' pool can't fit an image (bigger than a block, or a memory type the pool doesn't have), it falls through to the default VMA allocation exactly as before, dedicated memory included.WITHIN_BUDGETis copied intopai, so the new pool respects the budget too. Nothing here touches memory priority (the code doesn't useVK_EXT_memory_priority), so no change there.run_all.pyfinds it on its own (9 cases).Things to know, none of them blocking:
blockSizejust for the targets' pool would cut that down. At 1080p the targets are around 10 MB each.gpu/vk/vk_texture.cpp(main is 41 commits past the base), so a rebase is needed once #1416 lands.Nit: the
frame_no % 600 == 0log of kept finalized textures further down only runs on sweep frames. With 10 or 60 that's fine. If someone setsRX_VK_DEAD_EVERYto a value that doesn't divide 600 (7, say), that log quietly stops showing. Worth a word in the comment, or switch that check to a>= last + 600likedead_logged_at.@ -43,0 +47,4 @@VmaPool target_image_pool = VK_NULL_HANDLE;bool target_pool_tried = false;VmaPool images_pool();VmaPool target_images_pool() {Nit: apart from the handle, the log line and the
images_pool()gate, this is the same asimages_pool(). A smallmake_image_pool(VmaPool&)helper would keep the two from drifting, e.g. if one later gets its own block size.Nit: this
/// (every heap: ...)comment belongs tovma_log_heaps(). The new function went in between, so it now sits abovevma_log_image_blocks().