Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_pbr/src/meshlet/pipelines.rs
9441 views
1
use super::resource_manager::ResourceManager;
2
use bevy_asset::{load_embedded_asset, AssetServer, Handle};
3
use bevy_core_pipeline::{
4
core_3d::CORE_3D_DEPTH_FORMAT, mip_generation::DownsampleShaders, FullscreenShader,
5
};
6
use bevy_ecs::{
7
resource::Resource,
8
system::{Commands, Res},
9
world::World,
10
};
11
use bevy_render::render_resource::*;
12
use bevy_shader::Shader;
13
use bevy_utils::default;
14
15
#[derive(Resource)]
16
pub struct MeshletPipelines {
17
clear_visibility_buffer: CachedComputePipelineId,
18
clear_visibility_buffer_shadow_view: CachedComputePipelineId,
19
first_instance_cull: CachedComputePipelineId,
20
second_instance_cull: CachedComputePipelineId,
21
first_bvh_cull: CachedComputePipelineId,
22
second_bvh_cull: CachedComputePipelineId,
23
first_meshlet_cull: CachedComputePipelineId,
24
second_meshlet_cull: CachedComputePipelineId,
25
downsample_depth_first: CachedComputePipelineId,
26
downsample_depth_second: CachedComputePipelineId,
27
downsample_depth_first_shadow_view: CachedComputePipelineId,
28
downsample_depth_second_shadow_view: CachedComputePipelineId,
29
visibility_buffer_software_raster: CachedComputePipelineId,
30
visibility_buffer_software_raster_shadow_view: CachedComputePipelineId,
31
visibility_buffer_hardware_raster: CachedRenderPipelineId,
32
visibility_buffer_hardware_raster_shadow_view: CachedRenderPipelineId,
33
visibility_buffer_hardware_raster_shadow_view_unclipped: CachedRenderPipelineId,
34
resolve_depth: CachedRenderPipelineId,
35
resolve_depth_shadow_view: CachedRenderPipelineId,
36
resolve_material_depth: CachedRenderPipelineId,
37
remap_1d_to_2d_dispatch: Option<CachedComputePipelineId>,
38
fill_counts: CachedComputePipelineId,
39
pub(crate) meshlet_mesh_material: Handle<Shader>,
40
}
41
42
pub fn init_meshlet_pipelines(
43
mut commands: Commands,
44
resource_manager: Res<ResourceManager>,
45
fullscreen_shader: Res<FullscreenShader>,
46
downsample_shaders: Res<DownsampleShaders>,
47
pipeline_cache: Res<PipelineCache>,
48
asset_server: Res<AssetServer>,
49
) {
50
let clear_visibility_buffer_bind_group_layout = resource_manager
51
.clear_visibility_buffer_bind_group_layout
52
.clone();
53
let clear_visibility_buffer_shadow_view_bind_group_layout = resource_manager
54
.clear_visibility_buffer_shadow_view_bind_group_layout
55
.clone();
56
let first_instance_cull_bind_group_layout = resource_manager
57
.first_instance_cull_bind_group_layout
58
.clone();
59
let second_instance_cull_bind_group_layout = resource_manager
60
.second_instance_cull_bind_group_layout
61
.clone();
62
let first_bvh_cull_bind_group_layout =
63
resource_manager.first_bvh_cull_bind_group_layout.clone();
64
let second_bvh_cull_bind_group_layout =
65
resource_manager.second_bvh_cull_bind_group_layout.clone();
66
let first_meshlet_cull_bind_group_layout = resource_manager
67
.first_meshlet_cull_bind_group_layout
68
.clone();
69
let second_meshlet_cull_bind_group_layout = resource_manager
70
.second_meshlet_cull_bind_group_layout
71
.clone();
72
let downsample_depth_layout = resource_manager.downsample_depth_bind_group_layout.clone();
73
let downsample_depth_shadow_view_layout = resource_manager
74
.downsample_depth_shadow_view_bind_group_layout
75
.clone();
76
let visibility_buffer_raster_layout = resource_manager
77
.visibility_buffer_raster_bind_group_layout
78
.clone();
79
let visibility_buffer_raster_shadow_view_layout = resource_manager
80
.visibility_buffer_raster_shadow_view_bind_group_layout
81
.clone();
82
let resolve_depth_layout = resource_manager.resolve_depth_bind_group_layout.clone();
83
let resolve_depth_shadow_view_layout = resource_manager
84
.resolve_depth_shadow_view_bind_group_layout
85
.clone();
86
let resolve_material_depth_layout = resource_manager
87
.resolve_material_depth_bind_group_layout
88
.clone();
89
let remap_1d_to_2d_dispatch_layout = resource_manager
90
.remap_1d_to_2d_dispatch_bind_group_layout
91
.clone();
92
93
let downsample_depth_shader = downsample_shaders.depth.clone();
94
let vertex_state = fullscreen_shader.to_vertex_state();
95
let fill_counts_layout = resource_manager.fill_counts_bind_group_layout.clone();
96
97
let clear_visibility_buffer =
98
load_embedded_asset!(asset_server.as_ref(), "clear_visibility_buffer.wgsl");
99
let cull_instances = load_embedded_asset!(asset_server.as_ref(), "cull_instances.wgsl");
100
let cull_bvh = load_embedded_asset!(asset_server.as_ref(), "cull_bvh.wgsl");
101
let cull_clusters = load_embedded_asset!(asset_server.as_ref(), "cull_clusters.wgsl");
102
let visibility_buffer_software_raster = load_embedded_asset!(
103
asset_server.as_ref(),
104
"visibility_buffer_software_raster.wgsl"
105
);
106
let visibility_buffer_hardware_raster = load_embedded_asset!(
107
asset_server.as_ref(),
108
"visibility_buffer_hardware_raster.wgsl"
109
);
110
let resolve_render_targets =
111
load_embedded_asset!(asset_server.as_ref(), "resolve_render_targets.wgsl");
112
let remap_1d_to_2d_dispatch =
113
load_embedded_asset!(asset_server.as_ref(), "remap_1d_to_2d_dispatch.wgsl");
114
let fill_counts = load_embedded_asset!(asset_server.as_ref(), "fill_counts.wgsl");
115
let meshlet_mesh_material =
116
load_embedded_asset!(asset_server.as_ref(), "meshlet_mesh_material.wgsl");
117
118
commands.insert_resource(MeshletPipelines {
119
clear_visibility_buffer: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
120
label: Some("meshlet_clear_visibility_buffer_pipeline".into()),
121
layout: vec![clear_visibility_buffer_bind_group_layout],
122
immediate_size: 8,
123
shader: clear_visibility_buffer.clone(),
124
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into()],
125
..default()
126
}),
127
128
clear_visibility_buffer_shadow_view: pipeline_cache.queue_compute_pipeline(
129
ComputePipelineDescriptor {
130
label: Some("meshlet_clear_visibility_buffer_shadow_view_pipeline".into()),
131
layout: vec![clear_visibility_buffer_shadow_view_bind_group_layout],
132
immediate_size: 8,
133
shader: clear_visibility_buffer,
134
..default()
135
},
136
),
137
138
first_instance_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
139
label: Some("meshlet_first_instance_cull_pipeline".into()),
140
layout: vec![first_instance_cull_bind_group_layout.clone()],
141
immediate_size: 4,
142
shader: cull_instances.clone(),
143
shader_defs: vec![
144
"MESHLET_INSTANCE_CULLING_PASS".into(),
145
"MESHLET_FIRST_CULLING_PASS".into(),
146
],
147
..default()
148
}),
149
150
second_instance_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
151
label: Some("meshlet_second_instance_cull_pipeline".into()),
152
layout: vec![second_instance_cull_bind_group_layout.clone()],
153
immediate_size: 4,
154
shader: cull_instances,
155
shader_defs: vec![
156
"MESHLET_INSTANCE_CULLING_PASS".into(),
157
"MESHLET_SECOND_CULLING_PASS".into(),
158
],
159
..default()
160
}),
161
162
first_bvh_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
163
label: Some("meshlet_first_bvh_cull_pipeline".into()),
164
layout: vec![first_bvh_cull_bind_group_layout.clone()],
165
immediate_size: 8,
166
shader: cull_bvh.clone(),
167
shader_defs: vec![
168
"MESHLET_BVH_CULLING_PASS".into(),
169
"MESHLET_FIRST_CULLING_PASS".into(),
170
],
171
..default()
172
}),
173
174
second_bvh_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
175
label: Some("meshlet_second_bvh_cull_pipeline".into()),
176
layout: vec![second_bvh_cull_bind_group_layout.clone()],
177
immediate_size: 8,
178
shader: cull_bvh,
179
shader_defs: vec![
180
"MESHLET_BVH_CULLING_PASS".into(),
181
"MESHLET_SECOND_CULLING_PASS".into(),
182
],
183
..default()
184
}),
185
186
first_meshlet_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
187
label: Some("meshlet_first_meshlet_cull_pipeline".into()),
188
layout: vec![first_meshlet_cull_bind_group_layout.clone()],
189
immediate_size: 4,
190
shader: cull_clusters.clone(),
191
shader_defs: vec![
192
"MESHLET_CLUSTER_CULLING_PASS".into(),
193
"MESHLET_FIRST_CULLING_PASS".into(),
194
],
195
..default()
196
}),
197
198
second_meshlet_cull: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
199
label: Some("meshlet_second_meshlet_cull_pipeline".into()),
200
layout: vec![second_meshlet_cull_bind_group_layout.clone()],
201
immediate_size: 4,
202
shader: cull_clusters,
203
shader_defs: vec![
204
"MESHLET_CLUSTER_CULLING_PASS".into(),
205
"MESHLET_SECOND_CULLING_PASS".into(),
206
],
207
..default()
208
}),
209
210
downsample_depth_first: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
211
label: Some("meshlet_downsample_depth_first_pipeline".into()),
212
layout: vec![downsample_depth_layout.clone()],
213
immediate_size: 4,
214
shader: downsample_depth_shader.clone(),
215
shader_defs: vec![
216
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into(),
217
"MESHLET".into(),
218
],
219
entry_point: Some("downsample_depth_first".into()),
220
..default()
221
}),
222
223
downsample_depth_second: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
224
label: Some("meshlet_downsample_depth_second_pipeline".into()),
225
layout: vec![downsample_depth_layout.clone()],
226
immediate_size: 4,
227
shader: downsample_depth_shader.clone(),
228
shader_defs: vec![
229
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into(),
230
"MESHLET".into(),
231
],
232
entry_point: Some("downsample_depth_second".into()),
233
..default()
234
}),
235
236
downsample_depth_first_shadow_view: pipeline_cache.queue_compute_pipeline(
237
ComputePipelineDescriptor {
238
label: Some("meshlet_downsample_depth_first_pipeline".into()),
239
layout: vec![downsample_depth_shadow_view_layout.clone()],
240
immediate_size: 4,
241
shader: downsample_depth_shader.clone(),
242
shader_defs: vec!["MESHLET".into()],
243
entry_point: Some("downsample_depth_first".into()),
244
..default()
245
},
246
),
247
248
downsample_depth_second_shadow_view: pipeline_cache.queue_compute_pipeline(
249
ComputePipelineDescriptor {
250
label: Some("meshlet_downsample_depth_second_pipeline".into()),
251
layout: vec![downsample_depth_shadow_view_layout],
252
immediate_size: 4,
253
shader: downsample_depth_shader,
254
shader_defs: vec!["MESHLET".into()],
255
entry_point: Some("downsample_depth_second".into()),
256
zero_initialize_workgroup_memory: false,
257
},
258
),
259
260
visibility_buffer_software_raster: pipeline_cache.queue_compute_pipeline(
261
ComputePipelineDescriptor {
262
label: Some("meshlet_visibility_buffer_software_raster_pipeline".into()),
263
layout: vec![visibility_buffer_raster_layout.clone()],
264
immediate_size: 0,
265
shader: visibility_buffer_software_raster.clone(),
266
shader_defs: vec![
267
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into(),
268
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into(),
269
if remap_1d_to_2d_dispatch_layout.is_some() {
270
"MESHLET_2D_DISPATCH"
271
} else {
272
""
273
}
274
.into(),
275
],
276
..default()
277
},
278
),
279
280
visibility_buffer_software_raster_shadow_view: pipeline_cache.queue_compute_pipeline(
281
ComputePipelineDescriptor {
282
label: Some(
283
"meshlet_visibility_buffer_software_raster_shadow_view_pipeline".into(),
284
),
285
layout: vec![visibility_buffer_raster_shadow_view_layout.clone()],
286
immediate_size: 0,
287
shader: visibility_buffer_software_raster,
288
shader_defs: vec![
289
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into(),
290
if remap_1d_to_2d_dispatch_layout.is_some() {
291
"MESHLET_2D_DISPATCH"
292
} else {
293
""
294
}
295
.into(),
296
],
297
..default()
298
},
299
),
300
301
visibility_buffer_hardware_raster: pipeline_cache.queue_render_pipeline(
302
RenderPipelineDescriptor {
303
label: Some("meshlet_visibility_buffer_hardware_raster_pipeline".into()),
304
layout: vec![visibility_buffer_raster_layout.clone()],
305
immediate_size: 4,
306
vertex: VertexState {
307
shader: visibility_buffer_hardware_raster.clone(),
308
shader_defs: vec![
309
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into(),
310
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into(),
311
],
312
..default()
313
},
314
fragment: Some(FragmentState {
315
shader: visibility_buffer_hardware_raster.clone(),
316
shader_defs: vec![
317
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into(),
318
"MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into(),
319
],
320
targets: vec![Some(ColorTargetState {
321
format: TextureFormat::R8Uint,
322
blend: None,
323
write_mask: ColorWrites::empty(),
324
})],
325
..default()
326
}),
327
..default()
328
},
329
),
330
331
visibility_buffer_hardware_raster_shadow_view: pipeline_cache.queue_render_pipeline(
332
RenderPipelineDescriptor {
333
label: Some(
334
"meshlet_visibility_buffer_hardware_raster_shadow_view_pipeline".into(),
335
),
336
layout: vec![visibility_buffer_raster_shadow_view_layout.clone()],
337
immediate_size: 4,
338
vertex: VertexState {
339
shader: visibility_buffer_hardware_raster.clone(),
340
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into()],
341
..default()
342
},
343
fragment: Some(FragmentState {
344
shader: visibility_buffer_hardware_raster.clone(),
345
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into()],
346
targets: vec![Some(ColorTargetState {
347
format: TextureFormat::R8Uint,
348
blend: None,
349
write_mask: ColorWrites::empty(),
350
})],
351
..default()
352
}),
353
..default()
354
},
355
),
356
357
visibility_buffer_hardware_raster_shadow_view_unclipped: pipeline_cache
358
.queue_render_pipeline(RenderPipelineDescriptor {
359
label: Some(
360
"meshlet_visibility_buffer_hardware_raster_shadow_view_unclipped_pipeline"
361
.into(),
362
),
363
layout: vec![visibility_buffer_raster_shadow_view_layout],
364
immediate_size: 4,
365
vertex: VertexState {
366
shader: visibility_buffer_hardware_raster.clone(),
367
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into()],
368
..default()
369
},
370
fragment: Some(FragmentState {
371
shader: visibility_buffer_hardware_raster,
372
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS".into()],
373
targets: vec![Some(ColorTargetState {
374
format: TextureFormat::R8Uint,
375
blend: None,
376
write_mask: ColorWrites::empty(),
377
})],
378
..default()
379
}),
380
..default()
381
}),
382
383
resolve_depth: pipeline_cache.queue_render_pipeline(RenderPipelineDescriptor {
384
label: Some("meshlet_resolve_depth_pipeline".into()),
385
layout: vec![resolve_depth_layout],
386
vertex: vertex_state.clone(),
387
depth_stencil: Some(DepthStencilState {
388
format: CORE_3D_DEPTH_FORMAT,
389
depth_write_enabled: true,
390
depth_compare: CompareFunction::Always,
391
stencil: StencilState::default(),
392
bias: DepthBiasState::default(),
393
}),
394
fragment: Some(FragmentState {
395
shader: resolve_render_targets.clone(),
396
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into()],
397
entry_point: Some("resolve_depth".into()),
398
..default()
399
}),
400
..default()
401
}),
402
403
resolve_depth_shadow_view: pipeline_cache.queue_render_pipeline(RenderPipelineDescriptor {
404
label: Some("meshlet_resolve_depth_pipeline".into()),
405
layout: vec![resolve_depth_shadow_view_layout],
406
vertex: vertex_state.clone(),
407
depth_stencil: Some(DepthStencilState {
408
format: CORE_3D_DEPTH_FORMAT,
409
depth_write_enabled: true,
410
depth_compare: CompareFunction::Always,
411
stencil: StencilState::default(),
412
bias: DepthBiasState::default(),
413
}),
414
fragment: Some(FragmentState {
415
shader: resolve_render_targets.clone(),
416
entry_point: Some("resolve_depth".into()),
417
..default()
418
}),
419
..default()
420
}),
421
422
resolve_material_depth: pipeline_cache.queue_render_pipeline(RenderPipelineDescriptor {
423
label: Some("meshlet_resolve_material_depth_pipeline".into()),
424
layout: vec![resolve_material_depth_layout],
425
vertex: vertex_state,
426
primitive: PrimitiveState::default(),
427
depth_stencil: Some(DepthStencilState {
428
format: TextureFormat::Depth16Unorm,
429
depth_write_enabled: true,
430
depth_compare: CompareFunction::Always,
431
stencil: StencilState::default(),
432
bias: DepthBiasState::default(),
433
}),
434
fragment: Some(FragmentState {
435
shader: resolve_render_targets,
436
shader_defs: vec!["MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT".into()],
437
entry_point: Some("resolve_material_depth".into()),
438
targets: vec![],
439
}),
440
..default()
441
}),
442
443
fill_counts: pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
444
label: Some("meshlet_fill_counts_pipeline".into()),
445
layout: vec![fill_counts_layout],
446
shader: fill_counts,
447
shader_defs: vec![if remap_1d_to_2d_dispatch_layout.is_some() {
448
"MESHLET_2D_DISPATCH"
449
} else {
450
""
451
}
452
.into()],
453
..default()
454
}),
455
456
remap_1d_to_2d_dispatch: remap_1d_to_2d_dispatch_layout.map(|layout| {
457
pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {
458
label: Some("meshlet_remap_1d_to_2d_dispatch_pipeline".into()),
459
layout: vec![layout],
460
immediate_size: 4,
461
shader: remap_1d_to_2d_dispatch,
462
..default()
463
})
464
}),
465
466
meshlet_mesh_material,
467
});
468
}
469
470
impl MeshletPipelines {
471
pub fn get(
472
world: &World,
473
) -> Option<(
474
&ComputePipeline,
475
&ComputePipeline,
476
&ComputePipeline,
477
&ComputePipeline,
478
&ComputePipeline,
479
&ComputePipeline,
480
&ComputePipeline,
481
&ComputePipeline,
482
&ComputePipeline,
483
&ComputePipeline,
484
&ComputePipeline,
485
&ComputePipeline,
486
&ComputePipeline,
487
&ComputePipeline,
488
&RenderPipeline,
489
&RenderPipeline,
490
&RenderPipeline,
491
&RenderPipeline,
492
&RenderPipeline,
493
&RenderPipeline,
494
Option<&ComputePipeline>,
495
&ComputePipeline,
496
)> {
497
let pipeline_cache = world.get_resource::<PipelineCache>()?;
498
let pipeline = world.get_resource::<Self>()?;
499
Some((
500
pipeline_cache.get_compute_pipeline(pipeline.clear_visibility_buffer)?,
501
pipeline_cache.get_compute_pipeline(pipeline.clear_visibility_buffer_shadow_view)?,
502
pipeline_cache.get_compute_pipeline(pipeline.first_instance_cull)?,
503
pipeline_cache.get_compute_pipeline(pipeline.second_instance_cull)?,
504
pipeline_cache.get_compute_pipeline(pipeline.first_bvh_cull)?,
505
pipeline_cache.get_compute_pipeline(pipeline.second_bvh_cull)?,
506
pipeline_cache.get_compute_pipeline(pipeline.first_meshlet_cull)?,
507
pipeline_cache.get_compute_pipeline(pipeline.second_meshlet_cull)?,
508
pipeline_cache.get_compute_pipeline(pipeline.downsample_depth_first)?,
509
pipeline_cache.get_compute_pipeline(pipeline.downsample_depth_second)?,
510
pipeline_cache.get_compute_pipeline(pipeline.downsample_depth_first_shadow_view)?,
511
pipeline_cache.get_compute_pipeline(pipeline.downsample_depth_second_shadow_view)?,
512
pipeline_cache.get_compute_pipeline(pipeline.visibility_buffer_software_raster)?,
513
pipeline_cache
514
.get_compute_pipeline(pipeline.visibility_buffer_software_raster_shadow_view)?,
515
pipeline_cache.get_render_pipeline(pipeline.visibility_buffer_hardware_raster)?,
516
pipeline_cache
517
.get_render_pipeline(pipeline.visibility_buffer_hardware_raster_shadow_view)?,
518
pipeline_cache.get_render_pipeline(
519
pipeline.visibility_buffer_hardware_raster_shadow_view_unclipped,
520
)?,
521
pipeline_cache.get_render_pipeline(pipeline.resolve_depth)?,
522
pipeline_cache.get_render_pipeline(pipeline.resolve_depth_shadow_view)?,
523
pipeline_cache.get_render_pipeline(pipeline.resolve_material_depth)?,
524
match pipeline.remap_1d_to_2d_dispatch {
525
Some(id) => Some(pipeline_cache.get_compute_pipeline(id)?),
526
None => None,
527
},
528
pipeline_cache.get_compute_pipeline(pipeline.fill_counts)?,
529
))
530
}
531
}
532
533