Skip to main content

PooledBuffer

Struct PooledBuffer 

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

A storage buffer that returns to its context’s free list when dropped rather than being destroyed.

Recycling GPU memory sounds alarming and is safe here for two reasons. A buffer only reaches the free list when its last host-side handle drops, and the pool can then only hand it to a later dispatch — and later commands on one queue execute after earlier ones, so a new write can never overtake a pending read. And recycled buffers are not zeroed, which is fine because every kernel writes the whole of its output before anything reads it; tests/op_parity.rs would show stale tail elements immediately if that ever stopped being true.

recycle is the exception those reasons do not cover, and it is not theoretical — it corrupted wte gradients before it was understood. queue.write_buffer does not run in command order: its data is applied at the start of the next submit, ahead of every command buffer in it. So a buffer that is dropped, recycled, and then filled by upload while earlier dispatches reading its previous contents are still recorded and unsubmitted would have those dispatches read the new bytes. Buffers written by write_buffer therefore never join the pool: WgpuContext::upload sets recycle: false. They are weights and per-step id tensors, so the pool loses almost nothing.

Methods from Deref<Target = Buffer>§

Source

pub fn as_entire_binding(&self) -> BindingResource<'_>

Return the binding view of the entire buffer.

Source

pub fn as_entire_buffer_binding(&self) -> BufferBinding<'_>

Return the binding view of the entire buffer.

Source

pub unsafe fn as_hal<A>( &self, ) -> Option<impl Deref<Target = <A as Api>::Buffer> + WasmNotSendSync>
where A: HalApi,

Available on wgpu_core only.

Get the wgpu_hal buffer from this Buffer.

Find the Api struct corresponding to the active backend in wgpu_hal::api, and pass that struct to the to the A type parameter.

Returns a guard that dereferences to the type of the hal backend which implements A::Buffer.

§Deadlocks
  • The returned guard holds a read-lock on a device-local “destruction” lock, which will cause all calls to destroy to block until the guard is released.
§Errors

This method will return None if:

  • The buffer is not from the backend specified by A.
  • The buffer is from the webgpu or custom backend.
  • The buffer has had Self::destroy() called on it.
§Safety
  • The returned resource must not be destroyed unless the guard is the last reference to it and it is not in use by the GPU. The guard and handle may be dropped at any time however.
  • All the safety requirements of wgpu-hal must be upheld.
Source

pub fn slice<S>(&self, bounds: S) -> BufferSlice<'_>
where S: RangeBounds<u64>,

Returns a BufferSlice referring to the portion of self’s contents indicated by bounds. Regardless of what sort of data self stores, bounds start and end are given in bytes.

A BufferSlice can be used to supply vertex and index data, or to map buffer contents for access from the CPU. See the BufferSlice documentation for details.

The range argument can be half or fully unbounded: for example, buffer.slice(..) refers to the entire buffer, and buffer.slice(n..) refers to the portion starting at the nth byte and extending to the end of the buffer.

§Panics
  • If bounds is outside of the bounds of self.
  • If bounds has a length less than 1.
Source

pub fn unmap(&self)

Unmaps the buffer from host memory.

This terminates the effect of all previous map_async() operations and makes the buffer available for use by the GPU again.

Source

pub fn destroy(&self)

Destroy the associated native resources as soon as possible.

Source

pub fn size(&self) -> u64

Returns the length of the buffer allocation in bytes.

This is always equal to the size that was specified when creating the buffer.

Source

pub fn usage(&self) -> BufferUsages

Returns the allowed usages for this Buffer.

This is always equal to the usage that was specified when creating the buffer.

Source

pub fn map_async<S>( &self, mode: MapMode, bounds: S, callback: impl FnOnce(Result<(), BufferAsyncError>) + WasmNotSend + 'static, )
where S: RangeBounds<u64>,

Map the buffer to host (CPU) memory, making it available for reading or writing via get_mapped_range(). It is available once the callback is called with an Ok response.

For the callback to complete, either queue.submit(..), instance.poll_all(..), or device.poll(..) must be called elsewhere in the runtime, possibly integrated into an event loop or run on a separate thread.

The callback will be called on the thread that first calls the above functions after the GPU work has completed. There are no restrictions on the code you can run in the callback, however on native the call to the function will not complete until the callback returns, so prefer keeping callbacks short and used to set flags, send messages, etc.

As long as a buffer is mapped, it is not available for use by any other commands; at all times, either the GPU or the CPU has exclusive access to the contents of the buffer.

This can also be performed using BufferSlice::map_async().

§Panics
  • If the buffer is already mapped.
  • If the buffer’s BufferUsages do not allow the requested MapMode.
  • If bounds is outside of the bounds of self.
  • If bounds has a length less than 1.
  • If the start and end of bounds are not be aligned to MAP_ALIGNMENT.
Source

pub fn get_mapped_range<S>(&self, bounds: S) -> BufferView<'_>
where S: RangeBounds<u64>,

Gain read-only access to the bytes of a mapped Buffer.

Returns a BufferView referring to the buffer range represented by self. See the documentation for BufferView for details.

bounds may be less than the bounds passed to Self::map_async(), and multiple views may be obtained and used simultaneously as long as they do not overlap.

This can also be performed using BufferSlice::get_mapped_range().

§Panics
  • If bounds is outside of the bounds of self.
  • If bounds has a length less than 1.
  • If the start and end of bounds are not aligned to MAP_ALIGNMENT.
  • If the buffer to which self refers is not currently mapped.
  • If you try to create overlapping views of a buffer, mutable or otherwise.
Source

pub fn get_mapped_range_mut<S>(&self, bounds: S) -> BufferViewMut<'_>
where S: RangeBounds<u64>,

Gain write access to the bytes of a mapped Buffer.

Returns a BufferViewMut referring to the buffer range represented by self. See the documentation for BufferViewMut for more details.

bounds may be less than the bounds passed to Self::map_async(), and multiple views may be obtained and used simultaneously as long as they do not overlap.

This can also be performed using BufferSlice::get_mapped_range_mut().

§Panics
  • If bounds is outside of the bounds of self.
  • If bounds has a length less than 1.
  • If the start and end of bounds are not aligned to MAP_ALIGNMENT.
  • If the buffer to which self refers is not currently mapped.
  • If you try to create overlapping views of a buffer, mutable or otherwise.

Trait Implementations§

Source§

impl Debug for PooledBuffer

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Deref for PooledBuffer

Source§

type Target = Buffer

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Buffer

Dereferences the value.
Source§

impl Drop for PooledBuffer

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
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> 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> Downcast<T> for T

Source§

fn downcast(&self) -> &T

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

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

Source§

impl<T> WasmNotSendSync for T

Source§

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