render with swapchain

This commit is contained in:
David Allemang
2024-07-09 15:42:08 -04:00
parent 4f9a154176
commit 59912a4bc6
4 changed files with 86 additions and 8 deletions

View File

@@ -22,8 +22,16 @@ pub fn run(
_ = events; _ = events;
inline for (modules) |module| { inline for (modules) |module| {
if (@hasDecl(module, "frame")) if (@hasDecl(module, "frame")) {
module.frame(); if (@typeInfo(@TypeOf(module.frame)).Fn.return_type) |R| {
switch (@typeInfo(R)) {
.ErrorUnion => try module.frame(),
else => @compileError("frame must be void or !void."),
}
} else {
module.frame();
}
}
} }
// todo fixed timestep // todo fixed timestep

View File

@@ -6,6 +6,7 @@ const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const vk = @import("vk"); const vk = @import("vk");
const nu = @import("../nu.zig");
const au = @import("Render/au.zig"); const au = @import("Render/au.zig");
pub const Options = struct { pub const Options = struct {
@@ -26,15 +27,79 @@ pub const Options = struct {
frames_in_flight: u8 = 3, frames_in_flight: u8 = 3,
}; };
pub fn init(alloc: std.mem.Allocator) !void { var sc: au.SwapChain = undefined;
// todo make ctx not globals var flights: au.Flights = undefined;
pub fn init(alloc: std.mem.Allocator) !void {
// todo pick apart au into helpers; not a sub-module filled with its own globals.
try au.init(alloc); try au.init(alloc);
errdefer au.deinit(); errdefer au.deinit();
sc = try au.SwapChain.init(alloc);
errdefer sc.deinit();
flights = try au.Flights.init(alloc, nu.options.render.frames_in_flight);
errdefer flights.deinit();
} }
pub fn frame() void {} pub fn frame() !void {
const flight: au.Flights.Flight = flights.next();
try flight.wait();
while (true) {
_ = try sc.rebuild();
const target = sc.acquire(flight.acquire, .null_handle) catch |err| switch (err) {
error.OutOfDateKHR => {
sc.mark();
continue;
},
else => return err,
};
const render_area: vk.Rect2D = .{
.offset = .{ .x = 0, .y = 0 },
.extent = sc.cinfo.image_extent,
};
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 } });
target.begin_rendering(cmd, render_area);
target.end_rendering(cmd);
try cmd.endCommandBuffer();
try au.Q.submit(1, &.{
vk.SubmitInfo{
.wait_semaphore_count = 1,
.p_wait_semaphores = &.{flight.acquire},
.p_wait_dst_stage_mask = &.{
vk.PipelineStageFlags{ .color_attachment_output_bit = true },
},
.command_buffer_count = 1,
.p_command_buffers = &.{cmd.handle},
.signal_semaphore_count = 1,
.p_signal_semaphores = &.{flight.complete},
},
}, flight.fence);
if (sc.present(&.{flight.complete}, target)) |_| {
return;
} else |err| switch (err) {
error.OutOfDateKHR => {
try flight.wait();
sc.mark();
continue;
},
else => return err,
}
}
}
pub fn deinit() void { pub fn deinit() void {
au.D.deviceWaitIdle() catch {};
flights.deinit();
sc.deinit();
au.deinit(); au.deinit();
} }

View File

@@ -4,12 +4,17 @@ const au = @import("../au.zig");
const Self = @This(); const Self = @This();
const Flight = struct { pub const Flight = struct {
acquire: vk.Semaphore = .null_handle, acquire: vk.Semaphore = .null_handle,
complete: vk.Semaphore = .null_handle, complete: vk.Semaphore = .null_handle,
fence: vk.Fence = .null_handle, fence: vk.Fence = .null_handle,
pool: vk.CommandPool = .null_handle, pool: vk.CommandPool = .null_handle,
cmd: vk.CommandBuffer = .null_handle, cmd: vk.CommandBuffer = .null_handle,
pub fn wait(self: Flight) !void {
_ = try au.D.waitForFences(1, &.{self.fence}, vk.TRUE, std.math.maxInt(u64));
try au.D.resetFences(1, &.{self.fence});
}
}; };
alloc: std.mem.Allocator, alloc: std.mem.Allocator,

View File

@@ -11,7 +11,7 @@ images: std.ArrayListUnmanaged(vk.Image) = .{},
views: std.ArrayListUnmanaged(vk.ImageView) = .{}, views: std.ArrayListUnmanaged(vk.ImageView) = .{},
pub fn init(alloc: std.mem.Allocator) !Self { pub fn init(alloc: std.mem.Allocator) !Self {
const caps = try au.I.getPhysicalDeviceSurfaceCapabilitiesKHR(au.device_config.pdev, au.W.surface); const caps = try au.I.getPhysicalDeviceSurfaceCapabilitiesKHR(au.device_config.pdev, au.S.*);
var min_image_count = @max(3, caps.min_image_count + 1); // todo magic numbers var min_image_count = @max(3, caps.min_image_count + 1); // todo magic numbers
if (caps.max_image_count > 0) { if (caps.max_image_count > 0) {
@@ -24,7 +24,7 @@ pub fn init(alloc: std.mem.Allocator) !Self {
return .{ return .{
.alloc = alloc, .alloc = alloc,
.cinfo = .{ .cinfo = .{
.surface = au.W.surface, .surface = au.S.*,
.min_image_count = min_image_count, .min_image_count = min_image_count,
.image_format = format.format, .image_format = format.format,
.image_color_space = format.color_space, .image_color_space = format.color_space,