pub struct ReadbackStream { /* private fields */ }Expand description
High-throughput, non-blocking readback pipeline based on a ring buffer.
See module documentation for architecture details and usage.
Implementations§
Source§impl ReadbackStream
impl ReadbackStream
Sourcepub fn new(
device: &Device,
width: u32,
height: u32,
format: TextureFormat,
buffer_count: usize,
max_stash_size: usize,
) -> Result<ReadbackStream, ReadbackError>
pub fn new( device: &Device, width: u32, height: u32, format: TextureFormat, buffer_count: usize, max_stash_size: usize, ) -> Result<ReadbackStream, ReadbackError>
Creates a new readback stream with buffer_count ring-buffer slots.
§Arguments
device— GPU device for buffer allocation.width/height— Dimensions of the source render target.format— Pixel format (must supportblock_copy_size).buffer_count— Number of staging buffers (ring size). Typical values are 2–4; higher counts tolerate more GPU-to-CPU latency at the cost of VRAM.
§Errors
Returns ReadbackError::UnsupportedFormat if the format does not
have a known block copy size.
Sourcepub fn try_submit(
&mut self,
device: &Device,
queue: &Queue,
texture: &Texture,
) -> Result<(), ReadbackError>
pub fn try_submit( &mut self, device: &Device, queue: &Queue, texture: &Texture, ) -> Result<(), ReadbackError>
Submits a non-blocking copy from texture to the next ring-buffer slot.
The copy command is recorded and submitted immediately. When the GPU
completes the copy, a map_async callback pushes the slot index into
the internal channel, making it available via try_recv.
§Back-pressure
If all slots are in-flight, this method returns
ReadbackError::RingFull without blocking. The caller may
choose to skip the frame (real-time path) or drain via
try_recv.
Sourcepub fn submit_blocking(
&mut self,
device: &Device,
queue: &Queue,
texture: &Texture,
) -> Result<(), ReadbackError>
pub fn submit_blocking( &mut self, device: &Device, queue: &Queue, texture: &Texture, ) -> Result<(), ReadbackError>
Submits a copy, blocking when the ring buffer is full.
When all ring-buffer slots are occupied, this method:
- Blocks until the GPU completes at least one pending readback.
- Extracts the completed frame into
stashed_frames(using a recycled buffer fromfree_poolwhen available). - Proceeds with the submission on the freed slot.
This guarantees zero frame loss and is intended for offline workloads such as video export and dataset generation.
§Safety on WASM
wgpu::PollType::wait_indefinitely() will panic on WebAssembly.
Use try_submit for WASM targets.
§Stash limit
max_stash_size caps the number of completed-but-unconsumed frames
held in memory. If the stash is full, returns
ReadbackError::StashFull to prevent unbounded memory growth.
Sourcepub fn try_recv(&mut self) -> Result<Option<ReadbackFrame>, ReadbackError>
pub fn try_recv(&mut self) -> Result<Option<ReadbackFrame>, ReadbackError>
Returns the next ready frame without blocking, or None if no frame
is available yet.
This is the allocating receive path — a new Vec<u8> (or one
from the internal pool) is returned for each frame. For zero-copy
steady-state operation, prefer try_recv_into.
Sourcepub fn try_recv_into(
&mut self,
output: &mut Vec<u8>,
) -> Result<Option<u64>, ReadbackError>
pub fn try_recv_into( &mut self, output: &mut Vec<u8>, ) -> Result<Option<u64>, ReadbackError>
Zero-allocation receive: writes pixel data into a caller-supplied buffer.
On success the previous contents of output are swapped into the
internal free pool (preserving its heap capacity for future frames),
and output receives the new frame’s pixel data. Returns the frame
index, or None if no frame is ready.
After the initial warm-up period (≤ buffer_count frames), this
method performs zero heap allocations per call.
Sourcepub fn flush(
&mut self,
device: &Device,
) -> Result<Vec<ReadbackFrame>, ReadbackError>
pub fn flush( &mut self, device: &Device, ) -> Result<Vec<ReadbackFrame>, ReadbackError>
Blocks until all in-flight frames have been read back.
Returns all remaining frames (stashed + in-flight) as a Vec.
This should be called at the end of a recording session to ensure
no frames are lost.
Sourcepub fn format(&self) -> TextureFormat
pub fn format(&self) -> TextureFormat
Returns the pixel format of the readback stream.
Sourcepub fn dimensions(&self) -> (u32, u32)
pub fn dimensions(&self) -> (u32, u32)
Returns the render target dimensions.
Sourcepub fn bytes_per_pixel(&self) -> u32
pub fn bytes_per_pixel(&self) -> u32
Returns the number of bytes per pixel for the current format.
Sourcepub fn buffer_count(&self) -> usize
pub fn buffer_count(&self) -> usize
Returns the number of ring-buffer slots.
Sourcepub fn frames_submitted(&self) -> u64
pub fn frames_submitted(&self) -> u64
Returns the total number of frames submitted so far.
Sourcepub fn frame_byte_size(&self) -> usize
pub fn frame_byte_size(&self) -> usize
Returns the expected byte size of one tightly-packed frame.
Auto Trait Implementations§
impl Freeze for ReadbackStream
impl !RefUnwindSafe for ReadbackStream
impl Send for ReadbackStream
impl Sync for ReadbackStream
impl Unpin for ReadbackStream
impl UnsafeUnpin for ReadbackStream
impl !UnwindSafe for ReadbackStream
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
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.