From 54eaa2bdc6a12cc3ba243da0367806d77a63b544 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 30 Jul 2020 13:20:27 -0700 Subject: [PATCH] render: easier msaa color attachments and fix multi-window example --- crates/bevy_render/src/render_graph/base.rs | 55 ++++++++++++--------- crates/bevy_ui/src/render/mod.rs | 35 +++++-------- examples/window/multiple_windows.rs | 55 +++++++++++++++++---- 3 files changed, 88 insertions(+), 57 deletions(-) diff --git a/crates/bevy_render/src/render_graph/base.rs b/crates/bevy_render/src/render_graph/base.rs index 870bfa6c43..c3d8ce21da 100644 --- a/crates/bevy_render/src/render_graph/base.rs +++ b/crates/bevy_render/src/render_graph/base.rs @@ -19,8 +19,29 @@ pub struct Msaa { impl Default for Msaa { fn default() -> Self { - Self { - samples: 4, + Self { samples: 4 } + } +} + +impl Msaa { + pub fn color_attachment_descriptor( + &self, + attachment: TextureAttachment, + resolve_target: TextureAttachment, + ops: Operations, + ) -> RenderPassColorAttachmentDescriptor { + if self.samples > 1 { + RenderPassColorAttachmentDescriptor { + attachment, + resolve_target: Some(resolve_target), + ops, + } + } else { + RenderPassColorAttachmentDescriptor { + attachment, + resolve_target: None, + ops, + } } } } @@ -103,29 +124,15 @@ impl BaseRenderGraphBuilder for RenderGraph { } if config.add_main_pass { - let color_attachment = if msaa.samples > 1 { - RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::Input("color_attachment".to_string()), - resolve_target: Some(TextureAttachment::Input( - "color_resolve_target".to_string(), - )), - ops: Operations { - load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)), - store: true, - }, - } - } else { - RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::Input("color_attachment".to_string()), - resolve_target: None, - ops: Operations { - load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)), - store: true, - }, - } - }; let mut main_pass_node = PassNode::<&MainPass>::new(PassDescriptor { - color_attachments: vec![color_attachment], + color_attachments: vec![msaa.color_attachment_descriptor( + TextureAttachment::Input("color_attachment".to_string()), + TextureAttachment::Input("color_resolve_target".to_string()), + Operations { + load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)), + store: true, + }, + )], depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { attachment: TextureAttachment::Input("depth".to_string()), depth_ops: Some(Operations { diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index e742b105af..e8d2c158e7 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -4,8 +4,8 @@ use bevy_ecs::Resources; use bevy_render::{ camera::ActiveCameras, pass::{ - LoadOp, Operations, PassDescriptor, RenderPassColorAttachmentDescriptor, - RenderPassDepthStencilAttachmentDescriptor, TextureAttachment, + LoadOp, Operations, PassDescriptor, RenderPassDepthStencilAttachmentDescriptor, + TextureAttachment, }, pipeline::*, prelude::Msaa, @@ -86,28 +86,15 @@ impl UiRenderGraphBuilder for RenderGraph { let msaa = resources.get::().unwrap(); pipelines.set(UI_PIPELINE_HANDLE, build_ui_pipeline(&mut shaders)); - let color_attachment = if msaa.samples > 1 { - RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::Input("color_attachment".to_string()), - resolve_target: Some(TextureAttachment::Input("color_resolve_target".to_string())), - ops: Operations { - load: LoadOp::Load, - store: true, - }, - } - } else { - RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::Input("color_attachment".to_string()), - resolve_target: None, - ops: Operations { - load: LoadOp::Load, - store: true, - }, - } - }; - let mut ui_pass_node = PassNode::<&Node>::new(PassDescriptor { - color_attachments: vec![color_attachment], + color_attachments: vec![msaa.color_attachment_descriptor( + TextureAttachment::Input("color_attachment".to_string()), + TextureAttachment::Input("color_resolve_target".to_string()), + Operations { + load: LoadOp::Load, + store: true, + }, + )], depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { attachment: TextureAttachment::Input("depth".to_string()), depth_ops: Some(Operations { @@ -118,6 +105,7 @@ impl UiRenderGraphBuilder for RenderGraph { }), sample_count: msaa.samples, }); + ui_pass_node.add_camera(camera::UI_CAMERA); self.add_node(node::UI_PASS, ui_pass_node); @@ -151,7 +139,6 @@ impl UiRenderGraphBuilder for RenderGraph { .unwrap(); } - // ensure ui pass runs after main pass self.add_node_edge(base::node::MAIN_PASS, node::UI_PASS) .unwrap(); diff --git a/examples/window/multiple_windows.rs b/examples/window/multiple_windows.rs index 9575960954..2a41cafe60 100644 --- a/examples/window/multiple_windows.rs +++ b/examples/window/multiple_windows.rs @@ -8,6 +8,7 @@ use bevy::{ }, window::{CreateWindow, WindowDescriptor, WindowId}, }; +use bevy_render::texture::{Extent3d, TextureDimension}; /// This example creates a second window and draws a mesh from two different cameras. fn main() { @@ -24,6 +25,7 @@ fn setup( mut render_graph: ResMut, mut materials: ResMut>, asset_server: Res, + msaa: Res, ) { let window_id = WindowId::new(); @@ -54,6 +56,7 @@ fn setup( TextureDescriptor { format: TextureFormat::Depth32Float, usage: TextureUsage::OUTPUT_ATTACHMENT, + sample_count: msaa.samples, ..Default::default() }, ), @@ -62,16 +65,16 @@ fn setup( // add a new camera node for our new window render_graph.add_system_node("secondary_camera", CameraNode::new("Secondary")); - // add a new render pass for our new camera + // add a new render pass for our new window / camera let mut second_window_pass = PassNode::<&MainPass>::new(PassDescriptor { - color_attachments: vec![RenderPassColorAttachmentDescriptor { - attachment: TextureAttachment::Input("color".to_string()), - resolve_target: None, - ops: Operations { - load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.1)), + color_attachments: vec![msaa.color_attachment_descriptor( + TextureAttachment::Input("color_attachment".to_string()), + TextureAttachment::Input("color_resolve_target".to_string()), + Operations { + load: LoadOp::Clear(Color::rgb(0.1, 0.1, 0.3)), store: true, }, - }], + )], depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { attachment: TextureAttachment::Input("depth".to_string()), depth_ops: Some(Operations { @@ -80,7 +83,7 @@ fn setup( }), stencil_ops: None, }), - sample_count: 1, + sample_count: msaa.samples, }); second_window_pass.add_camera("Secondary"); @@ -93,7 +96,11 @@ fn setup( "second_window_swap_chain", WindowSwapChainNode::OUT_TEXTURE, "second_window_pass", - "color", + if msaa.samples > 1 { + "color_resolve_target" + } else { + "color_attachment" + }, ) .unwrap(); @@ -110,6 +117,36 @@ fn setup( .add_node_edge("secondary_camera", "second_window_pass") .unwrap(); + if msaa.samples > 1 { + render_graph.add_node( + "second_multi_sampled_color_attachment", + WindowTextureNode::new( + window_id, + TextureDescriptor { + size: Extent3d { + depth: 1, + width: 1, + height: 1, + }, + mip_level_count: 1, + sample_count: msaa.samples, + dimension: TextureDimension::D2, + format: TextureFormat::Bgra8UnormSrgb, + usage: TextureUsage::OUTPUT_ATTACHMENT, + }, + ), + ); + + render_graph + .add_slot_edge( + "second_multi_sampled_color_attachment", + WindowSwapChainNode::OUT_TEXTURE, + "second_window_pass", + "color_attachment", + ) + .unwrap(); + } + // SETUP SCENE // load the mesh