nu simplified; working swapchain, queue, and validators.
it compiles, but initialization is not done create debug messenger Use proxies wip swapchain wip swapchain - stub usage get device queue wip swapchain - scaffolded with segfault wip swapchain - fix segfault wip swapchain - working, but resize broken. semaphore issue with naive handling satisfy validation
This commit is contained in:
@@ -7,7 +7,10 @@ const builtin = @import("builtin");
|
||||
const vk = @import("vk");
|
||||
|
||||
const nu = @import("../nu.zig");
|
||||
const au = @import("Render/au.zig");
|
||||
// const au = @import("Render/au.zig");
|
||||
|
||||
const ctx = @import("Render/ctx.zig");
|
||||
const swap_chain = @import("Render/swap_chain.zig");
|
||||
|
||||
pub const Config = struct {
|
||||
app_name: [*:0]const u8 = "nu-au-app",
|
||||
@@ -24,7 +27,6 @@ pub const Config = struct {
|
||||
minor: u10 = 0,
|
||||
patch: u12 = 0,
|
||||
} = .{},
|
||||
frames_in_flight: u8 = 3,
|
||||
use_debug_messenger: bool = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => true,
|
||||
.ReleaseSmall, .ReleaseFast => false,
|
||||
@@ -34,84 +36,178 @@ const config = nu.config.render;
|
||||
|
||||
pub const depends = .{nu.Window};
|
||||
|
||||
var sc: au.SwapChain = undefined;
|
||||
var flights: au.Flights = undefined;
|
||||
const SwapChain = swap_chain.SwapChain(Flight);
|
||||
const Flight = struct {
|
||||
pool: vk.CommandPool = .null_handle,
|
||||
cmd: vk.CommandBuffer = .null_handle,
|
||||
|
||||
pub fn init() !Flight {
|
||||
const pool = try ctx.D.createCommandPool(
|
||||
&.{ .queue_family_index = ctx.family.* },
|
||||
null,
|
||||
);
|
||||
errdefer ctx.D.destroyCommandPool(pool, null);
|
||||
|
||||
var cmds: [1]vk.CommandBuffer = undefined;
|
||||
try ctx.D.allocateCommandBuffers(
|
||||
&vk.CommandBufferAllocateInfo{
|
||||
.command_buffer_count = 1,
|
||||
.command_pool = pool,
|
||||
.level = .primary,
|
||||
},
|
||||
&cmds,
|
||||
);
|
||||
errdefer ctx.D.freeCommandBuffers(pool, 1, &cmds);
|
||||
|
||||
return .{
|
||||
.pool = pool,
|
||||
.cmd = cmds[0],
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: Flight) void {
|
||||
const cmds: [1]vk.CommandBuffer = .{self.cmd};
|
||||
ctx.D.freeCommandBuffers(self.pool, 1, &cmds);
|
||||
ctx.D.destroyCommandPool(self.pool, null);
|
||||
}
|
||||
};
|
||||
|
||||
var _sc: SwapChain = undefined;
|
||||
var _flights: []Flight = undefined;
|
||||
|
||||
pub fn setup(alloc: std.mem.Allocator) !void {
|
||||
// todo pick apart au into helpers; not a sub-module filled with its own globals.
|
||||
try au.init(alloc);
|
||||
errdefer au.deinit();
|
||||
try ctx.init(alloc);
|
||||
errdefer ctx.deinit();
|
||||
|
||||
sc = try au.SwapChain.init(alloc);
|
||||
errdefer sc.deinit();
|
||||
_flights = try alloc.alloc(Flight, 3);
|
||||
errdefer alloc.free(_flights);
|
||||
errdefer for (_flights) |flight| flight.deinit();
|
||||
for (_flights) |*flight| flight.* = try Flight.init();
|
||||
|
||||
flights = try au.Flights.init(alloc, config.frames_in_flight);
|
||||
errdefer flights.deinit();
|
||||
_sc = try SwapChain.init(alloc, _flights);
|
||||
errdefer _sc.deinit();
|
||||
}
|
||||
|
||||
pub fn teardown() void {
|
||||
au.D.deviceWaitIdle() catch |err| std.debug.panic("Device wait failed: {!}", .{err});
|
||||
flights.deinit();
|
||||
sc.deinit();
|
||||
au.deinit();
|
||||
_sc.deinit();
|
||||
for (_flights) |flight| flight.deinit();
|
||||
ctx.deinit();
|
||||
}
|
||||
|
||||
pub fn render() !void {
|
||||
const flight: au.Flights.Flight = flights.next();
|
||||
try flight.wait();
|
||||
const target = try _sc.acquire();
|
||||
|
||||
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;
|
||||
try ctx.D.resetCommandPool(target.flight.pool, .{});
|
||||
var cmd = ctx.CommandBufferProxy.init(target.flight.cmd, ctx.dw);
|
||||
|
||||
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||
{
|
||||
cmd.pipelineBarrier(
|
||||
.{ .top_of_pipe_bit = true },
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
&.{
|
||||
vk.ImageMemoryBarrier{
|
||||
.src_access_mask = .{},
|
||||
.dst_access_mask = .{ .color_attachment_write_bit = true },
|
||||
.old_layout = .undefined,
|
||||
.new_layout = .color_attachment_optimal,
|
||||
.src_queue_family_index = 0, // values are the same; no transfer occurs
|
||||
.dst_queue_family_index = 0,
|
||||
.image = target.image,
|
||||
.subresource_range = .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.base_mip_level = 0,
|
||||
.level_count = 1,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
else => return err,
|
||||
};
|
||||
);
|
||||
|
||||
const render_area: vk.Rect2D = .{
|
||||
.offset = .{ .x = 0, .y = 0 },
|
||||
.extent = sc.cinfo.image_extent,
|
||||
};
|
||||
cmd.beginRendering(&vk.RenderingInfo{
|
||||
.render_area = render_area,
|
||||
.layer_count = 1,
|
||||
.view_mask = 0,
|
||||
.color_attachment_count = 1,
|
||||
.p_color_attachments = &.{
|
||||
vk.RenderingAttachmentInfo{
|
||||
.image_view = target.view,
|
||||
.image_layout = .color_attachment_optimal,
|
||||
.resolve_mode = .{},
|
||||
.resolve_image_view = .null_handle,
|
||||
.resolve_image_layout = .undefined,
|
||||
.load_op = .clear,
|
||||
.store_op = .store,
|
||||
.clear_value = .{ .color = .{ .float_32 = .{ 1, 0, 0, 1 } } },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
try au.D.resetCommandPool(flight.pool, .{});
|
||||
var cmd = au.CommandBufferProxy.init(flight.cmd, au.D.wrapper);
|
||||
cmd.endRendering();
|
||||
|
||||
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||
target.begin_rendering(cmd, render_area);
|
||||
cmd.pipelineBarrier(
|
||||
.{ .color_attachment_output_bit = true },
|
||||
.{ .bottom_of_pipe_bit = true },
|
||||
.{},
|
||||
0,
|
||||
null,
|
||||
0,
|
||||
null,
|
||||
1,
|
||||
&.{
|
||||
vk.ImageMemoryBarrier{
|
||||
.src_access_mask = .{ .color_attachment_write_bit = true },
|
||||
.dst_access_mask = .{},
|
||||
.old_layout = .color_attachment_optimal,
|
||||
.new_layout = .present_src_khr,
|
||||
.src_queue_family_index = 0, // values are the same; no transfer occurs.
|
||||
.dst_queue_family_index = 0,
|
||||
.image = target.image,
|
||||
.subresource_range = .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.base_mip_level = 0,
|
||||
.level_count = 1,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
try cmd.endCommandBuffer();
|
||||
|
||||
// todo manage frame in flight state for each hook; pass the current flight in as context.
|
||||
|
||||
nu.engine.invoke("present", .{cmd});
|
||||
|
||||
target.end_rendering(cmd);
|
||||
try cmd.endCommandBuffer();
|
||||
|
||||
try au.Q.submit(1, &.{
|
||||
try ctx.Q.submit(
|
||||
1,
|
||||
&.{
|
||||
vk.SubmitInfo{
|
||||
.wait_semaphore_count = 1,
|
||||
.p_wait_semaphores = &.{flight.acquire},
|
||||
// don't start writing to color attachment until the swapchain image has been acquired.
|
||||
.p_wait_semaphores = &.{
|
||||
target.acquired,
|
||||
},
|
||||
.p_wait_dst_stage_mask = &.{
|
||||
vk.PipelineStageFlags{ .color_attachment_output_bit = true },
|
||||
},
|
||||
.command_buffer_count = 1,
|
||||
.p_command_buffers = &.{cmd.handle},
|
||||
.p_command_buffers = &.{target.flight.cmd},
|
||||
.signal_semaphore_count = 1,
|
||||
.p_signal_semaphores = &.{flight.complete},
|
||||
.p_signal_semaphores = &.{target.complete},
|
||||
},
|
||||
}, flight.fence);
|
||||
},
|
||||
target.available, // target will become available again once these finish
|
||||
);
|
||||
|
||||
if (sc.present(&.{flight.complete}, target)) |_| {
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
error.OutOfDateKHR => {
|
||||
try flight.wait();
|
||||
sc.mark();
|
||||
continue;
|
||||
},
|
||||
else => return err,
|
||||
}
|
||||
}
|
||||
try _sc.present(target);
|
||||
}
|
||||
|
Reference in New Issue
Block a user