Files
QuaternionEngine/docs/FrameResources.md

2.2 KiB
Raw Blame History

Frame Resources: Per-Frame Command, Sync, and Transient Descriptors

Per-frame struct that owns the command buffer, semaphores/fence, a transient descriptor allocator, and a small deletion queue. Frames are indexed by FRAME_OVERLAP (currently 2) and rotated by _frameNumber in VulkanEngine.

  • File: src/core/frame/resources.h/.cpp

Responsibilities

  • Command recording: _mainCommandBuffer allocated from a per-frame _commandPool with RESET flag.
  • Synchronization: _swapchainSemaphore (image acquired), _renderSemaphore (render finished), _renderFence (CPU wait per frame).
  • Transient descriptors: _frameDescriptors is a DescriptorAllocatorGrowable cleared every frame via clear_pools().
  • Lifetime: _deletionQueue holds lambdas for transient GPU objects created during the frame (buffers/images) and is flushed at the start of the next frame.

Frame Flow (engine side)

  • Start of frame:
    • Wait on _renderFence (previous GPU work for this frame index), flush _deletionQueue, and clear _frameDescriptors pools.
    • Acquire swapchain image signaling _swapchainSemaphore.
    • Reset _renderFence and _mainCommandBuffer; begin recording.
    • Publish currentFrame pointer and drawExtent on EngineContext.
  • Graph build and execute:
    • Render Graph is cleared and rebuilt; ResourceManager::register_upload_pass(...) is added first if there are pending uploads.
    • Passes record using the published currentFrame to allocate transient descriptor sets and to enqueue per-frame cleanups.
  • Submit and present:
    • Submit cmd with wait on _swapchainSemaphore and signal _renderSemaphore, fence _renderFence.
    • Present waits on _renderSemaphore.

Do/Dont

  • Do use currentFrame->_frameDescriptors for descriptor sets that live only for this frame.
  • Do push transient resource destruction into currentFrame->_deletionQueue.
  • Dont stash per-frame descriptor sets across frames — they are reset on clear_pools().

Extending

  • If a pass needs additional short-lived command buffers, allocate them from _commandPool and reset per frame.
  • If you add frames-in-flight, update FRAME_OVERLAP and verify fences/semaphores and swapchain image acquisition logic.