pub struct VkAcquireBinary { /* private fields */ }Expand description
Per-frame fresh BINARY semaphore carrier — the NVIDIA-Windows
fallback path when VkAcquireTimeline cannot be GPU-waited by
the consumer (no exportable D3D12_FENCE timeline flavour AND no
GL_NV_timeline_semaphore + OPAQUE_WIN32 import support).
Unlike VkAcquireTimeline, which exports the same long-lived
timeline handle once at producer-pool init and Arc-clones it onto
every per-frame carrier, this carrier publishes a freshly-created
VkSemaphore for each frame. The producer creates the semaphore,
adds it to its vkQueueSubmit2 signal list, exports an NT handle
(Win32) / fd (POSIX), and stamps that handle here. The producer
then enqueues the underlying VkSemaphore onto a deferred-destroy
queue keyed on the per-frame timeline value, so cleanup happens
at the next per-frame copy after the timeline has advanced
past the per-frame value (i.e. after the signal has retired).
Why per-frame fresh and not persistent? Binary semaphores have
a strict pairing rule
(VUID-VkSubmitInfo-pSignalSemaphores-00135) — a binary semaphore
must be unsignaled at the time its signal-execution batch starts.
A persistent per-slot binary semaphore requires a paired waiter to
reset the payload between frames; under a stalled-consumer scenario
(consumer thread dropped a frame, didn’t issue
glWaitSemaphoreEXT), the next frame’s signal trips the VUID and
triggers VK_ERROR_DEVICE_LOST. Per-frame fresh sidesteps this
entirely, at the cost of a vkCreateSemaphore +
vkGetSemaphoreWin32HandleKHR + vkDestroySemaphore per frame.
Why no value field? Binary semaphores have a 2-state
payload (signaled / unsignaled) — there is no value parameter on
glWaitSemaphoreEXT for binary handles. The consumer just imports
the handle and queues glWaitSemaphoreEXT(sem, ..., NULL_VALUES).
Lifetime. The producer’s
std::sync::Arc<std::os::windows::io::OwnedHandle> /
std::sync::Arc<std::os::fd::OwnedFd> keeps the kernel-level NT
handle / fd alive until both the producer (which destroys the
VkSemaphore it minted) AND every consumer clone (which holds the
Arc on the carrier) have released it. The glImportSemaphoreWin32HandleEXT
/ glImportSemaphoreFdEXT call DUPs the kernel handle internally,
so GL imports continue to resolve against the underlying object
even after the producer-side VkSemaphore is destroyed.
Implementations§
Source§impl VkAcquireBinary
impl VkAcquireBinary
Sourcepub fn new_fd(fd: Arc<OwnedFd>) -> Self
Available on Hermit or Unix or WASI only.
pub fn new_fd(fd: Arc<OwnedFd>) -> Self
Unix constructor — fd is an fd from vkGetSemaphoreFdKHR on
a BINARY semaphore created with
VkExportSemaphoreCreateInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR.
Sourcepub fn with_wait_capability_ack(self, ack: Arc<AtomicBool>) -> Self
pub fn with_wait_capability_ack(self, ack: Arc<AtomicBool>) -> Self
Attach the producer’s consumer-capability ack bool — see
VkAcquireTimeline::with_wait_capability_ack.
Sourcepub fn ack_wait_capability(&self)
pub fn ack_wait_capability(&self)
Called by the consumer after glImportSemaphoreWin32HandleEXT +
glWaitSemaphoreEXT (or POSIX equivalent) has succeeded against
this carrier’s handle. See
VkAcquireTimeline::ack_wait_capability.
Sourcepub fn with_unstable_ack(self, unstable: Arc<AtomicBool>) -> Self
pub fn with_unstable_ack(self, unstable: Arc<AtomicBool>) -> Self
Attach the producer’s “binary path is unstable” back-channel —
the one-way latch a consumer trips via Self::signal_unstable
when a per-frame binary import / wait fails after an earlier
frame succeeded.
Sourcepub fn signal_unstable(&self)
pub fn signal_unstable(&self)
Called by the consumer when a per-frame binary import / wait
fails AFTER a prior frame’s success — the back-channel stamped by
Self::with_unstable_ack.
One-way latch: once flipped, the producer permanently re-engages
its CPU post-wait. Idempotent (later calls are cheap no-ops).