From 836daad0ae3690fdc01e435d16acf1e7142b40f3 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Mon, 1 Apr 2024 22:12:22 -0400 Subject: [PATCH] create swapchain, fetch images, image views --- src/main.zig | 121 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 16 deletions(-) diff --git a/src/main.zig b/src/main.zig index fd12717..9427a78 100644 --- a/src/main.zig +++ b/src/main.zig @@ -246,12 +246,12 @@ fn create_device( fn find_surface_format( pdev: vk.PhysicalDevice, + vki: gfx.InstanceDispatch, surface: vk.SurfaceKHR, preferred: vk.SurfaceFormatKHR, - vki: gfx.InstanceDispatch, ) !vk.SurfaceFormatKHR { var formats_buf: [64]vk.SurfaceFormatKHR = undefined; - var formats_count: u32 = 64; + var formats_count: u32 = @intCast(formats_buf.len); _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats_buf); const formats = formats_buf[0..formats_count]; @@ -264,6 +264,57 @@ fn find_surface_format( return formats[0]; } +fn find_present_mode( + pdev: vk.PhysicalDevice, + vki: gfx.InstanceDispatch, + surface: vk.SurfaceKHR, + preferred: vk.PresentModeKHR, +) !vk.PresentModeKHR { + var modes_buf: [8]vk.PresentModeKHR = undefined; + var modes_count: u32 = @intCast(modes_buf.len); + _ = try vki.getPhysicalDeviceSurfacePresentModesKHR(pdev, surface, &modes_count, &modes_buf); + const modes = modes_buf[0..modes_count]; + + for (modes) |mode| { + if (std.meta.eql(mode, preferred)) { + return mode; + } + } + + return .mailbox_khr; +} + +fn find_swap_extent( + pdev: vk.PhysicalDevice, + vki: gfx.InstanceDispatch, + surface: vk.SurfaceKHR, + window: *c.GLFWwindow, +) !vk.Extent2D { + const caps = try vki.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface); + var extent = caps.current_extent; + + if (extent.width == std.math.maxInt(u32)) { + c.glfwGetFramebufferSize(window, @ptrCast(&extent.width), @ptrCast(&extent.height)); + extent.width = std.math.clamp(extent.width, caps.min_image_extent.width, caps.max_image_extent.width); + extent.height = std.math.clamp(extent.height, caps.min_image_extent.height, caps.max_image_extent.height); + } + + return extent; +} + +fn find_swap_image_count( + pdev: vk.PhysicalDevice, + vki: gfx.InstanceDispatch, + surface: vk.SurfaceKHR, +) !u32 { + const caps = try vki.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface); + var count = caps.min_image_count + 1; + if (caps.max_image_count > 0) { + count = @min(count, caps.max_image_count); + } + return count; +} + pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); @@ -302,22 +353,60 @@ pub fn main() !void { .format = .b8g8r8a8_srgb, .color_space = .srgb_nonlinear_khr, }; - const format = try find_surface_format(pdev, surface, preferred_format, vki); + const format = try find_surface_format(pdev, vki, surface, preferred_format); + extent = try find_swap_extent(pdev, vki, surface, window); - _ = &extent; + const present_mode = try find_present_mode(pdev, vki, surface, .mailbox_khr); - // const gc: Context = .{ - // .vki = vki, - // .vkd = vkd, - // .pdev = pdev, - // .dev = dev, - // .surface = surface, - // .queue = queue, - // .family = family, - // }; - // - // var swapchain = try Swapchain.init(&gc, ally, extent, format); - // defer swapchain.deinit(); + const swap_image_count = try find_swap_image_count(pdev, vki, surface); + + var swapchain: vk.SwapchainKHR = .null_handle; + defer vkd.destroySwapchainKHR(dev, swapchain, null); + + var image_buf: [8]vk.Image = undefined; + @memset(&image_buf, .null_handle); + var images: []vk.Image = &.{}; + var image_views_buf: [8]vk.ImageView = undefined; + @memset(&image_views_buf, .null_handle); + var image_views: []vk.ImageView = &.{}; + + swapchain = try vkd.createSwapchainKHR(dev, &.{ + .surface = surface, + .min_image_count = swap_image_count, + .image_format = format.format, + .image_color_space = format.color_space, + .image_extent = extent, + .image_array_layers = 1, + .image_usage = .{ .color_attachment_bit = true }, + .image_sharing_mode = .exclusive, + .pre_transform = .{ .identity_bit_khr = true }, + .composite_alpha = .{ .opaque_bit_khr = true }, + .present_mode = present_mode, + .clipped = vk.TRUE, + .old_swapchain = swapchain, + }, null); + + var image_count: u32 = @intCast(image_buf.len); + _ = try vkd.getSwapchainImagesKHR(dev, swapchain, &image_count, &image_buf); + images = image_buf[0..image_count]; + image_views = image_views_buf[0..image_count]; + defer for (image_views) |view| vkd.destroyImageView(dev, view, null); + + for (images, image_views) |image, *view| { + view.* = try vkd.createImageView(dev, &.{ + .image = image, + .view_type = .@"2d", + .format = format.format, + .components = .{ .r = .identity, .g = .identity, .b = .identity, .a = .identity }, + .subresource_range = .{ + .aspect_mask = .{ .color_bit = true }, + .base_mip_level = 0, + .level_count = 1, + .base_array_layer = 0, + .layer_count = 1, + }, + }, null); + } const pipeline_layout = try vkd.createPipelineLayout(dev, &.{ .flags = .{},