use core::ops::DerefMut;
use unlit_ecs::World;
use unlit_wgpu::render_attachments::{create_depth_target, create_msaa_target};
use unlit_wgpu::resources::{ResHandle, ResourceGraph, TextureExt, TextureView};
use crate::source::RenderContext;
fn context_device(world: &World, ctx: RenderContext) -> wgpu::Device {
world
.root_scope()
.query_one::<&wgpu::Device>(ctx.device)
.expect("the context's device resource exists")
.clone()
}
fn context_graph<'w>(
world: &'w World,
ctx: RenderContext,
) -> impl DerefMut<Target = ResourceGraph> + 'w {
world
.root_scope()
.query_one::<&mut ResourceGraph>(ctx.graph)
.expect("the context's resource graph exists")
}
pub struct FrameAttachments {
ctx: RenderContext,
format: wgpu::TextureFormat,
size: (u32, u32),
sample_count: u32,
pub depth_view: Option<ResHandle<TextureView>>,
pub msaa_view: Option<ResHandle<TextureView>>,
}
impl FrameAttachments {
pub fn new(
world: &World,
ctx: RenderContext,
format: wgpu::TextureFormat,
size: (u32, u32),
sample_count: u32,
with_depth: bool,
) -> Self {
let device = context_device(world, ctx);
let mut graph = context_graph(world, ctx);
let depth_view = with_depth.then(|| {
let texture = create_depth_target(&device, size.0, size.1, sample_count);
graph.insert(
TextureExt::create_view(&texture, &wgpu::TextureViewDescriptor::default()),
None,
)
});
let msaa_view = (sample_count > 1).then(|| {
let texture = create_msaa_target(&device, format, size.0, size.1, sample_count);
graph.insert(
TextureExt::create_view(&texture, &wgpu::TextureViewDescriptor::default()),
None,
)
});
Self {
ctx,
format,
size,
sample_count,
depth_view,
msaa_view,
}
}
pub fn resize(&mut self, world: &World, size: (u32, u32)) {
if size == self.size {
return;
}
self.size = size;
let device = context_device(world, self.ctx);
let mut graph = context_graph(world, self.ctx);
if let Some(id) = self.depth_view.as_ref() {
let texture = create_depth_target(&device, size.0, size.1, self.sample_count);
graph
.replace(
id,
TextureExt::create_view(&texture, &wgpu::TextureViewDescriptor::default()),
)
.expect("the depth view is in the graph");
}
if let Some(id) = self.msaa_view.as_ref() {
let texture =
create_msaa_target(&device, self.format, size.0, size.1, self.sample_count);
graph
.replace(
id,
TextureExt::create_view(&texture, &wgpu::TextureViewDescriptor::default()),
)
.expect("the multisample view is in the graph");
}
graph.maintain();
}
}