144 lines
4.1 KiB
Zig
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;
|
|
}
|