diff --git a/crates/bevy_anti_aliasing/src/contrast_adaptive_sharpening/node.rs b/crates/bevy_anti_aliasing/src/contrast_adaptive_sharpening/node.rs index 070b57099707e..c1e6ccdda02c3 100644 --- a/crates/bevy_anti_aliasing/src/contrast_adaptive_sharpening/node.rs +++ b/crates/bevy_anti_aliasing/src/contrast_adaptive_sharpening/node.rs @@ -3,6 +3,7 @@ use std::sync::Mutex; use crate::contrast_adaptive_sharpening::ViewCasPipeline; use bevy_ecs::prelude::*; use bevy_render::{ + diagnostic::RecordDiagnostics, extract_component::{ComponentUniforms, DynamicUniformIndex}, render_graph::{Node, NodeRunError, RenderGraphContext}, render_resource::{ @@ -66,6 +67,8 @@ impl Node for CasNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let view_target = target.post_process_write(); let source = view_target.source; let destination = view_target.destination; @@ -110,11 +113,14 @@ impl Node for CasNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.time_span(&mut render_pass, "contrast_adaptive_sharpening"); render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, bind_group, &[uniform_index.index()]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_anti_aliasing/src/fxaa/node.rs b/crates/bevy_anti_aliasing/src/fxaa/node.rs index 8881607cba4e4..54d2afd33e736 100644 --- a/crates/bevy_anti_aliasing/src/fxaa/node.rs +++ b/crates/bevy_anti_aliasing/src/fxaa/node.rs @@ -3,6 +3,7 @@ use std::sync::Mutex; use crate::fxaa::{CameraFxaaPipeline, Fxaa, FxaaPipeline}; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ BindGroup, BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment, @@ -42,6 +43,8 @@ impl ViewNode for FxaaNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let post_process = target.post_process_write(); let source = post_process.source; let destination = post_process.destination; @@ -61,7 +64,7 @@ impl ViewNode for FxaaNode { }; let pass_descriptor = RenderPassDescriptor { - label: Some("fxaa_pass"), + label: Some("fxaa"), color_attachments: &[Some(RenderPassColorAttachment { view: destination, depth_slice: None, @@ -76,11 +79,14 @@ impl ViewNode for FxaaNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.pass_span(&mut render_pass, "fxaa"); render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_anti_aliasing/src/smaa/mod.rs b/crates/bevy_anti_aliasing/src/smaa/mod.rs index cafab566a0732..d54dff8e9ce5d 100644 --- a/crates/bevy_anti_aliasing/src/smaa/mod.rs +++ b/crates/bevy_anti_aliasing/src/smaa/mod.rs @@ -53,6 +53,7 @@ use bevy_math::{vec4, Vec4}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, extract_component::{ExtractComponent, ExtractComponentPlugin}, render_asset::RenderAssets, render_graph::{ @@ -824,6 +825,10 @@ impl ViewNode for SmaaNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + render_context.command_encoder().push_debug_group("smaa"); + let time_span = diagnostics.time_span(render_context.command_encoder(), "smaa"); + // Fetch the framebuffer textures. let postprocess = view_target.post_process_write(); let (source, destination) = (postprocess.source, postprocess.destination); @@ -864,6 +869,9 @@ impl ViewNode for SmaaNode { destination, ); + time_span.end(render_context.command_encoder()); + render_context.command_encoder().pop_debug_group(); + Ok(()) } } diff --git a/crates/bevy_anti_aliasing/src/taa/mod.rs b/crates/bevy_anti_aliasing/src/taa/mod.rs index 658e31aa586f6..263ebd00436ff 100644 --- a/crates/bevy_anti_aliasing/src/taa/mod.rs +++ b/crates/bevy_anti_aliasing/src/taa/mod.rs @@ -20,6 +20,7 @@ use bevy_math::vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ camera::{ExtractedCamera, MipBias, TemporalJitter}, + diagnostic::RecordDiagnostics, prelude::{Camera, Projection}, render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, render_resource::{ @@ -181,6 +182,9 @@ impl ViewNode for TemporalAntiAliasNode { ) else { return Ok(()); }; + + let diagnostics = render_context.diagnostic_recorder(); + let view_target = view_target.post_process_write(); let taa_bind_group = render_context.render_device().create_bind_group( @@ -198,7 +202,7 @@ impl ViewNode for TemporalAntiAliasNode { { let mut taa_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("taa_pass"), + label: Some("taa"), color_attachments: &[ Some(RenderPassColorAttachment { view: view_target.destination, @@ -217,12 +221,16 @@ impl ViewNode for TemporalAntiAliasNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut taa_pass, "taa"); + taa_pass.set_render_pipeline(taa_pipeline); taa_pass.set_bind_group(0, &taa_bind_group, &[]); if let Some(viewport) = camera.viewport.as_ref() { taa_pass.set_camera_viewport(viewport); } taa_pass.draw(0..3, 0..1); + + pass_span.end(&mut taa_pass); } Ok(()) diff --git a/crates/bevy_core_pipeline/src/auto_exposure/node.rs b/crates/bevy_core_pipeline/src/auto_exposure/node.rs index 222efe5c62bd0..c7f88dfb28d6f 100644 --- a/crates/bevy_core_pipeline/src/auto_exposure/node.rs +++ b/crates/bevy_core_pipeline/src/auto_exposure/node.rs @@ -10,6 +10,7 @@ use bevy_ecs::{ world::{FromWorld, World}, }; use bevy_render::{ + diagnostic::RecordDiagnostics, globals::GlobalsBuffer, render_asset::RenderAssets, render_graph::*, @@ -98,6 +99,8 @@ impl Node for AutoExposureNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let compute_bind_group = render_context.render_device().create_bind_group( None, &pipeline.histogram_layout, @@ -122,9 +125,10 @@ impl Node for AutoExposureNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("auto_exposure_pass"), + label: Some("auto_exposure"), timestamp_writes: None, }); + let pass_span = diagnostics.time_span(&mut compute_pass, "auto_exposure"); compute_pass.set_bind_group(0, &compute_bind_group, &[view_uniform_offset.offset]); compute_pass.set_pipeline(histogram_pipeline); @@ -136,6 +140,8 @@ impl Node for AutoExposureNode { compute_pass.set_pipeline(average_pipeline); compute_pass.dispatch_workgroups(1, 1, 1); + pass_span.end(&mut compute_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs index ec108b8753924..37d359785bfd6 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_transmissive_pass_3d_node.rs @@ -5,6 +5,7 @@ use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_image::ToExtents; use bevy_render::{ camera::{ExtractedCamera, MainPassResolutionOverride}, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_phase::ViewSortedRenderPhases, render_resource::{RenderPassDescriptor, StoreOp}, @@ -53,6 +54,8 @@ impl ViewNode for MainTransmissivePass3dNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let physical_target_size = camera.physical_target_size.unwrap(); let render_pass_descriptor = RenderPassDescriptor { @@ -95,6 +98,8 @@ impl ViewNode for MainTransmissivePass3dNode { let mut render_pass = render_context.begin_tracked_render_pass(render_pass_descriptor.clone()); + let pass_span = + diagnostics.pass_span(&mut render_pass, "main_transmissive_pass_3d"); if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); @@ -106,10 +111,14 @@ impl ViewNode for MainTransmissivePass3dNode { { error!("Error encountered while rendering the transmissive phase {err:?}"); } + + pass_span.end(&mut render_pass); } } else { let mut render_pass = render_context.begin_tracked_render_pass(render_pass_descriptor); + let pass_span = + diagnostics.pass_span(&mut render_pass, "main_transmissive_pass_3d"); if let Some(viewport) = Viewport::from_viewport_and_override( camera.viewport.as_ref(), @@ -121,6 +130,8 @@ impl ViewNode for MainTransmissivePass3dNode { if let Err(err) = transmissive_phase.render(&mut render_pass, world, view_entity) { error!("Error encountered while rendering the transmissive phase {err:?}"); } + + pass_span.end(&mut render_pass); } } diff --git a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs index 9a23c0e34d752..68d1634160f8a 100644 --- a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs +++ b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs @@ -8,6 +8,7 @@ use bevy_ecs::prelude::*; use bevy_image::ToExtents; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, render_resource::{binding_types::texture_2d, *}, renderer::RenderDevice, texture::{CachedTexture, TextureCache}, @@ -77,6 +78,8 @@ impl ViewNode for CopyDeferredLightingIdNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let bind_group = render_context.render_device().create_bind_group( "copy_deferred_lighting_id_bind_group", ©_deferred_lighting_id_pipeline.layout, @@ -84,7 +87,7 @@ impl ViewNode for CopyDeferredLightingIdNode { ); let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("copy_deferred_lighting_id_pass"), + label: Some("copy_deferred_lighting_id"), color_attachments: &[], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &deferred_lighting_id_depth_texture.texture.default_view, @@ -98,10 +101,14 @@ impl ViewNode for CopyDeferredLightingIdNode { occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "copy_deferred_lighting_id"); + render_pass.set_render_pipeline(pipeline); render_pass.set_bind_group(0, &bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/deferred/node.rs b/crates/bevy_core_pipeline/src/deferred/node.rs index ffd51763ca88b..db983c9043567 100644 --- a/crates/bevy_core_pipeline/src/deferred/node.rs +++ b/crates/bevy_core_pipeline/src/deferred/node.rs @@ -7,6 +7,7 @@ use bevy_render::render_graph::ViewNode; use bevy_render::view::{ExtractedView, NoIndirectDrawing}; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext}, render_phase::{TrackedRenderPass, ViewBinnedRenderPhases}, render_resource::{CommandEncoderDescriptor, RenderPassDescriptor, StoreOp}, @@ -131,6 +132,8 @@ fn run_deferred_prepass<'w>( return Ok(()); }; + let diagnostic = render_context.diagnostic_recorder(); + let mut color_attachments = vec![]; color_attachments.push( view_prepass_textures @@ -223,6 +226,7 @@ fn run_deferred_prepass<'w>( occlusion_query_set: None, }); let mut render_pass = TrackedRenderPass::new(&render_device, render_pass); + let pass_span = diagnostic.pass_span(&mut render_pass, label); if let Some(viewport) = Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override) { @@ -251,6 +255,7 @@ fn run_deferred_prepass<'w>( } } + pass_span.end(&mut render_pass); drop(render_pass); // After rendering to the view depth texture, copy it to the prepass depth texture diff --git a/crates/bevy_core_pipeline/src/dof/mod.rs b/crates/bevy_core_pipeline/src/dof/mod.rs index 0e65c4d0a4dfa..51ec0b97af61d 100644 --- a/crates/bevy_core_pipeline/src/dof/mod.rs +++ b/crates/bevy_core_pipeline/src/dof/mod.rs @@ -32,6 +32,7 @@ use bevy_math::ops; use bevy_reflect::{prelude::ReflectDefault, Reflect}; use bevy_render::{ camera::{PhysicalCameraParameters, Projection}, + diagnostic::RecordDiagnostics, extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, render_graph::{ NodeRunError, RenderGraphContext, RenderGraphExt as _, ViewNode, ViewNodeRunner, @@ -354,6 +355,8 @@ impl ViewNode for DepthOfFieldNode { let view_uniforms = world.resource::(); let global_bind_group = world.resource::(); + let diagnostics = render_context.diagnostic_recorder(); + // We can be in either Gaussian blur or bokeh mode here. Both modes are // similar, consisting of two passes each. We factor out the information // specific to each pass into @@ -448,6 +451,9 @@ impl ViewNode for DepthOfFieldNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&render_pass_descriptor); + let pass_span = + diagnostics.pass_span(&mut render_pass, pipeline_render_info.pass_label); + render_pass.set_pipeline(render_pipeline); // Set the per-view bind group. render_pass.set_bind_group(0, &view_bind_group, &[view_uniform_offset.offset]); @@ -459,6 +465,8 @@ impl ViewNode for DepthOfFieldNode { ); // Render the full-screen pass. render_pass.draw(0..3, 0..1); + + pass_span.end(&mut render_pass); } Ok(()) diff --git a/crates/bevy_core_pipeline/src/motion_blur/node.rs b/crates/bevy_core_pipeline/src/motion_blur/node.rs index 5fb8eeebcdc02..00e4d4df873d5 100644 --- a/crates/bevy_core_pipeline/src/motion_blur/node.rs +++ b/crates/bevy_core_pipeline/src/motion_blur/node.rs @@ -1,5 +1,6 @@ use bevy_ecs::{query::QueryItem, world::World}; use bevy_render::{ + diagnostic::RecordDiagnostics, extract_component::ComponentUniforms, globals::GlobalsBuffer, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, @@ -59,6 +60,8 @@ impl ViewNode for MotionBlurNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let post_process = view_target.post_process_write(); let layout = if msaa.samples() == 1 { @@ -81,7 +84,7 @@ impl ViewNode for MotionBlurNode { ); let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("motion_blur_pass"), + label: Some("motion_blur"), color_attachments: &[Some(RenderPassColorAttachment { view: post_process.destination, depth_slice: None, @@ -92,11 +95,14 @@ impl ViewNode for MotionBlurNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "motion_blur"); render_pass.set_render_pipeline(pipeline); render_pass.set_bind_group(0, &bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/msaa_writeback.rs b/crates/bevy_core_pipeline/src/msaa_writeback.rs index 4b63de7dad131..f1a833047fbb1 100644 --- a/crates/bevy_core_pipeline/src/msaa_writeback.rs +++ b/crates/bevy_core_pipeline/src/msaa_writeback.rs @@ -8,6 +8,7 @@ use bevy_color::LinearRgba; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, render_resource::*, renderer::RenderContext, @@ -74,6 +75,8 @@ impl ViewNode for MsaaWritebackNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + // The current "main texture" needs to be bound as an input resource, and we need the "other" // unused target to be the "resolve target" for the MSAA write. Therefore this is the same // as a post process write! @@ -105,11 +108,14 @@ impl ViewNode for MsaaWritebackNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.pass_span(&mut render_pass, "msaa_writeback"); render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, &bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/oit/resolve/node.rs b/crates/bevy_core_pipeline/src/oit/resolve/node.rs index 83b8c604f442a..b09ad63d21962 100644 --- a/crates/bevy_core_pipeline/src/oit/resolve/node.rs +++ b/crates/bevy_core_pipeline/src/oit/resolve/node.rs @@ -2,6 +2,7 @@ use bevy_camera::Viewport; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ camera::{ExtractedCamera, MainPassResolutionOverride}, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, RenderLabel, ViewNode}, render_resource::{BindGroupEntries, PipelineCache, RenderPassDescriptor}, renderer::RenderContext, @@ -50,6 +51,8 @@ impl ViewNode for OitResolveNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let depth_bind_group = render_context.render_device().create_bind_group( "oit_resolve_depth_bind_group", &resolve_pipeline.oit_depth_bind_group_layout, @@ -57,12 +60,13 @@ impl ViewNode for OitResolveNode { ); let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("oit_resolve_pass"), + label: Some("oit_resolve"), color_attachments: &[Some(view_target.get_color_attachment())], depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "oit_resolve"); if let Some(viewport) = Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override) @@ -75,6 +79,8 @@ impl ViewNode for OitResolveNode { render_pass.set_bind_group(1, &depth_bind_group, &[]); render_pass.draw(0..3, 0..1); + + pass_span.end(&mut render_pass); } Ok(()) diff --git a/crates/bevy_core_pipeline/src/post_process/mod.rs b/crates/bevy_core_pipeline/src/post_process/mod.rs index 72eac853a7d86..229d4e32c3aa6 100644 --- a/crates/bevy_core_pipeline/src/post_process/mod.rs +++ b/crates/bevy_core_pipeline/src/post_process/mod.rs @@ -19,6 +19,7 @@ use bevy_image::{BevyDefault, Image}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ camera::Camera, + diagnostic::RecordDiagnostics, extract_component::{ExtractComponent, ExtractComponentPlugin}, load_shader_library, render_asset::{RenderAssetUsages, RenderAssets}, @@ -371,12 +372,14 @@ impl ViewNode for PostProcessingNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + // Use the [`PostProcessWrite`] infrastructure, since this is a // full-screen pass. let post_process = view_target.post_process_write(); let pass_descriptor = RenderPassDescriptor { - label: Some("postprocessing pass"), + label: Some("postprocessing"), color_attachments: &[Some(RenderPassColorAttachment { view: post_process.destination, depth_slice: None, @@ -403,11 +406,14 @@ impl ViewNode for PostProcessingNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.pass_span(&mut render_pass, "postprocessing"); render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, &bind_group, &[**post_processing_uniform_buffer_offsets]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/tonemapping/node.rs b/crates/bevy_core_pipeline/src/tonemapping/node.rs index 58dd673264d18..d14f1251fc4b6 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/node.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/node.rs @@ -4,6 +4,7 @@ use crate::tonemapping::{TonemappingLuts, TonemappingPipeline, ViewTonemappingPi use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ + diagnostic::RecordDiagnostics, render_asset::RenderAssets, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ @@ -60,6 +61,8 @@ impl ViewNode for TonemappingNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let post_process = target.post_process_write(); let source = post_process.source; let destination = post_process.destination; @@ -114,7 +117,7 @@ impl ViewNode for TonemappingNode { }; let pass_descriptor = RenderPassDescriptor { - label: Some("tonemapping_pass"), + label: Some("tonemapping"), color_attachments: &[Some(RenderPassColorAttachment { view: destination, depth_slice: None, @@ -132,11 +135,14 @@ impl ViewNode for TonemappingNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.pass_span(&mut render_pass, "tonemapping"); render_pass.set_pipeline(pipeline); render_pass.set_bind_group(0, bind_group, &[view_uniform_offset.offset]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/upscaling/node.rs b/crates/bevy_core_pipeline/src/upscaling/node.rs index 493a1484c6e0d..93fc7d447856b 100644 --- a/crates/bevy_core_pipeline/src/upscaling/node.rs +++ b/crates/bevy_core_pipeline/src/upscaling/node.rs @@ -2,6 +2,7 @@ use crate::{blit::BlitPipeline, upscaling::ViewUpscalingPipeline}; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_render::{ camera::{CameraOutputMode, ClearColor, ClearColorConfig, ExtractedCamera}, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{BindGroup, PipelineCache, RenderPassDescriptor, TextureViewId}, renderer::RenderContext, @@ -32,6 +33,8 @@ impl ViewNode for UpscalingNode { let blit_pipeline = world.resource::(); let clear_color_global = world.resource::(); + let diagnostics = render_context.diagnostic_recorder(); + let clear_color = if let Some(camera) = camera { match camera.output_mode { CameraOutputMode::Write { clear_color, .. } => clear_color, @@ -67,7 +70,7 @@ impl ViewNode for UpscalingNode { }; let pass_descriptor = RenderPassDescriptor { - label: Some("upscaling_pass"), + label: Some("upscaling"), color_attachments: &[Some( target.out_texture_color_attachment(converted_clear_color), )], @@ -79,6 +82,7 @@ impl ViewNode for UpscalingNode { let mut render_pass = render_context .command_encoder() .begin_render_pass(&pass_descriptor); + let pass_span = diagnostics.pass_span(&mut render_pass, "upscaling"); if let Some(camera) = camera { if let Some(viewport) = &camera.viewport { @@ -92,6 +96,8 @@ impl ViewNode for UpscalingNode { render_pass.set_bind_group(0, bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_pbr/src/atmosphere/node.rs b/crates/bevy_pbr/src/atmosphere/node.rs index e09b27c590a04..93c1a33ae9db2 100644 --- a/crates/bevy_pbr/src/atmosphere/node.rs +++ b/crates/bevy_pbr/src/atmosphere/node.rs @@ -1,6 +1,7 @@ use bevy_ecs::{query::QueryItem, system::lifetimeless::Read, world::World}; use bevy_math::{UVec2, Vec3Swizzles}; use bevy_render::{ + diagnostic::RecordDiagnostics, extract_component::DynamicUniformIndex, render_graph::{NodeRunError, RenderGraphContext, RenderLabel, ViewNode}, render_resource::{ComputePass, ComputePassDescriptor, PipelineCache, RenderPassDescriptor}, @@ -70,12 +71,15 @@ impl ViewNode for AtmosphereLutsNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let command_encoder = render_context.command_encoder(); let mut luts_pass = command_encoder.begin_compute_pass(&ComputePassDescriptor { - label: Some("atmosphere_luts_pass"), + label: Some("atmosphere_luts"), timestamp_writes: None, }); + let pass_span = diagnostics.time_span(&mut luts_pass, "atmosphere_luts"); fn dispatch_2d(compute_pass: &mut ComputePass, size: UVec2) { const WORKGROUP_SIZE: u32 = 16; @@ -149,6 +153,8 @@ impl ViewNode for AtmosphereLutsNode { dispatch_2d(&mut luts_pass, settings.aerial_view_lut_size.xy()); + pass_span.end(&mut luts_pass); + Ok(()) } } @@ -191,16 +197,19 @@ impl ViewNode for RenderSkyNode { return Ok(()); }; //TODO: warning + let diagnostics = render_context.diagnostic_recorder(); + let mut render_sky_pass = render_context .command_encoder() .begin_render_pass(&RenderPassDescriptor { - label: Some("render_sky_pass"), + label: Some("render_sky"), color_attachments: &[Some(view_target.get_color_attachment())], depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_sky_pass, "render_sky"); render_sky_pass.set_pipeline(render_sky_pipeline); render_sky_pass.set_bind_group( @@ -216,6 +225,8 @@ impl ViewNode for RenderSkyNode { ); render_sky_pass.draw(0..3, 0..1); + pass_span.end(&mut render_sky_pass); + Ok(()) } } diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 3c303331ffc11..d1ca01fd1c7c5 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -21,6 +21,7 @@ use bevy_image::BevyDefault as _; use bevy_light::{EnvironmentMapLight, ShadowFilteringMethod}; use bevy_render::RenderStartup; use bevy_render::{ + diagnostic::RecordDiagnostics, extract_component::{ ComponentUniforms, ExtractComponent, ExtractComponentPlugin, UniformComponentPlugin, }, @@ -177,6 +178,8 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let bind_group_2 = render_context.render_device().create_bind_group( "deferred_lighting_layout_group_2", &deferred_lighting_layout.bind_group_layout_2, @@ -184,7 +187,7 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { ); let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("deferred_lighting_pass"), + label: Some("deferred_lighting"), color_attachments: &[Some(target.get_color_attachment())], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &deferred_lighting_id_depth_texture.texture.default_view, @@ -197,6 +200,7 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "deferred_lighting"); render_pass.set_render_pipeline(pipeline); render_pass.set_bind_group( @@ -215,6 +219,8 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { render_pass.set_bind_group(2, &bind_group_2, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_pbr/src/light_probe/generate.rs b/crates/bevy_pbr/src/light_probe/generate.rs index 85213119dc625..1cb0f91a09f77 100644 --- a/crates/bevy_pbr/src/light_probe/generate.rs +++ b/crates/bevy_pbr/src/light_probe/generate.rs @@ -921,11 +921,11 @@ impl Node for DownsamplingNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("lightprobe_copy_pass"), + label: Some("lightprobe_copy"), timestamp_writes: None, }); - let pass_span = diagnostics.pass_span(&mut compute_pass, "lightprobe_copy_pass"); + let pass_span = diagnostics.pass_span(&mut compute_pass, "lightprobe_copy"); compute_pass.set_pipeline(copy_pipeline); compute_pass.set_bind_group(0, &bind_groups.copy, &[]); @@ -1038,12 +1038,11 @@ impl Node for FilteringNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("lightprobe_radiance_map_pass"), + label: Some("lightprobe_radiance_map"), timestamp_writes: None, }); - let pass_span = - diagnostics.pass_span(&mut compute_pass, "lightprobe_radiance_map_pass"); + let pass_span = diagnostics.pass_span(&mut compute_pass, "lightprobe_radiance_map"); compute_pass.set_pipeline(radiance_pipeline); @@ -1072,12 +1071,12 @@ impl Node for FilteringNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("lightprobe_irradiance_map_pass"), + label: Some("lightprobe_irradiance_map"), timestamp_writes: None, }); let irr_span = - diagnostics.pass_span(&mut compute_pass, "lightprobe_irradiance_map_pass"); + diagnostics.pass_span(&mut compute_pass, "lightprobe_irradiance_map"); compute_pass.set_pipeline(irradiance_pipeline); compute_pass.set_bind_group(0, &bind_groups.irradiance, &[]); diff --git a/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs b/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs index b0e34d5e1a79a..9c0b4c4843fcf 100644 --- a/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs +++ b/crates/bevy_pbr/src/meshlet/material_shade_nodes.rs @@ -20,6 +20,7 @@ use bevy_ecs::{ }; use bevy_render::{ camera::{ExtractedCamera, MainPassResolutionOverride}, + diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor, @@ -89,8 +90,10 @@ impl ViewNode for MeshletMainOpaquePass3dNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("meshlet_main_opaque_pass_3d"), + label: Some("meshlet_material_opaque_3d_pass"), color_attachments: &[Some(target.get_color_attachment())], depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &meshlet_material_depth.default_view, @@ -103,6 +106,7 @@ impl ViewNode for MeshletMainOpaquePass3dNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "meshlet_material_opaque_3d_pass"); if let Some(viewport) = Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override) { @@ -140,6 +144,8 @@ impl ViewNode for MeshletMainOpaquePass3dNode { } } + pass_span.end(&mut render_pass); + Ok(()) } } @@ -198,6 +204,8 @@ impl ViewNode for MeshletPrepassNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let color_attachments = vec![ view_prepass_textures .normal @@ -213,7 +221,7 @@ impl ViewNode for MeshletPrepassNode { ]; let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("meshlet_prepass"), + label: Some("meshlet_material_prepass"), color_attachments: &color_attachments, depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &meshlet_material_depth.default_view, @@ -226,6 +234,7 @@ impl ViewNode for MeshletPrepassNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "meshlet_material_prepass"); if let Some(viewport) = Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override) { @@ -268,6 +277,8 @@ impl ViewNode for MeshletPrepassNode { } } + pass_span.end(&mut render_pass); + Ok(()) } } @@ -345,8 +356,10 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode { .map(|deferred_lighting_pass_id| deferred_lighting_pass_id.get_attachment()), ]; + let diagnostics = render_context.diagnostic_recorder(); + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("meshlet_deferred_prepass"), + label: Some("meshlet_material_deferred_prepass"), color_attachments: &color_attachments, depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { view: &meshlet_material_depth.default_view, @@ -359,6 +372,8 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = + diagnostics.pass_span(&mut render_pass, "meshlet_material_deferred_prepass"); if let Some(viewport) = Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override) { @@ -401,6 +416,8 @@ impl ViewNode for MeshletDeferredGBufferPrepassNode { } } + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs index 10104e10eefd9..e056853be39b5 100644 --- a/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs +++ b/crates/bevy_pbr/src/meshlet/visibility_buffer_raster_node.rs @@ -14,6 +14,7 @@ use bevy_ecs::{ use bevy_math::UVec2; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, render_graph::{Node, NodeRunError, RenderGraphContext}, render_resource::*, renderer::RenderContext, @@ -104,9 +105,15 @@ impl Node for MeshletVisibilityBufferRasterPassNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + render_context .command_encoder() .push_debug_group("meshlet_visibility_buffer_raster"); + let time_span = diagnostics.time_span( + render_context.command_encoder(), + "meshlet_visibility_buffer_raster", + ); let resource_manager = world.get_resource::().unwrap(); render_context.command_encoder().clear_buffer( @@ -239,6 +246,10 @@ impl Node for MeshletVisibilityBufferRasterPassNode { "meshlet_visibility_buffer_raster: {}", shadow_view.pass_name )); + let pass_span = diagnostics.time_span( + render_context.command_encoder(), + shadow_view.pass_name.clone(), + ); clear_visibility_buffer_pass( render_context, &meshlet_view_bind_groups.clear_visibility_buffer, @@ -331,8 +342,11 @@ impl Node for MeshletVisibilityBufferRasterPassNode { downsample_depth_second_shadow_view_pipeline, ); render_context.command_encoder().pop_debug_group(); + pass_span.end(render_context.command_encoder()); } + time_span.end(render_context.command_encoder()); + Ok(()) } } diff --git a/crates/bevy_pbr/src/render/gpu_preprocess.rs b/crates/bevy_pbr/src/render/gpu_preprocess.rs index 52df74cc26a2b..b7b2b7df06295 100644 --- a/crates/bevy_pbr/src/render/gpu_preprocess.rs +++ b/crates/bevy_pbr/src/render/gpu_preprocess.rs @@ -26,17 +26,16 @@ use bevy_ecs::{ system::{lifetimeless::Read, Commands, Query, Res, ResMut}, world::{FromWorld, World}, }; -use bevy_render::batching::gpu_preprocessing::{ - GpuPreprocessingMode, IndirectParametersGpuMetadata, UntypedPhaseIndirectParametersBuffers, -}; use bevy_render::{ batching::gpu_preprocessing::{ - BatchedInstanceBuffers, GpuOcclusionCullingWorkItemBuffers, GpuPreprocessingSupport, - IndirectBatchSet, IndirectParametersBuffers, IndirectParametersCpuMetadata, - IndirectParametersIndexed, IndirectParametersNonIndexed, - LatePreprocessWorkItemIndirectParameters, PreprocessWorkItem, PreprocessWorkItemBuffers, - UntypedPhaseBatchedInstanceBuffers, + BatchedInstanceBuffers, GpuOcclusionCullingWorkItemBuffers, GpuPreprocessingMode, + GpuPreprocessingSupport, IndirectBatchSet, IndirectParametersBuffers, + IndirectParametersCpuMetadata, IndirectParametersGpuMetadata, IndirectParametersIndexed, + IndirectParametersNonIndexed, LatePreprocessWorkItemIndirectParameters, PreprocessWorkItem, + PreprocessWorkItemBuffers, UntypedPhaseBatchedInstanceBuffers, + UntypedPhaseIndirectParametersBuffers, }, + diagnostic::RecordDiagnostics, experimental::occlusion_culling::OcclusionCulling, render_graph::{Node, NodeRunError, RenderGraphContext, RenderGraphExt}, render_resource::{ @@ -582,6 +581,8 @@ impl Node for EarlyGpuPreprocessNode { render_context: &mut RenderContext<'w>, world: &'w World, ) -> Result<(), NodeRunError> { + let diagnostics = render_context.diagnostic_recorder(); + // Grab the [`BatchedInstanceBuffers`]. let batched_instance_buffers = world.resource::>(); @@ -593,9 +594,10 @@ impl Node for EarlyGpuPreprocessNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("early mesh preprocessing"), + label: Some("early_mesh_preprocessing"), timestamp_writes: None, }); + let pass_span = diagnostics.time_span(&mut compute_pass, "early_mesh_preprocessing"); let mut all_views: SmallVec<[_; 8]> = SmallVec::new(); all_views.push(graph.view_entity()); @@ -771,6 +773,8 @@ impl Node for EarlyGpuPreprocessNode { } } + pass_span.end(&mut compute_pass); + Ok(()) } } @@ -818,6 +822,8 @@ impl Node for LateGpuPreprocessNode { render_context: &mut RenderContext<'w>, world: &'w World, ) -> Result<(), NodeRunError> { + let diagnostics = render_context.diagnostic_recorder(); + // Grab the [`BatchedInstanceBuffers`]. let batched_instance_buffers = world.resource::>(); @@ -829,9 +835,10 @@ impl Node for LateGpuPreprocessNode { render_context .command_encoder() .begin_compute_pass(&ComputePassDescriptor { - label: Some("late mesh preprocessing"), + label: Some("late_mesh_preprocessing"), timestamp_writes: None, }); + let pass_span = diagnostics.time_span(&mut compute_pass, "late_mesh_preprocessing"); // Run the compute passes. for (view, bind_groups, view_uniform_offset) in self.view_query.iter_manual(world) { @@ -940,6 +947,8 @@ impl Node for LateGpuPreprocessNode { } } + pass_span.end(&mut compute_pass); + Ok(()) } } @@ -967,7 +976,7 @@ impl Node for EarlyPrepassBuildIndirectParametersNode { render_context, world, &preprocess_pipelines.early_phase, - "early prepass indirect parameters building", + "early_prepass_indirect_parameters_building", ) } } @@ -995,7 +1004,7 @@ impl Node for LatePrepassBuildIndirectParametersNode { render_context, world, &preprocess_pipelines.late_phase, - "late prepass indirect parameters building", + "late_prepass_indirect_parameters_building", ) } } @@ -1017,7 +1026,7 @@ impl Node for MainBuildIndirectParametersNode { render_context, world, &preprocess_pipelines.main_phase, - "main indirect parameters building", + "main_indirect_parameters_building", ) } } @@ -1034,6 +1043,8 @@ fn run_build_indirect_parameters_node( return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let pipeline_cache = world.resource::(); let indirect_parameters_buffers = world.resource::(); @@ -1044,6 +1055,7 @@ fn run_build_indirect_parameters_node( label: Some(label), timestamp_writes: None, }); + let pass_span = diagnostics.time_span(&mut compute_pass, label); // Fetch the pipeline. let ( @@ -1063,6 +1075,7 @@ fn run_build_indirect_parameters_node( ) else { warn!("The build indirect parameters pipelines weren't ready"); + pass_span.end(&mut compute_pass); return Ok(()); }; @@ -1077,6 +1090,7 @@ fn run_build_indirect_parameters_node( ) else { // This will happen while the pipeline is being compiled and is fine. + pass_span.end(&mut compute_pass); return Ok(()); }; @@ -1148,6 +1162,8 @@ fn run_build_indirect_parameters_node( } } + pass_span.end(&mut compute_pass); + Ok(()) } diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index bec2a6d1a9597..051908d6476cc 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1254,7 +1254,7 @@ pub fn prepare_lights( ShadowView { depth_attachment, pass_name: format!( - "shadow pass point light {} {}", + "shadow_point_light_{}_{}", light_index, face_index_to_name(face_index) ), @@ -1359,7 +1359,7 @@ pub fn prepare_lights( commands.entity(view_light_entity).insert(( ShadowView { depth_attachment, - pass_name: format!("shadow pass spot light {light_index}"), + pass_name: format!("shadow_spot_light_{light_index}"), }, ExtractedView { retained_view_entity, @@ -1503,7 +1503,7 @@ pub fn prepare_lights( ShadowView { depth_attachment, pass_name: format!( - "shadow pass directional light {light_index} cascade {cascade_index}" + "shadow_directional_light_{light_index}_cascade_{cascade_index}" ), }, ExtractedView { diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index 001aa67c12387..a1170b9604dad 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -19,6 +19,7 @@ use bevy_image::ToExtents; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ camera::{ExtractedCamera, TemporalJitter}, + diagnostic::RecordDiagnostics, extract_component::ExtractComponent, globals::{GlobalsBuffer, GlobalsUniform}, load_shader_library, @@ -219,16 +220,18 @@ impl ViewNode for SsaoNode { return Ok(()); }; - render_context.command_encoder().push_debug_group("ssao"); + let diagnostics = render_context.diagnostic_recorder(); + + let command_encoder = render_context.command_encoder(); + command_encoder.push_debug_group("ssao"); + let time_span = diagnostics.time_span(command_encoder, "ssao"); { let mut preprocess_depth_pass = - render_context - .command_encoder() - .begin_compute_pass(&ComputePassDescriptor { - label: Some("ssao_preprocess_depth_pass"), - timestamp_writes: None, - }); + command_encoder.begin_compute_pass(&ComputePassDescriptor { + label: Some("ssao_preprocess_depth"), + timestamp_writes: None, + }); preprocess_depth_pass.set_pipeline(preprocess_depth_pipeline); preprocess_depth_pass.set_bind_group(0, &bind_groups.preprocess_depth_bind_group, &[]); preprocess_depth_pass.set_bind_group( @@ -244,13 +247,10 @@ impl ViewNode for SsaoNode { } { - let mut ssao_pass = - render_context - .command_encoder() - .begin_compute_pass(&ComputePassDescriptor { - label: Some("ssao_ssao_pass"), - timestamp_writes: None, - }); + let mut ssao_pass = command_encoder.begin_compute_pass(&ComputePassDescriptor { + label: Some("ssao"), + timestamp_writes: None, + }); ssao_pass.set_pipeline(ssao_pipeline); ssao_pass.set_bind_group(0, &bind_groups.ssao_bind_group, &[]); ssao_pass.set_bind_group( @@ -263,12 +263,10 @@ impl ViewNode for SsaoNode { { let mut spatial_denoise_pass = - render_context - .command_encoder() - .begin_compute_pass(&ComputePassDescriptor { - label: Some("ssao_spatial_denoise_pass"), - timestamp_writes: None, - }); + command_encoder.begin_compute_pass(&ComputePassDescriptor { + label: Some("ssao_spatial_denoise"), + timestamp_writes: None, + }); spatial_denoise_pass.set_pipeline(spatial_denoise_pipeline); spatial_denoise_pass.set_bind_group(0, &bind_groups.spatial_denoise_bind_group, &[]); spatial_denoise_pass.set_bind_group( @@ -283,7 +281,8 @@ impl ViewNode for SsaoNode { ); } - render_context.command_encoder().pop_debug_group(); + time_span.end(command_encoder); + command_encoder.pop_debug_group(); Ok(()) } } diff --git a/crates/bevy_pbr/src/ssr/mod.rs b/crates/bevy_pbr/src/ssr/mod.rs index 12e7b77f4d34d..b245aaffb8da3 100644 --- a/crates/bevy_pbr/src/ssr/mod.rs +++ b/crates/bevy_pbr/src/ssr/mod.rs @@ -24,8 +24,12 @@ use bevy_ecs::{ use bevy_image::BevyDefault as _; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ + diagnostic::RecordDiagnostics, extract_component::{ExtractComponent, ExtractComponentPlugin}, - render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, + load_shader_library, + render_graph::{ + NodeRunError, RenderGraph, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner, + }, render_resource::{ binding_types, AddressMode, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer, FilterMode, @@ -38,7 +42,6 @@ use bevy_render::{ view::{ExtractedView, Msaa, ViewTarget, ViewUniformOffset}, Render, RenderApp, RenderStartup, RenderSystems, }; -use bevy_render::{load_shader_library, render_graph::RenderGraph}; use bevy_utils::{once, prelude::default}; use tracing::info; @@ -281,6 +284,8 @@ impl ViewNode for ScreenSpaceReflectionsNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + // Set up a standard pair of postprocessing textures. let postprocess = view_target.post_process_write(); @@ -299,7 +304,7 @@ impl ViewNode for ScreenSpaceReflectionsNode { // Build the SSR render pass. let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("SSR pass"), + label: Some("ssr"), color_attachments: &[Some(RenderPassColorAttachment { view: postprocess.destination, depth_slice: None, @@ -310,6 +315,7 @@ impl ViewNode for ScreenSpaceReflectionsNode { timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "ssr"); // Set bind groups. render_pass.set_render_pipeline(render_pipeline); @@ -331,6 +337,8 @@ impl ViewNode for ScreenSpaceReflectionsNode { render_pass.set_bind_group(2, &ssr_bind_group, &[]); render_pass.draw(0..3, 0..1); + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index abd886018b009..e7d8d33b82b28 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -20,6 +20,7 @@ use bevy_ecs::{ use bevy_image::{BevyDefault, Image}; use bevy_math::{vec4, Mat3A, Mat4, Vec3, Vec3A, Vec4, Vec4Swizzles as _}; use bevy_render::{ + diagnostic::RecordDiagnostics, mesh::{ allocator::MeshAllocator, Mesh, MeshVertexBufferLayoutRef, RenderMesh, RenderMeshBufferInfo, }, @@ -358,6 +359,13 @@ impl ViewNode for VolumetricFogNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + render_context + .command_encoder() + .push_debug_group("volumetric_lighting"); + let time_span = + diagnostics.time_span(render_context.command_encoder(), "volumetric_lighting"); + let fog_assets = world.resource::(); let render_meshes = world.resource::>(); @@ -493,6 +501,9 @@ impl ViewNode for VolumetricFogNode { } } + time_span.end(render_context.command_encoder()); + render_context.command_encoder().pop_debug_group(); + Ok(()) } } diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index ad280e054f67d..77257630b64b4 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -27,7 +27,8 @@ use bevy_platform::{ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport}, - camera::ExtractedCamera, + camera::{extract_cameras, ExtractedCamera}, + diagnostic::RecordDiagnostics, extract_resource::ExtractResource, mesh::{ allocator::{MeshAllocator, SlabId}, @@ -51,9 +52,8 @@ use bevy_render::{ ExtractedView, NoIndirectDrawing, RenderVisibilityRanges, RenderVisibleEntities, RetainedViewEntity, ViewDepthTexture, ViewTarget, }, - Extract, Render, RenderApp, RenderDebugFlags, RenderSystems, + Extract, Render, RenderApp, RenderDebugFlags, RenderStartup, RenderSystems, }; -use bevy_render::{camera::extract_cameras, RenderStartup}; use core::{hash::Hash, ops::Range}; use tracing::error; @@ -384,13 +384,16 @@ impl ViewNode for Wireframe3dNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("wireframe_3d_pass"), + label: Some("wireframe_3d"), color_attachments: &[Some(target.get_color_attachment())], depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)), timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "wireframe_3d"); if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); @@ -401,6 +404,8 @@ impl ViewNode for Wireframe3dNode { return Err(NodeRunError::DrawError(err)); } + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_sprite/src/mesh2d/wireframe2d.rs b/crates/bevy_sprite/src/mesh2d/wireframe2d.rs index 912c25f9bb019..95a7473fec3f5 100644 --- a/crates/bevy_sprite/src/mesh2d/wireframe2d.rs +++ b/crates/bevy_sprite/src/mesh2d/wireframe2d.rs @@ -27,6 +27,7 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{ batching::gpu_preprocessing::GpuPreprocessingMode, camera::ExtractedCamera, + diagnostic::RecordDiagnostics, extract_resource::ExtractResource, mesh::{ allocator::{MeshAllocator, SlabId}, @@ -384,13 +385,16 @@ impl ViewNode for Wireframe2dNode { return Ok(()); }; + let diagnostics = render_context.diagnostic_recorder(); + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("wireframe_2d_pass"), + label: Some("wireframe_2d"), color_attachments: &[Some(target.get_color_attachment())], depth_stencil_attachment: Some(depth.get_attachment(StoreOp::Store)), timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "wireframe_2d"); if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); @@ -401,6 +405,8 @@ impl ViewNode for Wireframe2dNode { return Err(NodeRunError::DrawError(err)); } + pass_span.end(&mut render_pass); + Ok(()) } } diff --git a/crates/bevy_ui_render/src/render_pass.rs b/crates/bevy_ui_render/src/render_pass.rs index 59cbd8e4da00d..407f200e86b1c 100644 --- a/crates/bevy_ui_render/src/render_pass.rs +++ b/crates/bevy_ui_render/src/render_pass.rs @@ -8,13 +8,14 @@ use bevy_ecs::{ system::{lifetimeless::*, SystemParamItem}, }; use bevy_math::FloatOrd; -use bevy_render::sync_world::MainEntity; use bevy_render::{ camera::ExtractedCamera, + diagnostic::RecordDiagnostics, render_graph::*, render_phase::*, render_resource::{CachedRenderPipelineId, RenderPassDescriptor}, renderer::*, + sync_world::MainEntity, view::*, }; use tracing::error; @@ -79,6 +80,8 @@ impl Node for UiPassNode { return Ok(()); } + let diagnostics = render_context.diagnostic_recorder(); + // use the UI view entity if it is defined let view_entity = if let Ok(ui_camera_view) = self .ui_camera_view_query @@ -89,12 +92,14 @@ impl Node for UiPassNode { input_view_entity }; let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("ui_pass"), + label: Some("ui"), color_attachments: &[Some(target.get_unsampled_color_attachment())], depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, }); + let pass_span = diagnostics.pass_span(&mut render_pass, "ui"); + if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); } @@ -102,6 +107,8 @@ impl Node for UiPassNode { error!("Error encountered while rendering the ui phase {err:?}"); } + pass_span.end(&mut render_pass); + Ok(()) } }