1use super::{instance_manager::InstanceManager, meshlet_mesh_manager::MeshletMeshManager};
2use crate::ShadowView;
3use bevy_camera::{visibility::RenderLayers, Camera3d};
4use bevy_core_pipeline::{
5 experimental::mip_generation::{self, ViewDepthPyramid},
6 prepass::{PreviousViewData, PreviousViewUniforms},
7};
8use bevy_ecs::{
9 component::Component,
10 entity::{Entity, EntityHashMap},
11 query::AnyOf,
12 resource::Resource,
13 system::{Commands, Query, Res, ResMut},
14};
15use bevy_image::ToExtents;
16use bevy_math::{UVec2, Vec4Swizzles};
17use bevy_render::{
18 render_resource::*,
19 renderer::{RenderDevice, RenderQueue},
20 texture::{CachedTexture, TextureCache},
21 view::{ExtractedView, ViewUniform, ViewUniforms},
22};
23use binding_types::*;
24use core::iter;
25
26#[derive(Resource)]
28pub struct ResourceManager {
29 visibility_buffer_raster_clusters: Buffer,
31 pub visibility_buffer_raster_cluster_prev_counts: Buffer,
33 software_raster_cluster_count: Buffer,
35 bvh_traversal_queues: [Buffer; 2],
37 cluster_cull_candidate_queue: Buffer,
39 cull_queue_rightmost_slot: u32,
41
42 second_pass_candidates: Option<Buffer>,
44 depth_pyramid_sampler: Sampler,
46 depth_pyramid_dummy_texture: TextureView,
48
49 previous_depth_pyramids: EntityHashMap<TextureView>,
51
52 pub clear_visibility_buffer_bind_group_layout: BindGroupLayoutDescriptor,
54 pub clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayoutDescriptor,
55 pub first_instance_cull_bind_group_layout: BindGroupLayoutDescriptor,
56 pub second_instance_cull_bind_group_layout: BindGroupLayoutDescriptor,
57 pub first_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor,
58 pub second_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor,
59 pub first_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor,
60 pub second_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor,
61 pub visibility_buffer_raster_bind_group_layout: BindGroupLayoutDescriptor,
62 pub visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayoutDescriptor,
63 pub downsample_depth_bind_group_layout: BindGroupLayoutDescriptor,
64 pub downsample_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor,
65 pub resolve_depth_bind_group_layout: BindGroupLayoutDescriptor,
66 pub resolve_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor,
67 pub resolve_material_depth_bind_group_layout: BindGroupLayoutDescriptor,
68 pub material_shade_bind_group_layout: BindGroupLayoutDescriptor,
69 pub fill_counts_bind_group_layout: BindGroupLayoutDescriptor,
70 pub remap_1d_to_2d_dispatch_bind_group_layout: Option<BindGroupLayoutDescriptor>,
71}
72
73impl ResourceManager {
74 pub fn new(cluster_buffer_slots: u32, render_device: &RenderDevice) -> Self {
75 let needs_dispatch_remap =
76 cluster_buffer_slots > render_device.limits().max_compute_workgroups_per_dimension;
77 let cull_queue_size = 2 * cluster_buffer_slots as u64 * size_of::<u32>() as u64;
79
80 Self {
81 visibility_buffer_raster_clusters: render_device.create_buffer(&BufferDescriptor {
82 label: Some("meshlet_visibility_buffer_raster_clusters"),
83 size: cull_queue_size,
84 usage: BufferUsages::STORAGE,
85 mapped_at_creation: false,
86 }),
87 visibility_buffer_raster_cluster_prev_counts: render_device.create_buffer(
88 &BufferDescriptor {
89 label: Some("meshlet_visibility_buffer_raster_cluster_prev_counts"),
90 size: size_of::<u32>() as u64 * 2,
91 usage: BufferUsages::STORAGE | BufferUsages::COPY_DST,
92 mapped_at_creation: false,
93 },
94 ),
95 software_raster_cluster_count: render_device.create_buffer(&BufferDescriptor {
96 label: Some("meshlet_software_raster_cluster_count"),
97 size: size_of::<u32>() as u64,
98 usage: BufferUsages::STORAGE,
99 mapped_at_creation: false,
100 }),
101 bvh_traversal_queues: [
102 render_device.create_buffer(&BufferDescriptor {
103 label: Some("meshlet_bvh_traversal_queue_0"),
104 size: cull_queue_size,
105 usage: BufferUsages::STORAGE,
106 mapped_at_creation: false,
107 }),
108 render_device.create_buffer(&BufferDescriptor {
109 label: Some("meshlet_bvh_traversal_queue_1"),
110 size: cull_queue_size,
111 usage: BufferUsages::STORAGE,
112 mapped_at_creation: false,
113 }),
114 ],
115 cluster_cull_candidate_queue: render_device.create_buffer(&BufferDescriptor {
116 label: Some("meshlet_cluster_cull_candidate_queue"),
117 size: cull_queue_size,
118 usage: BufferUsages::STORAGE,
119 mapped_at_creation: false,
120 }),
121 cull_queue_rightmost_slot: cluster_buffer_slots - 1,
122
123 second_pass_candidates: None,
124 depth_pyramid_sampler: render_device.create_sampler(&SamplerDescriptor {
125 label: Some("meshlet_depth_pyramid_sampler"),
126 ..SamplerDescriptor::default()
127 }),
128 depth_pyramid_dummy_texture: mip_generation::create_depth_pyramid_dummy_texture(
129 render_device,
130 "meshlet_depth_pyramid_dummy_texture",
131 "meshlet_depth_pyramid_dummy_texture_view",
132 ),
133
134 previous_depth_pyramids: EntityHashMap::default(),
135
136 clear_visibility_buffer_bind_group_layout: BindGroupLayoutDescriptor::new(
138 "meshlet_clear_visibility_buffer_bind_group_layout",
139 &BindGroupLayoutEntries::single(
140 ShaderStages::COMPUTE,
141 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::WriteOnly),
142 ),
143 ),
144 clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new(
145 "meshlet_clear_visibility_buffer_shadow_view_bind_group_layout",
146 &BindGroupLayoutEntries::single(
147 ShaderStages::COMPUTE,
148 texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::WriteOnly),
149 ),
150 ),
151 first_instance_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
152 "meshlet_first_instance_culling_bind_group_layout",
153 &BindGroupLayoutEntries::sequential(
154 ShaderStages::COMPUTE,
155 (
156 texture_2d(TextureSampleType::Float { filterable: false }),
157 uniform_buffer::<ViewUniform>(true),
158 uniform_buffer::<PreviousViewData>(true),
159 storage_buffer_read_only_sized(false, None),
160 storage_buffer_read_only_sized(false, None),
161 storage_buffer_read_only_sized(false, None),
162 storage_buffer_read_only_sized(false, None),
163 storage_buffer_sized(false, None),
164 storage_buffer_sized(false, None),
165 storage_buffer_sized(false, None),
166 storage_buffer_sized(false, None),
167 storage_buffer_sized(false, None),
168 storage_buffer_sized(false, None),
169 ),
170 ),
171 ),
172 second_instance_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
173 "meshlet_second_instance_culling_bind_group_layout",
174 &BindGroupLayoutEntries::sequential(
175 ShaderStages::COMPUTE,
176 (
177 texture_2d(TextureSampleType::Float { filterable: false }),
178 uniform_buffer::<ViewUniform>(true),
179 uniform_buffer::<PreviousViewData>(true),
180 storage_buffer_read_only_sized(false, None),
181 storage_buffer_read_only_sized(false, None),
182 storage_buffer_read_only_sized(false, None),
183 storage_buffer_read_only_sized(false, None),
184 storage_buffer_sized(false, None),
185 storage_buffer_sized(false, None),
186 storage_buffer_sized(false, None),
187 storage_buffer_read_only_sized(false, None),
188 storage_buffer_read_only_sized(false, None),
189 ),
190 ),
191 ),
192 first_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
193 "meshlet_first_bvh_culling_bind_group_layout",
194 &BindGroupLayoutEntries::sequential(
195 ShaderStages::COMPUTE,
196 (
197 texture_2d(TextureSampleType::Float { filterable: false }),
198 uniform_buffer::<ViewUniform>(true),
199 uniform_buffer::<PreviousViewData>(true),
200 storage_buffer_read_only_sized(false, None),
201 storage_buffer_read_only_sized(false, None),
202 storage_buffer_read_only_sized(false, None),
203 storage_buffer_sized(false, None),
204 storage_buffer_sized(false, None),
205 storage_buffer_sized(false, None),
206 storage_buffer_sized(false, None),
207 storage_buffer_sized(false, None),
208 storage_buffer_sized(false, None),
209 storage_buffer_sized(false, None),
210 storage_buffer_sized(false, None),
211 storage_buffer_sized(false, None),
212 storage_buffer_sized(false, None),
213 storage_buffer_sized(false, None),
214 ),
215 ),
216 ),
217 second_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
218 "meshlet_second_bvh_culling_bind_group_layout",
219 &BindGroupLayoutEntries::sequential(
220 ShaderStages::COMPUTE,
221 (
222 texture_2d(TextureSampleType::Float { filterable: false }),
223 uniform_buffer::<ViewUniform>(true),
224 uniform_buffer::<PreviousViewData>(true),
225 storage_buffer_read_only_sized(false, None),
226 storage_buffer_read_only_sized(false, None),
227 storage_buffer_read_only_sized(false, None),
228 storage_buffer_sized(false, None),
229 storage_buffer_sized(false, None),
230 storage_buffer_sized(false, None),
231 storage_buffer_sized(false, None),
232 storage_buffer_sized(false, None),
233 storage_buffer_sized(false, None),
234 storage_buffer_sized(false, None),
235 storage_buffer_sized(false, None),
236 ),
237 ),
238 ),
239 first_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
240 "meshlet_first_meshlet_culling_bind_group_layout",
241 &BindGroupLayoutEntries::sequential(
242 ShaderStages::COMPUTE,
243 (
244 texture_2d(TextureSampleType::Float { filterable: false }),
245 uniform_buffer::<ViewUniform>(true),
246 uniform_buffer::<PreviousViewData>(true),
247 storage_buffer_read_only_sized(false, None),
248 storage_buffer_read_only_sized(false, None),
249 storage_buffer_sized(false, None),
250 storage_buffer_sized(false, None),
251 storage_buffer_read_only_sized(false, None),
252 storage_buffer_sized(false, None),
253 storage_buffer_read_only_sized(false, None),
254 storage_buffer_sized(false, None),
255 storage_buffer_sized(false, None),
256 storage_buffer_sized(false, None),
257 ),
258 ),
259 ),
260 second_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor::new(
261 "meshlet_second_meshlet_culling_bind_group_layout",
262 &BindGroupLayoutEntries::sequential(
263 ShaderStages::COMPUTE,
264 (
265 texture_2d(TextureSampleType::Float { filterable: false }),
266 uniform_buffer::<ViewUniform>(true),
267 uniform_buffer::<PreviousViewData>(true),
268 storage_buffer_read_only_sized(false, None),
269 storage_buffer_read_only_sized(false, None),
270 storage_buffer_sized(false, None),
271 storage_buffer_sized(false, None),
272 storage_buffer_read_only_sized(false, None),
273 storage_buffer_sized(false, None),
274 storage_buffer_read_only_sized(false, None),
275 storage_buffer_read_only_sized(false, None),
276 ),
277 ),
278 ),
279 downsample_depth_bind_group_layout: BindGroupLayoutDescriptor::new(
280 "meshlet_downsample_depth_bind_group_layout",
281 &BindGroupLayoutEntries::sequential(ShaderStages::COMPUTE, {
282 let write_only_r32float = || {
283 texture_storage_2d(TextureFormat::R32Float, StorageTextureAccess::WriteOnly)
284 };
285 (
286 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::ReadOnly),
287 write_only_r32float(),
288 write_only_r32float(),
289 write_only_r32float(),
290 write_only_r32float(),
291 write_only_r32float(),
292 texture_storage_2d(
293 TextureFormat::R32Float,
294 StorageTextureAccess::ReadWrite,
295 ),
296 write_only_r32float(),
297 write_only_r32float(),
298 write_only_r32float(),
299 write_only_r32float(),
300 write_only_r32float(),
301 write_only_r32float(),
302 sampler(SamplerBindingType::NonFiltering),
303 )
304 }),
305 ),
306 downsample_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new(
307 "meshlet_downsample_depth_shadow_view_bind_group_layout",
308 &BindGroupLayoutEntries::sequential(ShaderStages::COMPUTE, {
309 let write_only_r32float = || {
310 texture_storage_2d(TextureFormat::R32Float, StorageTextureAccess::WriteOnly)
311 };
312 (
313 texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::ReadOnly),
314 write_only_r32float(),
315 write_only_r32float(),
316 write_only_r32float(),
317 write_only_r32float(),
318 write_only_r32float(),
319 texture_storage_2d(
320 TextureFormat::R32Float,
321 StorageTextureAccess::ReadWrite,
322 ),
323 write_only_r32float(),
324 write_only_r32float(),
325 write_only_r32float(),
326 write_only_r32float(),
327 write_only_r32float(),
328 write_only_r32float(),
329 sampler(SamplerBindingType::NonFiltering),
330 )
331 }),
332 ),
333 visibility_buffer_raster_bind_group_layout: BindGroupLayoutDescriptor::new(
334 "meshlet_visibility_buffer_raster_bind_group_layout",
335 &BindGroupLayoutEntries::sequential(
336 ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE,
337 (
338 storage_buffer_read_only_sized(false, None),
339 storage_buffer_read_only_sized(false, None),
340 storage_buffer_read_only_sized(false, None),
341 storage_buffer_read_only_sized(false, None),
342 storage_buffer_read_only_sized(false, None),
343 storage_buffer_read_only_sized(false, None),
344 storage_buffer_read_only_sized(false, None),
345 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::Atomic),
346 uniform_buffer::<ViewUniform>(true),
347 ),
348 ),
349 ),
350 visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new(
351 "meshlet_visibility_buffer_raster_shadow_view_bind_group_layout",
352 &BindGroupLayoutEntries::sequential(
353 ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE,
354 (
355 storage_buffer_read_only_sized(false, None),
356 storage_buffer_read_only_sized(false, None),
357 storage_buffer_read_only_sized(false, None),
358 storage_buffer_read_only_sized(false, None),
359 storage_buffer_read_only_sized(false, None),
360 storage_buffer_read_only_sized(false, None),
361 storage_buffer_read_only_sized(false, None),
362 texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::Atomic),
363 uniform_buffer::<ViewUniform>(true),
364 ),
365 ),
366 ),
367 resolve_depth_bind_group_layout: BindGroupLayoutDescriptor::new(
368 "meshlet_resolve_depth_bind_group_layout",
369 &BindGroupLayoutEntries::single(
370 ShaderStages::FRAGMENT,
371 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::ReadOnly),
372 ),
373 ),
374 resolve_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new(
375 "meshlet_resolve_depth_shadow_view_bind_group_layout",
376 &BindGroupLayoutEntries::single(
377 ShaderStages::FRAGMENT,
378 texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::ReadOnly),
379 ),
380 ),
381 resolve_material_depth_bind_group_layout: BindGroupLayoutDescriptor::new(
382 "meshlet_resolve_material_depth_bind_group_layout",
383 &BindGroupLayoutEntries::sequential(
384 ShaderStages::FRAGMENT,
385 (
386 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::ReadOnly),
387 storage_buffer_read_only_sized(false, None),
388 storage_buffer_read_only_sized(false, None),
389 ),
390 ),
391 ),
392 material_shade_bind_group_layout: BindGroupLayoutDescriptor::new(
393 "meshlet_mesh_material_shade_bind_group_layout",
394 &BindGroupLayoutEntries::sequential(
395 ShaderStages::FRAGMENT,
396 (
397 texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::ReadOnly),
398 storage_buffer_read_only_sized(false, None),
399 storage_buffer_read_only_sized(false, None),
400 storage_buffer_read_only_sized(false, None),
401 storage_buffer_read_only_sized(false, None),
402 storage_buffer_read_only_sized(false, None),
403 storage_buffer_read_only_sized(false, None),
404 storage_buffer_read_only_sized(false, None),
405 ),
406 ),
407 ),
408 fill_counts_bind_group_layout: if needs_dispatch_remap {
409 BindGroupLayoutDescriptor::new(
410 "meshlet_fill_counts_bind_group_layout",
411 &BindGroupLayoutEntries::sequential(
412 ShaderStages::COMPUTE,
413 (
414 storage_buffer_sized(false, None),
415 storage_buffer_sized(false, None),
416 storage_buffer_sized(false, None),
417 storage_buffer_sized(false, None),
418 ),
419 ),
420 )
421 } else {
422 BindGroupLayoutDescriptor::new(
423 "meshlet_fill_counts_bind_group_layout",
424 &BindGroupLayoutEntries::sequential(
425 ShaderStages::COMPUTE,
426 (
427 storage_buffer_sized(false, None),
428 storage_buffer_sized(false, None),
429 storage_buffer_sized(false, None),
430 ),
431 ),
432 )
433 },
434 remap_1d_to_2d_dispatch_bind_group_layout: needs_dispatch_remap.then(|| {
435 BindGroupLayoutDescriptor::new(
436 "meshlet_remap_1d_to_2d_dispatch_bind_group_layout",
437 &BindGroupLayoutEntries::sequential(
438 ShaderStages::COMPUTE,
439 (
440 storage_buffer_sized(false, None),
441 storage_buffer_sized(false, None),
442 ),
443 ),
444 )
445 }),
446 }
447 }
448}
449
450#[derive(Component)]
453pub struct MeshletViewResources {
454 pub scene_instance_count: u32,
455 pub rightmost_slot: u32,
456 pub max_bvh_depth: u32,
457 instance_visibility: Buffer,
458 pub dummy_render_target: CachedTexture,
459 pub visibility_buffer: CachedTexture,
460 pub second_pass_count: Buffer,
461 pub second_pass_dispatch: Buffer,
462 pub second_pass_candidates: Buffer,
463 pub first_bvh_cull_count_front: Buffer,
464 pub first_bvh_cull_dispatch_front: Buffer,
465 pub first_bvh_cull_count_back: Buffer,
466 pub first_bvh_cull_dispatch_back: Buffer,
467 pub first_bvh_cull_queue: Buffer,
468 pub second_bvh_cull_count_front: Buffer,
469 pub second_bvh_cull_dispatch_front: Buffer,
470 pub second_bvh_cull_count_back: Buffer,
471 pub second_bvh_cull_dispatch_back: Buffer,
472 pub second_bvh_cull_queue: Buffer,
473 pub front_meshlet_cull_count: Buffer,
474 pub front_meshlet_cull_dispatch: Buffer,
475 pub back_meshlet_cull_count: Buffer,
476 pub back_meshlet_cull_dispatch: Buffer,
477 pub meshlet_cull_queue: Buffer,
478 pub visibility_buffer_software_raster_indirect_args: Buffer,
479 pub visibility_buffer_hardware_raster_indirect_args: Buffer,
480 pub depth_pyramid: ViewDepthPyramid,
481 previous_depth_pyramid: TextureView,
482 pub material_depth: Option<CachedTexture>,
483 pub view_size: UVec2,
484 not_shadow_view: bool,
485}
486
487#[derive(Component)]
488pub struct MeshletViewBindGroups {
489 pub clear_visibility_buffer: BindGroup,
490 pub first_instance_cull: BindGroup,
491 pub second_instance_cull: BindGroup,
492 pub first_bvh_cull_ping: BindGroup,
493 pub first_bvh_cull_pong: BindGroup,
494 pub second_bvh_cull_ping: BindGroup,
495 pub second_bvh_cull_pong: BindGroup,
496 pub first_meshlet_cull: BindGroup,
497 pub second_meshlet_cull: BindGroup,
498 pub downsample_depth: BindGroup,
499 pub visibility_buffer_raster: BindGroup,
500 pub resolve_depth: BindGroup,
501 pub resolve_material_depth: Option<BindGroup>,
502 pub material_shade: Option<BindGroup>,
503 pub remap_1d_to_2d_dispatch: Option<BindGroup>,
504 pub fill_counts: BindGroup,
505}
506
507pub fn prepare_meshlet_per_frame_resources(
509 mut resource_manager: ResMut<ResourceManager>,
510 mut instance_manager: ResMut<InstanceManager>,
511 views: Query<(
512 Entity,
513 &ExtractedView,
514 Option<&RenderLayers>,
515 AnyOf<(&Camera3d, &ShadowView)>,
516 )>,
517 mut texture_cache: ResMut<TextureCache>,
518 render_queue: Res<RenderQueue>,
519 render_device: Res<RenderDevice>,
520 mut commands: Commands,
521) {
522 if instance_manager.scene_instance_count == 0 {
523 return;
524 }
525
526 let instance_manager = instance_manager.as_mut();
527
528 instance_manager
530 .instance_uniforms
531 .write_buffer(&render_device, &render_queue);
532 instance_manager
533 .instance_aabbs
534 .write_buffer(&render_device, &render_queue);
535 instance_manager
536 .instance_material_ids
537 .write_buffer(&render_device, &render_queue);
538 instance_manager
539 .instance_bvh_root_nodes
540 .write_buffer(&render_device, &render_queue);
541
542 let needed_buffer_size = 4 * instance_manager.scene_instance_count as u64;
543 let second_pass_candidates = match &mut resource_manager.second_pass_candidates {
544 Some(buffer) if buffer.size() >= needed_buffer_size => buffer.clone(),
545 slot => {
546 let buffer = render_device.create_buffer(&BufferDescriptor {
547 label: Some("meshlet_second_pass_candidates"),
548 size: needed_buffer_size,
549 usage: BufferUsages::STORAGE,
550 mapped_at_creation: false,
551 });
552 *slot = Some(buffer.clone());
553 buffer
554 }
555 };
556
557 for (view_entity, view, render_layers, (_, shadow_view)) in &views {
558 let not_shadow_view = shadow_view.is_none();
559
560 let instance_visibility = instance_manager
561 .view_instance_visibility
562 .entry(view_entity)
563 .or_insert_with(|| {
564 let mut buffer = StorageBuffer::default();
565 buffer.set_label(Some("meshlet_view_instance_visibility"));
566 buffer
567 });
568 for (instance_index, (_, layers, not_shadow_caster)) in
569 instance_manager.instances.iter().enumerate()
570 {
571 if !render_layers
574 .unwrap_or(&RenderLayers::default())
575 .intersects(layers)
576 || (shadow_view.is_some() && *not_shadow_caster)
577 {
578 let vec = instance_visibility.get_mut();
579 let index = instance_index / 32;
580 let bit = instance_index - index * 32;
581 if vec.len() <= index {
582 vec.extend(iter::repeat_n(0, index - vec.len() + 1));
583 }
584 vec[index] |= 1 << bit;
585 }
586 }
587 instance_visibility.write_buffer(&render_device, &render_queue);
588 let instance_visibility = instance_visibility.buffer().unwrap().clone();
589
590 let dummy_render_target = texture_cache.get(
592 &render_device,
593 TextureDescriptor {
594 label: Some("meshlet_dummy_render_target"),
595 size: view.viewport.zw().to_extents(),
596 mip_level_count: 1,
597 sample_count: 1,
598 dimension: TextureDimension::D2,
599 format: TextureFormat::R8Uint,
600 usage: TextureUsages::RENDER_ATTACHMENT,
601 view_formats: &[],
602 },
603 );
604
605 let visibility_buffer = texture_cache.get(
606 &render_device,
607 TextureDescriptor {
608 label: Some("meshlet_visibility_buffer"),
609 size: view.viewport.zw().to_extents(),
610 mip_level_count: 1,
611 sample_count: 1,
612 dimension: TextureDimension::D2,
613 format: if not_shadow_view {
614 TextureFormat::R64Uint
615 } else {
616 TextureFormat::R32Uint
617 },
618 usage: TextureUsages::STORAGE_ATOMIC | TextureUsages::STORAGE_BINDING,
619 view_formats: &[],
620 },
621 );
622
623 let second_pass_count = render_device.create_buffer_with_data(&BufferInitDescriptor {
624 label: Some("meshlet_second_pass_count"),
625 contents: bytemuck::bytes_of(&0u32),
626 usage: BufferUsages::STORAGE,
627 });
628 let second_pass_dispatch = render_device.create_buffer_with_data(&BufferInitDescriptor {
629 label: Some("meshlet_second_pass_dispatch"),
630 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
631 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT,
632 });
633
634 let first_bvh_cull_count_front =
635 render_device.create_buffer_with_data(&BufferInitDescriptor {
636 label: Some("meshlet_first_bvh_cull_count_front"),
637 contents: bytemuck::bytes_of(&0u32),
638 usage: BufferUsages::STORAGE | BufferUsages::COPY_DST,
639 });
640 let first_bvh_cull_dispatch_front =
641 render_device.create_buffer_with_data(&BufferInitDescriptor {
642 label: Some("meshlet_first_bvh_cull_dispatch_front"),
643 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
644 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT | BufferUsages::COPY_DST,
645 });
646 let first_bvh_cull_count_back =
647 render_device.create_buffer_with_data(&BufferInitDescriptor {
648 label: Some("meshlet_first_bvh_cull_count_back"),
649 contents: bytemuck::bytes_of(&0u32),
650 usage: BufferUsages::STORAGE | BufferUsages::COPY_DST,
651 });
652 let first_bvh_cull_dispatch_back =
653 render_device.create_buffer_with_data(&BufferInitDescriptor {
654 label: Some("meshlet_first_bvh_cull_dispatch_back"),
655 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
656 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT | BufferUsages::COPY_DST,
657 });
658
659 let second_bvh_cull_count_front =
660 render_device.create_buffer_with_data(&BufferInitDescriptor {
661 label: Some("meshlet_second_bvh_cull_count_front"),
662 contents: bytemuck::bytes_of(&0u32),
663 usage: BufferUsages::STORAGE | BufferUsages::COPY_DST,
664 });
665 let second_bvh_cull_dispatch_front =
666 render_device.create_buffer_with_data(&BufferInitDescriptor {
667 label: Some("meshlet_second_bvh_cull_dispatch_front"),
668 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
669 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT | BufferUsages::COPY_DST,
670 });
671 let second_bvh_cull_count_back =
672 render_device.create_buffer_with_data(&BufferInitDescriptor {
673 label: Some("meshlet_second_bvh_cull_count_back"),
674 contents: bytemuck::bytes_of(&0u32),
675 usage: BufferUsages::STORAGE | BufferUsages::COPY_DST,
676 });
677 let second_bvh_cull_dispatch_back =
678 render_device.create_buffer_with_data(&BufferInitDescriptor {
679 label: Some("meshlet_second_bvh_cull_dispatch_back"),
680 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
681 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT | BufferUsages::COPY_DST,
682 });
683
684 let front_meshlet_cull_count =
685 render_device.create_buffer_with_data(&BufferInitDescriptor {
686 label: Some("meshlet_front_meshlet_cull_count"),
687 contents: bytemuck::bytes_of(&0u32),
688 usage: BufferUsages::STORAGE,
689 });
690 let front_meshlet_cull_dispatch =
691 render_device.create_buffer_with_data(&BufferInitDescriptor {
692 label: Some("meshlet_front_meshlet_cull_dispatch"),
693 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
694 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT,
695 });
696 let back_meshlet_cull_count =
697 render_device.create_buffer_with_data(&BufferInitDescriptor {
698 label: Some("meshlet_back_meshlet_cull_count"),
699 contents: bytemuck::bytes_of(&0u32),
700 usage: BufferUsages::STORAGE,
701 });
702 let back_meshlet_cull_dispatch =
703 render_device.create_buffer_with_data(&BufferInitDescriptor {
704 label: Some("meshlet_back_meshlet_cull_dispatch"),
705 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
706 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT,
707 });
708
709 let visibility_buffer_software_raster_indirect_args = render_device
710 .create_buffer_with_data(&BufferInitDescriptor {
711 label: Some("meshlet_visibility_buffer_software_raster_indirect_args"),
712 contents: DispatchIndirectArgs { x: 0, y: 1, z: 1 }.as_bytes(),
713 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT,
714 });
715
716 let visibility_buffer_hardware_raster_indirect_args = render_device
717 .create_buffer_with_data(&BufferInitDescriptor {
718 label: Some("meshlet_visibility_buffer_hardware_raster_indirect_args"),
719 contents: DrawIndirectArgs {
720 vertex_count: 128 * 3,
721 instance_count: 0,
722 first_vertex: 0,
723 first_instance: 0,
724 }
725 .as_bytes(),
726 usage: BufferUsages::STORAGE | BufferUsages::INDIRECT,
727 });
728
729 let depth_pyramid = ViewDepthPyramid::new(
730 &render_device,
731 &mut texture_cache,
732 &resource_manager.depth_pyramid_dummy_texture,
733 view.viewport.zw(),
734 "meshlet_depth_pyramid",
735 "meshlet_depth_pyramid_texture_view",
736 );
737
738 let previous_depth_pyramid =
739 match resource_manager.previous_depth_pyramids.get(&view_entity) {
740 Some(texture_view) => texture_view.clone(),
741 None => depth_pyramid.all_mips.clone(),
742 };
743 resource_manager
744 .previous_depth_pyramids
745 .insert(view_entity, depth_pyramid.all_mips.clone());
746
747 let material_depth = TextureDescriptor {
748 label: Some("meshlet_material_depth"),
749 size: view.viewport.zw().to_extents(),
750 mip_level_count: 1,
751 sample_count: 1,
752 dimension: TextureDimension::D2,
753 format: TextureFormat::Depth16Unorm,
754 usage: TextureUsages::RENDER_ATTACHMENT,
755 view_formats: &[],
756 };
757
758 commands.entity(view_entity).insert(MeshletViewResources {
759 scene_instance_count: instance_manager.scene_instance_count,
760 rightmost_slot: resource_manager.cull_queue_rightmost_slot,
761 max_bvh_depth: instance_manager.max_bvh_depth,
762 instance_visibility,
763 dummy_render_target,
764 visibility_buffer,
765 second_pass_count,
766 second_pass_dispatch,
767 second_pass_candidates: second_pass_candidates.clone(),
768 first_bvh_cull_count_front,
769 first_bvh_cull_dispatch_front,
770 first_bvh_cull_count_back,
771 first_bvh_cull_dispatch_back,
772 first_bvh_cull_queue: resource_manager.bvh_traversal_queues[0].clone(),
773 second_bvh_cull_count_front,
774 second_bvh_cull_dispatch_front,
775 second_bvh_cull_count_back,
776 second_bvh_cull_dispatch_back,
777 second_bvh_cull_queue: resource_manager.bvh_traversal_queues[1].clone(),
778 front_meshlet_cull_count,
779 front_meshlet_cull_dispatch,
780 back_meshlet_cull_count,
781 back_meshlet_cull_dispatch,
782 meshlet_cull_queue: resource_manager.cluster_cull_candidate_queue.clone(),
783 visibility_buffer_software_raster_indirect_args,
784 visibility_buffer_hardware_raster_indirect_args,
785 depth_pyramid,
786 previous_depth_pyramid,
787 material_depth: not_shadow_view
788 .then(|| texture_cache.get(&render_device, material_depth)),
789 view_size: view.viewport.zw(),
790 not_shadow_view,
791 });
792 }
793}
794
795pub fn prepare_meshlet_view_bind_groups(
796 meshlet_mesh_manager: Res<MeshletMeshManager>,
797 resource_manager: Res<ResourceManager>,
798 instance_manager: Res<InstanceManager>,
799 views: Query<(Entity, &MeshletViewResources)>,
800 view_uniforms: Res<ViewUniforms>,
801 previous_view_uniforms: Res<PreviousViewUniforms>,
802 render_device: Res<RenderDevice>,
803 pipeline_cache: Res<PipelineCache>,
804 mut commands: Commands,
805) {
806 let (Some(view_uniforms), Some(previous_view_uniforms)) = (
807 view_uniforms.uniforms.binding(),
808 previous_view_uniforms.uniforms.binding(),
809 ) else {
810 return;
811 };
812
813 for (view_entity, view_resources) in &views {
815 let clear_visibility_buffer = render_device.create_bind_group(
816 "meshlet_clear_visibility_buffer_bind_group",
817 &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view {
818 &resource_manager.clear_visibility_buffer_bind_group_layout
819 } else {
820 &resource_manager.clear_visibility_buffer_shadow_view_bind_group_layout
821 }),
822 &BindGroupEntries::single(&view_resources.visibility_buffer.default_view),
823 );
824
825 let first_instance_cull = render_device.create_bind_group(
826 "meshlet_first_instance_cull_bind_group",
827 &pipeline_cache
828 .get_bind_group_layout(&resource_manager.first_instance_cull_bind_group_layout),
829 &BindGroupEntries::sequential((
830 &view_resources.previous_depth_pyramid,
831 view_uniforms.clone(),
832 previous_view_uniforms.clone(),
833 instance_manager.instance_uniforms.binding().unwrap(),
834 view_resources.instance_visibility.as_entire_binding(),
835 instance_manager.instance_aabbs.binding().unwrap(),
836 instance_manager.instance_bvh_root_nodes.binding().unwrap(),
837 view_resources
838 .first_bvh_cull_count_front
839 .as_entire_binding(),
840 view_resources
841 .first_bvh_cull_dispatch_front
842 .as_entire_binding(),
843 view_resources.first_bvh_cull_queue.as_entire_binding(),
844 view_resources.second_pass_count.as_entire_binding(),
845 view_resources.second_pass_dispatch.as_entire_binding(),
846 view_resources.second_pass_candidates.as_entire_binding(),
847 )),
848 );
849
850 let second_instance_cull = render_device.create_bind_group(
851 "meshlet_second_instance_cull_bind_group",
852 &pipeline_cache
853 .get_bind_group_layout(&resource_manager.second_instance_cull_bind_group_layout),
854 &BindGroupEntries::sequential((
855 &view_resources.previous_depth_pyramid,
856 view_uniforms.clone(),
857 previous_view_uniforms.clone(),
858 instance_manager.instance_uniforms.binding().unwrap(),
859 view_resources.instance_visibility.as_entire_binding(),
860 instance_manager.instance_aabbs.binding().unwrap(),
861 instance_manager.instance_bvh_root_nodes.binding().unwrap(),
862 view_resources
863 .second_bvh_cull_count_front
864 .as_entire_binding(),
865 view_resources
866 .second_bvh_cull_dispatch_front
867 .as_entire_binding(),
868 view_resources.second_bvh_cull_queue.as_entire_binding(),
869 view_resources.second_pass_count.as_entire_binding(),
870 view_resources.second_pass_candidates.as_entire_binding(),
871 )),
872 );
873
874 let first_bvh_cull_ping = render_device.create_bind_group(
875 "meshlet_first_bvh_cull_ping_bind_group",
876 &pipeline_cache
877 .get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout),
878 &BindGroupEntries::sequential((
879 &view_resources.previous_depth_pyramid,
880 view_uniforms.clone(),
881 previous_view_uniforms.clone(),
882 meshlet_mesh_manager.bvh_nodes.binding(),
883 instance_manager.instance_uniforms.binding().unwrap(),
884 view_resources
885 .first_bvh_cull_count_front
886 .as_entire_binding(),
887 view_resources.first_bvh_cull_count_back.as_entire_binding(),
888 view_resources
889 .first_bvh_cull_dispatch_back
890 .as_entire_binding(),
891 view_resources.first_bvh_cull_queue.as_entire_binding(),
892 view_resources.front_meshlet_cull_count.as_entire_binding(),
893 view_resources.back_meshlet_cull_count.as_entire_binding(),
894 view_resources
895 .front_meshlet_cull_dispatch
896 .as_entire_binding(),
897 view_resources
898 .back_meshlet_cull_dispatch
899 .as_entire_binding(),
900 view_resources.meshlet_cull_queue.as_entire_binding(),
901 view_resources
902 .second_bvh_cull_count_front
903 .as_entire_binding(),
904 view_resources
905 .second_bvh_cull_dispatch_front
906 .as_entire_binding(),
907 view_resources.second_bvh_cull_queue.as_entire_binding(),
908 )),
909 );
910
911 let first_bvh_cull_pong = render_device.create_bind_group(
912 "meshlet_first_bvh_cull_pong_bind_group",
913 &pipeline_cache
914 .get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout),
915 &BindGroupEntries::sequential((
916 &view_resources.previous_depth_pyramid,
917 view_uniforms.clone(),
918 previous_view_uniforms.clone(),
919 meshlet_mesh_manager.bvh_nodes.binding(),
920 instance_manager.instance_uniforms.binding().unwrap(),
921 view_resources.first_bvh_cull_count_back.as_entire_binding(),
922 view_resources
923 .first_bvh_cull_count_front
924 .as_entire_binding(),
925 view_resources
926 .first_bvh_cull_dispatch_front
927 .as_entire_binding(),
928 view_resources.first_bvh_cull_queue.as_entire_binding(),
929 view_resources.front_meshlet_cull_count.as_entire_binding(),
930 view_resources.back_meshlet_cull_count.as_entire_binding(),
931 view_resources
932 .front_meshlet_cull_dispatch
933 .as_entire_binding(),
934 view_resources
935 .back_meshlet_cull_dispatch
936 .as_entire_binding(),
937 view_resources.meshlet_cull_queue.as_entire_binding(),
938 view_resources
939 .second_bvh_cull_count_front
940 .as_entire_binding(),
941 view_resources
942 .second_bvh_cull_dispatch_front
943 .as_entire_binding(),
944 view_resources.second_bvh_cull_queue.as_entire_binding(),
945 )),
946 );
947
948 let second_bvh_cull_ping = render_device.create_bind_group(
949 "meshlet_second_bvh_cull_ping_bind_group",
950 &pipeline_cache
951 .get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout),
952 &BindGroupEntries::sequential((
953 &view_resources.previous_depth_pyramid,
954 view_uniforms.clone(),
955 previous_view_uniforms.clone(),
956 meshlet_mesh_manager.bvh_nodes.binding(),
957 instance_manager.instance_uniforms.binding().unwrap(),
958 view_resources
959 .second_bvh_cull_count_front
960 .as_entire_binding(),
961 view_resources
962 .second_bvh_cull_count_back
963 .as_entire_binding(),
964 view_resources
965 .second_bvh_cull_dispatch_back
966 .as_entire_binding(),
967 view_resources.second_bvh_cull_queue.as_entire_binding(),
968 view_resources.front_meshlet_cull_count.as_entire_binding(),
969 view_resources.back_meshlet_cull_count.as_entire_binding(),
970 view_resources
971 .front_meshlet_cull_dispatch
972 .as_entire_binding(),
973 view_resources
974 .back_meshlet_cull_dispatch
975 .as_entire_binding(),
976 view_resources.meshlet_cull_queue.as_entire_binding(),
977 )),
978 );
979
980 let second_bvh_cull_pong = render_device.create_bind_group(
981 "meshlet_second_bvh_cull_pong_bind_group",
982 &pipeline_cache
983 .get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout),
984 &BindGroupEntries::sequential((
985 &view_resources.previous_depth_pyramid,
986 view_uniforms.clone(),
987 previous_view_uniforms.clone(),
988 meshlet_mesh_manager.bvh_nodes.binding(),
989 instance_manager.instance_uniforms.binding().unwrap(),
990 view_resources
991 .second_bvh_cull_count_back
992 .as_entire_binding(),
993 view_resources
994 .second_bvh_cull_count_front
995 .as_entire_binding(),
996 view_resources
997 .second_bvh_cull_dispatch_front
998 .as_entire_binding(),
999 view_resources.second_bvh_cull_queue.as_entire_binding(),
1000 view_resources.front_meshlet_cull_count.as_entire_binding(),
1001 view_resources.back_meshlet_cull_count.as_entire_binding(),
1002 view_resources
1003 .front_meshlet_cull_dispatch
1004 .as_entire_binding(),
1005 view_resources
1006 .back_meshlet_cull_dispatch
1007 .as_entire_binding(),
1008 view_resources.meshlet_cull_queue.as_entire_binding(),
1009 )),
1010 );
1011
1012 let first_meshlet_cull = render_device.create_bind_group(
1013 "meshlet_first_meshlet_cull_bind_group",
1014 &pipeline_cache
1015 .get_bind_group_layout(&resource_manager.first_meshlet_cull_bind_group_layout),
1016 &BindGroupEntries::sequential((
1017 &view_resources.previous_depth_pyramid,
1018 view_uniforms.clone(),
1019 previous_view_uniforms.clone(),
1020 meshlet_mesh_manager.meshlet_cull_data.binding(),
1021 instance_manager.instance_uniforms.binding().unwrap(),
1022 view_resources
1023 .visibility_buffer_software_raster_indirect_args
1024 .as_entire_binding(),
1025 view_resources
1026 .visibility_buffer_hardware_raster_indirect_args
1027 .as_entire_binding(),
1028 resource_manager
1029 .visibility_buffer_raster_cluster_prev_counts
1030 .as_entire_binding(),
1031 resource_manager
1032 .visibility_buffer_raster_clusters
1033 .as_entire_binding(),
1034 view_resources.front_meshlet_cull_count.as_entire_binding(),
1035 view_resources.back_meshlet_cull_count.as_entire_binding(),
1036 view_resources
1037 .back_meshlet_cull_dispatch
1038 .as_entire_binding(),
1039 view_resources.meshlet_cull_queue.as_entire_binding(),
1040 )),
1041 );
1042
1043 let second_meshlet_cull = render_device.create_bind_group(
1044 "meshlet_second_meshlet_cull_bind_group",
1045 &pipeline_cache
1046 .get_bind_group_layout(&resource_manager.second_meshlet_cull_bind_group_layout),
1047 &BindGroupEntries::sequential((
1048 &view_resources.previous_depth_pyramid,
1049 view_uniforms.clone(),
1050 previous_view_uniforms.clone(),
1051 meshlet_mesh_manager.meshlet_cull_data.binding(),
1052 instance_manager.instance_uniforms.binding().unwrap(),
1053 view_resources
1054 .visibility_buffer_software_raster_indirect_args
1055 .as_entire_binding(),
1056 view_resources
1057 .visibility_buffer_hardware_raster_indirect_args
1058 .as_entire_binding(),
1059 resource_manager
1060 .visibility_buffer_raster_cluster_prev_counts
1061 .as_entire_binding(),
1062 resource_manager
1063 .visibility_buffer_raster_clusters
1064 .as_entire_binding(),
1065 view_resources.back_meshlet_cull_count.as_entire_binding(),
1066 view_resources.meshlet_cull_queue.as_entire_binding(),
1067 )),
1068 );
1069
1070 let downsample_depth = view_resources.depth_pyramid.create_bind_group(
1071 &render_device,
1072 "meshlet_downsample_depth_bind_group",
1073 &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view {
1074 &resource_manager.downsample_depth_bind_group_layout
1075 } else {
1076 &resource_manager.downsample_depth_shadow_view_bind_group_layout
1077 }),
1078 &view_resources.visibility_buffer.default_view,
1079 &resource_manager.depth_pyramid_sampler,
1080 );
1081
1082 let visibility_buffer_raster = render_device.create_bind_group(
1083 "meshlet_visibility_raster_buffer_bind_group",
1084 &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view {
1085 &resource_manager.visibility_buffer_raster_bind_group_layout
1086 } else {
1087 &resource_manager.visibility_buffer_raster_shadow_view_bind_group_layout
1088 }),
1089 &BindGroupEntries::sequential((
1090 resource_manager
1091 .visibility_buffer_raster_clusters
1092 .as_entire_binding(),
1093 meshlet_mesh_manager.meshlets.binding(),
1094 meshlet_mesh_manager.indices.binding(),
1095 meshlet_mesh_manager.vertex_positions.binding(),
1096 instance_manager.instance_uniforms.binding().unwrap(),
1097 resource_manager
1098 .visibility_buffer_raster_cluster_prev_counts
1099 .as_entire_binding(),
1100 resource_manager
1101 .software_raster_cluster_count
1102 .as_entire_binding(),
1103 &view_resources.visibility_buffer.default_view,
1104 view_uniforms.clone(),
1105 )),
1106 );
1107
1108 let resolve_depth = render_device.create_bind_group(
1109 "meshlet_resolve_depth_bind_group",
1110 &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view {
1111 &resource_manager.resolve_depth_bind_group_layout
1112 } else {
1113 &resource_manager.resolve_depth_shadow_view_bind_group_layout
1114 }),
1115 &BindGroupEntries::single(&view_resources.visibility_buffer.default_view),
1116 );
1117
1118 let resolve_material_depth = view_resources.material_depth.as_ref().map(|_| {
1119 render_device.create_bind_group(
1120 "meshlet_resolve_material_depth_bind_group",
1121 &pipeline_cache.get_bind_group_layout(
1122 &resource_manager.resolve_material_depth_bind_group_layout,
1123 ),
1124 &BindGroupEntries::sequential((
1125 &view_resources.visibility_buffer.default_view,
1126 resource_manager
1127 .visibility_buffer_raster_clusters
1128 .as_entire_binding(),
1129 instance_manager.instance_material_ids.binding().unwrap(),
1130 )),
1131 )
1132 });
1133
1134 let material_shade = view_resources.material_depth.as_ref().map(|_| {
1135 render_device.create_bind_group(
1136 "meshlet_mesh_material_shade_bind_group",
1137 &pipeline_cache
1138 .get_bind_group_layout(&resource_manager.material_shade_bind_group_layout),
1139 &BindGroupEntries::sequential((
1140 &view_resources.visibility_buffer.default_view,
1141 resource_manager
1142 .visibility_buffer_raster_clusters
1143 .as_entire_binding(),
1144 meshlet_mesh_manager.meshlets.binding(),
1145 meshlet_mesh_manager.indices.binding(),
1146 meshlet_mesh_manager.vertex_positions.binding(),
1147 meshlet_mesh_manager.vertex_normals.binding(),
1148 meshlet_mesh_manager.vertex_uvs.binding(),
1149 instance_manager.instance_uniforms.binding().unwrap(),
1150 )),
1151 )
1152 });
1153
1154 let remap_1d_to_2d_dispatch = resource_manager
1155 .remap_1d_to_2d_dispatch_bind_group_layout
1156 .as_ref()
1157 .map(|layout| {
1158 render_device.create_bind_group(
1159 "meshlet_remap_1d_to_2d_dispatch_bind_group",
1160 &pipeline_cache.get_bind_group_layout(layout),
1161 &BindGroupEntries::sequential((
1162 view_resources
1163 .visibility_buffer_software_raster_indirect_args
1164 .as_entire_binding(),
1165 resource_manager
1166 .software_raster_cluster_count
1167 .as_entire_binding(),
1168 )),
1169 )
1170 });
1171
1172 let fill_counts = if resource_manager
1173 .remap_1d_to_2d_dispatch_bind_group_layout
1174 .is_some()
1175 {
1176 render_device.create_bind_group(
1177 "meshlet_fill_counts_bind_group",
1178 &pipeline_cache
1179 .get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout),
1180 &BindGroupEntries::sequential((
1181 view_resources
1182 .visibility_buffer_software_raster_indirect_args
1183 .as_entire_binding(),
1184 view_resources
1185 .visibility_buffer_hardware_raster_indirect_args
1186 .as_entire_binding(),
1187 resource_manager
1188 .visibility_buffer_raster_cluster_prev_counts
1189 .as_entire_binding(),
1190 resource_manager
1191 .software_raster_cluster_count
1192 .as_entire_binding(),
1193 )),
1194 )
1195 } else {
1196 render_device.create_bind_group(
1197 "meshlet_fill_counts_bind_group",
1198 &pipeline_cache
1199 .get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout),
1200 &BindGroupEntries::sequential((
1201 view_resources
1202 .visibility_buffer_software_raster_indirect_args
1203 .as_entire_binding(),
1204 view_resources
1205 .visibility_buffer_hardware_raster_indirect_args
1206 .as_entire_binding(),
1207 resource_manager
1208 .visibility_buffer_raster_cluster_prev_counts
1209 .as_entire_binding(),
1210 )),
1211 )
1212 };
1213
1214 commands.entity(view_entity).insert(MeshletViewBindGroups {
1215 clear_visibility_buffer,
1216 first_instance_cull,
1217 second_instance_cull,
1218 first_bvh_cull_ping,
1219 first_bvh_cull_pong,
1220 second_bvh_cull_ping,
1221 second_bvh_cull_pong,
1222 first_meshlet_cull,
1223 second_meshlet_cull,
1224 downsample_depth,
1225 visibility_buffer_raster,
1226 resolve_depth,
1227 resolve_material_depth,
1228 material_shade,
1229 remap_1d_to_2d_dispatch,
1230 fill_counts,
1231 });
1232 }
1233}