From cd9d77c24a6e246e605666921f0f42ea448a45e8 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Fri, 28 Jun 2024 21:31:30 -0400 Subject: [PATCH] extract Frame.record_render --- src/main.zig | 223 +++++++++++++++++++++++++++++---------------------- 1 file changed, 127 insertions(+), 96 deletions(-) diff --git a/src/main.zig b/src/main.zig index e4f899a..a45bc89 100644 --- a/src/main.zig +++ b/src/main.zig @@ -50,81 +50,31 @@ const vertices = [_]Vertex{ const indices = [_]Index{ 4, 5, 6, 6, 5, 7 }; -pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - defer _ = gpa.detectLeaks(); - const alloc = gpa.allocator(); +const Flight = struct { + acquire: vk.Semaphore = .null_handle, + complete: vk.Semaphore = .null_handle, + fence: vk.Fence = .null_handle, + pool: vk.CommandPool = .null_handle, + frame: Frame, +}; - try au.init(alloc); - defer au.deinit(); - - var sc = try au.SwapChain.init(alloc); - defer sc.deinit(); - - const flight = try alloc.alloc( - struct { - acquire: vk.Semaphore = .null_handle, - complete: vk.Semaphore = .null_handle, - fence: vk.Fence = .null_handle, - pool: vk.CommandPool = .null_handle, - }, - 3, // FRAMES IN FLIGHT - ); - defer alloc.free(flight); - - for (flight) |*frame| { - frame.acquire = try au.D.createSemaphore(&.{}, null); - frame.complete = try au.D.createSemaphore(&.{}, null); - frame.fence = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); - frame.pool = try au.D.createCommandPool(&.{ .queue_family_index = au.device_config.family }, null); +const Frame = struct { + pub fn init() !Frame { + return .{}; } - defer for (flight) |frame| { - au.D.destroySemaphore(frame.acquire, null); - au.D.destroySemaphore(frame.complete, null); - au.D.destroyFence(frame.fence, null); - au.D.destroyCommandPool(frame.pool, null); - }; - var flight_idx: usize = 0; - while (!au.W.should_close()) : (flight_idx = (flight_idx + 1) % flight.len) { - const frame = flight[flight_idx]; + pub fn deinit(self: Frame) void { + _ = self; + } - const events = if (au.W.focused()) - au.wait_events_timeout(0.1) - else - au.wait_events_timeout(0.5); - - 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, &.{frame.fence}, vk.TRUE, std.math.maxInt(u64)); - try au.D.resetFences(1, &.{frame.fence}); - try au.D.resetCommandPool(frame.pool, .{}); - - const acq = try au.D.acquireNextImageKHR( - sc.handle, - std.math.maxInt(u64), - frame.acquire, - .null_handle, - ); - const image = sc.getImage(acq.image_index); - const view = sc.getView(acq.image_index); - - var cmd = au.CommandBufferProxy.init(.null_handle, au.D.wrapper); - try au.D.allocateCommandBuffers(&.{ - .command_pool = frame.pool, - .level = .primary, - .command_buffer_count = 1, - }, @ptrCast(&cmd.handle)); - - try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } }); + pub fn record_render( + self: Frame, + cmd: au.CommandBufferProxy, + image: vk.Image, + view: vk.ImageView, + scissor: vk.Rect2D, + ) !void { + _ = self; cmd.pipelineBarrier( .{ .top_of_pipe_bit = true }, @@ -153,18 +103,6 @@ pub fn main() !void { }), ); - const viewport = vk.Viewport{ - .x = 0, - .y = 0, - .width = @floatFromInt(sc.cinfo.image_extent.width), - .height = @floatFromInt(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, - }; const info = vk.RenderingInfoKHR{ .render_area = scissor, .layer_count = 1, @@ -182,8 +120,16 @@ pub fn main() !void { }}, }; - cmd.setViewport(0, 1, &.{viewport}); + cmd.setViewport(0, 1, &.{.{ + .x = @floatFromInt(scissor.offset.x), + .y = @floatFromInt(scissor.offset.y), + .width = @floatFromInt(scissor.extent.width), + .height = @floatFromInt(scissor.extent.height), + .min_depth = 0, + .max_depth = 1, + }}); cmd.setScissor(0, 1, &.{scissor}); + cmd.beginRendering(&info); // todo @@ -221,25 +167,110 @@ pub fn main() !void { }, }), ); - try cmd.endCommandBuffer(); + } +}; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.detectLeaks(); + const alloc = gpa.allocator(); + + try au.init(alloc); + defer au.deinit(); + + var sc = try au.SwapChain.init(alloc); + defer sc.deinit(); + + const flights = try alloc.alloc(Flight, 3); // FRAMES IN FLIGHT + defer alloc.free(flights); + + for (flights) |*flight| { + flight.acquire = try au.D.createSemaphore(&.{}, null); + flight.complete = try au.D.createSemaphore(&.{}, null); + flight.fence = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); + flight.pool = try au.D.createCommandPool(&.{ .queue_family_index = au.device_config.family }, null); + flight.frame = try Frame.init(); + } + defer for (flights) |flight| { + au.D.destroySemaphore(flight.acquire, null); + au.D.destroySemaphore(flight.complete, null); + au.D.destroyFence(flight.fence, null); + au.D.destroyCommandPool(flight.pool, null); + flight.frame.deinit(); + }; + + var flight_idx: usize = 0; + while (!au.W.should_close()) : (flight_idx = (flight_idx + 1) % flights.len) { + const flight = flights[flight_idx]; + + const events = if (au.W.focused()) + au.wait_events_timeout(0.1) + else + au.wait_events_timeout(0.5); + + 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, &.{flight.fence}, vk.TRUE, std.math.maxInt(u64)); + try au.D.resetFences(1, &.{flight.fence}); + try au.D.resetCommandPool(flight.pool, .{}); + + const acq = try au.D.acquireNextImageKHR( + sc.handle, + std.math.maxInt(u64), + flight.acquire, + .null_handle, + ); + const image = sc.getImage(acq.image_index); + const view = sc.getView(acq.image_index); + + var render_cmd = au.CommandBufferProxy.init(.null_handle, au.D.wrapper); + try au.D.allocateCommandBuffers( + &.{ + .command_pool = flight.pool, + .level = .primary, + .command_buffer_count = 1, + }, + @ptrCast(&render_cmd.handle), + ); + + try render_cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } }); + + try flight.frame.record_render( + render_cmd, + image, + view, + vk.Rect2D{ .offset = .{ .x = 0, .y = 0 }, .extent = sc.cinfo.image_extent }, + ); + + try render_cmd.endCommandBuffer(); try au.Q.submit( 1, - @ptrCast(&vk.SubmitInfo{ - .wait_semaphore_count = 1, - .p_wait_semaphores = @ptrCast(&frame.acquire), - .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(&frame.complete), - }), - frame.fence, + &.{ + vk.SubmitInfo{ + .wait_semaphore_count = 1, + .p_wait_semaphores = @ptrCast(&flight.acquire), + .p_wait_dst_stage_mask = @ptrCast(&vk.PipelineStageFlags{ .color_attachment_output_bit = true }), + .command_buffer_count = 1, + .p_command_buffers = @ptrCast(&render_cmd.handle), + .signal_semaphore_count = 1, + .p_signal_semaphores = @ptrCast(&flight.complete), + }, + }, + flight.fence, ); _ = try au.Q.presentKHR(&vk.PresentInfoKHR{ .wait_semaphore_count = 1, - .p_wait_semaphores = &.{frame.complete}, + .p_wait_semaphores = &.{flight.complete}, .swapchain_count = 1, .p_swapchains = &.{sc.handle}, .p_image_indices = &.{acq.image_index},