multiple frames in flight

This commit is contained in:
2024-06-27 21:47:49 -04:00
parent 350cbb34f0
commit 1801959c4e

View File

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