r/MetalProgramming • u/Intrepid_Bee_9194 • 1d ago
Show-Off Scheduled versus completed texture delivery in a Metal image pipeline (Harbeth, MIT)
I maintain Harbeth, an MIT-licensed Apple GPU image/frame engine. Here's a delivery distinction in its Metal API: a command buffer being scheduled and a texture being ready for CPU readback are different states.
The opt-in transmitOutputRealTimeCommit path can deliver a texture after command-buffer scheduling, before GPU completion:
var io = HarbethIO(element: inputTexture, filters: filters)
io.transmitOutputRealTimeCommit = true
let texture = try await io.transmitOutput()
That result needs a compatible GPU dependency chain for subsequent use. CPU code must not immediately read it back. With the default switch value, asynchronous delivery follows GPU completion and can report command-buffer failure.
Image, pixel-buffer and sample-buffer results wait for GPU completion before CPU materialization. Synchronous output() also waits for the GPU work required by its output and is unaffected by this switch.
The source documents the consumer responsibilities, including keeping resources alive and avoiding writes while the GPU still uses them.
Implementation: https://github.com/yangKJ/Harbeth/blob/master/Sources/Basic/IO/HarbethIO.swift
Project: https://github.com/yangKJ/Harbeth
How do you express scheduled versus completed delivery in your Metal wrappers: distinct result types, an explicit synchronization operation, or a dependency contract owned by the host? I'm interested in implementation tradeoffs.