Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/meshlet/resource_manager.rs
9441 views
1
use super::{instance_manager::InstanceManager, meshlet_mesh_manager::MeshletMeshManager};
2
use crate::ShadowView;
3
use bevy_camera::{visibility::RenderLayers, Camera3d};
4
use bevy_core_pipeline::{
5
mip_generation::experimental::depth::{self, ViewDepthPyramid},
6
prepass::{PreviousViewData, PreviousViewUniforms},
7
};
8
use bevy_ecs::{
9
component::Component,
10
entity::{Entity, EntityHashMap},
11
query::AnyOf,
12
resource::Resource,
13
system::{Commands, Query, Res, ResMut},
14
};
15
use bevy_image::ToExtents;
16
use bevy_math::{UVec2, Vec4Swizzles};
17
use bevy_render::{
18
render_resource::*,
19
renderer::{RenderDevice, RenderQueue},
20
texture::{CachedTexture, TextureCache},
21
view::{ExtractedView, ViewUniform, ViewUniforms},
22
};
23
use binding_types::*;
24
use core::iter;
25
26
/// Manages per-view and per-cluster GPU resources for [`MeshletPlugin`](`super::MeshletPlugin`).
27
#[derive(Resource)]
28
pub struct ResourceManager {
29
/// Intermediate buffer of cluster IDs for use with rasterizing the visibility buffer
30
visibility_buffer_raster_clusters: Buffer,
31
/// Intermediate buffer of previous counts of clusters in rasterizer buckets
32
pub visibility_buffer_raster_cluster_prev_counts: Buffer,
33
/// Intermediate buffer of count of clusters to software rasterize
34
software_raster_cluster_count: Buffer,
35
/// BVH traversal queues
36
bvh_traversal_queues: [Buffer; 2],
37
/// Cluster cull candidate queue
38
cluster_cull_candidate_queue: Buffer,
39
/// Rightmost slot index of [`Self::visibility_buffer_raster_clusters`], [`Self::bvh_traversal_queues`], and [`Self::cluster_cull_candidate_queue`]
40
cull_queue_rightmost_slot: u32,
41
42
/// Second pass instance candidates
43
second_pass_candidates: Option<Buffer>,
44
/// Sampler for a depth pyramid
45
depth_pyramid_sampler: Sampler,
46
/// Dummy texture view for binding depth pyramids with less than the maximum amount of mips
47
depth_pyramid_dummy_texture: TextureView,
48
49
// TODO
50
previous_depth_pyramids: EntityHashMap<TextureView>,
51
52
// Bind group layouts
53
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
73
impl 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
// The IDs are a (u32, u32) of instance and index.
78
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: depth::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
// TODO: Buffer min sizes
137
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
// ------------ TODO: Everything under here needs to be rewritten and cached ------------
451
452
#[derive(Component)]
453
pub 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)]
488
pub 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
507
// TODO: Cache things per-view and skip running this system / optimize this system
508
pub 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
// TODO: Move this and the submit to a separate system and remove pub from the fields
529
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 either the layers don't match the view's layers or this is a shadow view
572
// and the instance is not a shadow caster, hide the instance for this view
573
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
// TODO: Remove this once wgpu allows render passes with no attachments
591
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
795
pub 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
// TODO: Some of these bind groups can be reused across multiple views
814
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
}
1234
1235