debug messenger and validation layers. fix dynamic rendering layout errors. still broken on quadro

This commit is contained in:
David Allemang
2024-03-30 22:46:57 -04:00
parent fb42f4c47f
commit 538c234213
2 changed files with 175 additions and 42 deletions

View File

@@ -1,5 +1,12 @@
const std = @import("std");
const builtin = @import("builtin");
const vk = @import("vk"); const vk = @import("vk");
pub const use_debug_messenger = switch (builtin.mode) {
.Debug, .ReleaseSafe => true,
.ReleaseSmall, .ReleaseFast => false,
};
pub const BaseDispatch = vk.BaseWrapper(.{ pub const BaseDispatch = vk.BaseWrapper(.{
.createInstance = true, .createInstance = true,
.getInstanceProcAddr = true, .getInstanceProcAddr = true,
@@ -19,6 +26,8 @@ pub const InstanceDispatch = vk.InstanceWrapper(.{
.getPhysicalDeviceSurfaceSupportKHR = true, .getPhysicalDeviceSurfaceSupportKHR = true,
.getPhysicalDeviceMemoryProperties = true, .getPhysicalDeviceMemoryProperties = true,
.getDeviceProcAddr = true, .getDeviceProcAddr = true,
.createDebugUtilsMessengerEXT = use_debug_messenger,
.destroyDebugUtilsMessengerEXT = use_debug_messenger,
}); });
pub const DeviceDispatch = vk.DeviceWrapper(.{ pub const DeviceDispatch = vk.DeviceWrapper(.{
@@ -72,4 +81,52 @@ pub const DeviceDispatch = vk.DeviceWrapper(.{
.cmdCopyBuffer = true, .cmdCopyBuffer = true,
.cmdBeginRenderingKHR = true, .cmdBeginRenderingKHR = true,
.cmdEndRenderingKHR = true, .cmdEndRenderingKHR = true,
.cmdPipelineBarrier = true,
}); });
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.getStderrMutex().lock();
defer std.debug.getStderrMutex().unlock();
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;
}

View File

@@ -2,7 +2,6 @@ const std = @import("std");
const vk = @import("vk"); const vk = @import("vk");
const c = @import("c.zig"); const c = @import("c.zig");
const shaders = @import("shaders"); const shaders = @import("shaders");
// const GraphicsContext = @import("graphics_context.zig").GraphicsContext;
const Swapchain = @import("swapchain.zig").Swapchain; const Swapchain = @import("swapchain.zig").Swapchain;
const Context = @import("swapchain.zig").Context; const Context = @import("swapchain.zig").Context;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
@@ -53,12 +52,44 @@ const vertices = [_]Vertex{
const indices = [_]Index{ 4, 5, 6, 6, 5, 7 }; const indices = [_]Index{ 4, 5, 6, 6, 5, 7 };
const InstancePair = std.meta.Tuple(&.{ vk.Instance, gfx.InstanceDispatch }); const InstancePair = std.meta.Tuple(&.{ vk.Instance, gfx.InstanceDispatch, vk.DebugUtilsMessengerEXT });
/// note: destroy with vki.destroyInstance(instance, null) /// note: destroy with vki.destroyInstance(instance, null)
fn create_instance(vkb: gfx.BaseDispatch) !InstancePair { fn create_instance(vkb: gfx.BaseDispatch) !InstancePair {
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.extension_info.ext_debug_utils.name,
});
try layers.appendSlice(&.{
"VK_LAYER_KHRONOS_validation",
});
}
var glfw_exts_count: u32 = 0; var glfw_exts_count: u32 = 0;
const glfw_exts = c.glfwGetRequiredInstanceExtensions(&glfw_exts_count); const glfw_exts: [*]const [*:0]const u8 =
@ptrCast(c.glfwGetRequiredInstanceExtensions(&glfw_exts_count));
try exts.appendSlice(glfw_exts[0..glfw_exts_count]);
const dumci: 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 = &gfx.debug_callback,
.p_user_data = null,
};
const instance = try vkb.createInstance(&vk.InstanceCreateInfo{ const instance = try vkb.createInstance(&vk.InstanceCreateInfo{
.p_application_info = &vk.ApplicationInfo{ .p_application_info = &vk.ApplicationInfo{
@@ -68,13 +99,23 @@ fn create_instance(vkb: gfx.BaseDispatch) !InstancePair {
.engine_version = vk.makeApiVersion(0, 0, 0, 0), .engine_version = vk.makeApiVersion(0, 0, 0, 0),
.api_version = vk.API_VERSION_1_3, .api_version = vk.API_VERSION_1_3,
}, },
.enabled_extension_count = glfw_exts_count, .enabled_extension_count = @intCast(exts.len),
.pp_enabled_extension_names = @ptrCast(glfw_exts), .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) &dumci else null,
}, null); }, null);
const vki = try gfx.InstanceDispatch.load(instance, vkb.dispatch.vkGetInstanceProcAddr); const vki = try gfx.InstanceDispatch.load(instance, vkb.dispatch.vkGetInstanceProcAddr);
errdefer vki.destroyInstance(instance, null);
return .{ instance, vki }; const messenger: vk.DebugUtilsMessengerEXT = if (gfx.use_debug_messenger)
try vki.createDebugUtilsMessengerEXT(instance, &dumci, null)
else
.null_handle;
errdefer if (gfx.use_debug_messenger)
vki.destroyDebugUtilsMessengerEXT(instance, messenger, null);
return .{ instance, vki, messenger };
} }
/// note: destroy with vki.destroySurfaceKHR(instance, surface, null) /// note: destroy with vki.destroySurfaceKHR(instance, surface, null)
@@ -123,7 +164,7 @@ fn create_device(
pdev_search: for (pdevs) |pdev| { pdev_search: for (pdevs) |pdev| {
const props = vki.getPhysicalDeviceProperties(pdev); const props = vki.getPhysicalDeviceProperties(pdev);
if (props.device_type != .discrete_gpu) continue :pdev_search; // if (props.device_type != .discrete_gpu) continue :pdev_search;
var format_count: u32 = undefined; var format_count: u32 = undefined;
_ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null); _ = try vki.getPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &format_count, null);
@@ -192,6 +233,9 @@ fn create_device(
.p_queue_create_infos = qci.ptr, .p_queue_create_infos = qci.ptr,
.enabled_extension_count = @intCast(required_device_extensions.len), .enabled_extension_count = @intCast(required_device_extensions.len),
.pp_enabled_extension_names = required_device_extensions.ptr, .pp_enabled_extension_names = required_device_extensions.ptr,
.p_next = &vk.PhysicalDeviceDynamicRenderingFeaturesKHR{
.dynamic_rendering = vk.TRUE,
},
}, null); }, null);
const vkd = try gfx.DeviceDispatch.load(dev, vki.dispatch.vkGetDeviceProcAddr); const vkd = try gfx.DeviceDispatch.load(dev, vki.dispatch.vkGetDeviceProcAddr);
errdefer vkd.destroyDevice(dev, null); errdefer vkd.destroyDevice(dev, null);
@@ -222,8 +266,10 @@ pub fn main() !void {
const vkb = try gfx.BaseDispatch.load(c.glfwGetInstanceProcAddress); const vkb = try gfx.BaseDispatch.load(c.glfwGetInstanceProcAddress);
const instance, const vki = try create_instance(vkb); const instance, const vki, const messenger = try create_instance(vkb);
defer vki.destroyInstance(instance, null); defer vki.destroyInstance(instance, null);
defer if (gfx.use_debug_messenger)
vki.destroyDebugUtilsMessengerEXT(instance, messenger, null);
const surface = try create_surface(instance, window); const surface = try create_surface(instance, window);
defer vki.destroySurfaceKHR(instance, surface, null); defer vki.destroySurfaceKHR(instance, surface, null);
@@ -234,38 +280,6 @@ pub fn main() !void {
const queue = vkd.getDeviceQueue(dev, family, 0); const queue = vkd.getDeviceQueue(dev, family, 0);
// var swapchain: vk.SwapchainKHR = .null_handle;
// defer vkd.destroySwapchainKHR(dev, swapchain, null);
//
// swapchain = try vkd.createSwapchainKHR(dev, &.{
// .surface = surface,
// .min_image_count = 3, // should compute
// .image_format = .r8g8b8a8_sint, // should compute
// // .image_format = .r8g8b8a8_sint, // should compute
// .image_color_space = .srgb_nonlinear_khr, // should compute
// .image_extent = extent, // should compute
// .image_array_layers = 1,
// .image_usage = .{ .color_attachment_bit = true, .transfer_dst_bit = true },
// .image_sharing_mode = .exclusive, // since we only choose one queue family
// .pre_transform = .{ .identity_bit_khr = true }, // should compute
// .composite_alpha = .{ .opaque_bit_khr = true },
// .present_mode = .mailbox_khr, // should compute
// .clipped = vk.TRUE,
// .old_swapchain = swapchain,
// }, null);
//
// _ = try vkd.queuePresentKHR(queue, &.{
// .wait_semaphore_count = 0,
// .swapchain_count = 1,
// .p_swapchains = &[_]vk.SwapchainKHR{swapchain},
// .p_image_indices = &[_]u32{0},
// });
//
// try vkd.deviceWaitIdle(dev);
//
// _ = pdev;
// extent = undefined;
const gc: Context = .{ const gc: Context = .{
.vki = vki, .vki = vki,
.vkd = vkd, .vkd = vkd,
@@ -485,13 +499,44 @@ fn createCommandBuffers(
for (cmdbufs, swapchain.swap_images) |cmdbuf, image| { for (cmdbufs, swapchain.swap_images) |cmdbuf, image| {
try gc.vkd.beginCommandBuffer(cmdbuf, &.{}); try gc.vkd.beginCommandBuffer(cmdbuf, &.{});
const pre_render_barriers: []const vk.ImageMemoryBarrier = &.{
vk.ImageMemoryBarrier{
.src_access_mask = .{},
.dst_access_mask = .{ .color_attachment_write_bit = true },
.old_layout = .undefined,
.new_layout = .color_attachment_optimal,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
.image = image.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
},
};
gc.vkd.cmdPipelineBarrier(
cmdbuf,
.{ .top_of_pipe_bit = true },
.{ .color_attachment_output_bit = true },
.{},
0,
null,
0,
null,
@intCast(pre_render_barriers.len),
pre_render_barriers.ptr,
);
gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport)); gc.vkd.cmdSetViewport(cmdbuf, 0, 1, @ptrCast(&viewport));
gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor)); gc.vkd.cmdSetScissor(cmdbuf, 0, 1, @ptrCast(&scissor));
const color_attachments = [_]vk.RenderingAttachmentInfoKHR{ const color_attachments = [_]vk.RenderingAttachmentInfoKHR{
.{ .{
.image_view = image.view, .image_view = image.view,
.image_layout = .present_src_khr, .image_layout = .color_attachment_optimal,
.resolve_mode = .{}, .resolve_mode = .{},
.resolve_image_view = .null_handle, .resolve_image_view = .null_handle,
.resolve_image_layout = .undefined, .resolve_image_layout = .undefined,
@@ -519,6 +564,37 @@ fn createCommandBuffers(
gc.vkd.cmdEndRenderingKHR(cmdbuf); gc.vkd.cmdEndRenderingKHR(cmdbuf);
const post_render_barriers: []const vk.ImageMemoryBarrier = &.{
vk.ImageMemoryBarrier{
.src_access_mask = .{ .color_attachment_write_bit = true },
.dst_access_mask = .{},
.old_layout = .color_attachment_optimal,
.new_layout = .present_src_khr,
.src_queue_family_index = 0,
.dst_queue_family_index = 0,
.image = image.image,
.subresource_range = .{
.aspect_mask = .{ .color_bit = true },
.base_mip_level = 0,
.level_count = 1,
.base_array_layer = 0,
.layer_count = 1,
},
},
};
gc.vkd.cmdPipelineBarrier(
cmdbuf,
.{ .color_attachment_output_bit = true },
.{ .bottom_of_pipe_bit = true },
.{},
0,
null,
0,
null,
@intCast(post_render_barriers.len),
post_render_barriers.ptr,
);
try gc.vkd.endCommandBuffer(cmdbuf); try gc.vkd.endCommandBuffer(cmdbuf);
} }