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