From 1b3302cc9956f6d1d49c063c1fbd9c6a8d4d4d07 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Mon, 1 Apr 2024 20:47:29 -0400 Subject: [PATCH] incremental - dropping swapchain --- src/main.zig | 44 ++++++++++++++++++++++++++----------- src/swapchain.zig | 55 ++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/main.zig b/src/main.zig index 3addfe1..6b0f869 100644 --- a/src/main.zig +++ b/src/main.zig @@ -246,6 +246,26 @@ fn create_device( return error.NoSuitableDevice; } +fn find_surface_format( + pdev: vk.PhysicalDevice, + surface: vk.SurfaceKHR, + preferred: vk.SurfaceFormatKHR, + vki: gfx.InstanceDispatch, +) !vk.SurfaceFormatKHR { + var formats_buf: [64]vk.SurfaceFormatKHR = undefined; + var formats_count: u32 = 64; + _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats_buf); + const formats = formats_buf[0..formats_count]; + + for (formats) |format| { + if (std.meta.eql(format, preferred)) { + return format; + } + } + + return formats[0]; +} + pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); @@ -278,6 +298,12 @@ pub fn main() !void { try create_device(ally, instance, surface, vki); defer vkd.destroyDevice(dev, null); + const preferred_format: vk.SurfaceFormatKHR = .{ + .format = .b8g8r8a8_srgb, + .color_space = .srgb_nonlinear_khr, + }; + const format = try find_surface_format(pdev, surface, preferred_format, vki); + const queue = vkd.getDeviceQueue(dev, family, 0); const gc: Context = .{ @@ -290,7 +316,7 @@ pub fn main() !void { .family = family, }; - var swapchain = try Swapchain.init(&gc, ally, extent); + var swapchain = try Swapchain.init(&gc, ally, extent, format); defer swapchain.deinit(); const pipeline_layout = try gc.vkd.createPipelineLayout(gc.dev, &.{ @@ -302,7 +328,7 @@ pub fn main() !void { }, null); defer gc.vkd.destroyPipelineLayout(gc.dev, pipeline_layout, null); - const pipeline = try createPipeline(&gc, pipeline_layout, swapchain); + const pipeline = try createPipeline(&gc, pipeline_layout, format); defer gc.vkd.destroyPipeline(gc.dev, pipeline, null); const pool = try gc.vkd.createCommandPool(gc.dev, &.{ @@ -348,7 +374,6 @@ pub fn main() !void { defer destroyCommandBuffers(&gc, pool, ally, cmdbufs); while (c.glfwWindowShouldClose(window) == c.GLFW_FALSE) { - std.log.debug("new frame", .{ }); var w: c_int = undefined; var h: c_int = undefined; c.glfwGetFramebufferSize(window, &w, &h); @@ -365,19 +390,14 @@ pub fn main() !void { error.OutOfDateKHR => Swapchain.PresentState.suboptimal, else => |narrow| return narrow, }; - - std.log.debug("state: {}", .{state}); if (state == .suboptimal or extent.width != @as(u32, @intCast(w)) or extent.height != @as(u32, @intCast(h))) { extent.width = @intCast(w); extent.height = @intCast(h); - std.log.debug("about to recreate", .{ }); - try swapchain.recreate(extent); + try swapchain.recreate(extent, format); - std.log.debug("about to destroy command buffers", .{ }); destroyCommandBuffers(&gc, pool, ally, cmdbufs); - - std.log.debug("about to create command buffers", .{ }); + cmdbufs = try createCommandBuffers( &gc, pool, @@ -607,7 +627,7 @@ fn destroyCommandBuffers(gc: *const Context, pool: vk.CommandPool, allocator: Al allocator.free(cmdbufs); } -fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, swapchain: Swapchain) !vk.Pipeline { +fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, format: vk.SurfaceFormatKHR) !vk.Pipeline { const vert = try gc.vkd.createShaderModule(gc.dev, &.{ .code_size = shaders.triangle_vert.len, .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)), @@ -701,7 +721,7 @@ fn createPipeline(gc: *const Context, layout: vk.PipelineLayout, swapchain: Swap const prci = vk.PipelineRenderingCreateInfoKHR{ .color_attachment_count = 1, - .p_color_attachment_formats = @ptrCast(&swapchain.surface_format.format), + .p_color_attachment_formats = @ptrCast(&format), .depth_attachment_format = .undefined, .stencil_attachment_format = .undefined, .view_mask = 0, diff --git a/src/swapchain.zig b/src/swapchain.zig index e250fde..b01d7ff 100644 --- a/src/swapchain.zig +++ b/src/swapchain.zig @@ -52,7 +52,6 @@ pub const Swapchain = struct { gc: *const Context, allocator: Allocator, - surface_format: vk.SurfaceFormatKHR, present_mode: vk.PresentModeKHR, extent: vk.Extent2D, handle: vk.SwapchainKHR, @@ -61,18 +60,28 @@ pub const Swapchain = struct { image_index: u32, next_image_acquired: vk.Semaphore, - pub fn init(gc: *const Context, allocator: Allocator, extent: vk.Extent2D) !Swapchain { - return try initRecycle(gc, allocator, extent, .null_handle); + pub fn init( + gc: *const Context, + allocator: Allocator, + extent: vk.Extent2D, + format: vk.SurfaceFormatKHR, + ) !Swapchain { + return try initRecycle(gc, allocator, extent, format, .null_handle); } - pub fn initRecycle(gc: *const Context, allocator: Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain { + pub fn initRecycle( + gc: *const Context, + allocator: Allocator, + extent: vk.Extent2D, + format: vk.SurfaceFormatKHR, + old_handle: vk.SwapchainKHR, + ) !Swapchain { const caps = try gc.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface); const actual_extent = findActualExtent(caps, extent); if (actual_extent.width == 0 or actual_extent.height == 0) { return error.InvalidSurfaceDimensions; } - const surface_format = try findSurfaceFormat(gc, allocator); const present_mode = try findPresentMode(gc, allocator); var image_count = caps.min_image_count + 1; @@ -83,8 +92,8 @@ pub const Swapchain = struct { const handle = try gc.vkd.createSwapchainKHR(gc.dev, &.{ .surface = gc.surface, .min_image_count = image_count, - .image_format = surface_format.format, - .image_color_space = surface_format.color_space, + .image_format = format.format, + .image_color_space = format.color_space, .image_extent = actual_extent, .image_array_layers = 1, .image_usage = .{ .color_attachment_bit = true, .transfer_dst_bit = true }, @@ -102,7 +111,7 @@ pub const Swapchain = struct { gc.vkd.destroySwapchainKHR(gc.dev, old_handle, null); } - const swap_images = try initSwapchainImages(gc, handle, surface_format.format, allocator); + const swap_images = try initSwapchainImages(gc, handle, format.format, allocator); errdefer { for (swap_images) |si| si.deinit(gc); allocator.free(swap_images); @@ -129,7 +138,6 @@ pub const Swapchain = struct { return Swapchain{ .gc = gc, .allocator = allocator, - .surface_format = surface_format, .present_mode = present_mode, .extent = actual_extent, .handle = handle, @@ -154,12 +162,16 @@ pub const Swapchain = struct { self.gc.vkd.destroySwapchainKHR(self.gc.dev, self.handle, null); } - pub fn recreate(self: *Swapchain, new_extent: vk.Extent2D) !void { + pub fn recreate( + self: *Swapchain, + new_extent: vk.Extent2D, + format: vk.SurfaceFormatKHR, + ) !void { const gc = self.gc; const allocator = self.allocator; const old_handle = self.handle; self.deinitExceptSwapchain(); - self.* = try initRecycle(gc, allocator, new_extent, old_handle); + self.* = try initRecycle(gc, allocator, new_extent, format, old_handle); } pub fn currentImage(self: Swapchain) vk.Image { @@ -318,27 +330,6 @@ fn initSwapchainImages(gc: *const Context, swapchain: vk.SwapchainKHR, format: v return swap_images; } -fn findSurfaceFormat(gc: *const Context, allocator: Allocator) !vk.SurfaceFormatKHR { - const preferred = vk.SurfaceFormatKHR{ - .format = .b8g8r8a8_srgb, - .color_space = .srgb_nonlinear_khr, - }; - - var count: u32 = undefined; - _ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, null); - const surface_formats = try allocator.alloc(vk.SurfaceFormatKHR, count); - defer allocator.free(surface_formats); - _ = try gc.vki.getPhysicalDeviceSurfaceFormatsKHR(gc.pdev, gc.surface, &count, surface_formats.ptr); - - for (surface_formats) |sfmt| { - if (std.meta.eql(sfmt, preferred)) { - return preferred; - } - } - - return surface_formats[0]; // There must always be at least one supported surface format -} - fn findPresentMode(gc: *const Context, allocator: Allocator) !vk.PresentModeKHR { var count: u32 = undefined; _ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);