use crate::renderer::Size;
use std::sync::atomic::{AtomicBool, Ordering};
use wgpu::{
BindGroup, BindGroupEntry, BindGroupLayout, BindGroupLayoutEntry, BindingType, Device,
Extent3d, TextureFormat, TextureView,
};
#[derive(Debug)]
pub struct IntermediateTextureResources {
texture_view: TextureView,
bind_group: BindGroup,
bind_group_layout: BindGroupLayout,
intermediate_texture_initialized: AtomicBool,
}
impl IntermediateTextureResources {
pub(crate) fn new(size: Size, device: &Device) -> IntermediateTextureResources {
let intermediate_texture = device.create_texture(&wgpu::TextureDescriptor {
size: Extent3d {
width: size.width,
height: size.height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: TextureFormat::R16Float,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
label: None,
view_formats: &[],
});
let texture_view =
intermediate_texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT | wgpu::ShaderStages::COMPUTE,
ty: BindingType::Texture {
multisampled: false,
view_dimension: wgpu::TextureViewDimension::D2,
sample_type: wgpu::TextureSampleType::Float { filterable: true },
},
count: None,
},
BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT | wgpu::ShaderStages::COMPUTE,
ty: BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
],
label: Some("intermediate_texture_bind_group_layout"),
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[
BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(&texture_view),
},
BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&sampler),
},
],
label: Some("intermediate_texture_bind_group"),
});
IntermediateTextureResources {
texture_view,
bind_group,
bind_group_layout,
intermediate_texture_initialized: AtomicBool::new(false),
}
}
pub(crate) fn bind_group(&self) -> &BindGroup {
&self.bind_group
}
pub(crate) fn bind_group_layout(&self) -> &BindGroupLayout {
&self.bind_group_layout
}
pub(crate) fn texture_view(&self) -> &TextureView {
&self.texture_view
}
pub(crate) fn is_texture_initialized(&self) -> bool {
self.intermediate_texture_initialized
.load(Ordering::Relaxed)
}
pub(crate) fn assume_texture_initialized(&self) {
self.intermediate_texture_initialized
.store(true, Ordering::Relaxed);
}
}