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