1use crate::backend::{BackendBuffer, BackendBufferOps};
8use crate::error::Result;
9
10#[allow(private_interfaces)]
14pub trait GpuBuf {
15 #[doc(hidden)]
16 fn raw(&self) -> &BackendBuffer;
17}
18
19pub struct Buffer<T: bytemuck::Pod> {
27 pub(crate) inner: BackendBuffer,
28 pub(crate) len: usize,
29 pub(crate) _marker: std::marker::PhantomData<T>,
30}
31
32impl<T: bytemuck::Pod> Buffer<T> {
33 pub const fn len(&self) -> usize {
35 self.len
36 }
37
38 pub const fn is_empty(&self) -> bool {
40 self.len == 0
41 }
42
43 pub const fn byte_size(&self) -> u64 {
45 match self.len.checked_mul(std::mem::size_of::<T>()) {
46 Some(s) => s as u64,
47 None => u64::MAX,
48 }
49 }
50
51 pub fn download(&self) -> Result<Vec<T>> {
55 let bytes = self.inner.read_back()?;
56 let elements = bytemuck::cast_slice(&bytes).to_vec();
57 Ok(elements)
58 }
59}
60
61#[allow(private_interfaces)]
62impl<T: bytemuck::Pod> GpuBuf for Buffer<T> {
63 fn raw(&self) -> &BackendBuffer {
64 &self.inner
65 }
66}
67
68impl<T: bytemuck::Pod> std::fmt::Debug for Buffer<T> {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 f.debug_struct("Buffer")
71 .field("len", &self.len)
72 .field("byte_size", &self.byte_size())
73 .field("type", &std::any::type_name::<T>())
74 .finish_non_exhaustive()
75 }
76}