rrtrace 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/src/renderer.rs CHANGED
@@ -1,3 +1,4 @@
1
+ use crate::BASE_TIME;
1
2
  use crate::renderer::vertex_arena::{AllocationId, VertexArena};
2
3
  use crate::trace_state::{CallBox, SlowTrace, VISIBLE_DURATION, encode_time};
3
4
  use glam::{Mat4, Vec3};
@@ -6,6 +7,7 @@ use std::collections::btree_map::Entry;
6
7
  use std::collections::{BTreeMap, BinaryHeap};
7
8
  use std::fmt::{Debug, Formatter};
8
9
  use std::sync::Arc;
10
+ use std::time::Instant;
9
11
  use std::{fmt, iter};
10
12
  use wgpu::BufferUsages;
11
13
  use wgpu::util::DeviceExt;
@@ -80,13 +82,11 @@ impl GCBox {
80
82
  wgpu::VertexBufferLayout {
81
83
  array_stride: std::mem::size_of::<GCBox>() as wgpu::BufferAddress,
82
84
  step_mode: wgpu::VertexStepMode::Instance,
83
- attributes: &[
84
- wgpu::VertexAttribute {
85
- offset: 0,
86
- shader_location: 1,
87
- format: wgpu::VertexFormat::Uint32x2,
88
- },
89
- ],
85
+ attributes: &[wgpu::VertexAttribute {
86
+ offset: 0,
87
+ shader_location: 1,
88
+ format: wgpu::VertexFormat::Uint32x2,
89
+ }],
90
90
  }
91
91
  }
92
92
  }
@@ -141,6 +141,116 @@ const GC_VERTICES: &[GCVertex] = &[
141
141
  },
142
142
  ];
143
143
 
144
+ #[repr(C)]
145
+ #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
146
+ struct LineVertex {
147
+ position: f32,
148
+ }
149
+
150
+ impl LineVertex {
151
+ fn desc() -> wgpu::VertexBufferLayout<'static> {
152
+ wgpu::VertexBufferLayout {
153
+ array_stride: std::mem::size_of::<LineVertex>() as wgpu::BufferAddress,
154
+ step_mode: wgpu::VertexStepMode::Vertex,
155
+ attributes: &[wgpu::VertexAttribute {
156
+ offset: 0,
157
+ shader_location: 0,
158
+ format: wgpu::VertexFormat::Float32,
159
+ }],
160
+ }
161
+ }
162
+ }
163
+
164
+ #[repr(C)]
165
+ #[derive(Copy, Clone, Debug, Default, bytemuck::Pod, bytemuck::Zeroable)]
166
+ struct LineSegment {
167
+ start_time: [u32; 2],
168
+ end_time: [u32; 2],
169
+ start_pos: [f32; 3],
170
+ end_pos: [f32; 3],
171
+ color: [f32; 4],
172
+ kind: u32,
173
+ _padding: [u32; 3],
174
+ }
175
+
176
+ impl LineSegment {
177
+ const KIND_THREAD: u32 = 0;
178
+ const KIND_WORLD: u32 = 1;
179
+
180
+ fn desc() -> wgpu::VertexBufferLayout<'static> {
181
+ wgpu::VertexBufferLayout {
182
+ array_stride: std::mem::size_of::<LineSegment>() as wgpu::BufferAddress,
183
+ step_mode: wgpu::VertexStepMode::Instance,
184
+ attributes: &[
185
+ wgpu::VertexAttribute {
186
+ offset: 0,
187
+ shader_location: 1,
188
+ format: wgpu::VertexFormat::Uint32x2,
189
+ },
190
+ wgpu::VertexAttribute {
191
+ offset: 8,
192
+ shader_location: 2,
193
+ format: wgpu::VertexFormat::Uint32x2,
194
+ },
195
+ wgpu::VertexAttribute {
196
+ offset: 16,
197
+ shader_location: 3,
198
+ format: wgpu::VertexFormat::Float32x3,
199
+ },
200
+ wgpu::VertexAttribute {
201
+ offset: 28,
202
+ shader_location: 4,
203
+ format: wgpu::VertexFormat::Float32x3,
204
+ },
205
+ wgpu::VertexAttribute {
206
+ offset: 40,
207
+ shader_location: 5,
208
+ format: wgpu::VertexFormat::Float32x4,
209
+ },
210
+ wgpu::VertexAttribute {
211
+ offset: 56,
212
+ shader_location: 6,
213
+ format: wgpu::VertexFormat::Uint32,
214
+ },
215
+ ],
216
+ }
217
+ }
218
+ }
219
+
220
+ const LINE_VERTICES: &[LineVertex] = &[LineVertex { position: 0.0 }, LineVertex { position: 1.0 }];
221
+
222
+ const AXIS_LINE_COLOR: [f32; 4] = [0.35, 0.4, 0.5, 1.0];
223
+ const THREAD_LINE_COLOR: [f32; 4] = [0.45, 0.7, 1.0, 1.0];
224
+ const AXIS_LINE_INSTANCES: &[LineSegment] = &[
225
+ LineSegment {
226
+ start_time: [0, 0],
227
+ end_time: [0, 0],
228
+ start_pos: [0.0, 0.0, 0.0],
229
+ end_pos: [VISIBLE_DURATION as f32 / 500000000.0, 0.0, 0.0],
230
+ color: AXIS_LINE_COLOR,
231
+ kind: LineSegment::KIND_WORLD,
232
+ _padding: [0; 3],
233
+ },
234
+ LineSegment {
235
+ start_time: [0, 0],
236
+ end_time: [0, 0],
237
+ start_pos: [0.0, 0.0, 0.0],
238
+ end_pos: [0.0, 1.0, 0.0],
239
+ color: AXIS_LINE_COLOR,
240
+ kind: LineSegment::KIND_WORLD,
241
+ _padding: [0; 3],
242
+ },
243
+ LineSegment {
244
+ start_time: [0, 0],
245
+ end_time: [0, 0],
246
+ start_pos: [0.0, 0.0, 0.0],
247
+ end_pos: [0.0, 0.0, 1.0],
248
+ color: AXIS_LINE_COLOR,
249
+ kind: LineSegment::KIND_WORLD,
250
+ _padding: [0; 3],
251
+ },
252
+ ];
253
+
144
254
  #[repr(C)]
