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