restructure

This commit is contained in:
2025-02-26 17:24:06 -05:00
parent a55775e21d
commit 8c82294c91
3 changed files with 158 additions and 58 deletions

View File

@@ -8,8 +8,6 @@ const glfw = @cImport({
@cInclude("GLFW/glfw3.h");
});
const Self = @This();
const apis: []const vk.ApiInfo = &(.{
vk.features.version_1_0,
vk.features.version_1_1,
@@ -31,13 +29,17 @@ const Instance = vk.InstanceProxy(apis);
const Device = vk.DeviceProxy(apis);
const Queue = vk.QueueProxy(apis);
const Core = @This();
alloc: std.mem.Allocator,
win: *glfw.GLFWwindow,
bw: *const Base,
b: *Base,
i: Instance,
d: Device,
q: Queue,
dm: switch (builtin.mode) {
window: *glfw.GLFWwindow,
pdev: vk.PhysicalDevice,
surface: vk.SurfaceKHR,
msg: switch (builtin.mode) {
.Debug, .ReleaseSafe => vk.DebugUtilsMessengerEXT,
else => void,
},
@@ -49,7 +51,10 @@ pub fn init(
height: u32 = 720,
title: []const u8 = "Hello World",
},
) !Self {
) !Core {
var self: Core = undefined;
self.alloc = alloc;
var arena = std.heap.ArenaAllocator.init(alloc);
defer arena.deinit();
const ialloc = arena.allocator();
@@ -64,7 +69,7 @@ pub fn init(
glfw.glfwWindowHint(glfw.GLFW_CLIENT_API, glfw.GLFW_NO_API);
glfw.glfwWindowHintString(glfw.GLFW_X11_CLASS_NAME, "floating_window");
glfw.glfwWindowHintString(glfw.GLFW_X11_INSTANCE_NAME, "floating_window");
const win = glfw.glfwCreateWindow(
self.window = glfw.glfwCreateWindow(
@intCast(options.width),
@intCast(options.height),
titlez,
@@ -73,9 +78,10 @@ pub fn init(
) orelse
return error.GLFWWindowFailed;
var bw = try alloc.create(vk.BaseWrapper(apis));
const bw = try alloc.create(vk.BaseWrapper(apis));
errdefer alloc.destroy(bw);
bw.* = try vk.BaseWrapper(apis).load(glfwGetInstanceProcAddress);
self.b = bw;
var iexts = std.ArrayList([*:0]const u8).init(ialloc);
var ilyrs = std.ArrayList([*:0]const u8).init(ialloc);
@@ -139,28 +145,37 @@ pub fn init(
else => {},
}
const instance = try bw.createInstance(
&ici,
null,
);
var iw = try alloc.create(vk.InstanceWrapper(apis));
self.i.handle = try self.b.createInstance(&ici, null);
const iw = try alloc.create(vk.InstanceWrapper(apis));
errdefer alloc.destroy(iw);
iw.* = try vk.InstanceWrapper(apis).load(instance, bw.dispatch.vkGetInstanceProcAddr);
errdefer iw.destroyInstance(instance, null);
iw.* = try vk.InstanceWrapper(apis).load(self.i.handle, bw.dispatch.vkGetInstanceProcAddr);
self.i.wrapper = iw;
errdefer self.i.destroyInstance(null);
const dm = switch (builtin.mode) {
.Debug, .ReleaseSafe => try iw.createDebugUtilsMessengerEXT(instance, &dmci, null),
self.msg = switch (builtin.mode) {
.Debug, .ReleaseSafe => try self.i.createDebugUtilsMessengerEXT(&dmci, null),
else => {},
};
errdefer switch (builtin.mode) {
.Debug, .ReleaseSafe => iw.destroyDebugUtilsMessengerEXT(instance, dm, null),
.Debug, .ReleaseSafe => self.i.destroyDebugUtilsMessengerEXT(self.msg, null),
else => {},
};
// Device selection. Just use the first one.
const pdevs: []vk.PhysicalDevice = try iw.enumeratePhysicalDevicesAlloc(instance, ialloc);
const pdevs: []vk.PhysicalDevice = try self.i.enumeratePhysicalDevicesAlloc(ialloc);
std.debug.assert(pdevs.len >= 1);
const pdev = pdevs[0];
self.pdev = pdevs[0];
switch (glfwCreateWindowSurface(
self.i.handle,
self.window,
null,
&self.surface,
)) {
.success => {},
else => return error.GLFWWindowSurfaceFailed,
}
errdefer self.i.destroySurfaceKHR(self.surface, null);
// Queue selection. Just use the first one.
const qci: []const vk.DeviceQueueCreateInfo = &.{
@@ -182,7 +197,7 @@ pub fn init(
vk.extensions.khr_timeline_semaphore.name,
});
const device = try iw.createDevice(pdev, &.{
self.d.handle = try self.i.createDevice(self.pdev, &.{
.enabled_extension_count = @intCast(dexts.items.len),
.pp_enabled_extension_names = dexts.items.ptr,
.enabled_layer_count = @intCast(dlyrs.items.len),
@@ -193,36 +208,33 @@ pub fn init(
.dynamic_rendering = vk.TRUE,
},
}, null);
var dw = try alloc.create(vk.DeviceWrapper(apis));
errdefer alloc.destroy(dw);
dw.* = try vk.DeviceWrapper(apis).load(device, iw.dispatch.vkGetDeviceProcAddr);
errdefer dw.destroyDevice(device, null);
const dw = try alloc.create(vk.DeviceWrapper(apis));
dw.* = try vk.DeviceWrapper(apis).load(self.d.handle, iw.dispatch.vkGetDeviceProcAddr);
self.d.wrapper = dw;
errdefer self.d.destroyDevice(null);
const queue = dw.getDeviceQueue(device, 0, 0);
self.q.handle = self.d.getDeviceQueue(0, 0);
self.q.wrapper = dw;
return Self{
.alloc = alloc,
.win = win,
.bw = bw,
.i = .{ .handle = instance, .wrapper = iw },
.d = .{ .handle = device, .wrapper = dw },
.q = .{ .handle = queue, .wrapper = dw },
.dm = dm,
};
return self;
}
pub fn deinit(self: Self) void {
pub fn deinit(self: Core) void {
self.d.destroyDevice(null);
self.alloc.destroy(self.d.wrapper);
self.i.destroySurfaceKHR(self.surface, null);
switch (builtin.mode) {
.Debug, .ReleaseSafe => self.i.destroyDebugUtilsMessengerEXT(self.dm, null),
.Debug, .ReleaseSafe => self.i.destroyDebugUtilsMessengerEXT(self.msg, null),
else => {},
}
self.i.destroyInstance(null);
self.alloc.destroy(self.d.wrapper);
self.alloc.destroy(self.i.wrapper);
self.alloc.destroy(self.bw);
self.alloc.destroy(self.b);
glfw.glfwTerminate();
}
@@ -231,19 +243,6 @@ extern fn glfwGetInstanceProcAddress(
procname: [*:0]const u8,
) vk.PfnVoidFunction;
extern fn glfwGetPhysicalDevicePresentationSupport(
instance: vk.Instance,
pdev: vk.PhysicalDevice,
queuefamily: u32,
) c_int;
extern fn glfwCreateWindowSurface(
instance: vk.Instance,
window: *glfw.GLFWwindow,
allocation_callbacks: ?*const vk.AllocationCallbacks,
surface: *vk.SurfaceKHR,
) vk.Result;
extern fn glfwGetRequiredInstanceExtensions(
count: *u32,
) [*][*:0]const u8;
@@ -294,3 +293,16 @@ fn debug_callback(
return vk.FALSE;
}
extern fn glfwCreateWindowSurface(
instance: vk.Instance,
window: *glfw.GLFWwindow,
allocation_callbacks: ?*const vk.AllocationCallbacks,
surface: *vk.SurfaceKHR,
) vk.Result;
extern fn glfwGetPhysicalDevicePresentationSupport(
instance: vk.Instance,
pdev: vk.PhysicalDevice,
queuefamily: u32,
) c_int;

View File

@@ -2,7 +2,7 @@ const std = @import("std");
const lib = @import("zig-shape-lib");
const builtin = @import("builtin");
const Core = @import("core.zig");
const Core = @import("Core.zig");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
@@ -15,11 +15,7 @@ pub fn main() !void {
std.log.debug("Created instance: {any}", .{core.i.handle});
std.log.debug("Created device: {any}", .{core.d.handle});
std.log.debug("Created queue: {any}", .{core.q.handle});
// var surface: vk.SurfaceKHR = undefined;
// if (glfwCreateWindowSurface(instance, window, null, &surface) != vk.Result.success) {
// return error.SurfaceCreateFailed;
// }
std.log.debug("Created surface: {any}", .{core.surface});
// var caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface);
// const format = search: {

92
src/swapchain.zig Normal file
View File

@@ -0,0 +1,92 @@
const std = @import("std");
const builtin = @import("builtin");
const Core = @import("Core.zig");
const vk = @import("vk");
const I = &Core.I;
const D = &Core.D;
const pdev = &Core.pdev;
const surface = &Core.surface;
pub fn SwapChain(Flight: type, N: u3) type {
return struct {
handle: vk.SwapchainKHR = .null_handle,
cinfo: vk.SwapchainCreateInfoKHR,
// todo populate and use this.
flights: std.MultiArrayList(struct{
fence: vk.Fence,
acquired: vk.Semaphore,
complete: vk.Semaphore,
}),
pub fn init(alloc: std.mem.Allocator) !SwapChain {
var arena = std.heap.ArenaAllocator.init(alloc);
defer arena.deinit();
const ialloc = arena.allocator();
const caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(
pdev,
surface,
);
const formats = try I.getPhysicalDeviceSurfaceFormatsAllocKHR(
pdev,
surface,
ialloc,
);
const format: vk.SurfaceFormatKHR = formats[0];
const mode: vk.PresentModeKHR = .fifo_khr;
return .{
.cinfo = vk.SwapchainCreateInfoKHR{
.surface = surface,
.min_image_count = std.math.clamp(
@min(3, caps.min_image_count + 1),
caps.min_image_count,
if (caps.max_image_count > 0) caps.max_image_count else 127,
),
.image_format = format.format,
.image_color_space = format.color_space,
.image_extent = undefined, // set in rebuild
.image_array_layers = 1,
.image_usage = .{ .color_attachment_bit = true },
.image_sharing_mode = .exclusive,
.pre_transform = .{ .identity_bit_khr = true },
.composite_alpha = .{ .opaque_bit_khr = true },
.present_mode = mode,
.clipped = vk.TRUE,
.old_swapchain = .null_handle,
},
};
}
fn build(self: *SwapChain) !void {
if (self.handle != .null_handle) return;
const caps = try I.getPhysicalDeviceSurfaceCapabilitiesKHR(
pdev,
surface,
);
self.cinfo.image_extent = caps.current_extent;
self.handle = try D.createSwapchainKHR(&self.cinfo, null);
D.destroySwapchainKHR(self.cinfo.old_swapchain, null);
self.cinfo.old_swapchain = self.handle;
}
pub fn acquire(self: *SwapChain) !void {
D.acquireNextImageKHR(self.handle, std.math.maxInt(u64), semaphore: Semaphore, fence: Fence)
}
pub fn invalidate(self: *SwapChain) void {
self.handle = .null_handle;
}
pub fn deinit(self: SwapChain) void {
D.destroySwapchainKHR(self.cinfo.old_swapchain, null);
}
};
}