From 3bf7c4e61b27b4452e6e956bcf8524318c80a96f Mon Sep 17 00:00:00 2001 From: David Allemang Date: Thu, 21 Mar 2024 14:14:43 -0400 Subject: [PATCH] vulkan-tutorial 05 --- src/Context.zig | 72 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/src/Context.zig b/src/Context.zig index 4b9b0a8..6f08bca 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -17,6 +17,12 @@ vki: InstanceDispatch, vkd: DeviceDispatch, instance: vk.Instance, +device: vk.Device, + +queues: struct { + graphics: vk.Queue, +}, + messenger: if (USE_DEBUG_LAYERS) vk.DebugUtilsMessengerEXT else void, pub fn init(allocator: std.mem.Allocator) !Self { @@ -161,26 +167,63 @@ pub fn init(allocator: std.mem.Allocator) !Self { defer allocator.free(queue_family_properties); vki.getPhysicalDeviceQueueFamilyProperties(selected.device, &queue_family_count, queue_family_properties.ptr); - var indices = struct { - graphics: ?u32 = null, - }{}; + // todo this should be incorporated with physical device selection/ranking. + const Indices = struct { + graphics: u32, + }; + const indices: Indices = find_index: { + var graphics: ?u32 = null; - for (queue_family_properties, 0..) |prop, idx| { - if (indices.graphics == null) { - if (prop.queue_flags.graphics_bit) { - indices.graphics = @intCast(idx); + for (queue_family_properties, 0..) |prop, idx| { + if (graphics == null and prop.queue_flags.graphics_bit) { + graphics = @intCast(idx); + } + + if (graphics != null) { + break :find_index .{ .graphics = graphics.? }; } } - if (indices.graphics != null) { - break; - } - } + return error.IncompatibleDeviceQueues; + }; + + const priorities = [_]f32{1.0}; + const queue_create_infos = [_]vk.DeviceQueueCreateInfo{ + .{ + .queue_family_index = indices.graphics, + .queue_count = priorities.len, + .p_queue_priorities = &priorities, + }, + }; + + const device_create_info = vk.DeviceCreateInfo{ + .queue_create_info_count = queue_create_infos.len, + .p_queue_create_infos = &queue_create_infos, + .p_enabled_features = &selected.feats, + // .enabled_extension_count = @intCast(exts.items.len), + // .pp_enabled_extension_names = exts.items.ptr, + .enabled_layer_count = @intCast(layers.items.len), + .pp_enabled_layer_names = layers.items.ptr, + }; + + self.device = try vki.createDevice( + selected.device, + &device_create_info, + null, + ); + self.vkd = try DeviceDispatch.load(self.device, vki.dispatch.vkGetDeviceProcAddr); + const vkd = self.vkd; + errdefer vkd.destroyDevice(self.device, null); + + self.queues = .{ + .graphics = vkd.getDeviceQueue(self.device, indices.graphics, 0), + }; return self; } pub fn deinit(self: Self) void { + self.vkd.destroyDevice(self.device, null); if (USE_DEBUG_LAYERS) self.vki.destroyDebugUtilsMessengerEXT( self.instance, self.messenger, @@ -260,6 +303,11 @@ const InstanceDispatch = vk.InstanceWrapper(.{ .getPhysicalDeviceProperties = true, .getPhysicalDeviceFeatures = true, .getPhysicalDeviceQueueFamilyProperties = true, + .createDevice = true, + .getDeviceProcAddr = true, }); -const DeviceDispatch = vk.DeviceWrapper(.{}); +const DeviceDispatch = vk.DeviceWrapper(.{ + .destroyDevice = true, + .getDeviceQueue = true, +});