mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +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},
|
||||
};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::render_phase::TrackedRenderPass;
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
||||
|
@ -77,13 +78,16 @@ impl Node for MainPass2dNode {
|
|||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
transparent_phase.render(
|
||||
world,
|
||||
render_context,
|
||||
view_entity,
|
||||
camera.viewport.as_ref(),
|
||||
pass_descriptor,
|
||||
);
|
||||
let render_pass = render_context
|
||||
.command_encoder
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||
|
||||
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
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
|||
core_3d::{AlphaMask3d, Camera3d, Opaque3d, Transparent3d},
|
||||
};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::render_phase::TrackedRenderPass;
|
||||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
|
||||
|
@ -95,13 +96,16 @@ impl Node for MainPass3dNode {
|
|||
}),
|
||||
};
|
||||
|
||||
opaque_phase.render(
|
||||
world,
|
||||
render_context,
|
||||
view_entity,
|
||||
camera.viewport.as_ref(),
|
||||
pass_descriptor,
|
||||
);
|
||||
let render_pass = render_context
|
||||
.command_encoder
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||
|
||||
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() {
|
||||
|
@ -127,13 +131,16 @@ impl Node for MainPass3dNode {
|
|||
}),
|
||||
};
|
||||
|
||||
alpha_mask_phase.render(
|
||||
world,
|
||||
render_context,
|
||||
view_entity,
|
||||
camera.viewport.as_ref(),
|
||||
pass_descriptor,
|
||||
);
|
||||
let render_pass = render_context
|
||||
.command_encoder
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||
|
||||
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() {
|
||||
|
@ -164,13 +171,16 @@ impl Node for MainPass3dNode {
|
|||
}),
|
||||
};
|
||||
|
||||
transparent_phase.render(
|
||||
world,
|
||||
render_context,
|
||||
view_entity,
|
||||
camera.viewport.as_ref(),
|
||||
pass_descriptor,
|
||||
);
|
||||
let render_pass = render_context
|
||||
.command_encoder
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||
|
||||
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
|
||||
|
|
|
@ -1785,13 +1785,12 @@ impl Node for ShadowPassNode {
|
|||
}),
|
||||
};
|
||||
|
||||
shadow_phase.render(
|
||||
world,
|
||||
render_context,
|
||||
view_light_entity,
|
||||
None,
|
||||
pass_descriptor,
|
||||
);
|
||||
let render_pass = render_context
|
||||
.command_encoder
|
||||
.begin_render_pass(&pass_descriptor);
|
||||
let mut render_pass = TrackedRenderPass::new(render_pass);
|
||||
|
||||
shadow_phase.render(&mut render_pass, world, view_light_entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,7 @@ mod draw_state;
|
|||
use bevy_ecs::entity::Entity;
|
||||
pub use draw::*;
|
||||
pub use draw_state::*;
|
||||
use wgpu::RenderPassDescriptor;
|
||||
|
||||
use crate::camera::Viewport;
|
||||
use crate::renderer::RenderContext;
|
||||
use bevy_ecs::prelude::{Component, Query};
|
||||
use bevy_ecs::world::World;
|
||||
|
||||
|
@ -35,29 +32,18 @@ impl<I: PhaseItem> RenderPhase<I> {
|
|||
I::sort(&mut self.items);
|
||||
}
|
||||
|
||||
pub fn render(
|
||||
pub fn render<'w>(
|
||||
&self,
|
||||
world: &World,
|
||||
render_context: &mut RenderContext,
|
||||
render_pass: &mut TrackedRenderPass<'w>,
|
||||
world: &'w World,
|
||||
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 mut draw_functions = draw_functions.write();
|
||||
|
||||
for item in &self.items {
|
||||
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,
|
||||
};
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue