hand-written interface wrapper
This commit is contained in:
44
build.zig
44
build.zig
@@ -7,38 +7,39 @@ pub fn build(b: *std.Build) void {
|
||||
const vk_dep = b.dependency("vk", .{});
|
||||
const volk_dep = b.dependency("volk", .{});
|
||||
|
||||
// const volk_c = b.addTranslateC(.{
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// .root_source_file = volk_dep.path("volk.c"),
|
||||
// .link_libc = true,
|
||||
// });
|
||||
// volk_c.addIncludePath(vk_dep.path("include"));
|
||||
|
||||
const vk = b.addModule("vulkan", .{
|
||||
const volk_h = b.addTranslateC(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/volk.zig"),
|
||||
.root_source_file = volk_dep.path("volk.h"),
|
||||
.link_libc = true,
|
||||
});
|
||||
vk.addIncludePath(vk_dep.path("include"));
|
||||
vk.addIncludePath(volk_dep.path("."));
|
||||
vk.addCSourceFile(.{ .file = volk_dep.path("volk.c"), .language = .c });
|
||||
|
||||
const mod = b.addModule("zig_vk_api_test", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
const volk = b.addModule("volk", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = volk_h.getOutput(),
|
||||
.link_libc = true,
|
||||
});
|
||||
volk.addIncludePath(vk_dep.path("include"));
|
||||
volk.addCSourceFile(.{ .file = volk_dep.path("volk.c"), .language = .c });
|
||||
|
||||
const vulkan = b.addModule("vulkan", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("vk/root.zig"),
|
||||
.imports = &.{
|
||||
.{ .name = "volk", .module = volk },
|
||||
},
|
||||
});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "zig_vk_api_test",
|
||||
.name = "main",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "zig_vk_api_test", .module = mod },
|
||||
.{ .name = "vk", .module = vk },
|
||||
.{ .name = "vk", .module = vulkan },
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -56,12 +57,6 @@ pub fn build(b: *std.Build) void {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const mod_tests = b.addTest(.{
|
||||
.root_module = mod,
|
||||
});
|
||||
|
||||
const run_mod_tests = b.addRunArtifact(mod_tests);
|
||||
|
||||
const exe_tests = b.addTest(.{
|
||||
.root_module = exe.root_module,
|
||||
});
|
||||
@@ -69,6 +64,5 @@ pub fn build(b: *std.Build) void {
|
||||
const run_exe_tests = b.addRunArtifact(exe_tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&run_mod_tests.step);
|
||||
test_step.dependOn(&run_exe_tests.step);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[tools]
|
||||
zig = "latest"
|
||||
zls = "latest"
|
||||
zig = "0.16.0"
|
||||
zls = "0.16.0"
|
||||
|
||||
178
src/main.zig
178
src/main.zig
@@ -1,67 +1,135 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const vk = @import("vk");
|
||||
|
||||
pub fn main() !void {
|
||||
if (vk.c.volkInitialize() != vk.c.VK_SUCCESS) @panic("Failed to initialize vk");
|
||||
defer vk.c.volkFinalize();
|
||||
// const log = std.log.scoped(.main);
|
||||
|
||||
const app_info = vk.c.VkApplicationInfo{
|
||||
.sType = vk.c.VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = null,
|
||||
.apiVersion = vk.c.VK_API_VERSION_1_4,
|
||||
.pApplicationName = "WIP",
|
||||
.applicationVersion = vk.c.VK_MAKE_VERSION(0, 0, 1),
|
||||
.pEngineName = "WIP",
|
||||
.engineVersion = vk.c.VK_MAKE_VERSION(0, 0, 1),
|
||||
};
|
||||
try vk.init();
|
||||
defer vk.deinit();
|
||||
|
||||
const ext_names: []const [*c]const u8 = &.{"VK_EXT_debug_utils"};
|
||||
const lyr_names: []const [*c]const u8 = &.{"VK_LAYER_KHRONOS_validation"};
|
||||
const ctx_ins: vk.InstanceContext = try .init(.{
|
||||
.api_version = .API_1_3,
|
||||
.log_message_types = .{
|
||||
.general = false,
|
||||
.performance = true,
|
||||
.validation = true,
|
||||
},
|
||||
});
|
||||
defer ctx_ins.deinit();
|
||||
const ins = ctx_ins.interface();
|
||||
|
||||
const ins_info = vk.c.VkInstanceCreateInfo{
|
||||
.sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = null,
|
||||
.flags = 0,
|
||||
.enabledExtensionCount = @intCast(ext_names.len),
|
||||
.ppEnabledExtensionNames = ext_names.ptr,
|
||||
.enabledLayerCount = @intCast(lyr_names.len),
|
||||
.ppEnabledLayerNames = lyr_names.ptr,
|
||||
.pApplicationInfo = &app_info,
|
||||
};
|
||||
const deb_info = vk.c.VkDebugUtilsMessengerCreateInfoEXT{
|
||||
.sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = null,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
var ins: vk.c.VkInstance = undefined;
|
||||
if (vk.c.vkCreateInstance.?(&ins_info, null, &ins) != vk.c.VK_SUCCESS) @panic("Failed to create VkInstance");
|
||||
vk.c.volkLoadInstanceOnly(ins);
|
||||
defer vk.c.vkDestroyInstance.?(ins, null);
|
||||
|
||||
var pdevs: [3]vk.c.VkPhysicalDevice = undefined;
|
||||
var pdev_count: u32 = 3;
|
||||
if (vk.c.vkEnumeratePhysicalDevices.?(
|
||||
ins,
|
||||
&pdev_count,
|
||||
&pdevs,
|
||||
) != vk.c.VK_SUCCESS) @panic("Failed to enumerate physical devices.");
|
||||
|
||||
// pub const PFN_vkEnumeratePhysicalDevices = ?*const fn (instance: VkInstance, pPhysicalDeviceCount: [*c]u32, pPhysicalDevices: [*c]VkPhysicalDevice) callconv(.c) VkResult;
|
||||
|
||||
// vk.c.vkEnumerateDeviceExtensionProperties();
|
||||
|
||||
// const info = vk.c.VkInstanceCreateInfo {
|
||||
// .sType = vk.c.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
// .pNext = null,
|
||||
// .
|
||||
// };
|
||||
|
||||
// vk.c.vkCreateInstance(pCreateInfo: [*c]const VkInstanceCreateInfo, pAllocator: [*c]const VkAllocationCallbacks, pInstance: [*c]VkInstance);
|
||||
var pdevs_buf: [8]vk.PhysicalDevice = undefined;
|
||||
for (try ins.enumerate_physical_devices(&pdevs_buf)) |pdev| {
|
||||
std.log.debug("{s}", .{ins.get_physical_device_properties(pdev).deviceName});
|
||||
}
|
||||
|
||||
// defer ctx_ins.deinit();
|
||||
// ctx_ins.deinit();
|
||||
|
||||
// const ins = ctx_ins.interface();
|
||||
|
||||
// const ext_names: []const [*c]const u8 = &.{"VK_EXT_debug_utils"};
|
||||
// const lyr_names: []const [*c]const u8 = &.{"VK_LAYER_KHRONOS_validation"};
|
||||
//
|
||||
// const deb_info = vk.VkDebugUtilsMessengerCreateInfoEXT{
|
||||
// .sType = vk.VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
// .pNext = null,
|
||||
// .flags = 0,
|
||||
// .messageSeverity =
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
|
||||
// .messageType =
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
|
||||
// // vk.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
// vk.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT,
|
||||
// .pfnUserCallback = &debug_messenger_callback,
|
||||
// .pUserData = null,
|
||||
// };
|
||||
// const ins_info = vk.VkInstanceCreateInfo{
|
||||
// .sType = vk.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
// .pNext = &deb_info,
|
||||
// .flags = 0,
|
||||
// .enabledExtensionCount = @intCast(ext_names.len),
|
||||
// .ppEnabledExtensionNames = ext_names.ptr,
|
||||
// .enabledLayerCount = @intCast(lyr_names.len),
|
||||
// .ppEnabledLayerNames = lyr_names.ptr,
|
||||
// .pApplicationInfo = &app_info,
|
||||
// };
|
||||
//
|
||||
// var ins: vk.VkInstance = undefined;
|
||||
// if (vk.vkCreateInstance.?(&ins_info, null, &ins) != vk.VK_SUCCESS) @panic("Failed to create VkInstance");
|
||||
// vk.volkLoadInstanceOnly(ins);
|
||||
// defer vk.vkDestroyInstance.?(ins, null);
|
||||
//
|
||||
// var deb: vk.VkDebugUtilsMessengerEXT = undefined;
|
||||
// if (vk.vkCreateDebugUtilsMessengerEXT.?(ins, &deb_info, null, &deb) != vk.VK_SUCCESS) @panic("Failed to create VkDebugUtilsMessengerEXT");
|
||||
// defer vk.vkDestroyDebugUtilsMessengerEXT.?(ins, deb, null);
|
||||
//
|
||||
// var pdevs: [8]vk.VkPhysicalDevice = undefined;
|
||||
// var pdev_count: u32 = 8;
|
||||
// if (vk.vkEnumeratePhysicalDevices.?(
|
||||
// ins,
|
||||
// &pdev_count,
|
||||
// &pdevs,
|
||||
// ) != vk.VK_SUCCESS) @panic("Failed to enumerate physical devices.");
|
||||
// const pdev = pdevs[0]; // assume the drivers will put the best device first
|
||||
// var props : vk.VkPhysicalDeviceProperties2 = .{ .sType = vk.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };
|
||||
// vk.vkGetPhysicalDeviceProperties2.?(pdev, &props);
|
||||
// log.info("Selected device {s} (API {d}.{d}.{d}, Driver {d})", .{
|
||||
// props.properties.deviceName,
|
||||
// vk.VK_API_VERSION_MAJOR(props.properties.apiVersion),
|
||||
// vk.VK_API_VERSION_MINOR(props.properties.apiVersion),
|
||||
// vk.VK_API_VERSION_PATCH(props.properties.apiVersion),
|
||||
// vk.VK_VERSION_MAJOR(props.properties.driverVersion),
|
||||
// });
|
||||
}
|
||||
|
||||
// fn debug_messenger_callback(
|
||||
// message_severity: vk.VkDebugUtilsMessageSeverityFlagBitsEXT,
|
||||
// message_types: vk.VkDebugUtilsMessageTypeFlagsEXT,
|
||||
// p_callback_data: [*c]const vk.VkDebugUtilsMessengerCallbackDataEXT,
|
||||
// _: ?*anyopaque,
|
||||
// ) callconv(.c) vk.VkBool32 {
|
||||
// var types_buf: [64]u8 = undefined;
|
||||
// var types_str : std.ArrayListUnmanaged(u8) = .initBuffer(&types_buf);
|
||||
//
|
||||
// if (message_types & vk.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT != 0) {
|
||||
// if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(" ");
|
||||
// types_str.appendSliceAssumeCapacity("validation");
|
||||
// }
|
||||
// if (message_types & vk.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT != 0) {
|
||||
// if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(" ");
|
||||
// types_str.appendSliceAssumeCapacity("performance");
|
||||
// }
|
||||
// if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(": ");
|
||||
//
|
||||
// const log = std.log.scoped(.vulkan);
|
||||
//
|
||||
// const fmt = "{s}{s}";
|
||||
// const arg = .{
|
||||
// types_str.items,
|
||||
// p_callback_data.*.pMessage,
|
||||
// };
|
||||
//
|
||||
// if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT != 0) {
|
||||
// log.err(fmt, arg);
|
||||
// if (builtin.mode == .Debug) @breakpoint();
|
||||
// } else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT != 0) {
|
||||
// log.warn(fmt, arg);
|
||||
// } else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT != 0) {
|
||||
// log.info(fmt, arg);
|
||||
// } else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT != 0) {
|
||||
// log.debug(fmt, arg);
|
||||
// } else {
|
||||
// log.debug(fmt, arg);
|
||||
// }
|
||||
//
|
||||
// return vk.VK_FALSE;
|
||||
// }
|
||||
|
||||
// pub fn main(init: std.process.Init) !void {
|
||||
// std.debug.print("{any}\n", .{vk});
|
||||
//
|
||||
|
||||
18
src/root.zig
18
src/root.zig
@@ -1,18 +0,0 @@
|
||||
//! By convention, root.zig is the root source file when making a package.
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
/// This is a documentation comment to explain the `printAnotherMessage` function below.
|
||||
///
|
||||
/// Accepting an `Io.Writer` instance is a handy way to write reusable code.
|
||||
pub fn printAnotherMessage(writer: *Io.Writer) Io.Writer.Error!void {
|
||||
try writer.print("Run `zig build test` to run the tests.\n", .{});
|
||||
}
|
||||
|
||||
pub fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
test "basic add functionality" {
|
||||
try std.testing.expect(add(3, 7) == 10);
|
||||
}
|
||||
25
src/volk.zig
25
src/volk.zig
@@ -1,25 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const c = @cImport({
|
||||
@cInclude("volk.h");
|
||||
});
|
||||
|
||||
pub const InstanceTable = blk: {
|
||||
const info = @typeInfo(c.VolkInstanceTable).@"struct";
|
||||
|
||||
var field_names: [info.fields.len][]const u8 = undefined;
|
||||
var field_types: [info.fields.len]type = undefined;
|
||||
var field_attrs: [info.fields.len]std.builtin.Type.StructField.Attributes = undefined;
|
||||
|
||||
for (info.fields, &field_names, &field_types, &field_attrs) |field, *field_name, *field_type, *field_attr| {
|
||||
field_name.* = field.name;
|
||||
field_type.* = std.meta.Child(field.type);
|
||||
field_attr.* = .{};
|
||||
}
|
||||
|
||||
break :blk @Struct(.auto, null, field_names, field_types, field_attrs);
|
||||
};
|
||||
|
||||
// pub const InstanceTable: type = {
|
||||
//
|
||||
// };
|
||||
267
vk/root.zig
Normal file
267
vk/root.zig
Normal file
@@ -0,0 +1,267 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const vk = @import("volk");
|
||||
|
||||
pub const InitError = error{
|
||||
InitializationFailed,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
pub fn init() InitError!void {
|
||||
switch (vk.volkInitialize()) {
|
||||
vk.VK_ERROR_INITIALIZATION_FAILED => return error.InitializationFailed,
|
||||
vk.VK_SUCCESS => {},
|
||||
else => return error.Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
vk.volkFinalize();
|
||||
}
|
||||
|
||||
pub const Version = packed struct(u32) {
|
||||
patch: u12,
|
||||
minor: u10,
|
||||
major: u7,
|
||||
variant: u3 = 0,
|
||||
|
||||
pub const API_1_0: Version = .{ .variant = 0, .major = 1, .minor = 0, .patch = 0 };
|
||||
pub const API_1_1: Version = .{ .variant = 0, .major = 1, .minor = 1, .patch = 0 };
|
||||
pub const API_1_2: Version = .{ .variant = 0, .major = 1, .minor = 2, .patch = 0 };
|
||||
pub const API_1_3: Version = .{ .variant = 0, .major = 1, .minor = 3, .patch = 0 };
|
||||
pub const API_1_4: Version = .{ .variant = 0, .major = 1, .minor = 4, .patch = 0 };
|
||||
};
|
||||
|
||||
pub const MessageTypes = struct {
|
||||
general: bool,
|
||||
performance: bool,
|
||||
validation: bool,
|
||||
};
|
||||
|
||||
pub const InstanceConfig = struct {
|
||||
api_version: Version,
|
||||
app_name: [*:0]const u8 = "",
|
||||
app_version: Version = .{ .major = 0, .minor = 0, .patch = 0 },
|
||||
engine_name: [*:0]const u8 = "",
|
||||
engine_version: Version = .{ .major = 0, .minor = 0, .patch = 0 },
|
||||
layer_names: []const [*:0]const u8 = &.{},
|
||||
extension_names: []const [*:0]const u8 = &.{},
|
||||
log_scope: ?@EnumLiteral() = .vulkan,
|
||||
log_message_types: MessageTypes = .{
|
||||
.general = false,
|
||||
.performance = true,
|
||||
.validation = true,
|
||||
},
|
||||
};
|
||||
|
||||
pub const PhysicalDevice = *const opaque {};
|
||||
|
||||
pub const Instance = struct {
|
||||
handle: vk.VkInstance,
|
||||
vtable: *const vk.VolkInstanceTable,
|
||||
|
||||
pub fn enumerate_physical_devices(self: Instance, buf: []PhysicalDevice) ![]PhysicalDevice {
|
||||
var count: u32 = @intCast(buf.len);
|
||||
if (self.vtable.vkEnumeratePhysicalDevices.?(self.handle, &count, @ptrCast(buf.ptr)) != vk.VK_SUCCESS) return error.Unknown;
|
||||
return buf[0..count];
|
||||
}
|
||||
|
||||
pub fn get_physical_device_properties(self: Instance, pdev: PhysicalDevice) vk.VkPhysicalDeviceProperties {
|
||||
var props: vk.VkPhysicalDeviceProperties = undefined;
|
||||
self.vtable.vkGetPhysicalDeviceProperties.?(@ptrCast(@constCast(pdev)), &props);
|
||||
return props;
|
||||
}
|
||||
};
|
||||
|
||||
pub const InstanceContext = struct {
|
||||
handle: vk.VkInstance,
|
||||
vtable: vk.VolkInstanceTable,
|
||||
debug: ?vk.VkDebugUtilsMessengerEXT,
|
||||
|
||||
pub const InstanceCreateError = error{
|
||||
Unknown,
|
||||
};
|
||||
pub fn init(config: InstanceConfig) InstanceCreateError!InstanceContext {
|
||||
const callback: vk.PFN_vkDebugUtilsMessengerCallbackEXT = if (config.log_scope) |scope| default_debug_callback(scope) else null;
|
||||
|
||||
var message_severity: vk.VkDebugUtilsMessageSeverityFlagsEXT = 0;
|
||||
if (config.log_scope) |scope| {
|
||||
if (std.log.logEnabled(.debug, scope)) message_severity |= vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
||||
if (std.log.logEnabled(.info, scope)) message_severity |= vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
|
||||
if (std.log.logEnabled(.warn, scope)) message_severity |= vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
||||
if (std.log.logEnabled(.err, scope)) message_severity |= vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
}
|
||||
|
||||
var message_type: vk.VkDebugUtilsMessageTypeFlagsEXT = 0;
|
||||
if (config.log_message_types.general) message_type |= vk.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
|
||||
if (config.log_message_types.performance) message_type |= vk.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
if (config.log_message_types.validation) message_type |= vk.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
|
||||
|
||||
var extension_names_buf: [256][*:0]const u8 = undefined;
|
||||
var extension_names: std.ArrayListUnmanaged([*:0]const u8) = .initBuffer(&extension_names_buf);
|
||||
extension_names.appendSliceAssumeCapacity(config.extension_names);
|
||||
|
||||
var layer_names_buf: [256][*:0]const u8 = undefined;
|
||||
var layer_names: std.ArrayListUnmanaged([*:0]const u8) = .initBuffer(&layer_names_buf);
|
||||
layer_names.appendSliceAssumeCapacity(config.layer_names);
|
||||
|
||||
var do_logging = message_severity != 0 and message_type != 0;
|
||||
|
||||
if (do_logging) {
|
||||
for (extension_names.items) |name| {
|
||||
if (std.mem.eql(u8, std.mem.span(name), "VK_EXT_debug_utils")) break;
|
||||
} else {
|
||||
var extension_props_buf: [256]vk.VkExtensionProperties = undefined;
|
||||
var count: u32 = @intCast(extension_props_buf.len);
|
||||
if (vk.vkEnumerateInstanceExtensionProperties.?(null, &count, &extension_props_buf) != vk.VK_SUCCESS) {
|
||||
do_logging = false;
|
||||
} else {
|
||||
for (extension_props_buf[0..count]) |prop| {
|
||||
if (std.mem.eql(u8, std.mem.sliceTo(&prop.extensionName, 0), "VK_EXT_debug_utils")) {
|
||||
extension_names.appendAssumeCapacity("VK_EXT_debug_utils");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
do_logging = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_logging and config.log_message_types.validation) {
|
||||
for (layer_names.items) |name| {
|
||||
if (std.mem.eql(u8, std.mem.span(name), "VK_LAYER_KHRONOS_validation")) break;
|
||||
} else {
|
||||
var layer_props_buf: [256]vk.VkLayerProperties = undefined;
|
||||
var count: u32 = @intCast(layer_props_buf.len);
|
||||
if (vk.vkEnumerateInstanceLayerProperties.?(&count, &layer_props_buf) != vk.VK_SUCCESS) {
|
||||
do_logging = false;
|
||||
} else {
|
||||
for (layer_props_buf[0..count]) |prop| {
|
||||
if (std.mem.eql(u8, std.mem.sliceTo(&prop.layerName, 0), "VK_LAYER_KHRONOS_validation")) {
|
||||
layer_names.appendAssumeCapacity("VK_LAYER_KHRONOS_validation");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const debug_info: vk.VkDebugUtilsMessengerCreateInfoEXT = .{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.pNext = null,
|
||||
.flags = 0,
|
||||
.messageSeverity = message_severity,
|
||||
.messageType = message_type,
|
||||
.pfnUserCallback = callback,
|
||||
.pUserData = null,
|
||||
};
|
||||
const app_info = vk.VkApplicationInfo{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||
.pNext = null,
|
||||
.apiVersion = @bitCast(config.api_version),
|
||||
.applicationVersion = @bitCast(config.app_version),
|
||||
.engineVersion = @bitCast(config.engine_version),
|
||||
.pApplicationName = config.app_name,
|
||||
.pEngineName = config.engine_name,
|
||||
};
|
||||
const info = vk.VkInstanceCreateInfo{
|
||||
.sType = vk.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = if (do_logging) &debug_info else null,
|
||||
.flags = 0,
|
||||
.pApplicationInfo = &app_info,
|
||||
.enabledLayerCount = @intCast(layer_names.items.len),
|
||||
.ppEnabledLayerNames = layer_names.items.ptr,
|
||||
.enabledExtensionCount = @intCast(extension_names.items.len),
|
||||
.ppEnabledExtensionNames = extension_names.items.ptr,
|
||||
};
|
||||
|
||||
// std.log.debug("{s} ", .{})
|
||||
|
||||
var result: InstanceContext = undefined;
|
||||
switch (vk.vkCreateInstance.?(&info, null, &result.handle)) {
|
||||
vk.VK_SUCCESS => {},
|
||||
else => return error.Unknown,
|
||||
}
|
||||
vk.volkLoadInstanceTable(&result.vtable, result.handle);
|
||||
|
||||
result.debug = null;
|
||||
if (do_logging) {
|
||||
var debug_handle: vk.VkDebugUtilsMessengerEXT = undefined;
|
||||
if (result.vtable.vkCreateDebugUtilsMessengerEXT.?(result.handle, &debug_info, null, &debug_handle) != vk.VK_SUCCESS) {
|
||||
do_logging = false;
|
||||
} else {
|
||||
result.debug = debug_handle;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn interface(self: *const InstanceContext) Instance {
|
||||
return .{ .handle = self.handle, .vtable = &self.vtable };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *const InstanceContext) void {
|
||||
if (self.debug) |debug_handle| {
|
||||
self.vtable.vkDestroyDebugUtilsMessengerEXT.?(self.handle, debug_handle, null);
|
||||
}
|
||||
self.vtable.vkDestroyInstance.?(self.handle, null);
|
||||
}
|
||||
};
|
||||
|
||||
fn default_debug_callback(scope: @EnumLiteral()) vk.PFN_vkDebugUtilsMessengerCallbackEXT {
|
||||
const impl = struct {
|
||||
fn impl(
|
||||
message_severity: vk.VkDebugUtilsMessageSeverityFlagBitsEXT,
|
||||
message_types: vk.VkDebugUtilsMessageTypeFlagsEXT,
|
||||
p_callback_data: [*c]const vk.VkDebugUtilsMessengerCallbackDataEXT,
|
||||
_: ?*anyopaque,
|
||||
) callconv(.c) vk.VkBool32 {
|
||||
var types_buf: [64]u8 = undefined;
|
||||
var types_str: std.ArrayListUnmanaged(u8) = .initBuffer(&types_buf);
|
||||
|
||||
if (message_types & vk.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT != 0) {
|
||||
if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(" ");
|
||||
types_str.appendSliceAssumeCapacity("general");
|
||||
}
|
||||
if (message_types & vk.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT != 0) {
|
||||
if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(" ");
|
||||
types_str.appendSliceAssumeCapacity("validation");
|
||||
}
|
||||
if (message_types & vk.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT != 0) {
|
||||
if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(" ");
|
||||
types_str.appendSliceAssumeCapacity("performance");
|
||||
}
|
||||
if (types_str.items.len > 0) types_str.appendSliceAssumeCapacity(": ");
|
||||
|
||||
const fmt = "{s}{s}";
|
||||
const arg = .{
|
||||
types_str.items,
|
||||
p_callback_data.*.pMessage,
|
||||
};
|
||||
|
||||
const log = std.log.scoped(scope);
|
||||
|
||||
if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT != 0) {
|
||||
log.err(fmt, arg);
|
||||
switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => @breakpoint(),
|
||||
else => {},
|
||||
}
|
||||
} else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT != 0) {
|
||||
log.warn(fmt, arg);
|
||||
} else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT != 0) {
|
||||
log.info(fmt, arg);
|
||||
} else if (message_severity & vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT != 0) {
|
||||
log.debug(fmt, arg);
|
||||
} else {
|
||||
log.debug(fmt, arg);
|
||||
}
|
||||
|
||||
return vk.VK_FALSE;
|
||||
}
|
||||
};
|
||||
return &impl.impl;
|
||||
}
|
||||
Reference in New Issue
Block a user