Skip to main content

katra_core/
payload.rs

1//! Structured event payloads.
2//!
3//! Payloads are plain, `Copy` scalar records so the hot capture path can
4//! store them into preallocated per-thread buffers with **zero heap
5//! allocation per event** (KatraProfiler budget: "avoid heap allocation
6//! unless justified").
7//!
8//! The enum layout is part of the trace format; **append new variants at
9//! the end**.
10
11use serde::{Deserialize, Serialize};
12
13/// Payload for file operations.
14#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
15pub struct FilePayload {
16    /// File identity hash ([`crate::FileKey`]).
17    pub file: u64,
18    /// Byte offset.
19    pub offset: u64,
20    /// Byte length.
21    pub length: u64,
22    /// Flags (open flags, wait flags, ...).
23    pub flags: u32,
24    /// Result (bytes transferred, NTSTATUS/HRESULT, or -1).
25    pub result: i64,
26}
27
28/// Payload for memory operations.
29#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
30pub struct MemPayload {
31    /// Size in bytes.
32    pub size: u64,
33    /// Alignment in bytes.
34    pub align: u32,
35    /// Arena/resource id (0 = process heap).
36    pub arena: u32,
37}
38
39/// Payload for synchronization operations.
40#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
41pub struct SyncPayload {
42    /// Sync kind (0 event, 1 mutex, 2 semaphore, 3 fence, 4 condvar, ...).
43    pub kind: u32,
44    /// Value (fence value, semaphore count, ...).
45    pub value: u64,
46}
47
48/// Payload for thread operations.
49#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
50pub struct ThreadPayload {
51    /// Action (0 create, 1 wakeup, 2 exit, 3 yield, ...).
52    pub action: u32,
53    /// Extra (target thread id, ...).
54    pub extra: u64,
55}
56
57/// Payload for D3D12 calls. The call identity is in [`crate::EventKind`];
58/// `a..d` carry call-specific scalar arguments.
59#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
60pub struct D3d12Payload {
61    /// Call-specific scalar 1.
62    pub a: u64,
63    /// Call-specific scalar 2.
64    pub b: u64,
65    /// Call-specific scalar 3.
66    pub c: u64,
67    /// Call-specific scalar 4.
68    pub d: u64,
69}
70
71/// Payload for Vulkan calls. The call identity is in [`crate::EventKind`].
72#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
73pub struct VulkanPayload {
74    /// Call-specific scalar 1.
75    pub a: u64,
76    /// Call-specific scalar 2.
77    pub b: u64,
78    /// Call-specific scalar 3.
79    pub c: u64,
80    /// Call-specific scalar 4.
81    pub d: u64,
82}
83
84/// Payload for GPU counters/samples.
85#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
86pub struct GpuPayload {
87    /// Counter id (0 timestamp, 1 idle bubble ns, 2 utilization %, ...).
88    pub counter: u32,
89    /// Value.
90    pub value: u64,
91}
92
93/// Payload for I/O events.
94#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
95pub struct IoPayload {
96    /// Queue depth at submission (or 0).
97    pub queue_depth: u32,
98    /// Operation latency in ns (0 if unknown).
99    pub latency_ns: u64,
100    /// Bytes transferred.
101    pub bytes: u64,
102    /// Operation (0 read, 1 submit batch, 2 complete, ...).
103    pub op: u32,
104}
105
106/// Payload for Katra-native events.
107#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
108pub struct KatraPayload {
109    /// Subsystem index (see [`crate::Subsystem`]).
110    pub subsystem: u16,
111    /// Promotion state index (see [`crate::PromotionState`]).
112    pub state: u16,
113    /// Detail (budget bytes, epoch, node id, ...).
114    pub detail: u64,
115}
116
117/// Payload for shader events.
118#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
119pub struct ShaderPayload {
120    /// Shader stage (0 vertex, 1 pixel, 2 compute, ...).
121    pub stage: u32,
122    /// Input identity hash (DXIL).
123    pub input_hash: u64,
124    /// Output identity hash (SPIR-V).
125    pub output_hash: u64,
126}
127
128/// Payload for cache events.
129#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
130pub struct CachePayload {
131    /// Cache layer (1 DXIL, 2 IR, 3 SPIR-V, 4 pipeline).
132    pub layer: u8,
133    /// Whether the lookup hit.
134    pub hit: bool,
135    /// Content key hash.
136    pub key: u64,
137    /// Artifact size in bytes.
138    pub size: u64,
139}
140
141/// Payload for present events.
142#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
143pub struct PresentPayload {
144    /// Frame index.
145    pub frame: u64,
146    /// Present mode (0 vsync, 1 immediate, 2 mailbox, ...).
147    pub present_mode: u32,
148}
149
150/// Payload for decompression events.
151#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
152pub struct DecompressPayload {
153    /// Compressed input bytes.
154    pub input_bytes: u64,
155    /// Decompressed output bytes.
156    pub output_bytes: u64,
157    /// Format (0 gdeflate, 1 gzip, 2 zlib, 3 raw deflate, ...).
158    pub format: u32,
159    /// Decompression latency in ns.
160    pub latency_ns: u64,
161}
162
163/// Payload for future/unknown event kinds (extension escape hatch).
164#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
165pub struct RawPayload {
166    /// Generic scalar 1.
167    pub a: u64,
168    /// Generic scalar 2.
169    pub b: u64,
170    /// Generic scalar 3.
171    pub c: u64,
172    /// Generic scalar 4.
173    pub d: u64,
174}
175
176/// The payload of a [`crate::TraceEvent`]. Plain scalars only; append-only.
177#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
178pub enum Payload {
179    /// No payload.
180    #[default]
181    None,
182    /// File operation.
183    File(FilePayload),
184    /// Memory operation.
185    Mem(MemPayload),
186    /// Synchronization operation.
187    Sync(SyncPayload),
188    /// Thread operation.
189    Thread(ThreadPayload),
190    /// D3D12 call.
191    D3d12(D3d12Payload),
192    /// Vulkan call.
193    Vulkan(VulkanPayload),
194    /// GPU sample.
195    Gpu(GpuPayload),
196    /// I/O operation.
197    Io(IoPayload),
198    /// Katra-native operation.
199    Katra(KatraPayload),
200    /// Shader operation.
201    Shader(ShaderPayload),
202    /// Cache operation.
203    Cache(CachePayload),
204    /// Present operation.
205    Present(PresentPayload),
206    /// Decompression operation.
207    Decompress(DecompressPayload),
208    /// Extension payload.
209    Raw(RawPayload),
210}
211
212impl Payload {
213    /// The payload kind as a stable string (for reports).
214    pub fn as_str(&self) -> &'static str {
215        match self {
216            Payload::None => "none",
217            Payload::File(_) => "file",
218            Payload::Mem(_) => "mem",
219            Payload::Sync(_) => "sync",
220            Payload::Thread(_) => "thread",
221            Payload::D3d12(_) => "d3d12",
222            Payload::Vulkan(_) => "vulkan",
223            Payload::Gpu(_) => "gpu",
224            Payload::Io(_) => "io",
225            Payload::Katra(_) => "katra",
226            Payload::Shader(_) => "shader",
227            Payload::Cache(_) => "cache",
228            Payload::Present(_) => "present",
229            Payload::Decompress(_) => "decompress",
230            Payload::Raw(_) => "raw",
231        }
232    }
233
234    /// Convenience constructor for a D3D12 call payload.
235    pub fn d3d12(a: u64, b: u64, c: u64, d: u64) -> Self {
236        Payload::D3d12(D3d12Payload { a, b, c, d })
237    }
238
239    /// Convenience constructor for a Vulkan call payload.
240    pub fn vulkan(a: u64, b: u64, c: u64, d: u64) -> Self {
241        Payload::Vulkan(VulkanPayload { a, b, c, d })
242    }
243
244    /// Convenience constructor for a raw payload.
245    pub fn raw(a: u64, b: u64, c: u64, d: u64) -> Self {
246        Payload::Raw(RawPayload { a, b, c, d })
247    }
248}