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>§
Sourcepub fn as_entire_binding(&self) -> BindingResource<'_>
pub fn as_entire_binding(&self) -> BindingResource<'_>
Return the binding view of the entire buffer.
Sourcepub fn as_entire_buffer_binding(&self) -> BufferBinding<'_>
pub fn as_entire_buffer_binding(&self) -> BufferBinding<'_>
Return the binding view of the entire buffer.
Sourcepub unsafe fn as_hal<A>(
&self,
) -> Option<impl Deref<Target = <A as Api>::Buffer> + WasmNotSendSync>where
A: HalApi,
Available on wgpu_core only.
pub unsafe fn as_hal<A>(
&self,
) -> Option<impl Deref<Target = <A as Api>::Buffer> + WasmNotSendSync>where
A: HalApi,
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
destroyto 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
webgpuorcustombackend. - 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.
Sourcepub fn slice<S>(&self, bounds: S) -> BufferSlice<'_>where
S: RangeBounds<u64>,
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
boundsis outside of the bounds ofself. - If
boundshas a length less than 1.
Sourcepub fn unmap(&self)
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.
Sourcepub fn size(&self) -> u64
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.
Sourcepub fn usage(&self) -> BufferUsages
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.
Sourcepub fn map_async<S>(
&self,
mode: MapMode,
bounds: S,
callback: impl FnOnce(Result<(), BufferAsyncError>) + WasmNotSend + 'static,
)where
S: RangeBounds<u64>,
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
BufferUsagesdo not allow the requestedMapMode. - If
boundsis outside of the bounds ofself. - If
boundshas a length less than 1. - If the start and end of
boundsare not be aligned toMAP_ALIGNMENT.
Sourcepub fn get_mapped_range<S>(&self, bounds: S) -> BufferView<'_>where
S: RangeBounds<u64>,
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
boundsis outside of the bounds ofself. - If
boundshas a length less than 1. - If the start and end of
boundsare not aligned toMAP_ALIGNMENT. - If the buffer to which
selfrefers is not currently mapped. - If you try to create overlapping views of a buffer, mutable or otherwise.
Sourcepub fn get_mapped_range_mut<S>(&self, bounds: S) -> BufferViewMut<'_>where
S: RangeBounds<u64>,
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
boundsis outside of the bounds ofself. - If
boundshas a length less than 1. - If the start and end of
boundsare not aligned toMAP_ALIGNMENT. - If the buffer to which
selfrefers is not currently mapped. - If you try to create overlapping views of a buffer, mutable or otherwise.
Trait Implementations§
Source§impl Debug for PooledBuffer
impl Debug for PooledBuffer
Source§impl Deref for PooledBuffer
impl Deref for PooledBuffer
Source§impl Drop for PooledBuffer
impl Drop for PooledBuffer
Auto Trait Implementations§
impl !RefUnwindSafe for PooledBuffer
impl !UnwindSafe for PooledBuffer
impl Freeze for PooledBuffer
impl Send for PooledBuffer
impl Sync for PooledBuffer
impl Unpin for PooledBuffer
impl UnsafeUnpin for PooledBuffer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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