trace: all the commands

This commit is contained in:
Dzmitry Malyshau 2020-04-28 19:16:22 -04:00 committed by Dzmitry Malyshau
parent d4705b6008
commit 622d9ecc74
7 changed files with 200 additions and 8 deletions

View File

@ -80,6 +80,7 @@ impl<B: GfxBackend> CommandAllocator<B> {
limits: wgt::Limits,
private_features: PrivateFeatures,
lowest_active_index: SubmissionIndex,
#[cfg(feature = "trace")] enable_tracing: bool,
) -> CommandBuffer<B> {
//debug_assert_eq!(device_id.backend(), B::VARIANT);
let thread_id = thread::current().id();
@ -112,6 +113,12 @@ impl<B: GfxBackend> CommandAllocator<B> {
used_swap_chain: None,
limits,
private_features,
#[cfg(feature = "trace")]
commands: if enable_tracing {
Some(Vec::new())
} else {
None
},
}
}
}

View File

@ -26,11 +26,14 @@ enum PipelineState {
}
#[derive(Clone, Copy, Debug, PeekPoke)]
enum ComputeCommand {
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub(crate) enum ComputeCommand {
SetBindGroup {
index: u8,
num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId,
#[cfg_attr(feature = "serde", serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>,
},
SetPipeline(id::ComputePipelineId),
@ -247,6 +250,43 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
ComputeCommand::End => break,
}
}
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => {
let mut pass_commands = Vec::new();
let mut pass_dynamic_offsets = Vec::new();
peeker = raw_data.as_ptr();
loop {
peeker = unsafe { ComputeCommand::peek_from(peeker, &mut command) };
match command {
ComputeCommand::SetBindGroup {
num_dynamic_offsets,
phantom_offsets,
..
} => {
let (new_peeker, offsets) = unsafe {
phantom_offsets.decode_unaligned(
peeker,
num_dynamic_offsets as usize,
raw_data_end,
)
};
peeker = new_peeker;
pass_dynamic_offsets.extend_from_slice(offsets);
}
ComputeCommand::End => break,
_ => {}
}
pass_commands.push(command);
}
list.push(crate::device::trace::Command::RunComputePass {
commands: pass_commands,
dynamic_offsets: pass_dynamic_offsets,
});
}
None => {}
}
}
}

View File