145
255
  #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
146
256
  struct CameraUniform {
@@ -160,6 +270,7 @@ struct SurfaceState {
160
270
  surface: wgpu::Surface<'static>,
161
271
  config: wgpu::SurfaceConfiguration,
162
272
  render_pipeline: wgpu::RenderPipeline,
273
+ line_pipeline: wgpu::RenderPipeline,
163
274
  gc_pipeline: wgpu::RenderPipeline,
164
275
  depth_texture: wgpu::TextureView,
165
276
  }
@@ -173,7 +284,8 @@ struct ThreadArena {
173
284
  #[derive(Debug, Eq, PartialEq)]
174
285
  struct TraceBatch {
175
286
  end_time: u64,
176
- thread_data: Vec<(u32, AllocationId)>,
287
+ thread_data: Vec<(u32, Option<AllocationId>)>,
288
+ line_data: Option<AllocationId>,
177
289
  gc_data: Option<AllocationId>,
178
290
  max_depth: u32,
179
291
  }
@@ -199,7 +311,9 @@ pub struct Renderer {
199
311
  shader: wgpu::ShaderModule,
200
312
  render_pipeline_layout: wgpu::PipelineLayout,
201
313
  vertex_buffer: wgpu::Buffer,
314
+ line_vertex_buffer: wgpu::Buffer,
202
315
  gc_vertex_buffer: wgpu::Buffer,
316
+ axis_line_buffer: wgpu::Buffer,
203
317
  index_buffer: wgpu::Buffer,
204
318
  num_indices: u32,
205
319
  camera_uniform: CameraUniform,
@@ -208,6 +322,7 @@ pub struct Renderer {
208
322
  lane_alignment: u32,
209
323
  trace_queue: Arc<crossbeam_queue::SegQueue<SlowTrace>>,
210
324
  data_per_thread: BTreeMap<u32, ThreadArena>,
325
+ thread_line_vertex: VertexArena<LineSegment>,
211
326
  gc_vertex: VertexArena<GCBox>,
212
327
  thread_queue: BinaryHeap<Reverse<TraceBatch>>,
213
328
  base_time: u64,
@@ -311,11 +426,21 @@ impl Renderer {
311
426
  contents: bytemuck::cast_slice(VERTICES),
312
427
  usage: wgpu::BufferUsages::VERTEX,
313
428
  });
429
+ let line_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
430
+ label: Some("Line Vertex Buffer"),
431
+ contents: bytemuck::cast_slice(LINE_VERTICES),
432
+ usage: wgpu::BufferUsages::VERTEX,
433
+ });
314
434
  let gc_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
315
435
  label: Some("GC Vertex Buffer"),
316
436
  contents: bytemuck::cast_slice(GC_VERTICES),
317
437
  usage: wgpu::BufferUsages::VERTEX,
318
438
  });
439
+ let axis_line_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
440
+ label: Some("Axis Line Buffer"),
441
+ contents: bytemuck::cast_slice(AXIS_LINE_INSTANCES),
442
+ usage: wgpu::BufferUsages::VERTEX,
443
+ });
319
444
  let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
320
445
  label: Some("Index Buffer"),
321
446
  contents: bytemuck::cast_slice(INDICES),
@@ -332,7 +457,9 @@ impl Renderer {
332
457
  shader,
333
458
  render_pipeline_layout,
334
459
  vertex_buffer,
460
+ line_vertex_buffer,
335
461
  gc_vertex_buffer,
462
+ axis_line_buffer,
336
463
  index_buffer,
337
464
  num_indices,
338
465
  camera_uniform,
@@ -341,6 +468,11 @@ impl Renderer {
341
468
  lane_alignment,
342
469
  trace_queue,
343
470
  data_per_thread: BTreeMap::new(),
471
+ thread_line_vertex: VertexArena::new(
472
+ device.clone(),
473
+ queue.clone(),
474
+ BufferUsages::COPY_DST | BufferUsages::VERTEX,
475
+ ),
344
476
  gc_vertex: VertexArena::new(
345
477
  device,
346
478
  queue,
@@ -459,12 +591,55 @@ impl Renderer {
459
591
  multiview_mask: None,
460
592
  });
461
593
 
594
+ let line_pipeline = self
595
+ .device
596
+ .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
597
+ label: Some("Line Pipeline"),
598
+ layout: Some(&self.render_pipeline_layout),
599
+ vertex: wgpu::VertexState {
600
+ module: &self.shader,
601
+ entry_point: Some("vs_line"),
602
+ buffers: &[LineVertex::desc(), LineSegment::desc()],
603
+ compilation_options: Default::default(),
604
+ },
605
+ fragment: Some(wgpu::FragmentState {
606
+ module: &self.shader,
607
+ entry_point: Some("fs_main"),
608
+ targets: &[Some(wgpu::ColorTargetState {
609
+ format: config.format,
610
+ blend: Some(wgpu::BlendState::ALPHA_BLENDING),
611
+ write_mask: wgpu::ColorWrites::ALL,
612
+ })],
613
+ compilation_options: Default::default(),
614
+ }),
615
+ primitive: wgpu::PrimitiveState {
616
+ topology: wgpu::PrimitiveTopology::LineList,
617
+ strip_index_format: None,
618
+ front_face: wgpu::FrontFace::Ccw,
619
+ cull_mode: None,
620
+ polygon_mode: wgpu::PolygonMode::Fill,
621
+ unclipped_depth: false,
622
+ conservative: false,
623
+ },
624
+ depth_stencil: Some(wgpu::DepthStencilState {
625
+ format: wgpu::TextureFormat::Depth32Float,
626
+ depth_write_enabled: false,
627
+ depth_compare: wgpu::CompareFunction::LessEqual,
628
+ stencil: wgpu::StencilState::default(),
629
+ bias: wgpu::DepthBiasState::default(),
630
+ }),
631
+ multisample: wgpu::MultisampleState::default(),
632
+ cache: None,
633
+ multiview_mask: None,
634
+ });
635
+
462
636
  let depth_texture = Self::create_depth_texture(&self.device, &config);
463
637
 
