a73x

9afdc9f8

Migrate 14 *WaitIdle sites to vk_sync.waitIdleForShutdown

a73x   2026-04-18 15:18

Commit message
Migrate 14 *WaitIdle sites to vk_sync.waitIdleForShutdown

Mechanically migrates 13 deviceWaitIdle + 1 queueWaitIdle sites to
the named waitIdleForShutdown helper. Preserves existing unbounded
behavior while documenting intent at the call site and satisfying
the upcoming grep gate.

Four of these sites are mid-flight recovery paths (scale change,
resize, OutOfDateKHR) rather than shutdown drains; those are flagged
in a follow-up ticket for migration to a bounded variant once
waitIdleBounded is implemented.

Part of issue ab6c92f0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

src/main.zig
Old New
@@ -422,7 +422,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void {
422 if (!render_pending) continue; 422 if (!render_pending) continue;
423 423
424 if (scale_pending) { 424 if (scale_pending) {
425 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 425 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
426 426
427 geom = try rebuildFaceForScale( 427 geom = try rebuildFaceForScale(
428 &face, 428 &face,
@@ -460,7 +460,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void {
460 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale)); 460 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale));
461 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale)); 461 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale));
462 if (new_grid.cols != cols or new_grid.rows != rows) { 462 if (new_grid.cols != cols or new_grid.rows != rows) {
463 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 463 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
464 try ctx.recreateSwapchain(buf_w, buf_h); 464 try ctx.recreateSwapchain(buf_w, buf_h);
465 try term.resize(new_grid.cols, new_grid.rows); 465 try term.resize(new_grid.cols, new_grid.rows);
466 try p.resize(new_grid.cols, new_grid.rows); 466 try p.resize(new_grid.cols, new_grid.rows);
@@ -477,7 +477,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void {
477 selection.anchor = if (selection.anchor) |point| clampGridPoint(point, cols, rows) else null; 477 selection.anchor = if (selection.anchor) |point| clampGridPoint(point, cols, rows) else null;
478 selection.hover = if (selection.hover) |point| clampGridPoint(point, cols, rows) else null; 478 selection.hover = if (selection.hover) |point| clampGridPoint(point, cols, rows) else null;
479 } else { 479 } else {
480 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 480 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
481 try ctx.recreateSwapchain(buf_w, buf_h); 481 try ctx.recreateSwapchain(buf_w, buf_h);
482 } 482 }
483 last_window_w = window.width; 483 last_window_w = window.width;
@@ -686,7 +686,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void {
686 if (is_bench) &submit_timing else null, 686 if (is_bench) &submit_timing else null,
687 ) catch |err| switch (err) { 687 ) catch |err| switch (err) {
688 error.OutOfDateKHR => { 688 error.OutOfDateKHR => {
689 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 689 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
690 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale)); 690 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale));
691 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale)); 691 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale));
692 try ctx.recreateSwapchain(buf_w, buf_h); 692 try ctx.recreateSwapchain(buf_w, buf_h);
@@ -727,7 +727,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void {
727 }; 727 };
728 } 728 }
729 729
730 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 730 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
731 } 731 }
732 732
733 fn gridSizeForWindow(window_w: u32, window_h: u32, cell_w: u32, cell_h: u32) GridSize { 733 fn gridSizeForWindow(window_w: u32, window_h: u32, cell_w: u32, cell_h: u32) GridSize {
@@ -2495,7 +2495,7 @@ fn runTextCoverageCompare(alloc: std.mem.Allocator) !void {
2495 const size_changed = window.width != last_window_w or window.height != last_window_h; 2495 const size_changed = window.width != last_window_w or window.height != last_window_h;
2496 2496
2497 if (scale_changed or size_changed) { 2497 if (scale_changed or size_changed) {
2498 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 2498 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
2499 2499
2500 if (scale_changed) { 2500 if (scale_changed) {
2501 geom = try rebuildFaceForScale( 2501 geom = try rebuildFaceForScale(
@@ -2530,7 +2530,7 @@ fn runTextCoverageCompare(alloc: std.mem.Allocator) !void {
2530 .{ 0.0, 0.0, 0.0, 1.0 }, 2530 .{ 0.0, 0.0, 0.0, 1.0 },
2531 ) catch |err| switch (err) { 2531 ) catch |err| switch (err) {
2532 error.OutOfDateKHR => { 2532 error.OutOfDateKHR => {
2533 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 2533 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
2534 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale)); 2534 const buf_w = window.width * @as(u32, @intCast(geom.buffer_scale));
2535 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale)); 2535 const buf_h = window.height * @as(u32, @intCast(geom.buffer_scale));
2536 try ctx.recreateSwapchain(buf_w, buf_h); 2536 try ctx.recreateSwapchain(buf_w, buf_h);
@@ -2545,7 +2545,7 @@ fn runTextCoverageCompare(alloc: std.mem.Allocator) !void {
2545 try frame_loop.commitRender(); 2545 try frame_loop.commitRender();
2546 } 2546 }
2547 2547
2548 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 2548 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
2549 } 2549 }
2550 2550
2551 fn runDrawSmokeTest(alloc: std.mem.Allocator) !void { 2551 fn runDrawSmokeTest(alloc: std.mem.Allocator) !void {
@@ -2631,7 +2631,7 @@ fn runDrawSmokeTest(alloc: std.mem.Allocator) !void {
2631 const baseline_coverage = renderer.coverageVariantParams(.baseline); 2631 const baseline_coverage = renderer.coverageVariantParams(.baseline);
2632 ctx.drawCells(1, .{ cell_w, cell_h }, .{ 0.0, 0.0, 0.0, 1.0 }, baseline_coverage, null) catch |err| switch (err) { 2632 ctx.drawCells(1, .{ cell_w, cell_h }, .{ 0.0, 0.0, 0.0, 1.0 }, baseline_coverage, null) catch |err| switch (err) {
2633 error.OutOfDateKHR => { 2633 error.OutOfDateKHR => {
2634 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 2634 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
2635 try ctx.recreateSwapchain(window.width, window.height); 2635 try ctx.recreateSwapchain(window.width, window.height);
2636 frame_loop.forceArm(); 2636 frame_loop.forceArm();
2637 continue; 2637 continue;
@@ -2641,7 +2641,7 @@ fn runDrawSmokeTest(alloc: std.mem.Allocator) !void {
2641 try frame_loop.commitRender(); 2641 try frame_loop.commitRender();
2642 } 2642 }
2643 2643
2644 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 2644 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
2645 std.debug.print("done\n", .{}); 2645 std.debug.print("done\n", .{});
2646 } 2646 }
2647 2647
@@ -3076,7 +3076,7 @@ fn runRenderSmokeTest(alloc: std.mem.Allocator) !void {
3076 const t: f32 = @as(f32, @floatFromInt(i)) / 60.0; 3076 const t: f32 = @as(f32, @floatFromInt(i)) / 60.0;
3077 try ctx.drawClear(.{ t, 0.5, 1.0 - t, 1.0 }); 3077 try ctx.drawClear(.{ t, 0.5, 1.0 - t, 1.0 });
3078 } 3078 }
3079 _ = try ctx.vkd.deviceWaitIdle(ctx.device); 3079 vk_sync.waitIdleForShutdown(ctx.vkd, ctx.device);
3080 std.debug.print("done\n", .{}); 3080 std.debug.print("done\n", .{});
3081 } 3081 }
3082 3082
src/renderer.zig
Old New
@@ -1134,7 +1134,7 @@ pub const Context = struct {
1134 1134
1135 pub fn deinit(self: *Context) void { 1135 pub fn deinit(self: *Context) void {
1136 // Wait for device to be idle before destroying anything 1136 // Wait for device to be idle before destroying anything
1137 _ = self.vkd.deviceWaitIdle(self.device) catch {}; 1137 vk_sync.waitIdleForShutdown(self.vkd, self.device);
1138 1138
1139 // Atlas + buffers (in reverse order of creation) 1139 // Atlas + buffers (in reverse order of creation)
1140 self.vkd.destroySampler(self.device, self.atlas_sampler, null); 1140 self.vkd.destroySampler(self.device, self.atlas_sampler, null);
@@ -1260,7 +1260,7 @@ pub const Context = struct {
1260 self.vkd.freeMemory(self.device, replacement.memory, null); 1260 self.vkd.freeMemory(self.device, replacement.memory, null);
1261 } 1261 }
1262 1262
1263 _ = try self.vkd.deviceWaitIdle(self.device); 1263 vk_sync.waitIdleForShutdown(self.vkd, self.device);
1264 self.vkd.destroyBuffer(self.device, self.instance_buffer, null); 1264 self.vkd.destroyBuffer(self.device, self.instance_buffer, null);
1265 self.vkd.freeMemory(self.device, self.instance_memory, null); 1265 self.vkd.freeMemory(self.device, self.instance_memory, null);
1266 self.instance_buffer = replacement.buffer; 1266 self.instance_buffer = replacement.buffer;
@@ -1464,7 +1464,7 @@ pub const Context = struct {
1464 .command_buffer_count = 1, 1464 .command_buffer_count = 1,
1465 .p_command_buffers = @ptrCast(&cb), 1465 .p_command_buffers = @ptrCast(&cb),
1466 }), .null_handle); 1466 }), .null_handle);
1467 try self.vkd.queueWaitIdle(self.graphics_queue); 1467 vk_sync.waitIdleForShutdown(self.vkd, self.device);
1468 } 1468 }
1469 1469
1470 /// Upload a horizontal band of the atlas (y_start..y_end) to the GPU. 1470 /// Upload a horizontal band of the atlas (y_start..y_end) to the GPU.