From 7b80ef4dbf3c1fe4adc9593194d158c0c1e52a2a Mon Sep 17 00:00:00 2001 From: David Allemang Date: Thu, 27 Jun 2024 21:08:07 -0400 Subject: [PATCH] submit command --- src/au/SwapChain.zig | 14 ++++- src/main.zig | 118 ++++++++++++++++++++++++++++--------------- 2 files changed, 88 insertions(+), 44 deletions(-) diff --git a/src/au/SwapChain.zig b/src/au/SwapChain.zig index 7773ac1..22a02a9 100644 --- a/src/au/SwapChain.zig +++ b/src/au/SwapChain.zig @@ -6,7 +6,8 @@ const Self = @This(); alloc: std.mem.Allocator, cinfo: vk.SwapchainCreateInfoKHR, -handle: vk.SwapchainKHR, +handle: vk.SwapchainKHR = .null_handle, +images: std.ArrayListUnmanaged(vk.Image) = .{}, pub fn init(alloc: std.mem.Allocator) !Self { const caps = try au.I.getPhysicalDeviceSurfaceCapabilitiesKHR(au.device_config.pdev, au.W.surface); @@ -36,11 +37,11 @@ pub fn init(alloc: std.mem.Allocator) !Self { .clipped = vk.TRUE, .old_swapchain = .null_handle, }, - .handle = .null_handle, }; } pub fn deinit(self: *Self) void { + self.images.deinit(self.alloc); au.D.destroySwapchainKHR(self.handle, null); } @@ -62,7 +63,16 @@ pub fn rebuild(self: *Self) !bool { au.D.destroySwapchainKHR(self.cinfo.old_swapchain, null); self.cinfo.old_swapchain = self.handle; + var count: u32 = undefined; + _ = try au.D.getSwapchainImagesKHR(self.handle, &count, null); + try self.images.resize(self.alloc, count); + _ = try au.D.getSwapchainImagesKHR(self.handle, &count, self.images.items.ptr); + // todo repopulate images and synchronization return true; } + +pub fn get(self: Self, idx: u32) vk.Image { + return self.images.items[idx]; +} diff --git a/src/main.zig b/src/main.zig index 7cdfae4..314190d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -105,39 +105,67 @@ pub fn main() !void { const pool = try au.D.createCommandPool(&.{ .queue_family_index = au.device_config.family }, null); defer au.D.destroyCommandPool(pool, null); - const fence: vk.Fence = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); - defer au.D.destroyFence(fence, null); - const sem_ready: vk.Semaphore = try au.D.createSemaphore(&.{}, null); defer au.D.destroySemaphore(sem_ready, null); const sem_done: vk.Semaphore = try au.D.createSemaphore(&.{}, null); defer au.D.destroySemaphore(sem_done, null); - const cmdbufs: [1]vk.CommandBuffer = undefined; - try au.D.allocateCommandBuffers( - &.{ .command_pool = pool, .command_buffer_count = @intCast(cmdbufs.len), .level = .primary }, - cmdbufs.ptr, - ); - defer au.D.freeCommandBuffers(pool, @intCast(cmdbufs.len), cmdbufs.ptr); + const fence: vk.Fence = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); + defer au.D.destroyFence(fence, null); - { - const cmd = au.CommandBufferProxy.init(cmdbufs[0], au.D); - const clear = vk.ClearValue{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } }; - const viewport = vk.Viewport{ - .x = 0, - .y = 0, - .width = sc.cinfo.image_extent.width, - .height = sc.cinfo.image_extent.height, - .min_depth = 0, - .max_depth = 1, - }; - const scissor = vk.Rect2D{ .offset = .{ .x = 0, .y = 0 }, .extent = sc.cinfo.image_extent }; + while (!au.W.should_close()) { + // todo switch mode depending on if window is focused + const events = au.wait_events_timeout(0.10); + + for (events) |u| { + switch (u) { + .framebufferSize => sc.mark(), + .cursorPos, .windowPos, .windowSize, .windowRefresh => {}, + else => |e| std.debug.print("{any}\n", .{e}), + } + } + + _ = try sc.rebuild(); + + _ = try au.D.waitForFences(1, &.{fence}, vk.TRUE, std.math.maxInt(u64)); + try au.D.resetFences(1, &.{fence}); + try au.D.resetCommandPool(pool, .{}); + + const acq = try au.D.acquireNextImageKHR( + sc.handle, + std.math.maxInt(u64), + sem_ready, + .null_handle, + ); + const image = sc.get(acq.image_index); + + var cmd = au.CommandBufferProxy.init(.null_handle, au.D.wrapper); + try au.D.allocateCommandBuffers(&.{ + .command_pool = pool, + .level = .primary, + .command_buffer_count = 1, + }, @ptrCast(&cmd.handle)); + + try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } }); + + // const clear = vk.ClearValue{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } }; + // const viewport = vk.Viewport{ + // .x = 0, + // .y = 0, + // .width = sc.cinfo.image_extent, + // .height = sc.cinfo.image_extent.height, + // .min_depth = 0, + // .max_depth = 1, + // }; + // const scissor = vk.Rect2D{ + // .offset = .{ .x = 0, .y = 0 }, + // .extent = sc.cinfo.image_extent, + // }; - try cmd.beginCommandBuffer(&.{}); cmd.pipelineBarrier( .{ .top_of_pipe_bit = true }, - .{ .color_attachment_output_bit = true }, + .{ .bottom_of_pipe_bit = true }, .{}, 0, null, @@ -146,31 +174,38 @@ pub fn main() !void { 1, @ptrCast(&vk.ImageMemoryBarrier{ .src_access_mask = .{}, - .dst_access_mask = .{ .color_attachment_write_bit = true }, + .dst_access_mask = .{}, .old_layout = .undefined, - .new_layout = .color_attachment_optimal, + .new_layout = .present_src_khr, .src_queue_family_index = 0, .dst_queue_family_index = 0, - .image = .null_handle, // todo this needs to point to the swapchain image, so I can't get away from recording a command buffer for each one. + .image = image, + .subresource_range = .{ + .aspect_mask = .{ .color_bit = true }, + .base_mip_level = 0, + .level_count = 1, + .base_array_layer = 0, + .layer_count = 1, + }, }), ); - } + try cmd.endCommandBuffer(); - while (!au.W.should_close()) { - // todo switch mode depending on if window is focused - const events = au.wait_events_timeout(0.10); + try au.Q.submit( + 1, + @ptrCast(&vk.SubmitInfo{ + .wait_semaphore_count = 1, + .p_wait_semaphores = @ptrCast(&sem_ready), + .p_wait_dst_stage_mask = @ptrCast(&vk.PipelineStageFlags{ .color_attachment_output_bit = true }), + .command_buffer_count = 1, + .p_command_buffers = @ptrCast(&cmd.handle), + .signal_semaphore_count = 1, + .p_signal_semaphores = @ptrCast(&sem_done), + }), + fence, + ); - for (events) |u| switch (u) { - .framebufferSize => sc.mark(), - .cursorPos, .windowPos, .windowSize, .windowRefresh => {}, - else => |e| std.debug.print("{any}\n", .{e}), - }; - - _ = try sc.rebuild(); - - const acq = try au.D.acquireNextImageKHR(sc.handle, std.math.maxInt(u64), sem_ready, .null_handle); - - const pre = try au.Q.presentKHR(&vk.PresentInfoKHR{ + _ = try au.Q.presentKHR(&vk.PresentInfoKHR{ .wait_semaphore_count = 1, .p_wait_semaphores = &.{sem_done}, .swapchain_count = 1, @@ -178,7 +213,6 @@ pub fn main() !void { .p_image_indices = &.{acq.image_index}, .p_results = null, }); - std.debug.print("present result: {}\n", .{pre}); } try au.D.deviceWaitIdle();