cvkg_render_gpu/passes/
composite.rs1use crate::kvasir::node::{ExecutionContext, KvasirNode};
2use crate::kvasir::nodes::{PassId, RES_BLOOM_A, RES_SCENE, RES_SWAPCHAIN};
3use crate::kvasir::resource::ResourceId;
4
5pub struct CompositeNode {
6 pub inputs: Vec<ResourceId>,
7 pub outputs: Vec<ResourceId>,
8 pub has_bloom: bool,
9 pub clear_target: bool,
12}
13
14impl CompositeNode {
15 pub fn new(has_bloom: bool, clear_target: bool) -> Self {
16 Self {
17 inputs: if has_bloom {
18 vec![RES_SCENE, RES_BLOOM_A]
19 } else {
20 vec![RES_SCENE]
21 },
22 outputs: vec![RES_SWAPCHAIN],
23 has_bloom,
24 clear_target,
25 }
26 }
27}
28
29impl KvasirNode for CompositeNode {
30 fn label(&self) -> &'static str {
31 "Composite"
32 }
33
34 fn inputs(&self) -> &[ResourceId] {
35 &self.inputs
36 }
37
38 fn outputs(&self) -> &[ResourceId] {
39 &self.outputs
40 }
41
42 fn pass_id(&self) -> PassId {
43 PassId::Composite
44 }
45
46 fn execute(&self, ctx: &mut ExecutionContext) {
47 let target_view = ctx.target_view;
48
49 let scene_view = match ctx.registry.get_texture_view(RES_SCENE) {
51 Some(v) => v,
52 None => {
53 log::error!("Missing texture view for {}", stringify!(RES_SCENE));
54 return;
55 }
56 };
57 let scene_texture_bind_group = ctx.get_or_create_bind_group(
58 (RES_SCENE, 1, false),
59 &ctx.renderer.texture_bind_group_layout,
60 &[
61 wgpu::BindGroupEntry {
62 binding: 0,
63 resource: wgpu::BindingResource::TextureViewArray(&vec![&scene_view; 32]),
64 },
65 wgpu::BindGroupEntry {
66 binding: 1,
67 resource: wgpu::BindingResource::Sampler(&ctx.renderer.dummy_sampler),
68 },
69 ],
70 Some("composite_scene_bg"),
71 );
72
73 let mut p = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
74 label: Some("Surtr P7 Composite"),
75 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
76 view: target_view,
77 resolve_target: None,
78 ops: wgpu::Operations {
79 load: if self.clear_target {
80 wgpu::LoadOp::Clear(wgpu::Color {
81 r: 0.0,
82 g: 0.0,
83 b: 0.0,
84 a: 1.0,
85 })
86 } else {
87 wgpu::LoadOp::Load
89 },
90 store: wgpu::StoreOp::Store,
91 },
92 depth_slice: None,
93 })],
94 depth_stencil_attachment: None,
95 timestamp_writes: ctx.renderer.skuld_queries.as_ref().map(|q| {
96 wgpu::RenderPassTimestampWrites {
97 query_set: q,
98 beginning_of_pass_write_index: None,
99 end_of_pass_write_index: Some(1),
100 }
101 }),
102 occlusion_query_set: None,
103 multiview_mask: None,
104 });
105
106 p.set_pipeline(&ctx.renderer.composite_pipeline);
107
108 let dummy_bg = &ctx.renderer.dummy_env_bind_group;
109 if self.has_bloom {
110 p.set_bind_group(1, ctx.bloom_env_bind_group_a, &[]);
111 } else {
112 p.set_bind_group(1, dummy_bg, &[]);
113 }
114
115 p.set_bind_group(0, &scene_texture_bind_group, &[]);
116 p.set_bind_group(2, &ctx.renderer.berserker_bind_group, &[]);
117 p.set_bind_group(3, &ctx.renderer.gradient_bind_group, &[]);
118 p.draw(0..3, 0..1);
119 }
120}