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; }