Skip to main content

CommandBuffer

Struct CommandBuffer 

Source
pub struct CommandBuffer { /* private fields */ }
Expand description

Work being recorded for the GPU: one concurrent compute encoder, with memory barriers inserted only where a dispatch depends on an earlier one.

Implementations§

Source§

impl CommandBuffer

Source

pub unsafe fn dispatch( &mut self, pipeline: &Pipeline, args: &[Arg<'_>], threads: usize, ) -> Result<()>

Encodes pipeline over threads threads (a 1-D grid) with args bound to slots 0..args.len(). The threadgroup size is derived from the pipeline’s limits.

Arguments are validated (slot count, inline size, offsets within their buffers, Arg::Same targets, ordering with other command buffers), but what the kernel does with them is not: nuvec cannot see which elements a kernel touches.

§Safety

The kernel, run over this grid, must access each bound buffer only within its length from the bound offset (and write only the buffers bound with Arg::Write or Arg::Same). An out-of-bounds access reads or writes memory that other buffers, possibly referenced by safe code, own.

Source

pub unsafe fn dispatch_groups( &mut self, pipeline: &Pipeline, args: &[Arg<'_>], groups: [usize; 3], threads: [usize; 3], ) -> Result<()>

Encodes pipeline over a grid of groups threadgroups of threads threads each, for kernels that cooperate within a threadgroup (reductions, tiled matrix products).

§Safety

As for dispatch: the kernel must access each bound buffer only within its length from the bound offset.

Source

pub unsafe fn dispatch_threads( &mut self, pipeline: &Pipeline, args: &[Arg<'_>], grid: [usize; 3], group: [usize; 3], ) -> Result<()>

Encodes pipeline over exactly grid threads in up to three dimensions, in threadgroups of group threads (the edge threadgroups are partial).

§Safety

As for dispatch: the kernel must access each bound buffer only within its length from the bound offset.

Source

pub fn barriers(&self) -> usize

Memory barriers inserted so far.

Source

pub fn signal_event(&mut self, event: &Event, value: u64)

Raises event to value once the GPU has finished the work encoded so far in this command buffer (Event::wait waits for it on the CPU).

Source

pub fn wait_event(&mut self, event: &Event, value: u64)

Makes the work encoded after this call wait on the GPU until event reaches value (the CPU raises it with Event::signal).

Source

pub fn commit(self) -> Submitted

Submits the work to the GPU. Dropping the returned Submitted waits for it and discards its result; Submitted::wait reports GPU errors.

Source

pub fn commit_then( self, on_complete: impl FnOnce(Result<()>) + Send + 'static, ) -> Pending

Submits the work and returns at once. on_complete runs exactly once with the command buffer’s result: on a Metal thread when the GPU finishes, or earlier on the thread that calls Pending::wait.

on_complete must not block, in particular not on other GPU work: Metal runs a queue’s completion handlers one at a time, so waiting there for another command buffer’s completion can deadlock. A panic in on_complete on Metal’s thread is caught and reported on standard error, so it never aborts the process; the result is still published to Pending::wait.

Source

pub fn enqueue_then( self, on_complete: impl FnOnce(Result<()>) + Send + 'static, ) -> (Pending, Deferred)

commit_then, but the GPU gets the work only once Deferred::commit is called (or the Deferred is dropped). The command buffer takes its place in the queue now: command buffers committed later run after it. Work that waits on the GPU for an event the CPU may raise late is committed this way once the event is raised, so the GPU never waits for it (Metal fails a command buffer that waits for seconds).

Trait Implementations§

Source§

impl Drop for CommandBuffer

Source§

fn drop(&mut self)

Abandoned work is never submitted; release the buffers’ guards. (Metal objects are released in an autorelease pool: their deallocation may autorelease others.)

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. 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> AutoreleaseSafe for T
where T: ?Sized,

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