multiple frames in flight
This commit is contained in:
315
src/main.zig
315
src/main.zig
@@ -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];
|
||||||
}
|
// }
|
||||||
|
Reference in New Issue
Block a user