adding debug logs levels, implementing some physical device functions

This commit is contained in:
2025-11-06 23:10:26 +01:00
parent f943ea4273
commit 1d44717760
6 changed files with 175 additions and 69 deletions

View File

@@ -14,7 +14,7 @@ To understand Vulkan — not as a humble API mere mortals call upon, but as a la
It does not seek to produce a performant or production-worthy driver. \ It does not seek to produce a performant or production-worthy driver. \
*The gods are merciful, but not that merciful.* *The gods are merciful, but not that merciful.*
# Build ## Build
If thou art truly determined: If thou art truly determined:
``` ```
@@ -26,7 +26,7 @@ The precise ritual varies by system — consult the tomes of your operating syst
Use at your own risk. If thy machine shudders, weeps, or attempts to flee — know that it was warned. Use at your own risk. If thy machine shudders, weeps, or attempts to flee — know that it was warned.
# License ## License
Released unto the world as MIT for study, experimentation, and the occasional horrified whisper. Released unto the world as MIT for study, experimentation, and the occasional horrified whisper.
Do with it as thou wilt, but accept the consequences as thine own. Do with it as thou wilt, but accept the consequences as thine own.

View File

@@ -22,6 +22,9 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr
interface.dispatch_table = &.{ interface.dispatch_table = &.{
.createDevice = createDevice, .createDevice = createDevice,
.getFormatProperties = getFormatProperties,
.getImageFormatProperties = getImageFormatProperties,
.getSparseImageFormatProperties = getSparseImageFormatProperties,
.release = destroy, .release = destroy,
}; };
@@ -44,6 +47,35 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr
.flags = .{}, // Host memory .flags = .{}, // Host memory
}; };
interface.features = .{
.robust_buffer_access = .true,
.shader_float_64 = .true,
.shader_int_64 = .true,
.shader_int_16 = .true,
};
var queue_family_props = [_]vk.QueueFamilyProperties{
.{
.queue_flags = .{ .graphics_bit = true, .compute_bit = true, .transfer_bit = true },
.queue_count = 1,
.timestamp_valid_bits = 0,
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
},
.{
.queue_flags = .{ .graphics_bit = true },
.queue_count = 1,
.timestamp_valid_bits = 0,
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
},
.{
.queue_flags = .{ .transfer_bit = true },
.queue_count = 1,
.timestamp_valid_bits = 0,
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
},
};
interface.queue_family_props = std.ArrayList(vk.QueueFamilyProperties).fromOwnedSlice(queue_family_props[0..]);
const info = cpuinfo.get(allocator) catch return VkError.InitializationFailed; const info = cpuinfo.get(allocator) catch return VkError.InitializationFailed;
defer info.deinit(allocator); defer info.deinit(allocator);
@@ -61,6 +93,48 @@ pub fn createDevice(interface: *Interface, allocator: std.mem.Allocator, infos:
return &device.interface; return &device.interface;
} }
pub fn getFormatProperties(interface: *Interface, format: vk.Format) VkError!vk.FormatProperties {
_ = interface;
_ = format;
return .{};
}
pub fn getImageFormatProperties(
interface: *Interface,
format: vk.Format,
image_type: vk.ImageType,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
) VkError!vk.ImageFormatProperties {
_ = interface;
_ = format;
_ = image_type;
_ = tiling;
_ = usage;
_ = flags;
return VkError.FormatNotSupported;
}
pub fn getSparseImageFormatProperties(
interface: *Interface,
format: vk.Format,
image_type: vk.ImageType,
samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
) VkError!vk.SparseImageFormatProperties {
_ = interface;
_ = format;
_ = image_type;
_ = samples;
_ = tiling;
_ = usage;
_ = flags;
return VkError.FormatNotSupported;
}
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void { pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
allocator.destroy(self); allocator.destroy(self);

View File

@@ -11,13 +11,16 @@ pub const ObjectType: vk.ObjectType = .physical_device;
props: vk.PhysicalDeviceProperties, props: vk.PhysicalDeviceProperties,
mem_props: vk.PhysicalDeviceMemoryProperties, mem_props: vk.PhysicalDeviceMemoryProperties,
format_props: vk.FormatProperties,
features: vk.PhysicalDeviceFeatures, features: vk.PhysicalDeviceFeatures,
queue_family_props: std.ArrayList(vk.QueueFamilyProperties),
instance: *const Instance, instance: *const Instance,
dispatch_table: *const DispatchTable, dispatch_table: *const DispatchTable,
pub const DispatchTable = struct { pub const DispatchTable = struct {
createDevice: *const fn (*Self, std.mem.Allocator, *const vk.DeviceCreateInfo) VkError!*Device, createDevice: *const fn (*Self, std.mem.Allocator, *const vk.DeviceCreateInfo) VkError!*Device,
getFormatProperties: *const fn (*Self, vk.Format) VkError!vk.FormatProperties,
getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties,
getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.SparseImageFormatProperties,
release: *const fn (*Self, std.mem.Allocator) VkError!void, release: *const fn (*Self, std.mem.Allocator) VkError!void,
}; };
@@ -41,7 +44,7 @@ pub fn init(allocator: std.mem.Allocator, instance: *const Instance) VkError!Sel
.memory_heap_count = 0, .memory_heap_count = 0,
.memory_heaps = undefined, .memory_heaps = undefined,
}, },
.format_props = .{}, .queue_family_props = .empty,
.features = .{}, .features = .{},
.instance = instance, .instance = instance,
.dispatch_table = undefined, .dispatch_table = undefined,
@@ -52,6 +55,33 @@ pub fn createDevice(self: *Self, allocator: std.mem.Allocator, infos: *const vk.
return try self.dispatch_table.createDevice(self, allocator, infos); return try self.dispatch_table.createDevice(self, allocator, infos);
} }
pub fn getFormatProperties(self: *Self, format: vk.Format) VkError!vk.FormatProperties {
return try self.dispatch_table.getFormatProperties(self, format);
}
pub fn getImageFormatProperties(
self: *Self,
format: vk.Format,
image_type: vk.ImageType,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
) VkError!vk.ImageFormatProperties {
return try self.dispatch_table.getImageFormatProperties(self, format, image_type, tiling, usage, flags);
}
pub fn getSparseImageFormatProperties(
self: *Self,
format: vk.Format,
image_type: vk.ImageType,
samples: vk.SampleCountFlags,
tiling: vk.ImageTiling,
usage: vk.ImageUsageFlags,
flags: vk.ImageCreateFlags,
) VkError!vk.SparseImageFormatProperties {
return try self.dispatch_table.getSparseImageFormatProperties(self, format, image_type, samples, tiling, usage, flags);
}
pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void { pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void {
try self.dispatch_table.release(self, allocator); try self.dispatch_table.release(self, allocator);
} }

