mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
trace: all the commands
This commit is contained in:
parent
d4705b6008
commit
622d9ecc74
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user