mew/
buffer.rs

1/// Define a storage buffer, with an optional internal type to align its size
2/// with.
3///
4/// For example, if the buffer stores an array of `f32` matrices, you could set
5/// the internal type to `[f32; 16]`, and the buffer descriptor will initialize
6/// a multiple of the internal type's size.  
7/// If omitted, the internal type will default to `u8`, so you can initialize
8/// the buffer using a number of bytes.
9///
10/// You also can specify the [`wgpu::BufferUsages`], but note that it requires
11/// either `STORAGE` or `UNIFORM` as the _first_ usage.
12///
13/// ```
14/// buffer! { MatrixBuffer <[f32; 16]> as UNIFORM | COPY_DST }
15/// ```
16#[macro_export]
17macro_rules! buffer {
18    { @buffertype STORAGE } => {
19        $crate::wgpu::BufferBindingType::Storage { read_only: true, }
20    };
21    { @buffertype UNIFORM } => {
22        $crate::wgpu::BufferBindingType::Uniform
23    };
24
25    { $struct:ident as $( $usage:ident )|+ } => {
26        $crate::buffer! { $struct <u8> as $( $usage )|+ }
27    };
28    { $struct:ident < $inner:ty > as $storageuniform:ident $( | $usage:ident )* } => {
29        pub struct $struct {
30            buffer: $crate::wgpu::Buffer,
31        }
32
33        impl ::std::ops::Deref for $struct {
34            type Target = $crate::wgpu::Buffer;
35            fn deref(&self) -> &Self::Target {
36                &self.buffer
37            }
38        }
39
40        impl $crate::MewBuffer for $struct {
41            fn new(buffer: $crate::wgpu::Buffer) -> Self {
42                Self {
43                    buffer,
44                }
45            }
46
47            fn binding_type() -> $crate::wgpu::BindingType {
48                $crate::wgpu::BindingType::Buffer {
49                    ty: $crate::buffer!{ @buffertype $storageuniform },
50                    has_dynamic_offset: false,
51                    min_binding_size: None,
52                }
53            }
54
55            fn buffer_desc(inner_size: u64) -> $crate::wgpu::BufferDescriptor<'static> {
56                $crate::wgpu::BufferDescriptor {
57                    label: Some(concat!(stringify!($struct), "<", stringify!($inner), "> Buffer")),
58                    size: inner_size * ::std::mem::size_of::<$inner>() as u64,
59                    usage: $crate::wgpu::BufferUsages::$storageuniform $( | $crate::wgpu::BufferUsages::$usage )*,
60                    mapped_at_creation: false,
61                }
62            }
63
64            fn as_binding<'a>(&'a self) -> $crate::wgpu::BindingResource<'a> {
65                self.buffer.as_entire_binding()
66            }
67        }
68    }
69}
70
71
72/// Trait for buffer wrapper types, to get layouts and descriptors about the
73/// inner buffer.
74pub trait MewBuffer {
75    /// Wrap a buffer.
76    fn new(buffer: wgpu::Buffer) -> Self;
77    /// Get the `BindingType` for the buffer.
78    fn binding_type() -> wgpu::BindingType;
79    /// Get the 'BufferDescriptor' for the buffer, with some count of its internal
80    /// type as the size.
81    fn buffer_desc(inner_size: u64) -> wgpu::BufferDescriptor<'static>;
82    fn as_binding<'a>(&'a self) -> wgpu::BindingResource<'a>;
83}