wgpu_async/
async_buffer.rs

1use crate::{async_device::AsyncDevice, WgpuFuture};
2use std::ops::{Deref, DerefMut, RangeBounds};
3use wgpu::{BufferAddress, BufferAsyncError};
4
5/// A wrapper around a [`wgpu::Buffer`] which shadows some methods to allow for async
6/// mapping using Rust's `async` API.
7#[derive(Debug)]
8pub struct AsyncBuffer
9where
10    Self: wgpu::WasmNotSend,
11{
12    pub(crate) device: AsyncDevice,
13    pub(crate) buffer: wgpu::Buffer,
14}
15
16impl AsyncBuffer {
17    /// Takes a slice of this buffer, in the same way a call to [`wgpu::Buffer::slice`] would,
18    /// except wraps the result in an [`AsyncBufferSlice`] so that the `map_async` method can be
19    /// awaited.
20    pub fn slice<S: RangeBounds<BufferAddress>>(&self, bounds: S) -> AsyncBufferSlice<'_> {
21        let buffer_slice = self.buffer.slice(bounds);
22        AsyncBufferSlice {
23            device: self.device.clone(),
24            buffer_slice,
25        }
26    }
27}
28impl Deref for AsyncBuffer {
29    type Target = wgpu::Buffer;
30
31    fn deref(&self) -> &Self::Target {
32        &self.buffer
33    }
34}
35impl DerefMut for AsyncBuffer {
36    fn deref_mut(&mut self) -> &mut Self::Target {
37        &mut self.buffer
38    }
39}
40impl<T> AsRef<T> for AsyncBuffer
41where
42    T: ?Sized,
43    <AsyncBuffer as Deref>::Target: AsRef<T>,
44{
45    fn as_ref(&self) -> &T {
46        self.deref().as_ref()
47    }
48}
49impl<T> AsMut<T> for AsyncBuffer
50where
51    <AsyncBuffer as Deref>::Target: AsMut<T>,
52{
53    fn as_mut(&mut self) -> &mut T {
54        self.deref_mut().as_mut()
55    }
56}
57
58/// A smart-pointer wrapper around a [`wgpu::BufferSlice`], offering a `map_async` method than can be `await`ed.
59#[derive(Debug)]
60pub struct AsyncBufferSlice<'a>
61where
62    Self: wgpu::WasmNotSend,
63{
64    device: AsyncDevice,
65    buffer_slice: wgpu::BufferSlice<'a>,
66}
67impl AsyncBufferSlice<'_> {
68    /// An awaitable version of [`wgpu::Buffer::map_async`].
69    pub fn map_async(&self, mode: wgpu::MapMode) -> WgpuFuture<Result<(), BufferAsyncError>> {
70        self.device
71            .do_async(|callback| self.buffer_slice.map_async(mode, callback))
72    }
73}
74impl<'a> Deref for AsyncBufferSlice<'a> {
75    type Target = wgpu::BufferSlice<'a>;
76
77    fn deref(&self) -> &Self::Target {
78        &self.buffer_slice
79    }
80}
81impl DerefMut for AsyncBufferSlice<'_> {
82    fn deref_mut(&mut self) -> &mut Self::Target {
83        &mut self.buffer_slice
84    }
85}
86impl<T> AsRef<T> for AsyncBufferSlice<'_>
87where
88    T: ?Sized,
89    <Self as Deref>::Target: AsRef<T>,
90{
91    fn as_ref(&self) -> &T {
92        self.deref().as_ref()
93    }
94}
95impl<T> AsMut<T> for AsyncBufferSlice<'_>
96where
97    <Self as Deref>::Target: AsMut<T>,
98{
99    fn as_mut(&mut self) -> &mut T {
100        self.deref_mut().as_mut()
101    }
102}