pub mod sample_type {
use crate::wgpu;
pub const FLOAT: wgpu::TextureSampleType = wgpu::TextureSampleType::Float { filterable: true, };
pub const FLOAT_NON_FILTERABLE: wgpu::TextureSampleType = wgpu::TextureSampleType::Float { filterable: false, };
pub const DEPTH: wgpu::TextureSampleType = wgpu::TextureSampleType::Depth;
pub const SINT: wgpu::TextureSampleType = wgpu::TextureSampleType::Sint;
pub const UINT: wgpu::TextureSampleType = wgpu::TextureSampleType::Uint;
}
use crate::wgpu;
#[macro_export]
macro_rules! texture {
{ $struct:ident { $($key:tt: $($vals:tt)|+),* $(,)? } } => {
$crate::texture! { @collect $struct {
usage: (COPY_DST | TEXTURE_BINDING),
dimension: D2,
sample_type: FLOAT,
}; $({$key: $($vals)|+} )* }
};
{ @collect $struct:ident {
usage: $_:tt,
dimension: $dimension:tt,
sample_type: $sample:tt,
}; {usage: $($usage:tt)|+} $($rest:tt)* } => {
$crate::texture! { @collect $struct {
usage: ($($usage)|+),
dimension: $dimension,
sample_type: $sample,
}; $($rest)* }
};
{ @collect $struct:ident {
usage: $usage:tt,
dimension: $_:tt,
sample_type: $sample:tt,
}; {dimension: $dimension:tt} $($rest:tt)* } => {
$crate::texture! { @collect $struct {
usage: $usage,
dimension: $dimension,
sample_type: $sample,
}; $($rest)* }
};
{ @collect $struct:ident {
usage: $usage:tt,
dimension: $dimension:tt,
sample_type: $_:tt,
}; {sample_type: $sample:tt} $($rest:tt)* } => {
$crate::texture! { @collect $struct {
usage: $usage,
dimension: $dimension,
sample_type: $sample,
}; $($rest)* }
};
{ @collect $struct:ident {
usage: ($( $usage:ident )|+) ,
dimension: $dimension:ident,
sample_type: $sample:ident,
}; } => {
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct $struct {
pub texture: $crate::wgpu::Texture,
pub view: $crate::wgpu::TextureView,
}
impl ::std::ops::Deref for $struct {
type Target = $crate::wgpu::Texture;
fn deref(&self) -> &Self::Target {
&self.texture
}
}
impl $crate::texture::MewTexture for $struct {
fn new(texture: $crate::wgpu::Texture) -> Self {
let view = texture.create_view(&$crate::wgpu::TextureViewDescriptor {
label: Some(concat!(stringify!($struct), " Texture View")),
format: Some(texture.format()),
dimension: Some($crate::wgpu::TextureViewDimension::$dimension),
usage: Some($( $crate::wgpu::TextureUsages::$usage )|+),
aspect: $crate::wgpu::TextureAspect::All,
base_mip_level: 0,
mip_level_count: None,
base_array_layer: 0,
array_layer_count: None,
});
Self {
texture,
view,
}
}
fn binding_type() -> $crate::wgpu::BindingType {
$crate::wgpu::BindingType::Texture {
sample_type: $crate::texture::sample_type::$sample,
view_dimension: $crate::wgpu::TextureViewDimension::$dimension,
multisampled: false,
}
}
fn buffer_desc(inner_size: (u32, u32, u32), format: $crate::wgpu::TextureFormat) -> $crate::wgpu::TextureDescriptor<'static> {
$crate::wgpu::TextureDescriptor {
label: Some(concat!(stringify!($struct), " Texture")),
size: $crate::wgpu::Extent3d {
width: inner_size.0,
height: inner_size.1,
depth_or_array_layers: inner_size.2,
},
mip_level_count: 1,
sample_count: 1,
dimension: $crate::wgpu::TextureViewDimension::$dimension.compatible_texture_dimension(),
format,
usage: $( $crate::wgpu::TextureUsages::$usage )|+,
view_formats: &[],
}
}
fn as_binding(&self) -> $crate::wgpu::BindingResource<'_> {
$crate::wgpu::BindingResource::TextureView(&self.view)
}
fn as_colour_attachment(&self, clear: Option<$crate::wgpu::Color>, depth_slice: Option<u32>) -> $crate::wgpu::RenderPassColorAttachment<'_> {
$crate::wgpu::RenderPassColorAttachment {
view: &self.view,
depth_slice,
resolve_target: None, ops: $crate::wgpu::Operations {
load: clear.map(|colour| $crate::wgpu::LoadOp::Clear(colour)).unwrap_or($crate::wgpu::LoadOp::Load),
store: $crate::wgpu::StoreOp::Store,
},
}
}
fn as_depth_attachment(&self) -> $crate::wgpu::RenderPassDepthStencilAttachment<'_> {
$crate::wgpu::RenderPassDepthStencilAttachment {
view: &self.view,
depth_ops: Some($crate::wgpu::Operations {
load: $crate::wgpu::LoadOp::Clear(1.0),
store: $crate::wgpu::StoreOp::Store,
}),
stencil_ops: None,
}
}
fn memory_estimate(&self) -> u64 {
self.texture.format().theoretical_memory_footprint($crate::wgpu::Extent3d {
width: self.texture.width(),
height: self.texture.height(),
depth_or_array_layers: self.texture.depth_or_array_layers(),
})
}
fn texel_layout(&self) -> $crate::wgpu::TexelCopyBufferLayout {
$crate::wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(self.texture.format().components() as u32 * self.texture.width()),
rows_per_image: Some(self.texture.height())
}
}
}
}
}
pub use texture;
pub trait MewTexture {
fn new(buffer: wgpu::Texture) -> Self;
fn binding_type() -> wgpu::BindingType;
fn buffer_desc(inner_size: (u32, u32, u32), format: wgpu::TextureFormat) -> wgpu::TextureDescriptor<'static>;
fn as_binding(&self) -> wgpu::BindingResource<'_>;
fn as_colour_attachment(&self, clear: Option<wgpu::Color>, depth_slice: Option<u32>) -> wgpu::RenderPassColorAttachment<'_>;
fn as_depth_attachment(&self) -> wgpu::RenderPassDepthStencilAttachment<'_>;
fn memory_estimate(&self) -> u64;
fn texel_layout(&self) -> wgpu::TexelCopyBufferLayout;
}