Skip to main content

VkAcquireBinary

Struct VkAcquireBinary 

Source
pub struct VkAcquireBinary { /* private fields */ }
Available on Hermit or Unix or WASI or Windows only.
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 ~55–90 µs/frame (vkCreateSemaphore + vkGetSemaphoreWin32HandleKHR + vkDestroySemaphore). A GL-fence feedback channel could make persistent per-slot binaries safe to reuse and avoid that overhead, at the cost of a second consumer→producer protocol.

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

Source

pub fn new_fd(fd: Arc<OwnedFd>) -> Self

Available on Hermit or Unix or WASI only.

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

pub fn fd(&self) -> &Arc<OwnedFd> ⓘ

Available on Hermit or Unix or WASI only.

Exported fd to the per-frame BINARY semaphore. POSIX counterpart of Self::handle.

Trait Implementations§

Source§

impl Clone for VkAcquireBinary

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for VkAcquireBinary

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> MaybeSend for T
where T: Send + ?Sized,

Source§

impl<T> MaybeSendSync for T
where T: Send + Sync + ?Sized,

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,