464
638
  self.surface_state = Some(SurfaceState {
465
639
  surface,
466
640
  config,
467
641
  render_pipeline,
642
+ line_pipeline,
468
643
  gc_pipeline,
469
644
  depth_texture,
470
645
  });
@@ -494,13 +669,14 @@ impl Renderer {
494
669
  }
495
670
 
496
671
  pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
497
- if let Some(state) = &mut self.surface_state {
498
- if new_size.width > 0 && new_size.height > 0 {
499
- state.config.width = new_size.width;
500
- state.config.height = new_size.height;
501
- state.surface.configure(&self.device, &state.config);
502
- state.depth_texture = Self::create_depth_texture(&self.device, &state.config);
503
- }
672
+ if let Some(state) = &mut self.surface_state
673
+ && new_size.width > 0
674
+ && new_size.height > 0
675
+ {
676
+ state.config.width = new_size.width;
677
+ state.config.height = new_size.height;
678
+ state.surface.configure(&self.device, &state.config);
679
+ state.depth_texture = Self::create_depth_texture(&self.device, &state.config);
504
680
  }
505
681
  }
506
682
 
@@ -509,22 +685,59 @@ impl Renderer {
509
685
  while let Some(trace) = self.trace_queue.pop() {
510
686
  updated = true;
511
687
  let mut allocation_ids = Vec::new();
512
- for (thread_id, call_box) in trace.data() {
513
- let s = self.data_per_thread.entry(thread_id).or_insert_with(|| ThreadArena {
514
- used_segments: 0,
515
- vertex: VertexArena::new(
516
- self.device.clone(),
517
- self.queue.clone(),
518
- BufferUsages::COPY_DST | BufferUsages::VERTEX,
519
- ),
520
- });
688
+ for thread_data in trace.data() {
689
+ let thread_id = thread_data.thread_id();
690
+ let call_box = thread_data.call_boxes();
691
+ let s = self
692
+ .data_per_thread
693
+ .entry(thread_id)
694
+ .or_insert_with(|| ThreadArena {
695
+ used_segments: 0,
696
+ vertex: VertexArena::new(
697
+ self.device.clone(),
698
+ self.queue.clone(),
699
+ BufferUsages::COPY_DST | BufferUsages::VERTEX,
700
+ ),
701
+ });
521
702
  s.used_segments += 1;
522
- let (allocation_id, slot) = s.vertex.alloc(call_box.len());
523
- slot.copy_from_slice(call_box);
703
+ let allocation_id = if call_box.is_empty() {
704
+ None
705
+ } else {
706
+ let (allocation_id, slot) = s.vertex.alloc(call_box.len());
707
+ slot.copy_from_slice(call_box);
708
+ Some(allocation_id)
709
+ };
524
710
  allocation_ids.push((thread_id, allocation_id));
525
711
  }
526
712
 
527
713
  let gc_events = trace.gc_events();
714
+ let line_count = trace.data().len();
715
+ let line_data = if line_count > 0 {
716
+ let mut line_segments = Vec::with_capacity(line_count);
717
+ for thread_data in trace.data() {
718
+ let thread_line = thread_data.thread_line();
719
+ let thread_id = thread_data.thread_id();
720
+ let lane = self
721
+ .data_per_thread
722
+ .keys()
723
+ .position(|&id| id == thread_id)
724
+ .unwrap_or(0) as f32;
725
+ line_segments.push(LineSegment {
726
+ start_time: thread_line.start_time(),
727
+ end_time: thread_line.end_time(),
728
+ start_pos: [0.0, 0.0, lane + 0.5],
729
+ end_pos: [0.0, 0.0, lane + 0.5],
730
+ color: THREAD_LINE_COLOR,
731
+ kind: LineSegment::KIND_THREAD,
732
+ _padding: [0; 3],
733
+ });
734
+ }
735
+ let (allocation_id, slot) = self.thread_line_vertex.alloc(line_segments.len());
736
+ slot.copy_from_slice(&line_segments);
737
+ Some(allocation_id)
738
+ } else {
739
+ None
740
+ };
528
741
  let gc_data = if !gc_events.is_empty() {
529
742
  let mut gc_boxes = Vec::with_capacity(gc_events.len());
530
743
  for &event_time in gc_events {
@@ -549,16 +762,18 @@ impl Renderer {
549
762
  end_time,
550
763
  max_depth,
551
764
  thread_data: allocation_ids,
765
+ line_data,
552
766
  gc_data,
553
767
  }));
554
- self.base_time = self.base_time.max(end_time);
555
768
  self.depth.insert(max_depth);
556
769
  }
770
+ self.base_time = (Instant::now() - *BASE_TIME.get().unwrap()).as_nanos() as u64;
557
771
  while let Some(Reverse(TraceBatch { end_time, .. })) = self.thread_queue.peek()
558
772
  && end_time + VISIBLE_DURATION < self.base_time
559
773
  {
560
774
  let Reverse(TraceBatch {
561
775
  thread_data,
776
+ line_data,
562
777
  max_depth,
563
778
  gc_data,
564
779
  ..
@@ -572,12 +787,15 @@ impl Renderer {
572
787
  s_ref.used_segments -= 1;
573
788
  if s_ref.used_segments == 0 {
574
789
  s.remove();
575
- } else {
790
+ } else if let Some(allocation_id) = allocation_id {
576
791
  s_ref.vertex.dealloc(allocation_id);
577
792
  }
578
793
  }
579
794
  }
580
795
  }
796
+ if let Some(line_allocation_id) = line_data {
797
+ self.thread_line_vertex.dealloc(line_allocation_id);
798
+ }
581
799
  if let Some(gc_allocation_id) = gc_data {
582
800
  self.gc_vertex.dealloc(gc_allocation_id);
583
801
  }
@@ -675,6 +893,22 @@ impl Renderer {
675
893
  });
676
894
  }
677
895
 
896
+ render_pass.set_pipeline(&state.line_pipeline);
897
+ render_pass.set_bind_group(0, camera_bind_group, &[0]);
898
+ render_pass.set_vertex_buffer(0, self.line_vertex_buffer.slice(..));
899
+ render_pass.set_vertex_buffer(1, self.axis_line_buffer.slice(..));
900
+ render_pass.draw(0..2, 0..AXIS_LINE_INSTANCES.len() as u32);
901
+
902
+ self.thread_line_vertex.sync();
903
+ self.thread_line_vertex.read_buffers(|buffer, len| {
904
+ if len == 0 {
905
+ return;
906
+ }
907
+ render_pass.set_vertex_buffer(0, self.line_vertex_buffer.slice(..));
908
+ render_pass.set_vertex_buffer(1, buffer.slice(..));
909
+ render_pass.draw(0..2, 0..len as u32);
910
+ });
911
+
678
912
  render_pass.set_pipeline(&state.gc_pipeline);
679
913
  render_pass.set_bind_group(0, camera_bind_group, &[0]);
680
914
  self.gc_vertex.sync();
@@ -732,15 +966,12 @@ where
732
966
  }
