main_transparent_pass_2d render node command encoding parallelization (#17735)
# Objective - Add command encoding parallelization to transparent 2d pass render node. - Improves https://github.com/bevyengine/bevy/issues/17733 ## Solution Using functionality added in https://github.com/bevyengine/bevy/pull/9172 ## Testing - Tested in personal project where multiple cameras are rendered with objects rendered in transparent 2d pass.
This commit is contained in:
parent
556b750782
commit
2d62026912
@ -4,8 +4,8 @@ use bevy_render::{
|
|||||||
camera::ExtractedCamera,
|
camera::ExtractedCamera,
|
||||||
diagnostic::RecordDiagnostics,
|
diagnostic::RecordDiagnostics,
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_phase::ViewSortedRenderPhases,
|
render_phase::{TrackedRenderPass, ViewSortedRenderPhases},
|
||||||
render_resource::{RenderPassDescriptor, StoreOp},
|
render_resource::{CommandEncoderDescriptor, RenderPassDescriptor, StoreOp},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::{ExtractedView, ViewDepthTexture, ViewTarget},
|
view::{ExtractedView, ViewDepthTexture, ViewTarget},
|
||||||
};
|
};
|
||||||
@ -42,63 +42,75 @@ impl ViewNode for MainTransparentPass2dNode {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
// This needs to run at least once to clear the background color, even if there are no items to render
|
let diagnostics = render_context.diagnostic_recorder();
|
||||||
{
|
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
let _main_pass_2d = info_span!("main_transparent_pass_2d").entered();
|
|
||||||
|
|
||||||
let diagnostics = render_context.diagnostic_recorder();
|
render_context.add_command_buffer_generation_task(move |render_device| {
|
||||||
|
// Command encoder setup
|
||||||
|
let mut command_encoder =
|
||||||
|
render_device.create_command_encoder(&CommandEncoderDescriptor {
|
||||||
|
label: Some("main_transparent_pass_2d_command_encoder"),
|
||||||
|
});
|
||||||
|
|
||||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
// This needs to run at least once to clear the background color, even if there are no items to render
|
||||||
label: Some("main_transparent_pass_2d"),
|
{
|
||||||
color_attachments: &[Some(target.get_color_attachment())],
|
|
||||||
// NOTE: For the transparent pass we load the depth buffer. There should be no
|
|
||||||
// need to write to it, but store is set to `true` as a workaround for issue #3776,
|
|
||||||
// https://github.com/bevyengine/bevy/issues/3776
|
|
||||||
// so that wgpu does not clear the depth buffer.
|
|
||||||
// As the opaque and alpha mask passes run first, opaque meshes can occlude
|
|
||||||
// transparent ones.
|
|
||||||
depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)),
|
|
||||||
timestamp_writes: None,
|
|
||||||
occlusion_query_set: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
let pass_span = diagnostics.pass_span(&mut render_pass, "main_transparent_pass_2d");
|
|
||||||
|
|
||||||
if let Some(viewport) = camera.viewport.as_ref() {
|
|
||||||
render_pass.set_camera_viewport(viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !transparent_phase.items.is_empty() {
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let _transparent_main_pass_2d_span =
|
let _main_pass_2d = info_span!("main_transparent_pass_2d").entered();
|
||||||
info_span!("transparent_main_pass_2d").entered();
|
|
||||||
if let Err(err) = transparent_phase.render(&mut render_pass, world, view_entity) {
|
let render_pass = command_encoder.begin_render_pass(&RenderPassDescriptor {
|
||||||
error!("Error encountered while rendering the transparent 2D phase {err:?}");
|
label: Some("main_transparent_pass_2d"),
|
||||||
|
color_attachments: &[Some(target.get_color_attachment())],
|
||||||
|
// NOTE: For the transparent pass we load the depth buffer. There should be no
|
||||||
|
// need to write to it, but store is set to `true` as a workaround for issue #3776,
|
||||||
|
// https://github.com/bevyengine/bevy/issues/3776
|
||||||
|
// so that wgpu does not clear the depth buffer.
|
||||||
|
// As the opaque and alpha mask passes run first, opaque meshes can occlude
|
||||||
|
// transparent ones.
|
||||||
|
depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)),
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
let mut render_pass = TrackedRenderPass::new(&render_device, render_pass);
|
||||||
|
|
||||||
|
let pass_span = diagnostics.pass_span(&mut render_pass, "main_transparent_pass_2d");
|
||||||
|
|
||||||
|
if let Some(viewport) = camera.viewport.as_ref() {
|
||||||
|
render_pass.set_camera_viewport(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !transparent_phase.items.is_empty() {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
let _transparent_main_pass_2d_span =
|
||||||
|
info_span!("transparent_main_pass_2d").entered();
|
||||||
|
if let Err(err) = transparent_phase.render(&mut render_pass, world, view_entity)
|
||||||
|
{
|
||||||
|
error!(
|
||||||
|
"Error encountered while rendering the transparent 2D phase {err:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pass_span.end(&mut render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_span.end(&mut render_pass);
|
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
||||||
}
|
// reset for the next render pass so add an empty render pass without a custom viewport
|
||||||
|
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||||
|
if camera.viewport.is_some() {
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
let _reset_viewport_pass_2d = info_span!("reset_viewport_pass_2d").entered();
|
||||||
|
let pass_descriptor = RenderPassDescriptor {
|
||||||
|
label: Some("reset_viewport_pass_2d"),
|
||||||
|
color_attachments: &[Some(target.get_color_attachment())],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
};
|
||||||
|
|
||||||
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
command_encoder.begin_render_pass(&pass_descriptor);
|
||||||
// reset for the next render pass so add an empty render pass without a custom viewport
|
}
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
|
||||||
if camera.viewport.is_some() {
|
|
||||||
#[cfg(feature = "trace")]
|
|
||||||
let _reset_viewport_pass_2d = info_span!("reset_viewport_pass_2d").entered();
|
|
||||||
let pass_descriptor = RenderPassDescriptor {
|
|
||||||
label: Some("reset_viewport_pass_2d"),
|
|
||||||
color_attachments: &[Some(target.get_color_attachment())],
|
|
||||||
depth_stencil_attachment: None,
|
|
||||||
timestamp_writes: None,
|
|
||||||
occlusion_query_set: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
render_context
|
command_encoder.finish()
|
||||||
.command_encoder()
|
});
|
||||||
.begin_render_pass(&pass_descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user