use bitflags::bitflags;
use derive_getters::Getters;
use crate::fatal;
use crate::render::{RenderSurface, Renderer};
use crate::render::types::*;
#[derive(Debug, Clone)]
pub struct TextureDescriptor {
pub width: u32,
pub height: u32,
pub depth: Option<u32>,
pub filter: FilterMode,
pub dimension: TextureDimension,
pub usage: TextureUsages,
pub format: TextureFormat,
pub mip_level_count: u32,
pub label: String,
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TextureResourceUsage: u8 {
const TEXTURE = 1;
const SAMPLER = 1 << 1;
const STORAGE = 1 << 2;
}
}
pub struct TextureResourceDescriptor {
pub usage: TextureResourceUsage,
pub sample_type: Option<TextureSampleType>,
pub sampler_binding_type: Option<SamplerBindingType>,
}
#[derive(Debug, Getters)]
pub struct Texture {
texture: wgpu::Texture,
view: wgpu::TextureView,
sampler: wgpu::Sampler,
descriptor: TextureDescriptor,
}
impl RenderSurface for Texture {
fn view(&self) -> &TextureView {
if !self.descriptor.usage.contains(wgpu::TextureUsages::RENDER_ATTACHMENT) {
fatal!("Texture, used as render surface, must have RENDER_ATTACHMENT usage");
}
&self.view
}
}
impl Texture {
pub fn new(
renderer: &Renderer,
descriptor: TextureDescriptor,
) -> Texture {
let size = wgpu::Extent3d {
width: descriptor.width,
height: descriptor.height,
depth_or_array_layers: descriptor.depth.unwrap_or(1),
};
let texture = renderer.device.create_texture(&wgpu::TextureDescriptor {
label: Some(format!("{} Texture", descriptor.label).as_str()),
size,
mip_level_count: descriptor.mip_level_count,
sample_count: 1,
dimension: descriptor.dimension,
format: descriptor.format,
usage: descriptor.usage,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = renderer.device.create_sampler(&wgpu::SamplerDescriptor {
label: Some(format!("{} Texture Sampler", descriptor.label).as_str()),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: descriptor.filter,
min_filter: descriptor.filter,
mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: 0.0,
lod_max_clamp: 100.0,
..Default::default()
});
Texture {
texture,
view,
sampler,
descriptor,
}
}
pub fn resize(&mut self, renderer: &Renderer, width: u32, height: u32) {
let mut descr = self.descriptor.clone();
descr.width = width;
descr.height = height;
*self = Texture::new(renderer, descr);
}
}