@ -27,7 +27,7 @@ use peek_poke::PeekPoke;
use std::{marker::PhantomData, mem, ptr, slice, thread::ThreadId};
#[derive(Clone, Copy, Debug, PeekPoke)]
struct PhantomSlice<T>(PhantomData<T>);
pub(crate) struct PhantomSlice<T>(PhantomData<T>);
impl<T> Default for PhantomSlice<T> {
fn default() -> Self {
@ -140,6 +140,8 @@ pub struct CommandBuffer<B: hal::Backend> {
pub(crate) used_swap_chain: Option<(Stored<id::SwapChainId>, B::Framebuffer)>,
limits: wgt::Limits,
private_features: PrivateFeatures,
#[cfg(feature = "trace")]
pub(crate) commands: Option<Vec<crate::device::trace::Command>>,
}
impl<B: GfxBackend> CommandBuffer<B> {

View File

@ -46,6 +46,8 @@ pub struct RenderPassDescriptor<'a> {
}
#[derive(Clone, Copy, Debug, Default, PeekPoke)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct Rect<T> {
pub x: T,
pub y: T,
@ -54,11 +56,14 @@ pub struct Rect<T> {
}
#[derive(Clone, Copy, Debug, PeekPoke)]
enum RenderCommand {
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub(crate) enum RenderCommand {
SetBindGroup {
index: u8,
num_dynamic_offsets: u8,
bind_group_id: id::BindGroupId,
#[cfg_attr(feature = "serde", serde(skip))]
phantom_offsets: PhantomSlice<DynamicOffset>,
},
SetPipeline(id::RenderPipelineId),
@ -329,6 +334,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut targets: RawRenderTargets = unsafe { mem::zeroed() };
assert!(unsafe { peeker.add(RawRenderTargets::max_size()) <= raw_data_end });
peeker = unsafe { RawRenderTargets::peek_from(peeker, &mut targets) };
#[cfg(feature = "trace")]
let command_peeker_base = peeker;
let color_attachments = targets
.colors
@ -1173,6 +1180,45 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => {
let mut pass_commands = Vec::new();
let mut pass_dynamic_offsets = Vec::new();
peeker = command_peeker_base;
loop {
peeker = unsafe { RenderCommand::peek_from(peeker, &mut command) };
match command {
RenderCommand::SetBindGroup {
num_dynamic_offsets,
phantom_offsets,
..
} => {
let (new_peeker, offsets) = unsafe {
phantom_offsets.decode_unaligned(
peeker,
num_dynamic_offsets as usize,
raw_data_end,
)
};
peeker = new_peeker;
pass_dynamic_offsets.extend_from_slice(offsets);
}
RenderCommand::End => break,
_ => {}
}
pass_commands.push(command);
}
list.push(crate::device::trace::Command::RunRenderPass {
target_colors: color_attachments.into_iter().collect(),
target_depth_stencil: depth_stencil_attachment.cloned(),
commands: pass_commands,
dynamic_offsets: pass_dynamic_offsets,
});
}
None => {}
}
log::trace!("Merging {:?} with the render pass", encoder_id);
unsafe {
raw.end_render_pass();

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[cfg(feature = "trace")]
use crate::device::trace::Command as TraceCommand;
use crate::{
conv,
device::{all_buffer_stages, all_image_stages},
@ -18,7 +20,9 @@ use std::iter;
const BITS_PER_BYTE: u32 = 8;
#[repr(C)]
#[derive(Debug)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct BufferCopyView {
pub buffer: BufferId,
pub offset: BufferAddress,
@ -27,7 +31,9 @@ pub struct BufferCopyView {
}
#[repr(C)]
#[derive(Debug)]
#[derive(Clone, Debug)]
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
pub struct TextureCopyView {
pub texture: TextureId,
pub mip_level: u32,
@ -90,6 +96,18 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// borrow the buffer tracker mutably...
let mut barriers = Vec::new();
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyBufferToBuffer {
src: source,
src_offset: source_offset,
dst: destination,
dst_offset: destination_offset,
size,
}),
None => (),
}
let (src_buffer, src_pending) =
cmb.trackers
.buffers
@ -135,6 +153,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[destination.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyBufferToTexture {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_buffer, src_pending) = cmb.trackers.buffers.use_replace(
&*buffer_guard,
source.buffer,
@ -199,6 +227,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (texture_guard, _) = hub.textures.read(&mut token);
let aspects = texture_guard[source.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyTextureToBuffer {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard,
source.texture,
@ -268,6 +306,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let aspects = texture_guard[source.texture].full_range.aspects
& texture_guard[destination.texture].full_range.aspects;
#[cfg(feature = "trace")]
match cmb.commands {
Some(ref mut list) => list.push(TraceCommand::CopyTextureToTexture {
src: source.clone(),
dst: destination.clone(),
size: copy_size,
}),
None => (),
}
let (src_texture, src_pending) = cmb.trackers.textures.use_replace(
&*texture_guard,
source.texture,

View File

@ -1536,6 +1536,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
device.limits.clone(),
device.private_features,
lowest_active_index,
#[cfg(feature = "trace")]
device.trace.is_some(),
);
unsafe {
let raw_command_buffer = command_buffer.raw.last_mut().unwrap();
@ -1662,6 +1664,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
// finish all the command buffers first
for &cmb_id in command_buffer_ids {
let comb = &mut command_buffer_guard[cmb_id];
#[cfg(feature = "trace")]
match device.trace {
Some(ref trace) => trace
.lock()
.add(Action::Submit(comb.commands.take().unwrap())),
None => (),
};
if let Some((sc_id, fbo)) = comb.used_swap_chain.take() {
let sc = &mut swap_chain_guard[sc_id.value];

View File

@ -2,7 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::id;
use crate::{
command::{BufferCopyView, TextureCopyView},
id,
};
use std::{io::Write as _, ops::Range};
//TODO: consider a readable Id that doesn't include the backend
@ -20,7 +23,7 @@ pub enum BindingResource {
}
#[derive(serde::Serialize)]
pub enum Action {
pub(crate) enum Action {
Init {
limits: wgt::Limits,
},
@ -82,6 +85,43 @@ pub enum Action {
data: FileName,
range: Range<wgt::BufferAddress>,
},
Submit(Vec<Command>),
}
#[derive(Debug, serde::Serialize)]
pub(crate) enum Command {
CopyBufferToBuffer {
src: id::BufferId,
src_offset: wgt::BufferAddress,
dst: id::BufferId,
dst_offset: wgt::BufferAddress,
size: wgt::BufferAddress,
},
CopyBufferToTexture {
src: BufferCopyView,
dst: TextureCopyView,
size: wgt::Extent3d,
},
CopyTextureToBuffer {
src: TextureCopyView,
dst: BufferCopyView,
size: wgt::Extent3d,
},
CopyTextureToTexture {
src: TextureCopyView,
dst: TextureCopyView,
size: wgt::Extent3d,
},
RunComputePass {
commands: Vec<crate::command::ComputeCommand>,
dynamic_offsets: Vec<wgt::DynamicOffset>,
},
RunRenderPass {
target_colors: Vec<crate::command::RenderPassColorAttachmentDescriptor>,
target_depth_stencil: Option<crate::command::RenderPassDepthStencilAttachmentDescriptor>,
commands: Vec<crate::command::RenderCommand>,
dynamic_offsets: Vec<wgt::DynamicOffset>,
},
}
#[derive(Debug)]
@ -112,7 +152,7 @@ impl Trace {
name
}
pub fn add(&mut self, action: Action) {
pub(crate) fn add(&mut self, action: Action) {
match ron::ser::to_string_pretty(&action, self.config.clone()) {
Ok(string) => {
let _ = write!(self.file, "{},\n", string);