use crate::kvasir::node::{ExecutionContext, KvasirNode};
use crate::kvasir::nodes::{PassId, RES_BLOOM_A, RES_SCENE, RES_SWAPCHAIN};
use crate::kvasir::resource::ResourceId;
pub struct CompositeNode {
pub inputs: Vec<ResourceId>,
pub outputs: Vec<ResourceId>,
pub has_bloom: bool,
pub clear_target: bool,
}
impl CompositeNode {
pub fn new(has_bloom: bool, clear_target: bool) -> Self {
Self {
inputs: if has_bloom {
vec![RES_SCENE, RES_BLOOM_A]
} else {
vec![RES_SCENE]
},
outputs: vec![RES_SWAPCHAIN],
has_bloom,
clear_target,
}
}
}
impl KvasirNode for CompositeNode {
fn label(&self) -> &'static str {
"Composite"
}
fn inputs(&self) -> &[ResourceId] {
&self.inputs
}
fn outputs(&self) -> &[ResourceId] {
&self.outputs
}
fn pass_id(&self) -> PassId {
PassId::Composite
}
fn execute(&self, ctx: &mut ExecutionContext) {
let target_view = ctx.target_view;
let scene_view = match ctx.registry.get_texture_view(RES_SCENE) {
Some(v) => v,
None => {
tracing::error!("Missing texture view for {}", stringify!(RES_SCENE));
return;
}
};
let scene_texture_bind_group = ctx.get_or_create_bind_group(
(RES_SCENE, 1, false),
&ctx.renderer.texture_bind_group_layout,
&[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureViewArray(&vec![&scene_view; 32]),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&ctx.renderer.dummy_sampler),
},
],
Some("composite_scene_bg"),
);
let mut p = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Surtr P7 Composite"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: target_view,
resolve_target: None,
ops: wgpu::Operations {
load: if self.clear_target {
wgpu::LoadOp::Clear(wgpu::Color {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
})
} else {
wgpu::LoadOp::Load
},
store: wgpu::StoreOp::Store,
},
depth_slice: None,
})],
depth_stencil_attachment: None,
timestamp_writes: ctx.renderer.skuld_queries.as_ref().map(|q| {
wgpu::RenderPassTimestampWrites {
query_set: q,
beginning_of_pass_write_index: None,
end_of_pass_write_index: Some(1),
}
}),
occlusion_query_set: None,
multiview_mask: None,
});
p.set_pipeline(&ctx.renderer.composite_pipeline);
let dummy_bg = &ctx.renderer.dummy_env_bind_group;
if self.has_bloom {
p.set_bind_group(1, ctx.bloom_env_bind_group_a, &[]);
} else {
p.set_bind_group(1, dummy_bg, &[]);
}
p.set_bind_group(0, &scene_texture_bind_group, &[]);
p.set_bind_group(2, &ctx.renderer.berserker_bind_group, &[]);
p.set_bind_group(3, &ctx.renderer.gradient_bind_group, &[]);
p.draw(0..3, 0..1);
}
}