Skip to content

Commit fc006c5

Browse files
committed
main_transparent_pass_2d render node command encoding parallelization
1 parent 6ed3c32 commit fc006c5

File tree

1 file changed

+68
-54
lines changed

1 file changed

+68
-54
lines changed

crates/bevy_core_pipeline/src/core_2d/main_transparent_pass_2d_node.rs

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use bevy_render::{
44
camera::ExtractedCamera,
55
diagnostic::RecordDiagnostics,
66
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
7-
render_phase::ViewSortedRenderPhases,
8-
render_resource::{RenderPassDescriptor, StoreOp},
7+
render_phase::{TrackedRenderPass, ViewSortedRenderPhases},
8+
render_resource::{CommandEncoderDescriptor, RenderPassDescriptor, StoreOp},
99
renderer::RenderContext,
1010
view::{ExtractedView, ViewDepthTexture, ViewTarget},
1111
};
@@ -42,63 +42,77 @@ impl ViewNode for MainTransparentPass2dNode {
4242
return Ok(());
4343
};
4444

45-
// This needs to run at least once to clear the background color, even if there are no items to render
46-
{
47-
#[cfg(feature = "trace")]
48-
let _main_pass_2d = info_span!("main_transparent_pass_2d").entered();
49-
50-
let diagnostics = render_context.diagnostic_recorder();
51-
52-
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
53-
label: Some("main_transparent_pass_2d"),
54-
color_attachments: &[Some(target.get_color_attachment())],
55-
// NOTE: For the transparent pass we load the depth buffer. There should be no
56-
// need to write to it, but store is set to `true` as a workaround for issue #3776,
57-
// https://github.com/bevyengine/bevy/issues/3776
58-
// so that wgpu does not clear the depth buffer.
59-
// As the opaque and alpha mask passes run first, opaque meshes can occlude
60-
// transparent ones.
61-
depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)),
62-
timestamp_writes: None,
63-
occlusion_query_set: None,
64-
});
65-
66-
let pass_span = diagnostics.pass_span(&mut render_pass, "main_transparent_pass_2d");
67-
68-
if let Some(viewport) = camera.viewport.as_ref() {
69-
render_pass.set_camera_viewport(viewport);
70-
}
45+
let diagnostics = render_context.diagnostic_recorder();
46+
47+
render_context.add_command_buffer_generation_task(move |render_device| {
48+
// Command encoder setup
49+
let mut command_encoder =
50+
render_device.create_command_encoder(&CommandEncoderDescriptor {
51+
label: Some("main_transparent_pass_2d_command_encoder"),
52+
});
7153

72-
if !transparent_phase.items.is_empty() {
54+
// This needs to run at least once to clear the background color, even if there are no items to render
55+
{
7356
#[cfg(feature = "trace")]
74-
let _transparent_main_pass_2d_span =
75-
info_span!("transparent_main_pass_2d").entered();
76-
if let Err(err) = transparent_phase.render(&mut render_pass, world, view_entity) {
77-
error!("Error encountered while rendering the transparent 2D phase {err:?}");
57+
let _main_pass_2d = info_span!("main_transparent_pass_2d").entered();
58+
59+
let render_pass = command_encoder.begin_render_pass(&RenderPassDescriptor {
60+
label: Some("main_transparent_pass_2d"),
61+
color_attachments: &[Some(target.get_color_attachment())],
62+
// NOTE: For the transparent pass we load the depth buffer. There should be no
63+
// need to write to it, but store is set to `true` as a workaround for issue #3776,
64+
// https://github.com/bevyengine/bevy/issues/3776
65+
// so that wgpu does not clear the depth buffer.
66+
// As the opaque and alpha mask passes run first, opaque meshes can occlude
67+
// transparent ones.
68+
depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)),
69+
timestamp_writes: None,
70+
occlusion_query_set: None,
71+
});
72+
let mut render_pass = TrackedRenderPass::new(&render_device, render_pass);
73+
74+
let pass_span = diagnostics.pass_span(&mut render_pass, "main_transparent_pass_2d");
75+
76+
if let Some(viewport) = camera.viewport.as_ref() {
77+
render_pass.set_camera_viewport(viewport);
78+
}
79+
80+
if !transparent_phase.items.is_empty() {
81+
#[cfg(feature = "trace")]
82+
let _transparent_main_pass_2d_span =
83+
info_span!("transparent_main_pass_2d").entered();
84+
if let Err(err) = transparent_phase.render(&mut render_pass, world, view_entity)
85+
{
86+
error!(
87+
"Error encountered while rendering the transparent 2D phase {err:?}"
88+
);
89+
}
7890
}
91+
92+
pass_span.end(&mut render_pass);
93+
}
94+
95+
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
96+
// reset for the next render pass so add an empty render pass without a custom viewport
97+
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
98+
if camera.viewport.is_some() {
99+
#[cfg(feature = "trace")]
100+
let _reset_viewport_pass_2d = info_span!("reset_viewport_pass_2d").entered();
101+
let pass_descriptor = RenderPassDescriptor {
102+
label: Some("reset_viewport_pass_2d"),
103+
color_attachments: &[Some(target.get_color_attachment())],
104+
depth_stencil_attachment: None,
105+
timestamp_writes: None,
106+
occlusion_query_set: None,
107+
};
108+
109+
render_context
110+
.command_encoder()
111+
.begin_render_pass(&pass_descriptor);
79112
}
80113

81-
pass_span.end(&mut render_pass);
82-
}
83-
84-
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
85-
// reset for the next render pass so add an empty render pass without a custom viewport
86-
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
87-
if camera.viewport.is_some() {
88-
#[cfg(feature = "trace")]
89-
let _reset_viewport_pass_2d = info_span!("reset_viewport_pass_2d").entered();
90-
let pass_descriptor = RenderPassDescriptor {
91-
label: Some("reset_viewport_pass_2d"),
92-
color_attachments: &[Some(target.get_color_attachment())],
93-
depth_stencil_attachment: None,
94-
timestamp_writes: None,
95-
occlusion_query_set: None,
96-
};
97-
98-
render_context
99-
.command_encoder()
100-
.begin_render_pass(&pass_descriptor);
101-
}
114+
command_encoder.finish()
115+
});
102116

103117
Ok(())
104118
}

0 commit comments

Comments
 (0)