[perf] Staged UploadDeviceLocal allocates+frees a fresh staging buffer every call (VulkanBuffer.cppm) #120
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics#120
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Found by an adversarially-verified performance audit (confirmed real after a skeptic pass).
Location:
interfaces/Crafter.Graphics-VulkanBuffer.cppm:281-300Severity: medium · Effort: moderate · Category: allocation
Problem
On non-ReBAR hardware the staged branch of
UploadDeviceLocaldoesCreate(create+getreq+alloc+map) +DeferredClear(later free) per call.Mesh::Refit/RecordProceduralBuildhit this every frame for deforming meshes — a full device-memory alloc/free cycle per mesh per frame, on exactly the hardware the path targets.Fix
Persistent per-buffer (or per-frame-in-flight ring) staging sized to a high-water mark, reallocated only on growth — mirroring the TLAS instance/metadata high-water reuse.
Constraint: allocate the persistent staging lazily (do not regress ReBAR)
The two branches split on
Device::PreferDirectDeviceWrite(bytes)(directWriteBudget != 0 && size <= directWriteBudget):directWriteBudget == max) → always takes the direct-writeifbranch (:262-280): map → memcpy → flush, no staging buffer ever constructed.== 0) orsize > capon a non-resizable 256 MB BAR → the stagedelsebranch (:281-300) that this issue fixes.So this change lives entirely in the
elsebranch and is a runtime no-op on ReBAR/UMA hardware (that branch is dead code there) — provided the persistent staging is allocated lazily, on first entry into theelsebranch, not eagerly as a member of everyVulkanBuffer. An eager member would make ReBAR/UMA systems carry a host-visible staging allocation they never touch — a memory regression. Allocate-on-first-stage keeps it a straight upgrade everywhere, including non-resizable-BAR machines where only buffers exceeding the cap take the staged path.