good but wrong teardown order; device wait idle
This commit is contained in:
@@ -29,7 +29,7 @@ pub fn main() !void {
|
|||||||
try nu.Render.init(alloc);
|
try nu.Render.init(alloc);
|
||||||
defer nu.Render.deinit();
|
defer nu.Render.deinit();
|
||||||
|
|
||||||
try nu.ImGui.init(alloc);
|
try nu.ImGui.init();
|
||||||
defer nu.ImGui.deinit();
|
defer nu.ImGui.deinit();
|
||||||
|
|
||||||
try App.init(alloc);
|
try App.init(alloc);
|
||||||
|
@@ -26,7 +26,11 @@ pub fn run(
|
|||||||
if (@typeInfo(@TypeOf(module.frame)).Fn.return_type) |R| {
|
if (@typeInfo(@TypeOf(module.frame)).Fn.return_type) |R| {
|
||||||
switch (@typeInfo(R)) {
|
switch (@typeInfo(R)) {
|
||||||
.ErrorUnion => try module.frame(),
|
.ErrorUnion => try module.frame(),
|
||||||
else => @compileError("frame must be void or !void."),
|
.Void => module.frame(),
|
||||||
|
else => {
|
||||||
|
@compileLog(module.frame, @typeInfo(R));
|
||||||
|
@compileError("frame must be void or !void.");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
module.frame();
|
module.frame();
|
||||||
|
@@ -2,11 +2,105 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const vk = @import("vk");
|
||||||
|
const nu = @import("../nu.zig");
|
||||||
|
const au = @import("Render/au.zig");
|
||||||
const Render = @import("Render.zig");
|
const Render = @import("Render.zig");
|
||||||
|
const Window = @import("Window.zig");
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) !void {
|
const im = @import("cimgui");
|
||||||
_ = alloc;
|
|
||||||
|
pub fn loader_wrapper(procname: [*c]const u8, _: ?*anyopaque) callconv(.C) vk.PfnVoidFunction {
|
||||||
|
return au.glfwGetInstanceProcAddress(au.I.handle, procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx: *im.c.ImGuiContext = undefined;
|
||||||
|
var descriptor_pool: vk.DescriptorPool = undefined;
|
||||||
|
|
||||||
|
pub fn init() !void {
|
||||||
|
ctx = im.c.igCreateContext(null) orelse {
|
||||||
|
return error.igCreateContextFailed;
|
||||||
|
};
|
||||||
|
errdefer im.c.igDestroyContext(ctx);
|
||||||
|
|
||||||
|
if (!im.c.ImGui_ImplVulkan_LoadFunctions(loader_wrapper, null)) {
|
||||||
|
return error.igVulkanLoadFunctionsFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!im.c.ImGui_ImplGlfw_InitForVulkan(@ptrCast(Window.handle), true)) {
|
||||||
|
return error.igGlfwInitFailed;
|
||||||
|
}
|
||||||
|
errdefer im.c.ImGui_ImplGlfw_Shutdown();
|
||||||
|
|
||||||
|
descriptor_pool = try au.D.createDescriptorPool(&vk.DescriptorPoolCreateInfo{
|
||||||
|
.flags = .{ .free_descriptor_set_bit = true },
|
||||||
|
.pool_size_count = 1,
|
||||||
|
.p_pool_sizes = &.{vk.DescriptorPoolSize{
|
||||||
|
.descriptor_count = 32,
|
||||||
|
.type = .combined_image_sampler,
|
||||||
|
}},
|
||||||
|
.max_sets = 32,
|
||||||
|
}, null);
|
||||||
|
errdefer au.D.destroyDescriptorPool(descriptor_pool, null);
|
||||||
|
|
||||||
|
if (im.c.ImGui_ImplVulkan_Init(@constCast(&im.c.ImGui_ImplVulkan_InitInfo{
|
||||||
|
.Instance = @ptrFromInt(@intFromEnum(au.I.handle)),
|
||||||
|
.PhysicalDevice = @ptrFromInt(@intFromEnum(au.device_config.pdev)),
|
||||||
|
.Device = @ptrFromInt(@intFromEnum(au.D.handle)),
|
||||||
|
.QueueFamily = au.device_config.family,
|
||||||
|
.Queue = @ptrFromInt(@intFromEnum(au.Q.handle)),
|
||||||
|
.DescriptorPool = @ptrFromInt(@intFromEnum(descriptor_pool)),
|
||||||
|
.RenderPass = null,
|
||||||
|
.MinImageCount = 2,
|
||||||
|
.ImageCount = @intCast(nu.options.render.frames_in_flight),
|
||||||
|
.PipelineRenderingCreateInfo = @bitCast(vk.PipelineRenderingCreateInfo{
|
||||||
|
.view_mask = 0,
|
||||||
|
.depth_attachment_format = .undefined,
|
||||||
|
.stencil_attachment_format = .undefined,
|
||||||
|
.color_attachment_count = 1,
|
||||||
|
.p_color_attachment_formats = &.{au.device_config.format.format},
|
||||||
|
}),
|
||||||
|
.MSAASamples = 0,
|
||||||
|
.PipelineCache = null,
|
||||||
|
.Subpass = 0,
|
||||||
|
.UseDynamicRendering = true,
|
||||||
|
.Allocator = null,
|
||||||
|
})) != true) {
|
||||||
|
return error.igVulkanInitFailed;
|
||||||
|
}
|
||||||
|
errdefer im.c.ImGui_ImplVulkan_Shutdown();
|
||||||
|
|
||||||
|
if (!im.c.ImGui_ImplVulkan_CreateFontsTexture()) {
|
||||||
|
return error.igVulkanFontTextureFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
try Render.add_present_callback(present);
|
||||||
|
errdefer Render.remove_present_callback(present);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frame() void {
|
||||||
|
im.c.ImGui_ImplGlfw_NewFrame();
|
||||||
|
im.c.ImGui_ImplVulkan_NewFrame();
|
||||||
|
im.c.igNewFrame();
|
||||||
|
|
||||||
|
im.c.igShowDemoWindow(null);
|
||||||
|
|
||||||
|
im.c.igEndFrame();
|
||||||
|
im.c.igRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
|
Render.remove_present_callback(present);
|
||||||
|
im.c.ImGui_ImplVulkan_Shutdown();
|
||||||
|
au.D.destroyDescriptorPool(descriptor_pool, null);
|
||||||
|
im.c.ImGui_ImplGlfw_Shutdown();
|
||||||
|
im.c.igDestroyContext(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn present(cmd: au.CommandBufferProxy) void {
|
||||||
|
im.c.ImGui_ImplVulkan_RenderDrawData(
|
||||||
|
im.c.igGetDrawData(),
|
||||||
|
@ptrFromInt(@intFromEnum(cmd.handle)),
|
||||||
|
null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@@ -30,11 +30,33 @@ pub const Options = struct {
|
|||||||
var sc: au.SwapChain = undefined;
|
var sc: au.SwapChain = undefined;
|
||||||
var flights: au.Flights = undefined;
|
var flights: au.Flights = undefined;
|
||||||
|
|
||||||
|
const PresentCallback = *const fn (au.CommandBufferProxy) void;
|
||||||
|
var present_callbacks: std.ArrayList(PresentCallback) = undefined;
|
||||||
|
|
||||||
|
pub fn add_present_callback(cb: PresentCallback) !void {
|
||||||
|
if (std.mem.indexOfScalar(PresentCallback, present_callbacks.items, cb)) |_| {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
try present_callbacks.append(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_present_callback(cb: PresentCallback) void {
|
||||||
|
if (std.mem.indexOfScalar(PresentCallback, present_callbacks.items, cb)) |idx| {
|
||||||
|
_ = present_callbacks.orderedRemove(idx);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) !void {
|
pub fn init(alloc: std.mem.Allocator) !void {
|
||||||
// todo pick apart au into helpers; not a sub-module filled with its own globals.
|
// 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();
|
||||||
|
|
||||||
|
present_callbacks = std.ArrayList(PresentCallback).init(alloc);
|
||||||
|
errdefer present_callbacks.deinit();
|
||||||
|
|
||||||
sc = try au.SwapChain.init(alloc);
|
sc = try au.SwapChain.init(alloc);
|
||||||
errdefer sc.deinit();
|
errdefer sc.deinit();
|
||||||
|
|
||||||
@@ -67,6 +89,9 @@ pub fn frame() !void {
|
|||||||
|
|
||||||
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try cmd.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
target.begin_rendering(cmd, render_area);
|
target.begin_rendering(cmd, render_area);
|
||||||
|
for (present_callbacks.items) |cb| {
|
||||||
|
cb(cmd);
|
||||||
|
}
|
||||||
target.end_rendering(cmd);
|
target.end_rendering(cmd);
|
||||||
try cmd.endCommandBuffer();
|
try cmd.endCommandBuffer();
|
||||||
|
|
||||||
@@ -98,6 +123,7 @@ pub fn frame() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
|
present_callbacks.deinit();
|
||||||
au.D.deviceWaitIdle() catch {};
|
au.D.deviceWaitIdle() catch {};
|
||||||
flights.deinit();
|
flights.deinit();
|
||||||
sc.deinit();
|
sc.deinit();
|
||||||
|
@@ -373,26 +373,26 @@ pub fn debug_callback(
|
|||||||
return vk.FALSE;
|
return vk.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn glfwVulkanSupported() c_int;
|
pub extern fn glfwVulkanSupported() c_int;
|
||||||
|
|
||||||
extern fn glfwGetInstanceProcAddress(
|
pub extern fn glfwGetInstanceProcAddress(
|
||||||
instance: vk.Instance,
|
instance: vk.Instance,
|
||||||
procname: [*:0]const u8,
|
procname: [*:0]const u8,
|
||||||
) vk.PfnVoidFunction;
|
) vk.PfnVoidFunction;
|
||||||
|
|
||||||
extern fn glfwGetPhysicalDevicePresentationSupport(
|
pub extern fn glfwGetPhysicalDevicePresentationSupport(
|
||||||
instance: vk.Instance,
|
instance: vk.Instance,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
queuefamily: u32,
|
queuefamily: u32,
|
||||||
) c_int;
|
) c_int;
|
||||||
|
|
||||||
extern fn glfwCreateWindowSurface(
|
pub extern fn glfwCreateWindowSurface(
|
||||||
instance: vk.Instance,
|
instance: vk.Instance,
|
||||||
window: *nu.Window.c.GLFWwindow,
|
window: *nu.Window.c.GLFWwindow,
|
||||||
allocation_callbacks: ?*const vk.AllocationCallbacks,
|
allocation_callbacks: ?*const vk.AllocationCallbacks,
|
||||||
surface: *vk.SurfaceKHR,
|
surface: *vk.SurfaceKHR,
|
||||||
) vk.Result;
|
) vk.Result;
|
||||||
|
|
||||||
extern fn glfwGetRequiredInstanceExtensions(
|
pub extern fn glfwGetRequiredInstanceExtensions(
|
||||||
count: *u32,
|
count: *u32,
|
||||||
) [*][*:0]const u8;
|
) [*][*:0]const u8;
|
||||||
|
Reference in New Issue
Block a user