mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
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 <51823519+kurtkuehnert@users.noreply.github.com>
This commit is contained in:
parent
a5b1c46d5b
commit
b833bdab17
5 changed files with 59 additions and 54 deletions
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
core_2d::{camera_2d::Camera2d, Transparent2d},
|
core_2d::{camera_2d::Camera2d, Transparent2d},
|
||||||
};
|
};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
|
use bevy_render::render_phase::TrackedRenderPass;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
camera::ExtractedCamera,
|
camera::ExtractedCamera,
|
||||||
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
||||||
|
@ -77,13 +78,16 @@ impl Node for MainPass2dNode {
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
transparent_phase.render(
|
let render_pass = render_context
|
||||||
world,
|
.command_encoder
|
||||||
render_context,
|
.begin_render_pass(&pass_descriptor);
|
||||||
view_entity,
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
camera.viewport.as_ref(),
|
|
||||||
pass_descriptor,
|
if let Some(viewport) = camera.viewport.as_ref() {
|
||||||
);
|
render_pass.set_camera_viewport(viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
transparent_phase.render(&mut render_pass, world, view_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
core_3d::{AlphaMask3d, Camera3d, Opaque3d, Transparent3d},
|
core_3d::{AlphaMask3d, Camera3d, Opaque3d, Transparent3d},
|
||||||
};
|
};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
|
use bevy_render::render_phase::TrackedRenderPass;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
camera::ExtractedCamera,
|
camera::ExtractedCamera,
|
||||||
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
||||||
|
@ -95,13 +96,16 @@ impl Node for MainPass3dNode {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
opaque_phase.render(
|
let render_pass = render_context
|
||||||
world,
|
.command_encoder
|
||||||
render_context,
|
.begin_render_pass(&pass_descriptor);
|
||||||
view_entity,
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
camera.viewport.as_ref(),
|
|
||||||
pass_descriptor,
|
if let Some(viewport) = camera.viewport.as_ref() {
|
||||||
);
|
render_pass.set_camera_viewport(viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
opaque_phase.render(&mut render_pass, world, view_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !alpha_mask_phase.items.is_empty() {
|
if !alpha_mask_phase.items.is_empty() {
|
||||||
|
@ -127,13 +131,16 @@ impl Node for MainPass3dNode {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
alpha_mask_phase.render(
|
let render_pass = render_context
|
||||||
world,
|
.command_encoder
|
||||||
render_context,
|
.begin_render_pass(&pass_descriptor);
|
||||||
view_entity,
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
camera.viewport.as_ref(),
|
|
||||||
pass_descriptor,
|
if let Some(viewport) = camera.viewport.as_ref() {
|
||||||
);
|
render_pass.set_camera_viewport(viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha_mask_phase.render(&mut render_pass, world, view_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !transparent_phase.items.is_empty() {
|
if !transparent_phase.items.is_empty() {
|
||||||
|
@ -164,13 +171,16 @@ impl Node for MainPass3dNode {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
transparent_phase.render(
|
let render_pass = render_context
|
||||||
world,
|
.command_encoder
|
||||||
render_context,
|
.begin_render_pass(&pass_descriptor);
|
||||||
view_entity,
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
camera.viewport.as_ref(),
|
|
||||||
pass_descriptor,
|
if let Some(viewport) = camera.viewport.as_ref() {
|
||||||
);
|
render_pass.set_camera_viewport(viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
transparent_phase.render(&mut render_pass, world, view_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
// WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't
|
||||||
|
|
|
@ -1785,13 +1785,12 @@ impl Node for ShadowPassNode {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
shadow_phase.render(
|
let render_pass = render_context
|
||||||
world,
|
.command_encoder
|
||||||
render_context,
|
.begin_render_pass(&pass_descriptor);
|
||||||
view_light_entity,
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
None,
|
|
||||||
pass_descriptor,
|
shadow_phase.render(&mut render_pass, world, view_light_entity);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ mod draw_state;
|
||||||
use bevy_ecs::entity::Entity;
|
use bevy_ecs::entity::Entity;
|
||||||
pub use draw::*;
|
pub use draw::*;
|
||||||
pub use draw_state::*;
|
pub use draw_state::*;
|
||||||
use wgpu::RenderPassDescriptor;
|
|
||||||
|
|
||||||
use crate::camera::Viewport;
|
|
||||||
use crate::renderer::RenderContext;
|
|
||||||
use bevy_ecs::prelude::{Component, Query};
|
use bevy_ecs::prelude::{Component, Query};
|
||||||
use bevy_ecs::world::World;
|
use bevy_ecs::world::World;
|
||||||
|
|
||||||
|
@ -35,29 +32,18 @@ impl<I: PhaseItem> RenderPhase<I> {
|
||||||
I::sort(&mut self.items);
|
I::sort(&mut self.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(
|
pub fn render<'w>(
|
||||||
&self,
|
&self,
|
||||||
world: &World,
|
render_pass: &mut TrackedRenderPass<'w>,
|
||||||
render_context: &mut RenderContext,
|
world: &'w World,
|
||||||
view: Entity,
|
view: Entity,
|
||||||
viewport: Option<&Viewport>,
|
|
||||||
pass_descriptor: RenderPassDescriptor,
|
|
||||||
) {
|
) {
|
||||||
let render_pass = render_context
|
|
||||||
.command_encoder
|
|
||||||
.begin_render_pass(&pass_descriptor);
|
|
||||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
|
||||||
|
|
||||||
if let Some(viewport) = viewport {
|
|
||||||
render_pass.set_camera_viewport(viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
let draw_functions = world.resource::<DrawFunctions<I>>();
|
let draw_functions = world.resource::<DrawFunctions<I>>();
|
||||||
let mut draw_functions = draw_functions.write();
|
let mut draw_functions = draw_functions.write();
|
||||||
|
|
||||||
for item in &self.items {
|
for item in &self.items {
|
||||||
let draw_function = draw_functions.get_mut(item.draw_function()).unwrap();
|
let draw_function = draw_functions.get_mut(item.draw_function()).unwrap();
|
||||||
draw_function.draw(world, &mut render_pass, view, item);
|
draw_function.draw(world, render_pass, view, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,13 @@ impl Node for UiPassNode {
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
transparent_phase.render(world, render_context, view_entity, None, pass_descriptor);
|
let render_pass = render_context
|
||||||
|
.command_encoder
|
||||||
|
.begin_render_pass(&pass_descriptor);
|
||||||
|
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||||
|
|
||||||
|
transparent_phase.render(&mut render_pass, world, view_entity);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue