Commit d5eca1c82213
tarball5 files changed+239-59
@@ -37,12 +37,22 @@ pub(crate) struct Device {
3737
pub push_descriptor: ash::khr::push_descriptor::Device,3838
pub dmabuf: Option<DmabufExt>,3939
pub name: String,40
+ /// Signalled fences kept for reuse, see `FenceInner`.41
+ pub spare_fences: Mutex<Vec<vk::Fence>>,4042
}4143
4244
impl Drop for Device {4345
fn drop(&mut self) {4446
unsafe {4547
let _ = self.device.device_wait_idle();48
+ for f in self49
+ .spare_fences50
+ .get_mut()51
+ .unwrap_or_else(|e| e.into_inner())52
+ .drain(..)53
+ {54
+ self.device.destroy_fence(f, None);55
+ }4656
self.device.destroy_device(None);4757
self.instance.destroy_instance(None);4858
}@@ -126,6 +136,7 @@ impl Shared {
126136
push_descriptor,127137
dmabuf,128138
name,139
+ spare_fences: Mutex::new(Vec::new()),129140
};130141
Ok(Self {131142
allocator: Mutex::new(allocator?),@@ -41,6 +41,8 @@ pub struct VulkanRenderer {
4141
dmabuf_targets: HashMap<WeakDmabuf, Arc<ImageInner>>,4242
pipelines: Pipelines,4343
pool: vk::CommandPool,44
+ /// Command buffers whose work finished, reset and reused by `begin`.45
+ spare_cmds: Vec<vk::CommandBuffer>,4446
samplers: [vk::Sampler; 4],4547
min_filter: TextureFilter,4648
mag_filter: TextureFilter,@@ -76,7 +78,10 @@ impl VulkanRenderer {
7678
d.create_command_pool(7779
&vk::CommandPoolCreateInfo::default()7880
.queue_family_index(shared.device.queue_family)79
- .flags(vk::CommandPoolCreateFlags::TRANSIENT),81
+ .flags(82
+ vk::CommandPoolCreateFlags::TRANSIENT83
+ | vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER,84
+ ),8085
None,8186
)?8287
};@@ -105,6 +110,7 @@ impl VulkanRenderer {
105110
dmabuf_targets: HashMap::new(),106111
pipelines: Pipelines::new(&shared)?,107112
pool,113
+ spare_cmds: Vec::new(),108114
samplers,109115
min_filter: TextureFilter::Linear,110116
mag_filter: TextureFilter::Linear,@@ -152,28 +158,33 @@ impl VulkanRenderer {
152158
}153159
154160
fn reap(&mut self) {155
- let d = &self.shared.device.device;156
- let pool = self.pool;161
+ let spare = &mut self.spare_cmds;157162
self.pending.retain(|p| {158163
if !p.fence.signaled() {159164
return true;160165
}161
- unsafe { d.free_command_buffers(pool, &[p.cmd]) };166
+ spare.push(p.cmd);162167
false163168
});164169
self.dmabuf_textures.retain(|k, _| !k.is_gone());165170
self.dmabuf_targets.retain(|k, _| !k.is_gone());166171
}167172
168
- fn begin(&self) -> Result<vk::CommandBuffer, Error> {173
+ fn begin(&mut self) -> Result<vk::CommandBuffer, Error> {169174
let d = &self.shared.device.device;170
- let cmd = unsafe {171
- d.allocate_command_buffers(172
- &vk::CommandBufferAllocateInfo::default()173
- .command_pool(self.pool)174
- .level(vk::CommandBufferLevel::PRIMARY)175
- .command_buffer_count(1),176
- )?[0]175
+ let cmd = match self.spare_cmds.pop() {176
+ Some(cmd) => {177
+ unsafe { d.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())? };178
+ cmd179
+ }180
+ None => unsafe {181
+ d.allocate_command_buffers(182
+ &vk::CommandBufferAllocateInfo::default()183
+ .command_pool(self.pool)184
+ .level(vk::CommandBufferLevel::PRIMARY)185
+ .command_buffer_count(1),186
+ )?[0]187
+ },177188
};178189
unsafe {179190
d.begin_command_buffer(@@ -188,8 +199,14 @@ impl VulkanRenderer {
188199
#[profiling::function]189200
fn end_and_submit(&self, cmd: vk::CommandBuffer) -> Result<Arc<FenceInner>, Error> {190201
let d = &self.shared.device.device;191
- unsafe { d.end_command_buffer(cmd)? };192
- let fence = FenceInner::new(&self.shared)?;202
+ {203
+ profiling::scope!("end_command_buffer");204
+ unsafe { d.end_command_buffer(cmd)? };205
+ }206
+ let fence = {207
+ profiling::scope!("create_fence");208
+ FenceInner::new(&self.shared)?209
+ };193210
let cmds = [vk::CommandBufferSubmitInfo::default().command_buffer(cmd)];194211
let submit = vk::SubmitInfo2::default().command_buffer_infos(&cmds);195212
let queue = self@@ -198,7 +215,10 @@ impl VulkanRenderer {
198215
.queue199216
.lock()200217
.unwrap_or_else(|e| e.into_inner());201
- unsafe { d.queue_submit2(*queue, &[submit], fence.fence())? };218
+ {219
+ profiling::scope!("queue_submit");220
+ unsafe { d.queue_submit2(*queue, &[submit], fence.fence())? };221
+ }202222
Ok(fence)203223
}204224
@@ -215,12 +235,7 @@ impl VulkanRenderer {
215235
);216236
let fence = self.end_and_submit(cmd)?;217237
let res = fence.wait();218
- unsafe {219
- self.shared220
- .device221
- .device222
- .free_command_buffers(self.pool, &[cmd])223
- };238
+ self.spare_cmds.push(cmd);224239
Ok(res?)225240
}226241
@@ -455,9 +470,9 @@ impl VulkanRenderer {
455470
height: h as u32,456471
depth: 1,457472
});473
+ let cmd = self.begin()?;458474
let d = &self.shared.device.device;459475
let family = self.shared.device.queue_family;460
- let cmd = self.begin()?;461476
unsafe {462477
acquire(d, cmd, family, image, vk::ImageLayout::TRANSFER_DST_OPTIMAL);463478
d.cmd_copy_buffer_to_image(@@ -30,7 +30,19 @@ impl FenceInner {
3030
if exportable {3131
info = info.push_next(&mut export);3232
}33
- let fence = unsafe { shared.device.device.create_fence(&info, None)? };33
+ let spare = shared34
+ .device35
+ .spare_fences36
+ .lock()37
+ .unwrap_or_else(|e| e.into_inner())38
+ .pop();39
+ let fence = match spare {40
+ Some(f) => {41
+ unsafe { shared.device.device.reset_fences(&[f])? };42
+ f43
+ }44
+ None => unsafe { shared.device.device.create_fence(&info, None)? },45
+ };3446
Ok(Arc::new(Self {3547
shared: shared.clone(),3648
fence,@@ -107,9 +119,26 @@ fn readable(fd: &OwnedFd, timeout: Option<&rustix::event::Timespec>) -> bool {
107119
}108120
}109121
122
+/// Fences go back to a pool instead of being destroyed, which cut the median123
+/// queue submit on NVIDIA from 87 to 52 us. One still pending is destroyed.110124
impl Drop for FenceInner {111125
fn drop(&mut self) {112
- unsafe { self.shared.device.device.destroy_fence(self.fence, None) };126
+ let d = &self.shared.device.device;127
+ let state = self.state.get_mut().unwrap_or_else(|e| e.into_inner());128
+ let idle = match state {129
+ State::Pending => unsafe { d.get_fence_status(self.fence) }.unwrap_or(false),130
+ State::Exported(_) => true,131
+ };132
+ if idle {133
+ self.shared134
+ .device135
+ .spare_fences136
+ .lock()137
+ .unwrap_or_else(|e| e.into_inner())138
+ .push(self.fence);139
+ } else {140
+ unsafe { d.destroy_fence(self.fence, None) };141
+ }113142
}114143
}115144
@@ -1,38 +1,150 @@
1
- Compiling monolith v0.0.0 (/home/bolt/code/monolith/crates/monolith)2
- Finished `release` profile [optimized] target(s) in 12.52s1
+ Finished `release` profile [optimized] target(s) in 0.09s32
Running `target/release/monolith run --backend drm , vkcube`4
-2026-10-16T13:53:37.943439Z INFO monolith::drm: primary GPU path=/dev/dri/card15
-2026-10-16T13:53:38.355268Z INFO monolith::drm: output connected name="DP-2" w=2560 h=1440 refresh=1656
-2026-10-16T13:53:38.355369Z INFO monolith::ipc: control socket path=/run/user/1000/monolith-wayland-2.sock7
-2026-10-16T13:53:38.355385Z INFO monolith: monolith running socket="wayland-2" device="NVIDIA GeForce RTX 3060"8
-2026-10-16T13:53:38.355828Z INFO monolith::commands: spawned pid=358143 argv=[",", "vkcube"]9
-2026-10-16T13:53:38.383773Z DEBUG monolith::drm: slow frame output="DP-2" took_ns=27867019 scene_ns=3700 render_ns=8621537 render_cpu_ns=2390802 queue_ns=21323310
-2026-10-16T13:53:38.387370Z DEBUG monolith::drm: frame rate output="DP-2" presented=1 vblanks=8700649 budget_us=298673
+2026-10-16T13:55:27.915038Z INFO monolith: logging spans slower than 1 ms4
+slow span input_seat>add_keyboard_with_context_flags>input_keyboard took_us=20875
+slow span input_seat>add_keyboard_with_context_flags took_us=21326
+slow span input_seat>add_keyboard took_us=21477
+2026-10-16T13:55:29.224103Z INFO monolith::drm: primary GPU path=/dev/dri/card18
+slow span drm_device>drm_atomic took_us=907229
+slow span drm_device took_us=9076710
+slow span new>acquire>acquire>create_buffer>create_buffer_with_flags>create_buffer_with_flags took_us=129811
+slow span new>acquire>acquire>create_buffer>create_buffer_with_flags took_us=132812
+slow span new>acquire>acquire>create_buffer took_us=133613
+slow span new>acquire>acquire took_us=134514
+slow span new>acquire took_us=135315
+slow span drm_device>drm_atomic>create_surface>drm_atomic>test_state took_us=1524116
+slow span new>test_state>test_state>test_state took_us=1526417
+slow span new>test_state>test_state took_us=1527318
+slow span new>test_state took_us=1528119
+slow span new took_us=1729920
+slow span drm_device>drm_atomic>create_surface>drm_atomic>test_state took_us=676521
+slow span drm_compositor>render_frame>test_state_complete>test_state>test_state took_us=678222
+slow span drm_compositor>render_frame>test_state_complete>test_state took_us=679023
+slow span drm_compositor>render_frame>test_state_complete took_us=679924
+slow span drm_compositor>render_frame>bind took_us=1557325
+slow span drm_compositor>render_frame took_us=2299626
+slow span render_frame took_us=2301827
+slow span drm_device>drm_atomic>create_surface>drm_atomic>commit took_us=9923728
+slow span commit>commit>commit took_us=9927229
+slow span commit>commit took_us=9928230
+slow span commit took_us=9929731
+2026-10-16T13:55:29.641815Z INFO monolith::drm: output connected name="DP-2" w=2560 h=1440 refresh=16532
+2026-10-16T13:55:29.641868Z INFO monolith::ipc: control socket path=/run/user/1000/monolith-wayland-2.sock33
+2026-10-16T13:55:29.641880Z INFO monolith: monolith running socket="wayland-2" device="NVIDIA GeForce RTX 3060"34
+2026-10-16T13:55:29.642294Z INFO monolith::commands: spawned pid=358809 argv=[",", "vkcube"]35
+slow span render_surface>import_texture>import_texture>upload_with took_us=1581236
+slow span render_surface>import_texture>import_texture took_us=2650137
+slow span render_surface>import_texture took_us=2651138
+slow span drm_compositor>render_frame>acquire>acquire>create_buffer>create_buffer_with_flags>create_buffer_with_flags took_us=125239
+slow span drm_compositor>render_frame>acquire>acquire>create_buffer>create_buffer_with_flags took_us=127840
+slow span drm_compositor>render_frame>acquire>acquire>create_buffer took_us=129541
+slow span drm_compositor>render_frame>acquire>acquire took_us=131442
+slow span drm_compositor>render_frame>acquire took_us=133043
+slow span drm_compositor>render_frame>add_framebuffer>framebuffer_from_bo>framebuffer_from_bo_internal took_us=777444
+slow span drm_compositor>render_frame>add_framebuffer>framebuffer_from_bo took_us=782145
+slow span drm_compositor>render_frame>add_framebuffer took_us=783746
+slow span drm_compositor>render_frame>bind took_us=1376747
+slow span drm_compositor>render_frame took_us=2330948
+slow span render_surface>render_frame took_us=2332349
+2026-10-16T13:55:29.692355Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=49995407 scene_ns=7600 render_ns=23337629 render_cpu_ns=2849132 queue_ns=12563250
+slow span render_surface took_us=5001351
+2026-10-16T13:55:29.697539Z DEBUG monolith::drm: frame rate output="DP-2" presented=1 vblanks=8719010 budget_us=519951152
Selected WSI platform: wayland1253
Selected GPU 0: NVIDIA GeForce RTX 3060, type: DiscreteGpu, apiVersion: 4211017 (1.4.329), driverVersion: -1797652352 (83.416.128) 13
-2026-10-16T13:53:39.387636Z DEBUG monolith::drm: frame rate output="DP-2" presented=10 vblanks=165 budget_us=240014
-2026-10-16T13:53:40.387865Z DEBUG monolith::drm: frame rate output="DP-2" presented=90 vblanks=164 budget_us=208215
-2026-10-16T13:53:40.442431Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6062851 budget_ns=255841416
-2026-10-16T13:53:41.388127Z DEBUG monolith::drm: frame rate output="DP-2" presented=163 vblanks=165 budget_us=269717
-2026-10-16T13:53:41.497723Z DEBUG monolith::drm: slow frame output="DP-2" took_ns=3177748 scene_ns=4680 render_ns=3092097 render_cpu_ns=387440 queue_ns=7937118
-2026-10-16T13:53:41.503321Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6052851 budget_ns=322793619
-2026-10-16T13:53:42.388427Z DEBUG monolith::drm: frame rate output="DP-2" presented=164 vblanks=165 budget_us=308120
-2026-10-16T13:53:43.255318Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6096851 budget_ns=323905821
-2026-10-16T13:53:43.388643Z DEBUG monolith::drm: frame rate output="DP-2" presented=164 vblanks=164 budget_us=321622
-2026-10-16T13:53:44.385342Z DEBUG monolith::input: bind cmd=Fullscreen23
-2026-10-16T13:53:44.388911Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=330024
-2026-10-16T13:53:44.619725Z DEBUG monolith::drm: slow frame output="DP-2" took_ns=41477278 scene_ns=13400 render_ns=41081802 render_cpu_ns=6374442 queue_ns=37524625
-2026-10-16T13:53:44.625342Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=96996106 budget_ns=320022726
-2026-10-16T13:53:45.389164Z DEBUG monolith::drm: frame rate output="DP-2" presented=131 vblanks=165 budget_us=324227
-2026-10-16T13:53:46.389427Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=324928
-2026-10-16T13:53:47.389678Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=318829
-2026-10-16T13:53:48.389939Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=324230
-2026-10-16T13:53:49.390191Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=320831
-2026-10-16T13:53:50.390452Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=318232
-2026-10-16T13:53:51.390710Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=317233
-2026-10-16T13:53:52.391010Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=328734
-2026-10-16T13:53:53.391226Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=164 budget_us=319035
-2026-10-16T13:53:54.391491Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=319536
-2026-10-16T13:53:55.391795Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=322737
-2026-10-16T13:53:56.392074Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=164 budget_us=340638
-2026-10-16T13:53:56.817264Z DEBUG monolith::input: bind cmd=Quit54
+2026-10-16T13:55:30.697736Z DEBUG monolith::drm: frame rate output="DP-2" presented=19 vblanks=164 budget_us=243755
+slow span import_dmabuf took_us=1785656
+slow span import_dmabuf took_us=2723857
+slow span import_dmabuf took_us=2015558
+2026-10-16T13:55:31.697991Z DEBUG monolith::drm: frame rate output="DP-2" presented=82 vblanks=164 budget_us=219159
+2026-10-16T13:55:32.679444Z DEBUG monolith::input: bind cmd=Fullscreen60
+2026-10-16T13:55:32.698256Z DEBUG monolith::drm: frame rate output="DP-2" presented=164 vblanks=165 budget_us=201361
+slow span import_dmabuf took_us=1770062
+slow span import_dmabuf took_us=2403763
+slow span import_dmabuf took_us=1567764
+slow span on_commit_buffer_handler>update_buffer took_us=634265
+slow span on_commit_buffer_handler took_us=639566
+slow span new>render_damage>render_output_internal took_us=2498867
+slow span new>render_damage>render_output>render_output_internal took_us=2504068
+slow span new>render_damage>render_output took_us=2507169
+slow span drm_compositor>render_frame>render_output took_us=2508070
+slow span drm_compositor>render_frame took_us=2514671
+slow span render_surface>render_frame took_us=2515872
+2026-10-16T13:55:32.913829Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=25435336 scene_ns=26330 render_ns=25175162 render_cpu_ns=5136493 queue_ns=22248473
+slow span render_surface took_us=2548374
+2026-10-16T13:55:32.922566Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=96993106 budget_ns=250876575
+2026-10-16T13:55:32.934693Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6064851 budget_ns=301160676
+2026-10-16T13:55:32.971061Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6068851 budget_ns=332739977
+slow span new>render_damage>render_output_internal>submit>end_and_submit took_us=581578
+slow span new>render_damage>render_output_internal>submit took_us=593079
+slow span new>render_damage>render_output_internal took_us=597180
+slow span new>render_damage>render_output>render_output_internal took_us=597881
+slow span new>render_damage>render_output took_us=600882
+slow span drm_compositor>render_frame>render_output took_us=601783
+slow span drm_compositor>render_frame took_us=608084
+slow span render_surface>render_frame took_us=609085
+2026-10-16T13:55:33.016548Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=6376037 scene_ns=33750 render_ns=6107272 render_cpu_ns=1178461 queue_ns=22344486
+slow span render_surface took_us=641887
+2026-10-16T13:55:33.019676Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6090851 budget_ns=341609188
+2026-10-16T13:55:33.698509Z DEBUG monolith::drm: frame rate output="DP-2" presented=128 vblanks=165 budget_us=334289
+2026-10-16T13:55:34.698766Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=331190
+slow span new>render_damage>render_output_internal>submit>end_and_submit took_us=560291
+slow span new>render_damage>render_output_internal>submit took_us=569092
+slow span new>render_damage>render_output_internal took_us=571293
+slow span new>render_damage>render_output>render_output_internal took_us=572094
+slow span new>render_damage>render_output took_us=573395
+slow span drm_compositor>render_frame>render_output took_us=574096
+slow span drm_compositor>render_frame took_us=578797
+slow span render_surface>render_frame took_us=579698
+2026-10-16T13:55:34.768375Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=6245805 scene_ns=8490 render_ns=5808747 render_cpu_ns=1863972 queue_ns=42460899
+slow span render_surface took_us=6312100
+2026-10-16T13:55:34.771529Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6069851 budget_ns=3362830101
+2026-10-16T13:55:35.699025Z DEBUG monolith::drm: frame rate output="DP-2" presented=164 vblanks=165 budget_us=3472102
+2026-10-16T13:55:36.699286Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3415103
+slow span new>render_damage>render_output_internal>submit>end_and_submit took_us=3063104
+slow span new>render_damage>render_output_internal>submit took_us=3108105
+slow span new>render_damage>render_output_internal took_us=3123106
+slow span new>render_damage>render_output>render_output_internal took_us=3130107
+slow span new>render_damage>render_output took_us=3141108
+slow span drm_compositor>render_frame>render_output took_us=3149109
+slow span drm_compositor>render_frame took_us=3170110
+slow span render_surface>render_frame took_us=3179111
+2026-10-16T13:55:37.432701Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=3290440 scene_ns=7500 render_ns=3204169 render_cpu_ns=3270391 queue_ns=75401112
+slow span render_surface took_us=3306113
+2026-10-16T13:55:37.699539Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3298114
+2026-10-16T13:55:38.699792Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3330115
+2026-10-16T13:55:39.700055Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3345116
+2026-10-16T13:55:40.700318Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3478117
+2026-10-16T13:55:41.700567Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3266118
+2026-10-16T13:55:42.700827Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3578119
+slow span new>render_damage>render_output_internal>submit>end_and_submit took_us=3009120
+slow span new>render_damage>render_output_internal>submit took_us=3120121
+slow span new>render_damage>render_output_internal took_us=3142122
+slow span new>render_damage>render_output>render_output_internal took_us=3155123
+slow span new>render_damage>render_output took_us=3174124
+slow span drm_compositor>render_frame>render_output took_us=3188125
+slow span drm_compositor>render_frame took_us=3220126
+slow span render_surface>render_frame took_us=3235127
+2026-10-16T13:55:43.640465Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=3363021 scene_ns=9080 render_ns=3252660 render_cpu_ns=3339252 queue_ns=97881128
+slow span render_surface took_us=3384129
+2026-10-16T13:55:43.646539Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6066851 budget_ns=3369191130
+2026-10-16T13:55:43.701091Z DEBUG monolith::drm: frame rate output="DP-2" presented=164 vblanks=165 budget_us=3591131
+2026-10-16T13:55:44.701355Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3399132
+2026-10-16T13:55:45.701605Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3279133
+2026-10-16T13:55:46.701869Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3357134
+2026-10-16T13:55:47.702145Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3503135
+2026-10-16T13:55:48.702451Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=165 budget_us=3412136
+2026-10-16T13:55:49.702636Z DEBUG monolith::drm: frame rate output="DP-2" presented=165 vblanks=164 budget_us=3267137
+slow span new>render_damage>render_output_internal>submit>end_and_submit took_us=3504138
+slow span new>render_damage>render_output_internal>submit took_us=3561139
+slow span new>render_damage>render_output_internal took_us=3578140
+slow span new>render_damage>render_output>render_output_internal took_us=3585141
+slow span new>render_damage>render_output took_us=3598142
+slow span drm_compositor>render_frame>render_output took_us=3605143
+slow span drm_compositor>render_frame took_us=3628144
+slow span render_surface>render_frame took_us=3636145
+2026-10-16T13:55:49.854584Z DEBUG render_surface: monolith::drm: slow frame output="DP-2" took_ns=3769619 scene_ns=9481 render_ns=3647066 render_cpu_ns=3739753 queue_ns=109462146
+slow span render_surface took_us=3793147
+2026-10-16T13:55:49.860264Z DEBUG monolith::drm: frame missed its vblank output="DP-2" late_ns=6067851 budget_ns=3373150148
+2026-10-16T13:55:50.378283Z DEBUG monolith::input: bind cmd=Quit149
+slow span drm_device>drm_atomic>create_surface>drm_atomic took_us=67389150
+slow span drm_device>drm_atomic>create_surface>drm_atomic>clear_state took_us=67443@@ -0,0 +1,13 @@
1
+# NVIDIA driver behaviour measured on an RTX 30602
+3
+Numbers from throwaway benchmarks against monolith's Vulkan renderer, October 2026.4
+5
+## Waiting on a pending VkFence sleeps in 10 ms steps6
+7
+`vkWaitForFences` on a fence whose work has not finished yet returned after a 10.06 ms median, for GPU work that finishes in under 200 us. Waiting 200 us before calling it gave a 2 us median. Exporting the fence as a sync_file and polling the fd wakes on completion, at a 15 us median and 213 us worst case. render-vk waits this way now.8
+9
+## Every 1024th queue submit stalls for milliseconds10
+11
+`vkQueueSubmit2` normally takes 30 to 90 us, but every 1024th call takes 2.5 to 15 ms, at the same submission indices in every run (1015, 2039, ...). This holds with or without exportable fences and with pooled fences and command buffers, so it is per submission, probably an internal ring wrapping. At 165 Hz it shows up as one dropped frame every 6.2 s.12
+13
+Open for M7. Either spend the 1024th submission on an empty submit at a moment with slack, or move submission to its own thread so the render path never waits on it.