diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 3de385a7c..6d3fe88c2 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -222,6 +222,17 @@ impl RenderBundle { let buffer = &buffer_guard[buffer_id]; comb.draw_indexed_indirect(&buffer.raw, offset, 1, 0); } + RenderCommand::PushDebugGroup { + color: _, + len: _, + phantom_marker: _, + } => unimplemented!(), + RenderCommand::InsertDebugMarker { + color: _, + len: _, + phantom_marker: _, + } => unimplemented!(), + RenderCommand::PopDebugGroup => unimplemented!(), RenderCommand::ExecuteBundle(_) | RenderCommand::SetBlendColor(_) | RenderCommand::SetStencilReference(_) @@ -724,6 +735,17 @@ impl Global { commands.push(command); } RenderCommand::End => break, + RenderCommand::PushDebugGroup { + color: _, + len: _, + phantom_marker: _, + } => unimplemented!(), + RenderCommand::InsertDebugMarker { + color: _, + len: _, + phantom_marker: _, + } => unimplemented!(), + RenderCommand::PopDebugGroup => unimplemented!(), RenderCommand::ExecuteBundle(_) | RenderCommand::SetBlendColor(_) | RenderCommand::SetStencilReference(_) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 57066239c..247d07cea 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -17,7 +17,7 @@ use hal::command::CommandBuffer as _; use peek_poke::{Peek, PeekPoke, Poke}; use wgt::{BufferAddress, BufferUsage, DynamicOffset, BIND_BUFFER_ALIGNMENT}; -use std::iter; +use std::{iter, str}; #[derive(Debug, PartialEq)] enum PipelineState { @@ -42,9 +42,28 @@ pub enum ComputeCommand { buffer_id: id::BufferId, offset: BufferAddress, }, + PushDebugGroup { + color: u32, + len: usize, + #[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))] + phantom_marker: PhantomSlice, + }, + PopDebugGroup, + InsertDebugMarker { + color: u32, + len: usize, + #[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))] + phantom_marker: PhantomSlice, + }, End, } +#[derive(Debug)] +struct State { + binder: Binder, + debug_scope_depth: u32, +} + impl Default for ComputeCommand { fn default() -> Self { ComputeCommand::End @@ -100,7 +119,6 @@ impl Global { let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token); let cmb = &mut cmb_guard[encoder_id]; let raw = cmb.raw.last_mut().unwrap(); - let mut binder = Binder::new(cmb.limits.max_bind_groups); let (_, mut token) = hub.render_bundles.read(&mut token); let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token); @@ -111,6 +129,11 @@ impl Global { let mut pipeline_state = PipelineState::Required; + let mut state = State { + binder: Binder::new(cmb.limits.max_bind_groups), + debug_scope_depth: 0, + }; + let mut peeker = raw_data.as_ptr(); let raw_data_end = unsafe { raw_data.as_ptr().add(raw_data.len()) }; let mut command = ComputeCommand::Dispatch([0; 3]); // dummy @@ -165,9 +188,12 @@ impl Global { &*texture_guard, ); - if let Some((pipeline_layout_id, follow_ups)) = - binder.provide_entry(index as usize, bind_group_id, bind_group, offsets) - { + if let Some((pipeline_layout_id, follow_ups)) = state.binder.provide_entry( + index as usize, + bind_group_id, + bind_group, + offsets, + ) { let bind_groups = iter::once(bind_group.raw.raw()).chain( follow_ups .clone() @@ -199,13 +225,16 @@ impl Global { } // Rebind resources - if binder.pipeline_layout_id != Some(pipeline.layout_id.value) { + if state.binder.pipeline_layout_id != Some(pipeline.layout_id.value) { let pipeline_layout = &pipeline_layout_guard[pipeline.layout_id.value]; - binder.pipeline_layout_id = Some(pipeline.layout_id.value); - binder.reset_expectations(pipeline_layout.bind_group_layout_ids.len()); + state.binder.pipeline_layout_id = Some(pipeline.layout_id.value); + state + .binder + .reset_expectations(pipeline_layout.bind_group_layout_ids.len()); let mut is_compatible = true; - for (index, (entry, bgl_id)) in binder + for (index, (entry, bgl_id)) in state + .binder .entries .iter_mut() .zip(&pipeline_layout.bind_group_layout_ids) @@ -266,6 +295,39 @@ impl Global { raw.dispatch_indirect(&src_buffer.raw, offset); } } + ComputeCommand::PushDebugGroup { + color, + len, + phantom_marker, + } => unsafe { + state.debug_scope_depth += 1; + + let (new_peeker, label) = + { phantom_marker.decode_unaligned(peeker, len, raw_data_end) }; + peeker = new_peeker; + + raw.begin_debug_marker(str::from_utf8(label).unwrap(), color) + }, + ComputeCommand::PopDebugGroup => unsafe { + assert_ne!( + state.debug_scope_depth, 0, + "Can't pop debug group, because number of pushed debug groups is zero!" + ); + state.debug_scope_depth -= 1; + + raw.end_debug_marker() + }, + ComputeCommand::InsertDebugMarker { + color, + len, + phantom_marker, + } => unsafe { + let (new_peeker, label) = + { phantom_marker.decode_unaligned(peeker, len, raw_data_end) }; + peeker = new_peeker; + + raw.insert_debug_marker(str::from_utf8(label).unwrap(), color) + }, ComputeCommand::End => break, } } @@ -312,7 +374,7 @@ impl Global { pub mod compute_ffi { use super::{super::PhantomSlice, ComputeCommand}; use crate::{id, RawString}; - use std::{convert::TryInto, slice}; + use std::{convert::TryInto, ffi, slice}; use wgt::{BufferAddress, DynamicOffset}; type RawPass = super::super::RawPass; @@ -368,21 +430,40 @@ pub mod compute_ffi { } #[no_mangle] - pub extern "C" fn wgpu_compute_pass_push_debug_group(_pass: &mut RawPass, _label: RawString) { - //TODO - } - - #[no_mangle] - pub extern "C" fn wgpu_compute_pass_pop_debug_group(_pass: &mut RawPass) { - //TODO - } - - #[no_mangle] - pub extern "C" fn wgpu_compute_pass_insert_debug_marker( - _pass: &mut RawPass, - _label: RawString, + pub unsafe extern "C" fn wgpu_compute_pass_push_debug_group( + pass: &mut RawPass, + label: RawString, + color: u32, ) { - //TODO + let bytes = ffi::CStr::from_ptr(label).to_bytes(); + + pass.encode(&ComputeCommand::PushDebugGroup { + color, + len: bytes.len(), + phantom_marker: PhantomSlice::default(), + }); + pass.encode_slice(bytes); + } + + #[no_mangle] + pub unsafe extern "C" fn wgpu_compute_pass_pop_debug_group(pass: &mut RawPass) { + pass.encode(&ComputeCommand::PopDebugGroup); + } + + #[no_mangle] + pub unsafe extern "C" fn wgpu_compute_pass_insert_debug_marker( + pass: &mut RawPass, + label: RawString, + color: u32, + ) { + let bytes = ffi::CStr::from_ptr(label).to_bytes(); + + pass.encode(&ComputeCommand::InsertDebugMarker { + color, + len: bytes.len(), + phantom_marker: PhantomSlice::default(), + }); + pass.encode_slice(bytes); } #[no_mangle] diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 8e2aa2730..34cf0af7b 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -24,6 +24,8 @@ use crate::{ PrivateFeatures, Stored, }; +use hal::command::CommandBuffer as _; + use peek_poke::PeekPoke; use std::{marker::PhantomData, mem, ptr, slice, thread::ThreadId}; @@ -276,4 +278,51 @@ impl Global { log::debug!("Command buffer {:?} {:#?}", encoder_id, comb.trackers); encoder_id } + + pub fn command_encoder_push_debug_group( + &self, + encoder_id: id::CommandEncoderId, + label: &str, + ) { + let hub = B::hub(self); + let mut token = Token::root(); + + let (mut cmb_guard, _) = hub.command_buffers.write(&mut token); + let cmb = &mut cmb_guard[encoder_id]; + let cmb_raw = cmb.raw.last_mut().unwrap(); + + unsafe { + cmb_raw.begin_debug_marker(label, 0); + } + } + + pub fn command_encoder_insert_debug_marker( + &self, + encoder_id: id::CommandEncoderId, + label: &str, + ) { + let hub = B::hub(self); + let mut token = Token::root(); + + let (mut cmb_guard, _) = hub.command_buffers.write(&mut token); + let cmb = &mut cmb_guard[encoder_id]; + let cmb_raw = cmb.raw.last_mut().unwrap(); + + unsafe { + cmb_raw.insert_debug_marker(label, 0); + } + } + + pub fn command_encoder_pop_debug_group(&self, encoder_id: id::CommandEncoderId) { + let hub = B::hub(self); + let mut token = Token::root(); + + let (mut cmb_guard, _) = hub.command_buffers.write(&mut token); + let cmb = &mut cmb_guard[encoder_id]; + let cmb_raw = cmb.raw.last_mut().unwrap(); + + unsafe { + cmb_raw.end_debug_marker(); + } + } } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 7544a82d3..c32b8892d 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -30,7 +30,7 @@ use wgt::{ RenderPassDepthStencilAttachmentDescriptorBase, StoreOp, TextureUsage, BIND_BUFFER_ALIGNMENT, }; -use std::{borrow::Borrow, collections::hash_map::Entry, fmt, iter, mem, ops::Range, slice}; +use std::{borrow::Borrow, collections::hash_map::Entry, fmt, iter, mem, ops::Range, slice, str}; pub type RenderPassColorAttachmentDescriptor = RenderPassColorAttachmentDescriptorBase; @@ -131,6 +131,19 @@ pub enum RenderCommand { buffer_id: id::BufferId, offset: BufferAddress, }, + PushDebugGroup { + color: u32, + len: usize, + #[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))] + phantom_marker: PhantomSlice, + }, + PopDebugGroup, + InsertDebugMarker { + color: u32, + len: usize, + #[cfg_attr(any(feature = "trace", feature = "replay"), serde(skip))] + phantom_marker: PhantomSlice, + }, ExecuteBundle(id::RenderBundleId), End, } @@ -329,6 +342,7 @@ struct State { pipeline: OptionalState, index: IndexState, vertex: VertexState, + debug_scope_depth: u32, } impl State { @@ -905,6 +919,7 @@ impl Global { pipeline: OptionalState::Required, index: IndexState::default(), vertex: VertexState::default(), + debug_scope_depth: 0, }; let mut command = RenderCommand::Draw { @@ -1281,6 +1296,39 @@ impl Global { raw.draw_indexed_indirect(&buffer.raw, offset, 1, 0); } } + RenderCommand::PushDebugGroup { + color, + len, + phantom_marker, + } => unsafe { + state.debug_scope_depth += 1; + + let (new_peeker, label) = + { phantom_marker.decode_unaligned(peeker, len, raw_data_end) }; + peeker = new_peeker; + + raw.begin_debug_marker(str::from_utf8(label).unwrap(), color) + }, + RenderCommand::PopDebugGroup => unsafe { + assert_ne!( + state.debug_scope_depth, 0, + "Can't pop debug group, because number of pushed debug groups is zero!" + ); + state.debug_scope_depth -= 1; + + raw.end_debug_marker() + }, + RenderCommand::InsertDebugMarker { + color, + len, + phantom_marker, + } => unsafe { + let (new_peeker, label) = + { phantom_marker.decode_unaligned(peeker, len, raw_data_end) }; + peeker = new_peeker; + + raw.insert_debug_marker(str::from_utf8(label).unwrap(), color) + }, RenderCommand::ExecuteBundle(bundle_id) => { let bundle = trackers .bundles @@ -1408,7 +1456,7 @@ pub mod render_ffi { RenderCommand, }; use crate::{id, RawString}; - use std::{convert::TryInto, slice}; + use std::{convert::TryInto, ffi, slice}; use wgt::{BufferAddress, BufferSize, Color, DynamicOffset}; type RawPass = super::super::RawPass; @@ -1568,18 +1616,40 @@ pub mod render_ffi { } #[no_mangle] - pub extern "C" fn wgpu_render_pass_push_debug_group(_pass: &mut RawPass, _label: RawString) { - //TODO + pub unsafe extern "C" fn wgpu_render_pass_push_debug_group( + pass: &mut RawPass, + label: RawString, + color: u32, + ) { + let bytes = ffi::CStr::from_ptr(label).to_bytes(); + + pass.encode(&RenderCommand::PushDebugGroup { + color, + len: bytes.len(), + phantom_marker: PhantomSlice::default(), + }); + pass.encode_slice(bytes); } #[no_mangle] - pub extern "C" fn wgpu_render_pass_pop_debug_group(_pass: &mut RawPass) { - //TODO + pub unsafe extern "C" fn wgpu_render_pass_pop_debug_group(pass: &mut RawPass) { + pass.encode(&RenderCommand::PopDebugGroup); } #[no_mangle] - pub extern "C" fn wgpu_render_pass_insert_debug_marker(_pass: &mut RawPass, _label: RawString) { - //TODO + pub unsafe extern "C" fn wgpu_render_pass_insert_debug_marker( + pass: &mut RawPass, + label: RawString, + color: u32, + ) { + let bytes = ffi::CStr::from_ptr(label).to_bytes(); + + pass.encode(&RenderCommand::InsertDebugMarker { + color, + len: bytes.len(), + phantom_marker: PhantomSlice::default(), + }); + pass.encode_slice(bytes); } #[no_mangle]