diff --git a/src/main.zig b/src/main.zig index e080826..6800f6f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4,8 +4,6 @@ const c = @import("c.zig"); const shaders = @import("shaders"); const Allocator = std.mem.Allocator; -const gfx = @import("gfx.zig"); - const au = @import("au.zig"); const app_name = "vulkan-zig triangle example"; @@ -63,19 +61,46 @@ pub fn main() !void { var sc = try au.SwapChain.init(alloc); defer sc.deinit(); - const pool = try au.D.createCommandPool(&.{ .queue_family_index = au.device_config.family }, null); - defer au.D.destroyCommandPool(pool, null); + var flight = std.MultiArrayList(struct { + acquire: vk.Semaphore, + complete: vk.Semaphore, + fence: vk.Fence, + pool: vk.CommandPool, + }){}; + defer { + for (flight.items(.acquire)) |sem| { + au.D.destroySemaphore(sem, null); + } + for (flight.items(.complete)) |sem| { + au.D.destroySemaphore(sem, null); + } + for (flight.items(.fence)) |fnc| { + au.D.destroyFence(fnc, null); + } + for (flight.items(.pool)) |pool| { + au.D.destroyCommandPool(pool, null); + } + flight.deinit(alloc); + } - const sem_ready: vk.Semaphore = try au.D.createSemaphore(&.{}, null); - defer au.D.destroySemaphore(sem_ready, null); + try flight.resize(alloc, 3); // FRAMES IN FLIGHT + for (flight.items(.acquire)) |*sem| { + sem.* = try au.D.createSemaphore(&.{}, null); + } + for (flight.items(.complete)) |*sem| { + sem.* = try au.D.createSemaphore(&.{}, null); + } + for (flight.items(.fence)) |*fnc| { + fnc.* = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); + } + for (flight.items(.pool)) |*pool| { + pool.* = try au.D.createCommandPool(&.{ .queue_family_index = au.device_config.family }, null); + } - const sem_done: vk.Semaphore = try au.D.createSemaphore(&.{}, null); - defer au.D.destroySemaphore(sem_done, null); + var flight_idx: usize = 0; + while (!au.W.should_close()) : (flight_idx = (flight_idx + 1) % flight.len) { + const frame = flight.get(flight_idx); - const fence: vk.Fence = try au.D.createFence(&.{ .flags = .{ .signaled_bit = true } }, null); - defer au.D.destroyFence(fence, null); - - while (!au.W.should_close()) { // todo switch mode depending on if window is focused const events = au.wait_events_timeout(0.10); @@ -89,14 +114,14 @@ pub fn main() !void { _ = 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, .{}); + _ = 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), - sem_ready, + frame.acquire, .null_handle, ); const image = sc.getImage(acq.image_index); @@ -104,7 +129,7 @@ pub fn main() !void { var cmd = au.CommandBufferProxy.init(.null_handle, au.D.wrapper); try au.D.allocateCommandBuffers(&.{ - .command_pool = pool, + .command_pool = frame.pool, .level = .primary, .command_buffer_count = 1, }, @ptrCast(&cmd.handle)); @@ -212,24 +237,24 @@ pub fn main() !void { 1, @ptrCast(&vk.SubmitInfo{ .wait_semaphore_count = 1, - .p_wait_semaphores = @ptrCast(&sem_ready), + .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(&sem_done), + .p_signal_semaphores = @ptrCast(&frame.complete), }), - fence, + frame.fence, ); _ = try au.Q.presentKHR(&vk.PresentInfoKHR{ .wait_semaphore_count = 1, - .p_wait_semaphores = &.{sem_done}, + .p_wait_semaphores = &.{frame.complete}, .swapchain_count = 1, .p_swapchains = &.{sc.handle}, .p_image_indices = &.{acq.image_index}, .p_results = null, - }); + }); // todo suboptimal? } try au.D.deviceWaitIdle(); @@ -271,126 +296,126 @@ pub fn main() !void { // try gfx.uploadData(Index, dev.pdev, inst.vki, dev.dev, dev.vkd, dev.queue, dev.pool, index_buffer, &indices); } -fn createPipeline( - dev: vk.Device, - layout: vk.PipelineLayout, - format: vk.SurfaceFormatKHR, - vkd: gfx.Device.Wrapper, -) !vk.Pipeline { - const vert = try vkd.createShaderModule(dev, &.{ - .code_size = shaders.triangle_vert.len, - .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)), - }, null); - defer vkd.destroyShaderModule(dev, vert, null); - - const frag = try vkd.createShaderModule(dev, &.{ - .code_size = shaders.triangle_frag.len, - .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)), - }, null); - defer vkd.destroyShaderModule(dev, frag, null); - - const pssci = [_]vk.PipelineShaderStageCreateInfo{ - .{ - .stage = .{ .vertex_bit = true }, - .module = vert, - .p_name = "main", - }, - .{ - .stage = .{ .fragment_bit = true }, - .module = frag, - .p_name = "main", - }, - }; - - const color_blend_attachment_states = [_]vk.PipelineColorBlendAttachmentState{ - vk.PipelineColorBlendAttachmentState{ - .blend_enable = vk.FALSE, - .src_color_blend_factor = .one, - .dst_color_blend_factor = .zero, - .color_blend_op = .add, - .src_alpha_blend_factor = .one, - .dst_alpha_blend_factor = .zero, - .alpha_blend_op = .add, - .color_write_mask = .{ .r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true }, - }, - }; - - const dynamic_states = [_]vk.DynamicState{ - .viewport, - .scissor, - }; - - const create_infos = [_]vk.GraphicsPipelineCreateInfo{ - .{ - .flags = .{}, - .stage_count = @intCast(pssci.len), - .p_stages = &pssci, - .p_vertex_input_state = &vk.PipelineVertexInputStateCreateInfo{ - .vertex_binding_description_count = 1, - .p_vertex_binding_descriptions = @ptrCast(&Vertex.binding_description), - .vertex_attribute_description_count = Vertex.attribute_description.len, - .p_vertex_attribute_descriptions = &Vertex.attribute_description, - }, - .p_input_assembly_state = &vk.PipelineInputAssemblyStateCreateInfo{ - .topology = .triangle_list, - .primitive_restart_enable = vk.FALSE, - }, - .p_tessellation_state = null, - .p_viewport_state = &vk.PipelineViewportStateCreateInfo{ - .viewport_count = 1, - .p_viewports = undefined, // set in createCommandBuffers with cmdSetViewport - .scissor_count = 1, - .p_scissors = undefined, // set in createCommandBuffers with cmdSetScissor - }, - .p_rasterization_state = &vk.PipelineRasterizationStateCreateInfo{ - .depth_clamp_enable = vk.FALSE, - .rasterizer_discard_enable = vk.FALSE, - .polygon_mode = .fill, - .cull_mode = .{ .back_bit = true }, - .front_face = .counter_clockwise, - .depth_bias_enable = vk.FALSE, - .depth_bias_constant_factor = 0, - .depth_bias_clamp = 0, - .depth_bias_slope_factor = 0, - .line_width = 1, - }, - .p_multisample_state = &vk.PipelineMultisampleStateCreateInfo{ - .rasterization_samples = .{ .@"1_bit" = true }, - .sample_shading_enable = vk.FALSE, - .min_sample_shading = 1, - .alpha_to_coverage_enable = vk.FALSE, - .alpha_to_one_enable = vk.FALSE, - }, - .p_depth_stencil_state = null, - .p_color_blend_state = &vk.PipelineColorBlendStateCreateInfo{ - .logic_op_enable = vk.FALSE, - .logic_op = .copy, - .attachment_count = @intCast(color_blend_attachment_states.len), - .p_attachments = &color_blend_attachment_states, - .blend_constants = [_]f32{ 0, 0, 0, 0 }, - }, - .p_dynamic_state = &vk.PipelineDynamicStateCreateInfo{ - .flags = .{}, - .dynamic_state_count = @intCast(dynamic_states.len), - .p_dynamic_states = &dynamic_states, - }, - .layout = layout, - .render_pass = .null_handle, - .subpass = 0, - .base_pipeline_handle = .null_handle, - .base_pipeline_index = -1, - .p_next = &vk.PipelineRenderingCreateInfoKHR{ - .color_attachment_count = 1, - .p_color_attachment_formats = @ptrCast(&format), - .depth_attachment_format = .undefined, - .stencil_attachment_format = .undefined, - .view_mask = 0, - }, - }, - }; - - var pipelines: [create_infos.len]vk.Pipeline = undefined; - _ = try vkd.createGraphicsPipelines(dev, .null_handle, @intCast(create_infos.len), &create_infos, null, &pipelines); - std.debug.assert(pipelines.len == 1); - return pipelines[0]; -} +// fn createPipeline( +// dev: vk.Device, +// layout: vk.PipelineLayout, +// format: vk.SurfaceFormatKHR, +// vkd: gfx.Device.Wrapper, +// ) !vk.Pipeline { +// const vert = try vkd.createShaderModule(dev, &.{ +// .code_size = shaders.triangle_vert.len, +// .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_vert)), +// }, null); +// defer vkd.destroyShaderModule(dev, vert, null); +// +// const frag = try vkd.createShaderModule(dev, &.{ +// .code_size = shaders.triangle_frag.len, +// .p_code = @as([*]const u32, @ptrCast(&shaders.triangle_frag)), +// }, null); +// defer vkd.destroyShaderModule(dev, frag, null); +// +// const pssci = [_]vk.PipelineShaderStageCreateInfo{ +// .{ +// .stage = .{ .vertex_bit = true }, +// .module = vert, +// .p_name = "main", +// }, +// .{ +// .stage = .{ .fragment_bit = true }, +// .module = frag, +// .p_name = "main", +// }, +// }; +// +// const color_blend_attachment_states = [_]vk.PipelineColorBlendAttachmentState{ +// vk.PipelineColorBlendAttachmentState{ +// .blend_enable = vk.FALSE, +// .src_color_blend_factor = .one, +// .dst_color_blend_factor = .zero, +// .color_blend_op = .add, +// .src_alpha_blend_factor = .one, +// .dst_alpha_blend_factor = .zero, +// .alpha_blend_op = .add, +// .color_write_mask = .{ .r_bit = true, .g_bit = true, .b_bit = true, .a_bit = true }, +// }, +// }; +// +// const dynamic_states = [_]vk.DynamicState{ +// .viewport, +// .scissor, +// }; +// +// const create_infos = [_]vk.GraphicsPipelineCreateInfo{ +// .{ +// .flags = .{}, +// .stage_count = @intCast(pssci.len), +// .p_stages = &pssci, +// .p_vertex_input_state = &vk.PipelineVertexInputStateCreateInfo{ +// .vertex_binding_description_count = 1, +// .p_vertex_binding_descriptions = @ptrCast(&Vertex.binding_description), +// .vertex_attribute_description_count = Vertex.attribute_description.len, +// .p_vertex_attribute_descriptions = &Vertex.attribute_description, +// }, +// .p_input_assembly_state = &vk.PipelineInputAssemblyStateCreateInfo{ +// .topology = .triangle_list, +// .primitive_restart_enable = vk.FALSE, +// }, +// .p_tessellation_state = null, +// .p_viewport_state = &vk.PipelineViewportStateCreateInfo{ +// .viewport_count = 1, +// .p_viewports = undefined, // set in createCommandBuffers with cmdSetViewport +// .scissor_count = 1, +// .p_scissors = undefined, // set in createCommandBuffers with cmdSetScissor +// }, +// .p_rasterization_state = &vk.PipelineRasterizationStateCreateInfo{ +// .depth_clamp_enable = vk.FALSE, +// .rasterizer_discard_enable = vk.FALSE, +// .polygon_mode = .fill, +// .cull_mode = .{ .back_bit = true }, +// .front_face = .counter_clockwise, +// .depth_bias_enable = vk.FALSE, +// .depth_bias_constant_factor = 0, +// .depth_bias_clamp = 0, +// .depth_bias_slope_factor = 0, +// .line_width = 1, +// }, +// .p_multisample_state = &vk.PipelineMultisampleStateCreateInfo{ +// .rasterization_samples = .{ .@"1_bit" = true }, +// .sample_shading_enable = vk.FALSE, +// .min_sample_shading = 1, +// .alpha_to_coverage_enable = vk.FALSE, +// .alpha_to_one_enable = vk.FALSE, +// }, +// .p_depth_stencil_state = null, +// .p_color_blend_state = &vk.PipelineColorBlendStateCreateInfo{ +// .logic_op_enable = vk.FALSE, +// .logic_op = .copy, +// .attachment_count = @intCast(color_blend_attachment_states.len), +// .p_attachments = &color_blend_attachment_states, +// .blend_constants = [_]f32{ 0, 0, 0, 0 }, +// }, +// .p_dynamic_state = &vk.PipelineDynamicStateCreateInfo{ +// .flags = .{}, +// .dynamic_state_count = @intCast(dynamic_states.len), +// .p_dynamic_states = &dynamic_states, +// }, +// .layout = layout, +// .render_pass = .null_handle, +// .subpass = 0, +// .base_pipeline_handle = .null_handle, +// .base_pipeline_index = -1, +// .p_next = &vk.PipelineRenderingCreateInfoKHR{ +// .color_attachment_count = 1, +// .p_color_attachment_formats = @ptrCast(&format), +// .depth_attachment_format = .undefined, +// .stencil_attachment_format = .undefined, +// .view_mask = 0, +// }, +// }, +// }; +// +// var pipelines: [create_infos.len]vk.Pipeline = undefined; +// _ = try vkd.createGraphicsPipelines(dev, .null_handle, @intCast(create_infos.len), &create_infos, null, &pipelines); +// std.debug.assert(pipelines.len == 1); +// return pipelines[0]; +// }