wgpu_core/device/
trace.rs

1#[cfg(feature = "trace")]
2mod record;
3#[cfg(feature = "replay")]
4mod replay;
5
6use core::{convert::Infallible, ops::Range};
7
8use alloc::{string::String, vec::Vec};
9use macro_rules_attribute::apply;
10
11use crate::{
12    command::{serde_object_reference_struct, BasePass, Command, ReferenceType, RenderCommand},
13    id::{markers, PointerId},
14    pipeline::GeneralRenderPipelineDescriptor,
15};
16
17#[cfg(feature = "trace")]
18pub use record::*;
19#[cfg(feature = "replay")]
20pub use replay::*;
21
22type FileName = String;
23
24pub const FILE_NAME: &str = "trace.ron";
25
26#[derive(Debug)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub enum Data {
29    File(FileName),
30    String(DataKind, String),
31    Binary(DataKind, Vec<u8>),
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35#[cfg_attr(
36    feature = "serde",
37    derive(serde::Serialize, serde::Deserialize),
38    serde(rename_all = "lowercase")
39)]
40pub enum DataKind {
41    Bin,
42    Wgsl,
43
44    /// IR of Naga module, serialized in RON format
45    Ron,
46    Spv,
47    Dxil,
48    Hlsl,
49    Msl,
50    Glsl,
51}
52
53impl core::fmt::Display for DataKind {
54    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55        let s = match self {
56            DataKind::Bin => "bin",
57            DataKind::Wgsl => "wgsl",
58            DataKind::Ron => "ron",
59            DataKind::Spv => "spv",
60            DataKind::Dxil => "dxil",
61            DataKind::Hlsl => "hlsl",
62            DataKind::Msl => "msl",
63            DataKind::Glsl => "glsl",
64        };
65        write!(f, "{s}")
66    }
67}
68
69impl DataKind {
70    #[cfg(feature = "replay")]
71    fn is_string(&self) -> bool {
72        match *self {
73            DataKind::Wgsl | DataKind::Ron | DataKind::Hlsl | DataKind::Msl | DataKind::Glsl => {
74                true
75            }
76            DataKind::Bin | DataKind::Spv | DataKind::Dxil => false,
77        }
78    }
79}
80
81impl Data {
82    pub fn kind(&self) -> DataKind {
83        match self {
84            Data::File(file) => {
85                if file.ends_with(".bin") {
86                    DataKind::Bin
87                } else if file.ends_with(".wgsl") {
88                    DataKind::Wgsl
89                } else if file.ends_with(".ron") {
90                    DataKind::Ron
91                } else if file.ends_with(".spv") {
92                    DataKind::Spv
93                } else if file.ends_with(".dxil") {
94                    DataKind::Dxil
95                } else if file.ends_with(".hlsl") {
96                    DataKind::Hlsl
97                } else if file.ends_with(".msl") {
98                    DataKind::Msl
99                } else if file.ends_with(".glsl") {
100                    DataKind::Glsl
101                } else {
102                    panic!("unknown data file extension: {file}");
103                }
104            }
105            Data::String(kind, _) => *kind,
106            Data::Binary(kind, _) => *kind,
107        }
108    }
109}
110
111#[allow(clippy::large_enum_variant)]
112#[derive(Debug)]
113#[apply(serde_object_reference_struct)]
114pub enum Action<'a, R: ReferenceType> {
115    Init {
116        desc: crate::device::DeviceDescriptor<'a>,
117        backend: wgt::Backend,
118    },
119    ConfigureSurface(
120        R::Surface,
121        wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
122    ),
123    CreateBuffer(R::Buffer, crate::resource::BufferDescriptor<'a>),
124    FreeBuffer(R::Buffer),
125    DestroyBuffer(R::Buffer),
126    CreateTexture(R::Texture, crate::resource::TextureDescriptor<'a>),
127    FreeTexture(R::Texture),
128    DestroyTexture(R::Texture),
129    CreateTextureView {
130        id: R::TextureView,
131        parent: R::Texture,
132        desc: crate::resource::TextureViewDescriptor<'a>,
133    },
134    DestroyTextureView(R::TextureView),
135    CreateExternalTexture {
136        id: R::ExternalTexture,
137        desc: crate::resource::ExternalTextureDescriptor<'a>,
138        planes: alloc::boxed::Box<[R::TextureView]>,
139    },
140    FreeExternalTexture(R::ExternalTexture),
141    DestroyExternalTexture(R::ExternalTexture),
142    CreateSampler(
143        PointerId<markers::Sampler>,
144        crate::resource::SamplerDescriptor<'a>,
145    ),
146    DestroySampler(PointerId<markers::Sampler>),
147    GetSurfaceTexture {
148        id: R::Texture,
149        parent: R::Surface,
150    },
151    Present(R::Surface),
152    DiscardSurfaceTexture(R::Surface),
153    CreateBindGroupLayout(
154        PointerId<markers::BindGroupLayout>,
155        crate::binding_model::BindGroupLayoutDescriptor<'a>,
156    ),
157    GetRenderPipelineBindGroupLayout {
158        id: PointerId<markers::BindGroupLayout>,
159        pipeline: PointerId<markers::RenderPipeline>,
160        index: u32,
161    },
162    GetComputePipelineBindGroupLayout {
163        id: PointerId<markers::BindGroupLayout>,
164        pipeline: PointerId<markers::ComputePipeline>,
165        index: u32,
166    },
167    DestroyBindGroupLayout(PointerId<markers::BindGroupLayout>),
168    CreatePipelineLayout(
169        PointerId<markers::PipelineLayout>,
170        crate::binding_model::ResolvedPipelineLayoutDescriptor<
171            'a,
172            PointerId<markers::BindGroupLayout>,
173        >,
174    ),
175    DestroyPipelineLayout(PointerId<markers::PipelineLayout>),
176    CreateBindGroup(PointerId<markers::BindGroup>, TraceBindGroupDescriptor<'a>),
177    DestroyBindGroup(PointerId<markers::BindGroup>),
178    CreateShaderModule {
179        id: PointerId<markers::ShaderModule>,
180        desc: crate::pipeline::ShaderModuleDescriptor<'a>,
181        data: Data,
182    },
183    CreateShaderModulePassthrough {
184        id: PointerId<markers::ShaderModule>,
185        data: Vec<Data>,
186
187        entry_point: String,
188        label: crate::Label<'a>,
189        num_workgroups: (u32, u32, u32),
190        runtime_checks: wgt::ShaderRuntimeChecks,
191    },
192    DestroyShaderModule(PointerId<markers::ShaderModule>),
193    CreateComputePipeline {
194        id: PointerId<markers::ComputePipeline>,
195        desc: TraceComputePipelineDescriptor<'a>,
196    },
197    DestroyComputePipeline(PointerId<markers::ComputePipeline>),
198    CreateGeneralRenderPipeline {
199        id: PointerId<markers::RenderPipeline>,
200        desc: TraceGeneralRenderPipelineDescriptor<'a>,
201    },
202    DestroyRenderPipeline(PointerId<markers::RenderPipeline>),
203    CreatePipelineCache {
204        id: PointerId<markers::PipelineCache>,
205        desc: crate::pipeline::PipelineCacheDescriptor<'a>,
206    },
207    DestroyPipelineCache(PointerId<markers::PipelineCache>),
208    CreateRenderBundle {
209        id: R::RenderBundle,
210        desc: crate::command::RenderBundleEncoderDescriptor<'a>,
211        base: BasePass<RenderCommand<R>, Infallible>,
212    },
213    DestroyRenderBundle(PointerId<markers::RenderBundle>),
214    CreateQuerySet {
215        id: PointerId<markers::QuerySet>,
216        desc: crate::resource::QuerySetDescriptor<'a>,
217    },
218    DestroyQuerySet(PointerId<markers::QuerySet>),
219    WriteBuffer {
220        id: R::Buffer,
221        data: Data,
222        range: Range<wgt::BufferAddress>,
223        queued: bool,
224    },
225    WriteTexture {
226        to: wgt::TexelCopyTextureInfo<R::Texture>,
227        data: Data,
228        layout: wgt::TexelCopyBufferLayout,
229        size: wgt::Extent3d,
230    },
231    Submit(crate::SubmissionIndex, Vec<Command<R>>),
232    FailedCommands {
233        commands: Option<Vec<Command<R>>>,
234        /// If `None`, then encoding failed due to a validation error (returned
235        /// from `CommandEncoder::finish`). If `Some`, submission failed due to
236        /// a resource having been destroyed.
237        failed_at_submit: Option<crate::SubmissionIndex>,
238        error: String,
239    },
240    CreateBlas {
241        id: R::Blas,
242        desc: crate::resource::BlasDescriptor<'a>,
243        sizes: wgt::BlasGeometrySizeDescriptors,
244    },
245    DestroyBlas(R::Blas),
246    CreateTlas {
247        id: R::Tlas,
248        desc: crate::resource::TlasDescriptor<'a>,
249    },
250    DestroyTlas(R::Tlas),
251}
252
253/// cbindgen:ignore
254pub type TraceBindGroupDescriptor<'a> = crate::binding_model::BindGroupDescriptor<
255    'a,
256    PointerId<markers::BindGroupLayout>,
257    PointerId<markers::Buffer>,
258    PointerId<markers::Sampler>,
259    PointerId<markers::TextureView>,
260    PointerId<markers::Tlas>,
261    PointerId<markers::ExternalTexture>,
262>;
263
264/// Not a public API. For use by `player` only.
265///
266/// cbindgen:ignore
267#[doc(hidden)]
268pub type TraceGeneralRenderPipelineDescriptor<'a> = GeneralRenderPipelineDescriptor<
269    'a,
270    PointerId<markers::PipelineLayout>,
271    PointerId<markers::ShaderModule>,
272    PointerId<markers::PipelineCache>,
273>;
274
275/// Not a public API. For use by `player` only.
276///
277/// cbindgen:ignore
278#[doc(hidden)]
279pub type TraceComputePipelineDescriptor<'a> = crate::pipeline::ComputePipelineDescriptor<
280    'a,
281    PointerId<markers::PipelineLayout>,
282    PointerId<markers::ShaderModule>,
283    PointerId<markers::PipelineCache>,
284>;