From e245a26b0256a9186606b7c98841657f8a70a4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kurt=20K=C3=BChnert?= Date: Fri, 23 Dec 2022 14:35:38 +0100 Subject: [PATCH] extract common `RenderPhase` render logic --- .../src/core_2d/main_pass_2d_node.rs | 25 +++---- .../src/core_3d/main_pass_3d_node.rs | 68 ++++++------------- crates/bevy_pbr/src/render/light.rs | 12 +--- crates/bevy_render/src/render_phase/mod.rs | 32 +++++++++ crates/bevy_ui/src/render/render_pass.rs | 14 +--- 5 files changed, 64 insertions(+), 87 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs index d8057b1d00d4f0..1ab2f1dda86ac5 100644 --- a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs +++ b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs @@ -6,7 +6,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_phase::RenderPhase, render_resource::{LoadOp, Operations, RenderPassDescriptor}, renderer::RenderContext, view::{ExtractedView, ViewTarget}, @@ -77,22 +77,13 @@ impl Node for MainPass2dNode { depth_stencil_attachment: None, }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } // WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index a1f17dedf0f064..3ba8e3c0d4a685 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -6,7 +6,7 @@ use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_phase::RenderPhase, render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor}, renderer::RenderContext, view::{ExtractedView, ViewDepthTexture, ViewTarget}, @@ -95,21 +95,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &opaque_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + opaque_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } if !alpha_mask_phase.items.is_empty() { @@ -135,21 +127,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &alpha_mask_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + alpha_mask_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } if !transparent_phase.items.is_empty() { @@ -180,21 +164,13 @@ impl Node for MainPass3dNode { }), }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - if let Some(viewport) = camera.viewport.as_ref() { - tracked_pass.set_camera_viewport(viewport); - } - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render( + world, + render_context, + view_entity, + camera.viewport.as_ref(), + pass_descriptor, + ); } // WebGL2 quirk: if ending with a render pass with a custom viewport, the viewport isn't diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index ec429a23b53890..b4dc6ee52c14bc 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1783,17 +1783,7 @@ impl Node for ShadowPassNode { }), }; - let draw_functions = world.resource::>(); - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for item in &shadow_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_light_entity, item); - } + shadow_phase.render(world, render_context, view_entity, None, pass_descriptor); } } diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 792772c8a08875..2e0b5c641469a7 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -1,10 +1,15 @@ mod draw; 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; /// A resource to collect and sort draw requests for specific [`PhaseItems`](PhaseItem). #[derive(Component)] @@ -29,6 +34,33 @@ impl RenderPhase { pub fn sort(&mut self) { I::sort(&mut self.items); } + + pub fn render( + &self, + world: &World, + render_context: &mut RenderContext, + 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::>(); + let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); + + 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); + } + } } impl RenderPhase { diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 8a4260dd8c2b51..98b1a1acadb5e6 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -85,19 +85,7 @@ impl Node for UiPassNode { depth_stencil_attachment: None, }; - let draw_functions = world.resource::>(); - - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); - - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); - for item in &transparent_phase.items { - let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); - draw_function.draw(world, &mut tracked_pass, view_entity, item); - } + transparent_phase.render(world, render_context, view_entity, None, pass_descriptor); Ok(()) } }