View File

@@ -13,21 +13,28 @@ pub const PhysicalDevice = @import("PhysicalDevice.zig");
pub const VulkanAllocator = @import("VulkanAllocator.zig"); pub const VulkanAllocator = @import("VulkanAllocator.zig");
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1; pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS"; pub const DRIVER_LOGS_ENV_NAME = "STROLL_LOGS_LEVEL";
pub const std_options: std.Options = .{ pub const std_options: std.Options = .{
.log_level = .debug, .log_level = .debug,
.logFn = logger.log, .logFn = logger.log,
}; };
pub fn retrieveDriverDataAs(handle: anytype, comptime T: type) !*T { pub const LogVerboseLevel = enum {
comptime { None,
switch (@typeInfo(@TypeOf(handle))) { Standard,
.pointer => |p| std.debug.assert(@hasField(p.child, "driver_data")), High,
else => @compileError("Invalid type passed to 'retrieveDriverDataAs': " ++ @typeName(@TypeOf(handle))), };
}
} pub inline fn getLogVerboseLevel() LogVerboseLevel {
return @ptrCast(@alignCast(@field(handle, "driver_data"))); const allocator = std.heap.page_allocator;
const level = std.process.getEnvVarOwned(allocator, DRIVER_LOGS_ENV_NAME) catch return .None;
return if (std.mem.eql(u8, level, "none"))
.None
else if (std.mem.eql(u8, level, "all"))
.High
else
.Standard;
} }
comptime { comptime {

View File

@@ -1,6 +1,7 @@
const std = @import("std"); const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const root = @import("root"); const root = @import("root");
const lib = @import("lib.zig");
const logger = @import("logger.zig"); const logger = @import("logger.zig");
const error_set = @import("error_set.zig"); const error_set = @import("error_set.zig");
@@ -17,7 +18,12 @@ const PhysicalDevice = @import("PhysicalDevice.zig");
// This file contains all exported Vulkan entrypoints. // This file contains all exported Vulkan entrypoints.
fn functionMapElement(comptime name: []const u8) struct { []const u8, vk.PfnVoidFunction } { fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []const u8) void {
if (lib.getLogVerboseLevel() != .High) return;
std.log.scoped(scope).err("Could not find function {s}", .{name});
}
fn functionMapEntryPoint(comptime name: []const u8) struct { []const u8, vk.PfnVoidFunction } {
const stroll_name = std.fmt.comptimePrint("stroll{s}", .{name[2..]}); const stroll_name = std.fmt.comptimePrint("stroll{s}", .{name[2..]});
return if (std.meta.hasFn(@This(), name)) return if (std.meta.hasFn(@This(), name))
@@ -29,38 +35,38 @@ fn functionMapElement(comptime name: []const u8) struct { []const u8, vk.PfnVoid
} }
const icd_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const icd_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapElement("vk_icdGetInstanceProcAddr"), functionMapEntryPoint("vk_icdGetInstanceProcAddr"),
functionMapElement("vk_icdGetPhysicalDeviceProcAddr"), functionMapEntryPoint("vk_icdGetPhysicalDeviceProcAddr"),
functionMapElement("vk_icdNegotiateLoaderICDInterfaceVersion"), functionMapEntryPoint("vk_icdNegotiateLoaderICDInterfaceVersion"),
}); });
const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapElement("vkCreateInstance"), functionMapEntryPoint("vkCreateInstance"),
functionMapElement("vkGetInstanceProcAddr"), functionMapEntryPoint("vkGetInstanceProcAddr"),
functionMapElement("vkEnumerateInstanceExtensionProperties"), functionMapEntryPoint("vkEnumerateInstanceExtensionProperties"),
functionMapElement("vkEnumerateInstanceVersion"), functionMapEntryPoint("vkEnumerateInstanceVersion"),
}); });
const instance_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const instance_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapElement("vkDestroyInstance"), functionMapEntryPoint("vkDestroyInstance"),
functionMapElement("vkEnumeratePhysicalDevices"), functionMapEntryPoint("vkEnumeratePhysicalDevices"),
functionMapElement("vkGetDeviceProcAddr"), functionMapEntryPoint("vkGetDeviceProcAddr"),
}); });
const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapElement("vkCreateDevice"), functionMapEntryPoint("vkCreateDevice"),
functionMapElement("vkEnumerateDeviceExtensionProperties"), functionMapEntryPoint("vkEnumerateDeviceExtensionProperties"),
functionMapElement("vkGetPhysicalDeviceFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceFormatProperties"),
functionMapElement("vkGetPhysicalDeviceFeatures"), functionMapEntryPoint("vkGetPhysicalDeviceFeatures"),
functionMapElement("vkGetPhysicalDeviceImageFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceImageFormatProperties"),
functionMapElement("vkGetPhysicalDeviceProperties"), functionMapEntryPoint("vkGetPhysicalDeviceProperties"),
functionMapElement("vkGetPhysicalDeviceMemoryProperties"), functionMapEntryPoint("vkGetPhysicalDeviceMemoryProperties"),
functionMapElement("vkGetPhysicalDeviceQueueFamilyProperties"), functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties"),
functionMapElement("vkGetPhysicalDeviceSparseImageFormatProperties"), functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties"),
}); });
const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{ const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
functionMapElement("vkDestroyDevice"), functionMapEntryPoint("vkDestroyDevice"),
}); });
// ICD Interface ============================================================================================================================================= // ICD Interface =============================================================================================================================================
@@ -84,7 +90,7 @@ pub export fn stroll_icdGetPhysicalDeviceProcAddr(_: vk.Instance, p_name: ?[*:0]
if (physical_device_pfn_map.get(name)) |pfn| return pfn; if (physical_device_pfn_map.get(name)) |pfn| return pfn;
std.log.scoped(.vk_icdGetPhysicalDeviceProcAddr).err("Could not find function {s}", .{name}); entryPointNotFoundErrorLog(.vk_icdGetPhysicalDeviceProcAddr, name);
return null; return null;
} }
@@ -96,14 +102,14 @@ pub export fn vkGetInstanceProcAddr(p_instance: vk.Instance, p_name: ?[*:0]const
if (global_pfn_map.get(name)) |pfn| return pfn; if (global_pfn_map.get(name)) |pfn| return pfn;
if (p_instance == .null_handle) { if (p_instance == .null_handle) {
std.log.scoped(.vkGetInstanceProcAddr).err("Could not find global entrypoint {s}", .{name}); entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null; return null;
} }
if (instance_pfn_map.get(name)) |pfn| return pfn; if (instance_pfn_map.get(name)) |pfn| return pfn;
if (physical_device_pfn_map.get(name)) |pfn| return pfn; if (physical_device_pfn_map.get(name)) |pfn| return pfn;
if (device_pfn_map.get(name)) |pfn| return pfn; if (device_pfn_map.get(name)) |pfn| return pfn;
std.log.scoped(.vkGetInstanceProcAddr).err("Could not find entrypoint {s}", .{name}); entryPointNotFoundErrorLog(.vkGetInstanceProcAddr, name);
return null; return null;
} }
@@ -194,9 +200,8 @@ pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.Phy
} }
pub export fn strollGetPhysicalDeviceFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, properties: *vk.FormatProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, properties: *vk.FormatProperties) callconv(vk.vulkan_call_conv) void {
_ = format;
const self = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch return; const self = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch return;
properties.* = self.format_props; properties.* = self.getFormatProperties(format) catch return;
} }
pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevice, features: *vk.PhysicalDeviceFeatures) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevice, features: *vk.PhysicalDeviceFeatures) callconv(vk.vulkan_call_conv) void {
@@ -205,14 +210,9 @@ pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevi
} }
pub export fn strollGetPhysicalDeviceImageFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, image_type: vk.ImageType, tiling: vk.ImageTiling, usage: vk.ImageUsageFlags, flags: vk.ImageCreateFlags, properties: *vk.ImageFormatProperties) callconv(vk.vulkan_call_conv) vk.Result { pub export fn strollGetPhysicalDeviceImageFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, image_type: vk.ImageType, tiling: vk.ImageTiling, usage: vk.ImageUsageFlags, flags: vk.ImageCreateFlags, properties: *vk.ImageFormatProperties) callconv(vk.vulkan_call_conv) vk.Result {
_ = p_physical_device; const self = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
_ = format; properties.* = self.getImageFormatProperties(format, image_type, tiling, usage, flags) catch |err| return toVkResult(err);
_ = image_type; return .success;
_ = tiling;
_ = usage;
_ = flags;
_ = properties;
return .error_format_not_supported;
} }
pub export fn strollGetPhysicalDeviceProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceProperties(p_physical_device: vk.PhysicalDevice, properties: *vk.PhysicalDeviceProperties) callconv(vk.vulkan_call_conv) void {
@@ -226,9 +226,11 @@ pub export fn strollGetPhysicalDeviceMemoryProperties(p_physical_device: vk.Phys
} }
pub export fn strollGetPhysicalDeviceQueueFamilyProperties(p_physical_device: vk.PhysicalDevice, count: *u32, properties: ?[*]vk.QueueFamilyProperties) callconv(vk.vulkan_call_conv) void { pub export fn strollGetPhysicalDeviceQueueFamilyProperties(p_physical_device: vk.PhysicalDevice, count: *u32, properties: ?[*]vk.QueueFamilyProperties) callconv(vk.vulkan_call_conv) void {
_ = p_physical_device; const self = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch return;
_ = properties; count.* = @intCast(self.queue_family_props.items.len);
count.* = 0; if (properties) |props| {
@memcpy(props[0..count.*], self.queue_family_props.items[0..count.*]);
}
} }
pub export fn strollGetPhysicalDeviceSparseImageFormatProperties( pub export fn strollGetPhysicalDeviceSparseImageFormatProperties(
@@ -241,15 +243,9 @@ pub export fn strollGetPhysicalDeviceSparseImageFormatProperties(
flags: vk.ImageCreateFlags, flags: vk.ImageCreateFlags,
properties: *vk.SparseImageFormatProperties, properties: *vk.SparseImageFormatProperties,
) callconv(vk.vulkan_call_conv) vk.Result { ) callconv(vk.vulkan_call_conv) vk.Result {
_ = p_physical_device; const self = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
_ = format; properties.* = self.getSparseImageFormatProperties(format, image_type, samples, tiling, usage, flags) catch |err| return toVkResult(err);
_ = image_type; return .success;
_ = samples;
_ = tiling;
_ = usage;
_ = flags;
_ = properties;
return .error_format_not_supported;
} }
// Device functions ========================================================================================================================================== // Device functions ==========================================================================================================================================
@@ -272,6 +268,6 @@ pub export fn strollGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u
if (p_device == .null_handle) return null; if (p_device == .null_handle) return null;
if (device_pfn_map.get(name)) |pfn| return pfn; if (device_pfn_map.get(name)) |pfn| return pfn;
std.log.scoped(.vkGetDeviceProcAddr).err("Could not find entrypoint {s}", .{name}); entryPointNotFoundErrorLog(.vkGetDeviceProcAddr, name);
return null; return null;
} }

