fix crash in immediate present mode

This commit is contained in:
David Allemang
2024-07-08 17:21:09 -04:00
committed by David Allemang
parent 2f678f273f
commit 1cb340e154
2 changed files with 63 additions and 64 deletions

View File

@@ -57,10 +57,6 @@ fn record_render(
cmd.drawIndexed(indices.len, 1, 0, 0, 0);
}
pub fn loader_wrapper(procname: [*c]const u8, _: ?*anyopaque) callconv(.C) vk.PfnVoidFunction {
return c.glfwGetInstanceProcAddress(au.I.handle, procname);
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.detectLeaks();
@@ -69,14 +65,6 @@ pub fn main() !void {
try au.init(alloc);
defer au.deinit();
{
const props = au.I.getPhysicalDeviceProperties(au.device_config.pdev);
std.debug.print(
"Selected Device:\n {s}\n mode: {}\n",
.{ props.device_name, au.device_config.mode },
);
}
var sc = try au.SwapChain.init(alloc);
defer sc.deinit();
@@ -105,7 +93,6 @@ pub fn main() !void {
defer uber.deinit();
const vkalloc = au.VkAllocator.init();
std.debug.print("heaps: {any}\ntypes: {any}\n", .{ vkalloc.heaps(), vkalloc.types() });
const vertex_buffer = try au.D.createBuffer(&vk.BufferCreateInfo{
.size = @sizeOf(@TypeOf(vertices)),
@@ -215,64 +202,78 @@ pub fn main() !void {
}
}
_ = 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 tgt = try sc.acquire(flight.acquire, .null_handle);
// TODO need to check the standard to see what happens to a fence or semaphore on OutOfDateKHR error.
// acquire, submit, and present.
var cmd = au.CommandBufferProxy.init(flight.cmd, au.D.wrapper);
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
while (true) {
_ = try sc.rebuild();
const render_area: vk.Rect2D = .{
.offset = .{ .x = 0, .y = 0 },
.extent = sc.cinfo.image_extent,
};
const target = sc.acquire(flight.acquire, .null_handle) catch |err| switch (err) {
error.OutOfDateKHR => {
sc.mark();
continue;
},
else => return err,
};
tgt.begin_rendering(cmd, render_area);
record_render(
cmd,
uber,
render_area,
vertex_buffer,
index_buffer,
descriptorSet,
);
ui.Draw(cmd);
tgt.end_rendering(cmd);
try au.D.resetCommandPool(flight.pool, .{});
var cmd = au.CommandBufferProxy.init(flight.cmd, au.D.wrapper);
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
for (vertex_data) |*v| {
for (v.pos[0..2]) |*f| {
f.* += (rand.float(f32) - 0.5) * 0.001;
const render_area: vk.Rect2D = .{
.offset = .{ .x = 0, .y = 0 },
.extent = sc.cinfo.image_extent,
};
target.begin_rendering(cmd, render_area);
record_render(
cmd,
uber,
render_area,
vertex_buffer,
index_buffer,
descriptorSet,
);
ui.Draw(cmd);
target.end_rendering(cmd);
for (vertex_data) |*v| {
for (v.pos[0..2]) |*f| {
f.* += (rand.float(f32) - 0.5) * 0.001;
}
}
try cmd.endCommandBuffer();
try au.Q.submit(
1,
&.{
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(&cmd.handle),
.signal_semaphore_count = 1,
.p_signal_semaphores = @ptrCast(&flight.complete),
},
},
flight.fence,
);
if (sc.present(&.{flight.complete}, target)) |_| {
break;
} else |err| switch (err) {
error.OutOfDateKHR => {
sc.mark();
continue;
},
else => return err,
}
}
try cmd.endCommandBuffer();
au.Q.submit(
1,
&.{
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(&cmd.handle),
.signal_semaphore_count = 1,
.p_signal_semaphores = @ptrCast(&flight.complete),
},
},
flight.fence,
) catch {
std.debug.print("Failed to submit.\nWaiting for idle...", .{});
au.D.deviceWaitIdle() catch
std.debug.print("deviceWaitIdle failed\n", .{});
@panic("Submission failed");
};
_ = try sc.present(&.{flight.complete}, tgt); // todo suboptimal?
}
try au.D.deviceWaitIdle();