maplibre/render/
main_pass.rs1use std::ops::Deref;
7
8use wgpu::StoreOp;
9
10use crate::{
11 render::{
12 draw_graph,
13 graph::{Node, NodeRunError, RenderContext, RenderGraphContext, SlotInfo},
14 render_phase::{LayerItem, RenderPhase, TileMaskItem},
15 resource::TrackedRenderPass,
16 Eventually::Initialized,
17 RenderResources,
18 },
19 tcs::world::World,
20};
21
22pub struct MainPassNode {}
23
24impl MainPassNode {
25 pub fn new() -> Self {
26 Self {}
27 }
28}
29
30impl Node for MainPassNode {
31 fn input(&self) -> Vec<SlotInfo> {
32 vec![]
33 }
34
35 fn update(&mut self, _state: &mut RenderResources) {}
36
37 fn run(
38 &self,
39 _graph: &mut RenderGraphContext,
40 render_context: &mut RenderContext,
41 state: &RenderResources,
42 world: &World,
43 ) -> Result<(), NodeRunError> {
44 let Initialized(render_target) = &state.render_target else {
45 return Ok(());
46 };
47 let Initialized(multisampling_texture) = &state.multisampling_texture else {
48 return Ok(());
49 };
50 let Initialized(depth_texture) = &state.depth_texture else {
51 return Ok(());
52 };
53
54 let color_attachment = if let Some(texture) = multisampling_texture {
55 wgpu::RenderPassColorAttachment {
56 view: &texture.view,
57 ops: wgpu::Operations {
58 load: wgpu::LoadOp::Clear(wgpu::Color {
59 r: 0.0,
60 g: 0.0,
61 b: 0.0,
62 a: 0.0,
63 }),
64 store: StoreOp::Store,
65 },
66 resolve_target: Some(render_target.deref()),
67 }
68 } else {
69 wgpu::RenderPassColorAttachment {
70 view: render_target.deref(),
71 ops: wgpu::Operations {
72 load: wgpu::LoadOp::Clear(wgpu::Color {
73 r: 0.0,
74 g: 0.0,
75 b: 0.0,
76 a: 0.0,
77 }),
78 store: StoreOp::Store,
79 },
80 resolve_target: None,
81 }
82 };
83
84 let render_pass =
85 render_context
86 .command_encoder
87 .begin_render_pass(&wgpu::RenderPassDescriptor {
88 label: Some("main_pass"),
89 color_attachments: &[Some(color_attachment)],
90 depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
91 view: &depth_texture.view,
92 depth_ops: Some(wgpu::Operations {
93 load: wgpu::LoadOp::Clear(0.0),
94 store: StoreOp::Store,
95 }),
96 stencil_ops: Some(wgpu::Operations {
97 load: wgpu::LoadOp::Clear(0),
98 store: StoreOp::Store,
99 }),
100 }),
101 timestamp_writes: None,
102 occlusion_query_set: None,
103 });
104
105 let mut tracked_pass = TrackedRenderPass::new(render_pass);
106
107 if let Some(mask_items) = world.resources.get::<RenderPhase<TileMaskItem>>() {
110 log::trace!("RenderPhase<TileMaskItem>::size() = {}", mask_items.size());
111 for item in mask_items {
112 item.draw_function.draw(&mut tracked_pass, world, item);
113 }
114 }
115
116 if let Some(layer_items) = world.resources.get::<RenderPhase<LayerItem>>() {
117 log::trace!("RenderPhase<LayerItem>::size() = {}", layer_items.size());
118
119 for item in layer_items {
124 item.draw_function.draw(&mut tracked_pass, world, item);
125 }
126 }
127
128 Ok(())
129 }
130}
131
132pub struct MainPassDriverNode;
133
134impl Node for MainPassDriverNode {
135 fn run(
136 &self,
137 graph: &mut RenderGraphContext,
138 _render_context: &mut RenderContext,
139 _resources: &RenderResources,
140 _world: &World,
141 ) -> Result<(), NodeRunError> {
142 graph.run_sub_graph(draw_graph::NAME, vec![])?;
143
144 Ok(())
145 }
146}