From 783b70a12e47aaf286092a6fbea2eeff75b9b5cb Mon Sep 17 00:00:00 2001 From: Sebastian Emanuel Dawid Date: Tue, 13 May 2025 11:56:03 +0200 Subject: [PATCH] Make sure the example does not segfault if it crashes during swapchain recreation. --- examples/swapchain.zig | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/swapchain.zig b/examples/swapchain.zig index db81de0..c4707aa 100644 --- a/examples/swapchain.zig +++ b/examples/swapchain.zig @@ -46,7 +46,7 @@ pub const Swapchain = struct { else .exclusive; - const handle = try gc.dev.createSwapchainKHR(&.{ + const handle = gc.dev.createSwapchainKHR(&.{ .surface = gc.surface, .min_image_count = image_count, .image_format = surface_format.format, @@ -62,7 +62,9 @@ pub const Swapchain = struct { .present_mode = present_mode, .clipped = vk.TRUE, .old_swapchain = old_handle, - }, null); + }, null) catch { + return error.SwapchainCreationFailed; + }; errdefer gc.dev.destroySwapchainKHR(handle, null); if (old_handle != .null_handle) { @@ -113,6 +115,8 @@ pub const Swapchain = struct { } pub fn deinit(self: Swapchain) void { + // if we have no swapchain none of these should exist and we can just return + if (self.handle == .null_handle) return; self.deinitExceptSwapchain(); self.gc.dev.destroySwapchainKHR(self.handle, null); } @@ -122,7 +126,18 @@ pub const Swapchain = struct { const allocator = self.allocator; const old_handle = self.handle; self.deinitExceptSwapchain(); - self.* = try initRecycle(gc, allocator, new_extent, old_handle); + // set current handle to NULL_HANDLE to signal that the current swapchain does no longer need to be + // de-initialized if we fail to recreate it. + self.handle = .null_handle; + self.* = initRecycle(gc, allocator, new_extent, old_handle) catch |err| switch (err) { + error.SwapchainCreationFailed => { + // we failed while recreating so our current handle still exists, + // but we won't destroy it in the deferred deinit of this object. + gc.dev.destroySwapchainKHR(old_handle, null); + return err; + }, + else => return err, + }; } pub fn currentImage(self: Swapchain) vk.Image {