const std = @import("std"); const vk = @import("vulkan"); const base = @import("base"); const SoftPhysicalDevice = @import("SoftPhysicalDevice.zig"); const Dispatchable = base.Dispatchable; const VkError = base.VkError; const Self = @This(); pub const Interface = base.Instance; interface: Interface, threaded: std.Io.Threaded, io_impl: std.Io, allocator: std.mem.Allocator, fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties { var props: vk.ExtensionProperties = .{ .extension_name = @splat(0), .spec_version = @bitCast(ext.version), }; @memcpy(props.extension_name[0..ext.name.len], ext.name); return props; } pub const extensions = [_]vk.ExtensionProperties{ castExtension(vk.extensions.khr_device_group_creation), castExtension(vk.extensions.khr_get_physical_device_properties_2), castExtension(vk.extensions.khr_surface), castExtension(vk.extensions.khr_wayland_surface), //castExtension(vk.extensions.khr_xlib_surface), //castExtension(vk.extensions.khr_xcb_surface), }; pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface { const self = allocator.create(Self) catch return VkError.OutOfHostMemory; errdefer allocator.destroy(self); self.allocator = std.heap.smp_allocator; self.threaded = if (comptime base.config.soft_single_threaded) .init_single_threaded else std.Io.Threaded.init(self.allocator, .{}); self.io_impl = self.threaded.io(); self.interface = try base.Instance.init(allocator, infos); self.interface.dispatch_table = &.{ .destroy = destroy, }; self.interface.vtable = &.{ .requestPhysicalDevices = requestPhysicalDevices, .releasePhysicalDevices = releasePhysicalDevices, .io = io, }; return &self.interface; } fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); self.threaded.deinit(); allocator.destroy(self); } fn requestPhysicalDevices(interface: *Interface, allocator: std.mem.Allocator, _: []base.drm.Card) VkError!void { // Software driver has only one physical device (the CPU) const physical_device = try SoftPhysicalDevice.create(allocator, interface); errdefer physical_device.interface.release(allocator) catch @panic("Caught an error while handling an error"); const dispatchable = try Dispatchable(base.PhysicalDevice).wrap(allocator, &physical_device.interface); errdefer dispatchable.destroy(allocator); interface.physical_devices.append(allocator, dispatchable) catch return VkError.OutOfHostMemory; } fn releasePhysicalDevices(interface: *Interface, allocator: std.mem.Allocator) VkError!void { for (interface.physical_devices.items) |physical_device| { try physical_device.object.release(allocator); physical_device.destroy(allocator); } interface.physical_devices.deinit(allocator); interface.physical_devices = .empty; } fn io(interface: *Interface) std.Io { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); return self.io_impl; }