Repository navigation
Conversation
Joey-Magnus
left a comment
There was a problem hiding this comment.
I ran the suite merged into main: tests/test_texture_staging_publication.py fails because its stubs lack env_on and create_buffer_cached, which vk_texture.cpp:468 now needs.
Beyond that:
- It changes defaults for everyone with resizable BAR. Staging arenas, including the ones the ASTC decoder reads as storage buffers, move from VRAM behind the BAR to cached host memory (
:468), with no numbers on NVIDIA, AMD or Deck. - On 6 GB or smaller cards, idle staging goes from 64 to 128 MB (
:3806), and one arena never expires. That's pinned system RAM, which main's comments describe running 16 GB laptops out of memory.
The tail reuse (:449) looks correct. I'd want the host-cached part opt-in or measured.
ghost
left a comment
There was a problem hiding this comment.
Thanks. I agree with Joey-Magnus's review: the suite failure he found is real (tests/test_texture_staging_publication.py cuts staging() out of the source, and its fixture tests/texture_staging_publication_test.cpp stubs create_buffer only, so it needs env_on and create_buffer_cached stubs in this PR), and the default change and the 64 to 128 MB keep on small cards are his points, not repeated here. No CI checks have run on the branch.
What I checked on top of that:
- The tail reuse is sound. The new slice starts past
a.used, aligned to at leastnonCoherentAtomSize(and the ASTC caller's storage offset alignment), so neither the CPU writes nor the flush touch bytes an older submission still reads, and bumpingvaluetorec_valuejust holds the arena until the newest reader completes. It would be worth a case in the fixture: an arena in flight (value < rec_value, not completed) gets a second slice at an aligned offset past the first, with no new arena made. - Host-cached arenas are correct even where that memory is not coherent: both
staging()callers already flush their range (vk_texture.cpp:994,:1711). The open question is only speed: the ASTC decoder then reads its blocks over PCIe instead of from BAR VRAM. The existingvk: a staging arena of N MB took X ms to makelog line gives the before/after the description's "100+ ms" claim needs. - Nit:
vramis read withenv_onthree times (two statics plus once more inside thekeeplambda, which could just use the static above it).
My suggestion: split it. The tail reuse is a small, clear win I'd approve on its own once the test passes; keep the host-cached arenas and the warm arena behind a switch (or bring numbers from a ReBAR card and a 6 GB one) in a follow-up.
Other open PRs by the same author: #2462 and #2467 also edit vk_texture.cpp, but in other functions (readback ring, eviction pacing), so no overlap with the staging code here. #2482, #2487 and #2491 are in other files.
| } | ||
| } | ||
| for (Arena& a : arenas) { | ||
| if (a.value < rec_value) { |
There was a problem hiding this comment.
This part looks right to me (see the body); a fixture case for an in-flight arena's tail would pin it down.
| static const bool vram = env_on("RX_VK_STAGING_VRAM"); | ||
| const VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; | ||
| if (!(vram ? create_buffer(size, usage, true, a.buffer, a.allocation, &m) | ||
| : create_buffer_cached(size, usage, a.buffer, a.allocation, &m, true))) |
There was a problem hiding this comment.
This flips every ReBAR user to cached host memory, including the buffers the ASTC compute decoder reads as storage. Correctness is fine (both callers flush), but I'd make this opt-in (e.g. RX_VK_STAGING_HOST=1) until there are numbers, rather than opt-out with RX_VK_STAGING_VRAM. The fixture also needs env_on / create_buffer_cached stubs because of this line.
When staging texture uploads, uncompleted in-flight arenas (value < rec_value) with unused tail capacity were skipped, forcing immediate allocation of fresh 64 MB arenas and pinning tens of megabytes of staging memory. - Check in-flight arenas (a.value < rec_value) for remaining tail capacity, aligning past a.used and advancing the arena's timeline stamp to rec_value - Add in-flight tail suballocation test case to texture staging publication suite
63f03e9 to
a08020d
Compare
|
Rebased onto
|
Joey-Magnus
left a comment
There was a problem hiding this comment.
Narrowing it resolves my first review: the host-cached default and the 128 MB keep on small cards are gone, and the fixture needs no new stubs.
The tail reuse in staging() (gpu/vk/vk_texture.cpp:454) is correct. The slice starts past a.used, aligned to at least nonCoherentAtomSize, so neither the CPU writes nor the flush touch bytes an older submission still reads, and raising value to rec_value only keeps the arena until its newest reader completes. Completed arenas are still reused from offset 0 first, so this only replaces making a new 64 MB arena, and the inflight-tail case covers it.
I merged it into current main and ran tests/run_all.py: all pass except test_lift_cache.py (fails on main here too) and test_recorder_sync.py, which timed out under machine load and doesn't touch this code. The CI reds are main's own failures from early Nov 12 and pass on current main, so a re-run should clear them. The description's "pinning tens of megabytes" has no number from the game; the staging arena ... took X ms to make log line would show it, but I wouldn't hold the merge on that.
Problem
When staging texture uploads, uncompleted in-flight arenas (
value < rec_value) with unused tail capacity were skipped, forcing immediate allocation of fresh 64 MB arenas and pinning tens of megabytes of staging memory.Solution
a.value < rec_value) for remaining unused tail space if no completed arena is available, aligning pasta.usedto at leastnonCoherentAtomSizeand advancing the arena's timeline stamp torec_value.inflight-tailcase totests/texture_staging_publication_test.cppandtests/test_texture_staging_publication.pyto verify that in-flight arenas are suballocated without allocating a new buffer and flush independently.Verification
python3 -I -B tests/test_texture_staging_publication.py --headers /usr/include(passes all cases across coherent and noncoherent caches)