maplibre/render/systems/
resource_system.rs1use std::{borrow::Cow, mem};
4
5use crate::{
6 context::MapContext,
7 render::{
8 eventually::Eventually,
9 resource::{BackingBufferDescriptor, RenderPipeline, Texture, TilePipeline},
10 settings::Msaa,
11 shaders,
12 shaders::{Shader, ShaderTileMetadata},
13 tile_view_pattern::{TileViewPattern, WgpuTileViewPattern, DEFAULT_TILE_VIEW_PATTERN_SIZE},
14 MaskPipeline, Renderer,
15 },
16 tcs::system::{System, SystemError, SystemResult},
17};
18
19#[derive(Default)]
20pub struct ResourceSystem;
21
22impl System for ResourceSystem {
23 fn name(&self) -> Cow<'static, str> {
24 "resource_system".into()
25 }
26
27 fn run(
28 &mut self,
29 MapContext {
30 renderer:
31 Renderer {
32 settings,
33 device,
34 resources: state,
35 ..
36 },
37 world,
38 ..
39 }: &mut MapContext,
40 ) -> SystemResult {
41 let Some((tile_view_pattern, mask_pipeline)) = world.resources.query_mut::<(
42 &mut Eventually<WgpuTileViewPattern>,
43 &mut Eventually<MaskPipeline>,
44 )>() else {
45 return Err(SystemError::Dependencies);
46 };
47
48 let surface = &mut state.surface;
49
50 let size = surface.size();
51
52 surface.reconfigure(device);
53
54 state
55 .render_target
56 .initialize(|| surface.create_view(device));
57
58 state.depth_texture.reinitialize(
59 || {
60 Texture::new(
61 Some("depth texture"),
62 device,
63 settings.depth_texture_format,
64 size.width(),
65 size.height(),
66 if surface.is_multisampling_supported(settings.msaa) {
67 settings.msaa
68 } else {
69 Msaa { samples: 1 }
70 },
71 wgpu::TextureUsages::RENDER_ATTACHMENT,
72 )
73 },
74 &(size.width(), size.height()),
75 );
76
77 state.multisampling_texture.reinitialize(
78 || {
79 if settings.msaa.is_multisampling()
80 && surface.is_multisampling_supported(settings.msaa)
81 {
82 Some(Texture::new(
83 Some("multisampling texture"),
84 device,
85 surface.surface_format(),
86 size.width(),
87 size.height(),
88 settings.msaa,
89 wgpu::TextureUsages::RENDER_ATTACHMENT,
90 ))
91 } else {
92 None
93 }
94 },
95 &(size.width(), size.height()),
96 );
97
98 tile_view_pattern.initialize(|| {
99 let tile_view_buffer_desc = wgpu::BufferDescriptor {
100 label: Some("tile view buffer"),
101 size: mem::size_of::<ShaderTileMetadata>() as wgpu::BufferAddress
102 * DEFAULT_TILE_VIEW_PATTERN_SIZE,
103 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
104 mapped_at_creation: false,
105 };
106
107 TileViewPattern::new(BackingBufferDescriptor::new(
108 device.create_buffer(&tile_view_buffer_desc),
109 tile_view_buffer_desc.size,
110 ))
111 });
112
113 mask_pipeline.initialize(|| {
114 let mask_shader = shaders::TileMaskShader {
115 format: surface.surface_format(),
116 draw_colors: false,
117 debug_lines: false,
118 };
119
120 let pipeline = TilePipeline::new(
121 "mask_pipeline".into(),
122 *settings,
123 mask_shader.describe_vertex(),
124 mask_shader.describe_fragment(),
125 true,
126 true,
127 false,
128 false,
129 surface.is_multisampling_supported(settings.msaa),
130 false,
131 false,
132 )
133 .describe_render_pipeline()
134 .initialize(device);
135 MaskPipeline(pipeline)
136 });
137
138 Ok(())
139 }
140}