733
967
 
734
968
  fn remove(&mut self, value: T) {
735
- match self.inner.entry(value) {
736
- Entry::Vacant(_) => return,
737
- Entry::Occupied(mut entry) => {
738
- let count = entry.get_mut();
739
- if *count <= 1 {
740
- entry.remove();
741
- } else {
742
- *count -= 1;
743
- }
969
+ if let Entry::Occupied(mut entry) = self.inner.entry(value) {
970
+ let count = entry.get_mut();
971
+ if *count <= 1 {
972
+ entry.remove();
973
+ } else {
974
+ *count -= 1;
744
975
  }
745
976
  }
746
977
  }
data/src/ringbuffer.rs CHANGED
@@ -50,13 +50,13 @@ impl RRTraceEvent {
50
50
  pub const SIZE: usize = 65_536;
51
51
  pub const MASK: usize = SIZE - 1;
52
52
 
53
- #[repr(C, align(64))]
53
+ #[repr(C, align(128))]
54
54
  struct RRTraceEventRingBufferWriter {
55
55
  write_index: AtomicU64,
56
56
  read_index_cache: u64,
57
57
  }
58
58
 
59
- #[repr(C, align(64))]
59
+ #[repr(C, align(128))]
60
60
  struct RRTraceEventRingBufferReader {
61
61
  read_index: AtomicU64,
62
62
  write_index_cache: u64,