mew/
texture.rs

1/// usage: variants of wgpu::TextureUsages
2/// format: variant of wgpu::TextureFormat
3/// dimension: variant of wgpu::TextureViewDimension
4/// sample_type: FLOAT or DEPTH
5#[macro_export]
6macro_rules! texture {
7    { @sampletype Float } => {
8        $crate::wgpu::TextureSampleType::Float { filterable: false, }
9    };
10    { @sampletype FloatFiltering } => {
11        $crate::wgpu::TextureSampleType::Float { filterable: true, }
12    };
13    { @sampletype Depth } => {
14        $crate::wgpu::TextureSampleType::Depth
15    };
16    { @sampletype Sint } => {
17        $crate::wgpu::TextureSampleType::Sint
18    };
19    { @sampletype Uint } => {
20        $crate::wgpu::TextureSampleType::Uint
21    };
22
23    { $struct:ident {
24        usage: $( $usage:ident )|+ ,
25        format: $format:ident,
26        dimension: $dimension:ident,
27        sample_type: $sample:ident,
28    } } => {
29        #[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
30        pub struct $struct {
31            texture: $crate::wgpu::Texture,
32            view: $crate::wgpu::TextureView,
33        }
34
35        impl ::std::ops::Deref for $struct {
36            type Target = $crate::wgpu::Texture;
37            fn deref(&self) -> &Self::Target {
38                &self.texture
39            }
40        }
41
42        impl $crate::texture::MewTexture for $struct {
43            fn new(texture: $crate::wgpu::Texture) -> Self {
44                let view = texture.create_view(&$crate::wgpu::TextureViewDescriptor {
45                    label: Some(concat!(stringify!($struct), " Texture View")),
46                    format: Some(texture.format()),
47                    dimension: Some($crate::wgpu::TextureViewDimension::$dimension),
48                    usage: Some($( $crate::wgpu::TextureUsages::$usage )|+),
49                    aspect: $crate::wgpu::TextureAspect::All,
50                    base_mip_level: 0,
51                    mip_level_count: None,
52                    base_array_layer: 0,
53                    array_layer_count: None,
54                });
55                Self {
56                    texture,
57                    view,
58                }
59            }
60
61            fn binding_type() -> $crate::wgpu::BindingType {
62                $crate::wgpu::BindingType::Texture {
63                    sample_type: $crate::texture! { @sampletype $sample },
64                    view_dimension: $crate::wgpu::TextureViewDimension::$dimension,
65                    multisampled: false,
66                }
67            }
68
69            fn buffer_desc(inner_size: (u32, u32, u32)) -> $crate::wgpu::TextureDescriptor<'static> {
70                $crate::wgpu::TextureDescriptor {
71                    label: Some(concat!(stringify!($struct), " Texture")),
72                    size: $crate::wgpu::Extent3d {
73                        width: inner_size.0,
74                        height: inner_size.1,
75                        depth_or_array_layers: inner_size.2,
76                    },
77                    mip_level_count: 1,
78                    sample_count: 1,
79                    dimension: $crate::wgpu::TextureViewDimension::$dimension.compatible_texture_dimension(),
80                    format: $crate::wgpu::TextureFormat::$format,
81                    usage: $( $crate::wgpu::TextureUsages::$usage )|+,
82                    view_formats: &[],
83                }
84            }
85
86            fn as_binding<'a>(&'a self) -> $crate::wgpu::BindingResource<'a> {
87                $crate::wgpu::BindingResource::TextureView(&self.view)
88            }
89
90            fn as_colour_attachment<'a>(&'a self, clear: Option<$crate::wgpu::Color>) -> $crate::wgpu::RenderPassColorAttachment<'a> {
91                $crate::wgpu::RenderPassColorAttachment {
92                    view: &self.view,
93                    depth_slice: None,  // ??????
94                    resolve_target: None,  // ???
95                    ops: $crate::wgpu::Operations {
96                        load: clear.map(|colour| $crate::wgpu::LoadOp::Clear(colour)).unwrap_or($crate::wgpu::LoadOp::Load),
97                        store: $crate::wgpu::StoreOp::Store,  // Also duh
98                    },
99                }
100            }
101
102            fn as_depth_attachment<'a>(&'a self) -> $crate::wgpu::RenderPassDepthStencilAttachment<'a> {
103                $crate::wgpu::RenderPassDepthStencilAttachment {
104                    view: &self.view,
105                    depth_ops: Some($crate::wgpu::Operations {
106                        load: $crate::wgpu::LoadOp::Clear(1.0),
107                        store: $crate::wgpu::StoreOp::Store,
108                    }),
109                    stencil_ops: None,
110                }
111            }
112
113            fn pixel_size() -> u32 {
114                $crate::wgpu::TextureFormat::$format.components() as u32
115            }
116
117            fn texel_layout(&self) -> $crate::wgpu::TexelCopyBufferLayout {
118                $crate::wgpu::TexelCopyBufferLayout {
119                    offset: 0,
120                    bytes_per_row: Some(Self::pixel_size() * self.texture.width()),
121                    rows_per_image: Some(self.texture.height())
122                }
123            }
124        }
125    }
126}
127pub use texture;
128
129
130pub trait MewTexture {
131    fn new(buffer: wgpu::Texture) -> Self;
132    fn binding_type() -> wgpu::BindingType;
133    fn buffer_desc(inner_size: (u32, u32, u32)) -> wgpu::TextureDescriptor<'static>;
134    fn as_binding<'a>(&'a self) -> wgpu::BindingResource<'a>;
135    fn as_colour_attachment<'a>(&'a self, clear: Option<wgpu::Color>) -> wgpu::RenderPassColorAttachment<'a>;
136    fn as_depth_attachment<'a>(&'a self) -> wgpu::RenderPassDepthStencilAttachment<'a>;
137    fn pixel_size() -> u32;
138    fn texel_layout(&self) -> wgpu::TexelCopyBufferLayout;
139}