View File

@@ -2,6 +2,7 @@ const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const zdt = @import("zdt"); const zdt = @import("zdt");
const root = @import("root"); const root = @import("root");
const lib = @import("lib.zig");
comptime { comptime {
if (!@hasDecl(root, "DRIVER_NAME")) { if (!@hasDecl(root, "DRIVER_NAME")) {
@@ -12,11 +13,6 @@ comptime {
} }
} }
const is_posix = switch (builtin.os.tag) {
.windows, .uefi, .wasi => false,
else => true,
};
var indent_level: usize = 0; var indent_level: usize = 0;
pub fn indent() void { pub fn indent() void {
@@ -34,7 +30,7 @@ pub fn unindent() void {
} }
pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal), comptime format: []const u8, args: anytype) void { pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal), comptime format: []const u8, args: anytype) void {
if (!std.process.hasEnvVarConstant(root.DRIVER_LOGS_ENV_NAME)) { if (lib.getLogVerboseLevel() == .None) {
return; return;
} }
@@ -65,13 +61,16 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal),
var writer: *std.Io.Writer = &stderr_writer.interface; var writer: *std.Io.Writer = &stderr_writer.interface;
var out_config = std.Io.tty.Config.detect(stderr_file); var out_config = std.Io.tty.Config.detect(stderr_file);
const timezone = zdt.Timezone.tzLocal(std.heap.page_allocator) catch zdt.Timezone.UTC; var timezone = zdt.Timezone.tzLocal(std.heap.page_allocator) catch zdt.Timezone.UTC;
defer timezone.deinit();
const now = zdt.Datetime.now(.{ .tz = &timezone }) catch return; const now = zdt.Datetime.now(.{ .tz = &timezone }) catch return;
out_config.setColor(writer, .magenta) catch {}; out_config.setColor(writer, .magenta) catch {};
writer.print("[" ++ root.DRIVER_NAME ++ " StrollDriver ", .{}) catch return; writer.print("[StrollDriver ", .{}) catch return;
out_config.setColor(writer, .cyan) catch {};
writer.print(root.DRIVER_NAME, .{}) catch return;
out_config.setColor(writer, .yellow) catch {}; out_config.setColor(writer, .yellow) catch {};
writer.print("{d:02}:{d:02}:{d:02}.{d:03}", .{ now.hour, now.minute, now.second, @divFloor(now.nanosecond, std.time.ns_per_ms) }) catch return; writer.print(" {d:02}:{d:02}:{d:02}.{d:03}", .{ now.hour, now.minute, now.second, @divFloor(now.nanosecond, std.time.ns_per_ms) }) catch return;
out_config.setColor(writer, .magenta) catch {}; out_config.setColor(writer, .magenta) catch {};
writer.print("]", .{}) catch return; writer.print("]", .{}) catch return;