From 8dd3e31a57d089893a104200f660a8355a89aa1d Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 22 Aug 2020 20:04:58 +0200 Subject: [PATCH] [rs] Added debug marker/groups for ComputePass & CommandEncoder --- wgpu/examples/boids/main.rs | 4 +++ wgpu/examples/hello-compute/main.rs | 1 + wgpu/examples/shadow/main.rs | 52 +++++++++++++++++++---------- wgpu/src/backend/direct.rs | 32 ++++++++++++++++++ wgpu/src/backend/web.rs | 23 +++++++++++++ wgpu/src/lib.rs | 38 +++++++++++++++++++++ 6 files changed, 132 insertions(+), 18 deletions(-) diff --git a/wgpu/examples/boids/main.rs b/wgpu/examples/boids/main.rs index 54099c199f..1169dddf17 100644 --- a/wgpu/examples/boids/main.rs +++ b/wgpu/examples/boids/main.rs @@ -279,6 +279,7 @@ impl framework::Example for Example { let mut command_encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + command_encoder.push_debug_group("compute boid movement"); { // compute pass let mut cpass = command_encoder.begin_compute_pass(); @@ -286,7 +287,9 @@ impl framework::Example for Example { cpass.set_bind_group(0, &self.particle_bind_groups[self.frame_num % 2], &[]); cpass.dispatch(self.work_group_count, 1, 1); } + command_encoder.pop_debug_group(); + command_encoder.push_debug_group("render boids"); { // render pass let mut rpass = command_encoder.begin_render_pass(&render_pass_descriptor); @@ -297,6 +300,7 @@ impl framework::Example for Example { rpass.set_vertex_buffer(1, self.vertices_buffer.slice(..)); rpass.draw(0..3, 0..NUM_PARTICLES); } + command_encoder.pop_debug_group(); // update frame count self.frame_num += 1; diff --git a/wgpu/examples/hello-compute/main.rs b/wgpu/examples/hello-compute/main.rs index 7162dc9fed..ddd8a64995 100644 --- a/wgpu/examples/hello-compute/main.rs +++ b/wgpu/examples/hello-compute/main.rs @@ -134,6 +134,7 @@ async fn execute_gpu(numbers: Vec) -> Vec { let mut cpass = encoder.begin_compute_pass(); cpass.set_pipeline(&compute_pipeline); cpass.set_bind_group(0, &bind_group, &[]); + cpass.insert_debug_marker("compute collatz iterations"); cpass.dispatch(numbers.len() as u32, 1, 1); // Number of cells to run, the (x,y,z) size of item being processed } // Sets adds copy operation to command encoder. diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 55ec611795..4d802bd345 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -752,7 +752,13 @@ impl framework::Example for Example { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.push_debug_group("shadow passes"); for (i, light) in self.lights.iter().enumerate() { + encoder.push_debug_group(&format!( + "shadow pass {} (light at position {:?})", + i, light.pos + )); + // The light uniform buffer already has the projection, // let's just copy it over to the shadow uniform buffer. encoder.copy_buffer_to_buffer( @@ -763,29 +769,38 @@ impl framework::Example for Example { 64, ); - let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[], - depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { - attachment: &light.target_view, - depth_ops: Some(wgpu::Operations { - load: wgpu::LoadOp::Clear(1.0), - store: true, - }), - stencil_ops: None, - }), - }); - pass.set_pipeline(&self.shadow_pass.pipeline); - pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]); + encoder.insert_debug_marker("render entities"); + { + let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + color_attachments: &[], + depth_stencil_attachment: Some( + wgpu::RenderPassDepthStencilAttachmentDescriptor { + attachment: &light.target_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.0), + store: true, + }), + stencil_ops: None, + }, + ), + }); + pass.set_pipeline(&self.shadow_pass.pipeline); + pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]); - for entity in &self.entities { - pass.set_bind_group(1, &self.entity_bind_group, &[entity.uniform_offset]); - pass.set_index_buffer(entity.index_buf.slice(..)); - pass.set_vertex_buffer(0, entity.vertex_buf.slice(..)); - pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); + for entity in &self.entities { + pass.set_bind_group(1, &self.entity_bind_group, &[entity.uniform_offset]); + pass.set_index_buffer(entity.index_buf.slice(..)); + pass.set_vertex_buffer(0, entity.vertex_buf.slice(..)); + pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); + } } + + encoder.pop_debug_group(); } + encoder.pop_debug_group(); // forward pass + encoder.push_debug_group("forward rendering pass"); { let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { @@ -820,6 +835,7 @@ impl framework::Example for Example { pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); } } + encoder.pop_debug_group(); queue.submit(iter::once(encoder.finish())); } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 70f9fd2aaa..2907310d91 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -96,6 +96,22 @@ mod pass_impl { ) } } + fn insert_debug_marker(&mut self, label: &str) { + unsafe { + let label = std::ffi::CString::new(label).unwrap(); + wgpu_compute_pass_insert_debug_marker(self, label.as_ptr().into(), 0); + } + } + + fn push_debug_group(&mut self, group_label: &str) { + unsafe { + let label = std::ffi::CString::new(group_label).unwrap(); + wgpu_compute_pass_push_debug_group(self, label.as_ptr().into(), 0); + } + } + fn pop_debug_group(&mut self) { + wgpu_compute_pass_pop_debug_group(self); + } fn dispatch(&mut self, x: u32, y: u32, z: u32) { wgpu_compute_pass_dispatch(self, x, y, z) } @@ -1244,6 +1260,22 @@ impl crate::Context for Context { wgc::gfx_select!(*encoder => global.command_encoder_finish(*encoder, &desc)).unwrap_pretty() } + fn command_encoder_insert_debug_marker(&self, encoder: &Self::CommandEncoderId, label: &str) { + let global = &self.0; + wgc::gfx_select!(*encoder => global.command_encoder_insert_debug_marker(*encoder, &label)) + .unwrap_pretty() + } + fn command_encoder_push_debug_group(&self, encoder: &Self::CommandEncoderId, label: &str) { + let global = &self.0; + wgc::gfx_select!(*encoder => global.command_encoder_push_debug_group(*encoder, &label)) + .unwrap_pretty() + } + fn command_encoder_pop_debug_group(&self, encoder: &Self::CommandEncoderId) { + let global = &self.0; + wgc::gfx_select!(*encoder => global.command_encoder_pop_debug_group(*encoder)) + .unwrap_pretty() + } + fn render_bundle_encoder_finish( &self, encoder: Self::RenderBundleEncoderId, diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index b2aed264bf..bfea9e8f2f 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -88,6 +88,19 @@ impl crate::ComputePassInner for ComputePass { fn set_push_constants(&mut self, _offset: u32, _data: &[u32]) { panic!("PUSH_CONSTANTS feature must be enabled to call multi_draw_indexed_indirect") } + + fn insert_debug_marker(&mut self, _label: &str) { + unimplemented!() + } + + fn push_debug_group(&mut self, _group_label: &str) { + unimplemented!() + } + + fn pop_debug_group(&mut self) { + unimplemented!() + } + fn dispatch(&mut self, x: u32, y: u32, z: u32) { self.0.dispatch_with_y_and_z(x, y, z); } @@ -1436,6 +1449,16 @@ impl crate::Context for Context { Sendable(encoder.finish_with_descriptor(&mapped_desc)) } + fn command_encoder_insert_debug_marker(&self, encoder: &Self::CommandEncoderId, label: &str) { + unimplemented!() + } + fn command_encoder_push_debug_group(&self, encoder: &Self::CommandEncoderId, label: &str) { + unimplemented!() + } + fn command_encoder_pop_debug_group(&self, encoder: &Self::CommandEncoderId) { + unimplemented!() + } + fn render_bundle_encoder_finish( &self, _encoder: Self::RenderBundleEncoderId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 10d4d90316..6436466a71 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -56,6 +56,9 @@ trait ComputePassInner { offsets: &[DynamicOffset], ); fn set_push_constants(&mut self, offset: u32, data: &[u32]); + fn insert_debug_marker(&mut self, label: &str); + fn push_debug_group(&mut self, group_label: &str); + fn pop_debug_group(&mut self); fn dispatch(&mut self, x: u32, y: u32, z: u32); fn dispatch_indirect( &mut self, @@ -368,6 +371,11 @@ trait Context: Debug + Send + Sized + Sync { pass: &mut Self::RenderPassId, ); fn command_encoder_finish(&self, encoder: &Self::CommandEncoderId) -> Self::CommandBufferId; + + fn command_encoder_insert_debug_marker(&self, encoder: &Self::CommandEncoderId, label: &str); + fn command_encoder_push_debug_group(&self, encoder: &Self::CommandEncoderId, label: &str); + fn command_encoder_pop_debug_group(&self, encoder: &Self::CommandEncoderId); + fn render_bundle_encoder_finish( &self, encoder: Self::RenderBundleEncoderId, @@ -1905,6 +1913,21 @@ impl CommandEncoder { copy_size, ); } + + /// Inserts debug marker. + pub fn insert_debug_marker(&mut self, label: &str) { + Context::command_encoder_insert_debug_marker(&*self.context, &self.id, label); + } + + /// Start record commands and group it into debug marker group. + pub fn push_debug_group(&mut self, label: &str) { + Context::command_encoder_push_debug_group(&*self.context, &self.id, label); + } + + /// Stops command recording and creates debug group. + pub fn pop_debug_group(&mut self) { + Context::command_encoder_pop_debug_group(&*self.context, &self.id); + } } impl<'a> RenderPass<'a> { @@ -2297,6 +2320,21 @@ impl<'a> ComputePass<'a> { ComputePassInner::set_pipeline(&mut self.id, &pipeline.id); } + /// Inserts debug marker. + pub fn insert_debug_marker(&mut self, label: &str) { + self.id.insert_debug_marker(label); + } + + /// Start record commands and group it into debug marker group. + pub fn push_debug_group(&mut self, label: &str) { + self.id.push_debug_group(label); + } + + /// Stops command recording and creates debug group. + pub fn pop_debug_group(&mut self) { + self.id.pop_debug_group(); + } + /// Dispatches compute work operations. /// /// `x`, `y` and `z` denote the number of work groups to dispatch in each dimension.