Persistent · transient · frame-buffered — three lifetimes, one staging ring
Three-layer GPU resource lifecycle. Optional — the core works fine with raw
VulkanBuffer / VulkanImage. Use VMM when you want batched staging
uploads, a zero-cost per-frame transient pool, or lifetime-tagged
persistent allocations.
Layer 1 VmmRawAlloc thin typed VMA wrappers
Layer 2 VmmRegistry every allocation tagged with a Lifetime
Layer 3 VulkanMemoryManager pools and strategies
| Lifetime | Behaviour |
|---|---|
Persistent |
Freed at Shutdown or explicit FreeBuffer / FreeImage. |
TransientFrame |
Auto-freed when the frame slot it was allocated in comes around again. |
FrameBuffered |
One instance per frame slot. |
Manual |
Registry tracks it for stats only; caller frees it. |
- StagingRing — single CPU-visible ring for batched uploads.
StageToBuffer/StageToImagequeue copies;EndFrame/FlushStagingsubmit the batch. - TransientPool — one CPU→GPU block per frame slot, persistently mapped.
Zero-cost pointer bumps; reset on
BeginFrame. - Persistent allocations — textures, static meshes, anything that outlives a frame.
vkWaitForFences(..., sync.GetInFlightFence(slot), ...); // MUST come first
vmm.BeginFrame(slot, absoluteFrame);
VCK::VmmBuffer dyn = vmm.AllocTransient(slot, "ui_verts",
size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
dyn.Upload(data, size);
// ... record draws ...
vmm.EndFrame(slot); // submits staging batch, resets ringVCK::VmmBuffer vb = vmm.AllocPersistent("static-verts", size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT);
vmm.StageToBuffer(vb, src, size);
vmm.FlushStaging(); // one-shot submit + wait + ring resetVCK::VmmImage img = vmm.AllocPersistentImage(
"texture", width, height, VK_FORMAT_R8G8B8A8_SRGB,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
vmm.StageToImage(img, pixels, pixelsBytes);
vmm.FlushStaging();vmm.LogStats(); // registry + staging ring + transient pool snapshotUse it as a sanity check: it prints per-lifetime counts, total bytes, and the staging ring's current high-water mark.
- v0.3:
VulkanMemoryManager::SubmitStagingCmdnow uses a per-submitVkFence(novkQueueWaitIdle). When the transfer queue is dedicated, staging submits to the transfer family and records a release/acquire ownership-barrier pair so the graphics queue sees the expected image layout (Vulkan §7.7.4). The acquire is CPU-serialised today — a semaphore-driven async acquire is on the v0.4 roadmap. - v0.3: The staging ring still resets at the end of each
EndFrame/FlushStaging; per-frame staging is still the recommended pattern for pipelined uploads. VulkanOneTimeCommand::Enduses a short-circuitingvkWaitForFencesso a failed submit no longer hangs the caller (v0.3 fix).