Skip to content

Commit b833bda

Browse files
committed
Allow to reuse the same RenderPass for multiple RenderPhases (#7043)
# Objective - The recently merged PR #7013 does not allow multiple `RenderPhase`s to share the same `RenderPass`. - Due to the introduced overhead we want to minimize the number of `RenderPass`es recorded during each frame. ## Solution - Take a constructed `TrackedRenderPass` instead of a `RenderPassDiscriptor` as a parameter to the `RenderPhase::render` method. --- ## Changelog To enable multiple `RenderPhases` to share the same `TrackedRenderPass`, the `RenderPhase::render` signature has changed. ```rust pub fn render<'w>( &self, render_pass: &mut TrackedRenderPass<'w>, world: &'w World, view: Entity) ``` Co-authored-by: Kurt Kühnert <[email protected]>
1 parent a5b1c46 commit b833bda

File tree

5 files changed

+59
-54
lines changed

5 files changed

+59
-54
lines changed

crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
core_2d::{camera_2d::Camera2d, Transparent2d},
44
};
55
use bevy_ecs::prelude::*;
6+
use bevy_render::render_phase::TrackedRenderPass;
67
use bevy_render::{
78
camera::ExtractedCamera,
89
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
@@ -77,13 +78,16 @@ impl Node for MainPass2dNode {
7778
depth_stencil_attachment: None,
7879
};
7980

80-
transparent_phase.render(
81-
world,
82-
render_context,
83-
view_entity,
84-
camera.viewport.as_ref(),
85-
pass_descriptor,
86-
);
81+
let render_pass = render_context
82+
.command_encoder
83+
.begin_render_pass(&pass_descriptor);
84+
let mut render_pass = TrackedRenderPass::new(render_pass);
85+
86+
if let Some(viewport) = camera.viewport.as_ref() {
87+
render_pass.set_camera_viewport(viewport);
88+
}
89+
90+
transparent_phase.render(&mut render_pass, world, view_entity);
8791
}
8892

8993
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't

crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
core_3d::{AlphaMask3d, Camera3d, Opaque3d, Transparent3d},
44
};
55
use bevy_ecs::prelude::*;
6+
use bevy_render::render_phase::TrackedRenderPass;
67
use bevy_render::{
78
camera::ExtractedCamera,
89
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
@@ -95,13 +96,16 @@ impl Node for MainPass3dNode {
9596
}),
9697
};
9798

98-
opaque_phase.render(
99-
world,
100-
render_context,
101-
view_entity,
102-
camera.viewport.as_ref(),
103-
pass_descriptor,
104-
);
99+
let render_pass = render_context
100+
.command_encoder
101+
.begin_render_pass(&pass_descriptor);
102+
let mut render_pass = TrackedRenderPass::new(render_pass);
103+
104+
if let Some(viewport) = camera.viewport.as_ref() {
105+
render_pass.set_camera_viewport(viewport);
106+
}
107+
108+
opaque_phase.render(&mut render_pass, world, view_entity);
105109
}
106110

107111
if !alpha_mask_phase.items.is_empty() {
@@ -127,13 +131,16 @@ impl Node for MainPass3dNode {
127131
}),
128132
};
129133

130-
alpha_mask_phase.render(
131-
world,
132-
render_context,
133-
view_entity,
134-
camera.viewport.as_ref(),
135-
pass_descriptor,
136-
);
134+
let render_pass = render_context
135+
.command_encoder
136+
.begin_render_pass(&pass_descriptor);
137+
let mut render_pass = TrackedRenderPass::new(render_pass);
138+
139+
if let Some(viewport) = camera.viewport.as_ref() {
140+
render_pass.set_camera_viewport(viewport);
141+
}
142+
143+
alpha_mask_phase.render(&mut render_pass, world, view_entity);
137144
}
138145

139146
if !transparent_phase.items.is_empty() {
@@ -164,13 +171,16 @@ impl Node for MainPass3dNode {
164171
}),
165172
};
166173

167-
transparent_phase.render(
168-
world,
169-
render_context,
170-
view_entity,
171-
camera.viewport.as_ref(),
172-
pass_descriptor,
173-
);
174+
let render_pass = render_context
175+
.command_encoder
176+
.begin_render_pass(&pass_descriptor);
177+
let mut render_pass = TrackedRenderPass::new(render_pass);
178+
179+
if let Some(viewport) = camera.viewport.as_ref() {
180+
render_pass.set_camera_viewport(viewport);
181+
}
182+
183+
transparent_phase.render(&mut render_pass, world, view_entity);
174184
}
175185

176186
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't

crates/bevy_pbr/src/render/light.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,13 +1785,12 @@ impl Node for ShadowPassNode {
17851785
}),
17861786
};
17871787

1788-
shadow_phase.render(
1789-
world,
1790-
render_context,
1791-
view_light_entity,
1792-
None,
1793-
pass_descriptor,
1794-
);
1788+
let render_pass = render_context
1789+
.command_encoder
1790+
.begin_render_pass(&pass_descriptor);
1791+
let mut render_pass = TrackedRenderPass::new(render_pass);
1792+
1793+
shadow_phase.render(&mut render_pass, world, view_light_entity);
17951794
}
17961795
}
17971796

crates/bevy_render/src/render_phase/mod.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ mod draw_state;
44
use bevy_ecs::entity::Entity;
55
pub use draw::*;
66
pub use draw_state::*;
7-
use wgpu::RenderPassDescriptor;
87

9-
use crate::camera::Viewport;
10-
use crate::renderer::RenderContext;
118
use bevy_ecs::prelude::{Component, Query};
129
use bevy_ecs::world::World;
1310

@@ -35,29 +32,18 @@ impl<I: PhaseItem> RenderPhase<I> {
3532
I::sort(&mut self.items);
3633
}
3734

38-
pub fn render(
35+
pub fn render<'w>(
3936
&self,
40-
world: &World,
41-
render_context: &mut RenderContext,
37+
render_pass: &mut TrackedRenderPass<'w>,
38+
world: &'w World,
4239
view: Entity,
43-
viewport: Option<&Viewport>,
44-
pass_descriptor: RenderPassDescriptor,
4540
) {
46-
let render_pass = render_context
47-
.command_encoder
48-
.begin_render_pass(&pass_descriptor);
49-
let mut render_pass = TrackedRenderPass::new(render_pass);
50-
51-
if let Some(viewport) = viewport {
52-
render_pass.set_camera_viewport(viewport);
53-
}
54-
5541
let draw_functions = world.resource::<DrawFunctions<I>>();
5642
let mut draw_functions = draw_functions.write();
5743

5844
for item in &self.items {
5945
let draw_function = draw_functions.get_mut(item.draw_function()).unwrap();
60-
draw_function.draw(world, &mut render_pass, view, item);
46+
draw_function.draw(world, render_pass, view, item);
6147
}
6248
}
6349
}

crates/bevy_ui/src/render/render_pass.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,13 @@ impl Node for UiPassNode {
8585
depth_stencil_attachment: None,
8686
};
8787

88-
transparent_phase.render(world, render_context, view_entity, None, pass_descriptor);
88+
let render_pass = render_context
89+
.command_encoder
90+
.begin_render_pass(&pass_descriptor);
91+
let mut render_pass = TrackedRenderPass::new(render_pass);
92+
93+
transparent_phase.render(&mut render_pass, world, view_entity);
94+
8995
Ok(())
9096
}
9197
}

0 commit comments

Comments
 (0)