Files
zig-experiments/src/gfx/Instance.zig
2024-06-05 16:04:50 -04:00

144 lines
4.1 KiB
Zig

const std = @import("std");
const builtin = @import("builtin");
const vk = @import("vk");
const c = @import("../c.zig");
const gfx = @import("../gfx.zig");
const Self = @This();
const app_info: vk.ApplicationInfo = .{
.p_application_name = "zig-glfw-vulkan",
.application_version = vk.makeApiVersion(0, 0, 0, 0),
.p_engine_name = "zig-glfw-vulkan",
.engine_version = vk.makeApiVersion(0, 0, 0, 0),
.api_version = vk.API_VERSION_1_3,
};
ref: vk.Instance,
vki: Wrapper,
base: *const gfx.Base,
messenger: if (gfx.use_debug_messenger) vk.DebugUtilsMessengerEXT else void,
pub fn init(
base: *const gfx.Base,
) !Self {
var exts: std.BoundedArray([*:0]const u8, 32) = .{};
var layers: std.BoundedArray([*:0]const u8, 32) = .{};
if (gfx.use_debug_messenger) {
try exts.appendSlice(&.{
vk.extensions.ext_debug_utils.name,
});
try layers.appendSlice(&.{
"VK_LAYER_KHRONOS_validation",
});
}
var glfw_exts_count: u32 = 0;
const glfw_exts: [*]const [*:0]const u8 =
@ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_exts_count));
try exts.appendSlice(glfw_exts[0..glfw_exts_count]);
const mci: vk.DebugUtilsMessengerCreateInfoEXT = .{
.message_severity = .{
.error_bit_ext = true,
.info_bit_ext = true,
.verbose_bit_ext = true,
.warning_bit_ext = true,
},
.message_type = .{
.device_address_binding_bit_ext = true,
.general_bit_ext = false,
.performance_bit_ext = true,
.validation_bit_ext = true,
},
.pfn_user_callback = &debug_callback,
.p_user_data = null,
};
const ref = try base.vkb.createInstance(&.{
.p_application_info = &app_info,
.enabled_extension_count = @intCast(exts.len),
.pp_enabled_extension_names = &exts.buffer,
.enabled_layer_count = @intCast(layers.len),
.pp_enabled_layer_names = &layers.buffer,
.p_next = if (gfx.use_debug_messenger) &mci else null,
}, null);
const vki = try Wrapper.load(ref, base.vkb.dispatch.vkGetInstanceProcAddr);
errdefer vki.destroyInstance(ref, null);
const messenger = if (gfx.use_debug_messenger)
try vki.createDebugUtilsMessengerEXT(ref, &mci, null)
else
void{};
errdefer if (gfx.use_debug_messenger)
vki.destroyDebugUtilsMessengerEXT(ref, messenger, null);
return .{
.ref = ref,
.vki = vki,
.base = base,
.messenger = messenger,
};
}
pub fn deinit(self: Self) void {
if (gfx.use_debug_messenger)
self.vki.destroyDebugUtilsMessengerEXT(self.ref, self.messenger, null);
self.vki.destroyInstance(self.ref, null);
}
pub const Wrapper = vk.InstanceWrapper(gfx.apis);
pub fn debug_callback(
msg_severity: vk.DebugUtilsMessageSeverityFlagsEXT,
msg_type: vk.DebugUtilsMessageTypeFlagsEXT,
p_data: ?*const vk.DebugUtilsMessengerCallbackDataEXT,
_: ?*anyopaque,
) callconv(vk.vulkan_call_conv) vk.Bool32 {
// ripped from std.log.defaultLog
const data = p_data orelse return vk.FALSE;
const message = data.p_message orelse return vk.FALSE;
const severity_prefix = if (msg_severity.verbose_bit_ext)
"verbose:"
else if (msg_severity.info_bit_ext)
"info:"
else if (msg_severity.warning_bit_ext)
"warning:"
else if (msg_severity.error_bit_ext)
"error:"
else
"?:";
const type_prefix = if (msg_type.general_bit_ext)
""
else if (msg_type.validation_bit_ext)
"validation:"
else if (msg_type.performance_bit_ext)
"performance:"
else if (msg_type.device_address_binding_bit_ext)
"device_address_binding:"
else
"?:";
const stderr = std.io.getStdErr().writer();
var bw = std.io.bufferedWriter(stderr);
const writer = bw.writer();
std.debug.lockStdErr();
defer std.debug.unlockStdErr();
nosuspend {
writer.print("vk-{s}{s} {s}\n", .{ severity_prefix, type_prefix, message }) catch return vk.FALSE;
bw.flush() catch return vk.FALSE;
}
return vk.FALSE;
}