-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvulkan_debug.zig
135 lines (119 loc) · 5.76 KB
/
vulkan_debug.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// NOTE: Vulkan Validation Layer incomplete,
// I mess up when porting the callbacks and is not working.
const std = @import("std");
const vk = @cImport({
@cInclude("vulkan.h");
});
pub const validation_layers = [_][*c]const u8{ "VK_LAYER_KHRONOS_validation" };
pub var debug_messenger: vk.VkDebugUtilsMessengerEXT = undefined;
fn vkcheck(result: vk.VkResult, comptime err_msg: []const u8) !void {
if (result != vk.VK_SUCCESS) {
std.io.getStdOut().writer().print("Vulkan error : {s}\n", .{ err_msg }) catch unreachable;
std.debug.print("Vulkan error : {s}\n", .{ err_msg });
@panic(err_msg);
//return error.VulkanError;
}
}
pub fn checkExtensionProperties() !void {
var extension_count: u32 = 0;
try vkcheck(vk.vkEnumerateInstanceExtensionProperties(null, &extension_count, null), "Failed to enumerate instance extensions");
std.debug.print("{d} extensions supported\n", .{ extension_count });
const extensions = try std.heap.page_allocator.alloc(vk.VkExtensionProperties, extension_count);
defer std.heap.page_allocator.free(extensions);
try vkcheck(vk.vkEnumerateInstanceExtensionProperties(null, &extension_count, extensions.ptr), "Failed to get instance extensions");
std.debug.print("Available extensions :\n", .{});
for (extensions) |extension| {
const extension_len = std.mem.indexOf(u8, extension.extensionName[0..], &[_]u8{0}) orelse 256;
std.debug.print(" {s}\n", .{extension.extensionName[0..extension_len]});
}
}
pub fn checkValidationLayerSupport() bool {
var layer_count: u32 = 0;
_ = vk.vkEnumerateInstanceLayerProperties(&layer_count, null);
const available_layers = std.heap.page_allocator.alloc(vk.VkLayerProperties, layer_count) catch unreachable;
defer std.heap.page_allocator.free(available_layers);
_ = vk.vkEnumerateInstanceLayerProperties(&layer_count, available_layers.ptr);
std.debug.print("Validation check, searching: \n", .{});
for (validation_layers) |layer_name| {
const layer_name_span = std.mem.span(layer_name);
const layer_name_len = layer_name_span.len;
std.debug.print(" {s}\nValidation properties list :\n", .{ layer_name_span });
var found: bool = false;
for (available_layers) |layer_properties| {
std.debug.print(" {s}\n", .{ layer_properties.layerName });
const prop_name_len = std.mem.indexOf(u8, layer_properties.layerName[0..], &[_]u8{0}) orelse 256;
if (layer_name_len == prop_name_len) {
std.debug.print("Found:\n {s}\n", .{ &layer_properties.layerName });
if (std.mem.eql(u8, layer_name_span, layer_properties.layerName[0..prop_name_len])) {
found = true;
break;
}
}
}
if (!found) return false;
}
return true;
}
// pub extern fn vkCreateDebugUtilsMessengerEXT(
// instance: vk.VkInstance,
// pCreateInfo: *const vk.VkDebugUtilsMessengerCreateInfoEXT,
// pAllocator: ?*const vk.VkAllocationCallbacks,
// pDebugMessenger: *vk.VkDebugUtilsMessengerEXT) callconv(.C) vk.VkResult;
pub fn CreateDebugUtilsMessengerEXT(instance: vk.VkInstance, pCreateInfo: *const vk.VkDebugUtilsMessengerCreateInfoEXT, pAllocator: ?*const vk.VkAllocationCallbacks, pDebugMessenger: *vk.VkDebugUtilsMessengerEXT) callconv(.C) vk.VkResult {
const func: vk.PFN_vkDebugUtilsMessengerCallbackEXT = @ptrCast(vk.vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"));
if (func) |f| {
return f(instance, pCreateInfo, pAllocator, pDebugMessenger);
} else {
return vk.VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
// pub extern fn vkDestroyDebugUtilsMessengerEXT(
// instance: vk.VkInstance,
// debugMessenger: vk.VkDebugUtilsMessengerEXT,
// pAllocator: ?*const vk.VkAllocationCallbacks) void;
pub fn DestroyDebugUtilsMessengerEXT(instance: vk.VkInstance, debugMessenger: vk.VkDebugUtilsMessengerEXT, pAllocator: ?*const vk.VkAllocationCallbacks) callconv(.C) void {
_ = debugMessenger; _ = pAllocator;
const func = vk.vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
if (func) |f| {
f(); //f(instance, debugMessenger, pAllocator);
}
}
pub fn populateDebugMessengerCreateInfo(createInfo: *vk.VkDebugUtilsMessengerCreateInfoEXT) void {
createInfo.* = 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_WARNING_BIT_EXT |
vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
.messageType =
vk.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
vk.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
vk.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
.pfnUserCallback = debugCallback,
.pUserData = null,
};
}
pub fn setupDebugMessenger(instance: vk.VkInstance) !void {
//TODO: try to make this work, NOTE: enable at deinit too.
// https://github.com/Overv/VulkanTutorial/blob/main/code/02_validation_layers.cpp
_ = instance;
return;
// var createInfo: vk.VkDebugUtilsMessengerCreateInfoEXT = undefined;
// populateDebugMessengerCreateInfo(&createInfo);
// try vkcheck(CreateDebugUtilsMessengerEXT(instance, &createInfo, null, &debug_messenger),
// "Failed to create debug utils messenger extension.");
}
fn debugCallback (
messageSeverity: vk.VkDebugUtilsMessageSeverityFlagBitsEXT,
messageType: vk.VkDebugUtilsMessageTypeFlagsEXT,
pCallbackData: [*c]const vk.VkDebugUtilsMessengerCallbackDataEXT,
pUserData: ?*anyopaque,
) callconv(.C) vk.VkBool32 {
if (messageSeverity >= vk.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
std.debug.print("Validation layer :\n severity : {any}\n type : {any}\n callback_data: {any}\n message : {any}\n", .{
messageSeverity, messageType, pCallbackData.*.pMessage, pUserData });
}
return vk.VK_FALSE;
}