Make sure the example does not segfault if it crashes during swapchain

recreation.
This commit is contained in:
Sebastian Emanuel Dawid
2025-05-13 11:56:03 +02:00
parent dfc5a3db4e
commit 783b70a12e

View File

@@ -46,7 +46,7 @@ pub const Swapchain = struct {
else else
.exclusive; .exclusive;
const handle = try gc.dev.createSwapchainKHR(&.{ const handle = gc.dev.createSwapchainKHR(&.{
.surface = gc.surface, .surface = gc.surface,
.min_image_count = image_count, .min_image_count = image_count,
.image_format = surface_format.format, .image_format = surface_format.format,
@@ -62,7 +62,9 @@ pub const Swapchain = struct {
.present_mode = present_mode, .present_mode = present_mode,
.clipped = vk.TRUE, .clipped = vk.TRUE,
.old_swapchain = old_handle, .old_swapchain = old_handle,
}, null); }, null) catch {
return error.SwapchainCreationFailed;
};
errdefer gc.dev.destroySwapchainKHR(handle, null); errdefer gc.dev.destroySwapchainKHR(handle, null);
if (old_handle != .null_handle) { if (old_handle != .null_handle) {
@@ -113,6 +115,8 @@ pub const Swapchain = struct {
} }
pub fn deinit(self: Swapchain) void { 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.deinitExceptSwapchain();
self.gc.dev.destroySwapchainKHR(self.handle, null); self.gc.dev.destroySwapchainKHR(self.handle, null);
} }
@@ -122,7 +126,18 @@ pub const Swapchain = struct {
const allocator = self.allocator; const allocator = self.allocator;
const old_handle = self.handle; const old_handle = self.handle;
self.deinitExceptSwapchain(); 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 { pub fn currentImage(self: Swapchain) vk.Image {