6be8f234
main: add exponential backoff on Vulkan timeout retries
a73x 2026-04-18 15:25
If the driver is genuinely wedged, the timeout-retry loop would spin at full speed. Track consecutive VkWaitTimeout / VkAcquireTimeout events and sleep 5ms * N (capped at 100ms) before retrying. Counter resets on any successful frame. Closes issue ab6c92f0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diff --git a/src/main.zig b/src/main.zig index 06d7af1..ec3e25f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -337,6 +337,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void { var render_pending = true; var resize_pending = false; var scale_pending = false; var consecutive_vk_timeouts: u32 = 0; while (!window.should_close and p.isChildAlive()) { const repeat_timeout_ms = remainingRepeatTimeoutMs(keyboard.nextRepeatDeadlineNs()); @@ -601,6 +602,9 @@ fn runTerminal(alloc: std.mem.Allocator) !void { ) catch |err| switch (err) { error.VkWaitTimeout => { vk_sync.logVkTimeout(@src(), .atlas); consecutive_vk_timeouts +|= 1; const backoff_us: u64 = @min(@as(u64, consecutive_vk_timeouts) * 5_000, 100_000); std.Thread.sleep(backoff_us * std.time.ns_per_us); render_pending = true; continue; }, @@ -696,11 +700,15 @@ fn runTerminal(alloc: std.mem.Allocator) !void { }, error.VkWaitTimeout, error.VkAcquireTimeout => { vk_sync.logVkTimeout(@src(), .fence); consecutive_vk_timeouts +|= 1; const backoff_us: u64 = @min(@as(u64, consecutive_vk_timeouts) * 5_000, 100_000); std.Thread.sleep(backoff_us * std.time.ns_per_us); render_pending = true; continue; }, else => return err, }; consecutive_vk_timeouts = 0; frame_timing.gpu_submit_us = usFromTimer(§ion_timer); frame_timing.wait_fences_us = submit_timing.wait_fences_us; frame_timing.acquire_us = submit_timing.acquire_us;