Visitar URL original
vulkan/utils-framegraph at main · expipiplus1/vulkan · GitHub
Skip to content

Latest commit

 

History

History

utils-framegraph

README.md

vulkan-utils-framegraph

Vulkan adapter for the fragr frame graph: resource types whose preRead / preWrite hooks place cmdPipelineBarrier image transitions automatically, so passes declare what they access and the graph records the barriers.

Vulkan.Utils.FrameGraph.Image provides ManagedImage — an image plus a tracked ImageState (layout, stage, access). Declare an access with a Usage (encoded into Fragr.Flags via usageFlags); the hook diffs the tracked state against the usage's target and emits the transition, then updates the tracked state.

import Fragr qualified as FG
import Vulkan.Utils.FrameGraph.Image (ImageDesc (..), Usage (..), newManagedImage, usageFlags)

offscreen <- newManagedImage image Vk.IMAGE_ASPECT_COLOR_BIT
h <- FG.importResource g "offscreen" (ImageDesc "offscreen") offscreen
h' <- -- in a pass setup: FG.writeWith h (usageFlags ColorAttachment)
      -- a later pass: FG.readWith h' (usageFlags SampledFragment)

Ctx ManagedImage is the CommandBuffer the barriers record into; run the graph with FG.execute g cmdBuffer ().

Scope

ManagedImage participates as an imported resource: the graph tracks its layout and places barriers but does not own its allocation. Graph-owned transient images with deferred (frames-in-flight-safe) reclamation are future work — that needs FG.executeQueued + a RecycleQueue, since single-queue execute would free a transient during recording, before the GPU has run.

The layout-diff model inserts a barrier whenever the target ImageState differs from the tracked one, and also for every write access with the state unchanged (same-state WAW); only read-after-read skips the barrier.

When consecutive accesses land on different queues the barrier's source scope is replaced by the destination stage with no access mask: execution ordering and memory availability must come from the driver's inter-queue semaphore, and the barrier chains to its wait. Two caveats follow: the submit wait's dstStageMask must cover the consuming usage's stage, and cross-queue-family access is only supported for CONCURRENT-shared images — no ownership release/acquire pair is emitted (PassSync acquires/releases are dropped by recordingBackend), so an EXCLUSIVE image's contents are undefined on the new family.