From a7c3ce3a69e6a419a5504c1738b8ee1367cf559b Mon Sep 17 00:00:00 2001 From: David Allemang Date: Thu, 21 Mar 2024 13:45:36 -0400 Subject: [PATCH] vulkan-tutorial 04 --- src/Context.zig | 75 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/src/Context.zig b/src/Context.zig index 68fbc5e..4b9b0a8 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -24,6 +24,7 @@ pub fn init(allocator: std.mem.Allocator) !Self { self.allocator = allocator; self.vkb = try BaseDispatch.load(&c.glfwGetInstanceProcAddress); + const vkb = self.vkb; var exts = std.ArrayList([*:0]const u8).init(allocator); defer exts.deinit(); @@ -44,16 +45,16 @@ pub fn init(allocator: std.mem.Allocator) !Self { std.log.debug("requesting layers: {s}", .{layers.items}); var available_ext_count: u32 = 0; - _ = try self.vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, null); + _ = try vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, null); const available_exts = try allocator.alloc(vk.ExtensionProperties, available_ext_count); defer allocator.free(available_exts); - _ = try self.vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, available_exts.ptr); + _ = try vkb.enumerateInstanceExtensionProperties(null, &available_ext_count, available_exts.ptr); var available_layer_count: u32 = 0; - _ = try self.vkb.enumerateInstanceLayerProperties(&available_layer_count, null); + _ = try vkb.enumerateInstanceLayerProperties(&available_layer_count, null); const available_layers = try allocator.alloc(vk.LayerProperties, available_layer_count); defer allocator.free(available_layers); - _ = try self.vkb.enumerateInstanceLayerProperties(&available_layer_count, available_layers.ptr); + _ = try vkb.enumerateInstanceLayerProperties(&available_layer_count, available_layers.ptr); for (exts.items) |name| { const required_name = std.mem.sliceTo(name, 0); @@ -109,21 +110,73 @@ pub fn init(allocator: std.mem.Allocator) !Self { .p_next = if (USE_DEBUG_LAYERS) &debug_create_info else null, }; - self.instance = try self.vkb.createInstance(&create_info, null); - self.vki = try InstanceDispatch.load(self.instance, self.vkb.dispatch.vkGetInstanceProcAddr); - errdefer self.vki.destroyInstance(self.instance, null); + self.instance = try vkb.createInstance(&create_info, null); + self.vki = try InstanceDispatch.load(self.instance, vkb.dispatch.vkGetInstanceProcAddr); + const vki = self.vki; + errdefer vki.destroyInstance(self.instance, null); - if (USE_DEBUG_LAYERS) self.messenger = try self.vki.createDebugUtilsMessengerEXT( + if (USE_DEBUG_LAYERS) self.messenger = try vki.createDebugUtilsMessengerEXT( self.instance, &debug_create_info, null, ); - errdefer if (USE_DEBUG_LAYERS) self.vki.destroyDebugUtilsMessengerEXT( + errdefer if (USE_DEBUG_LAYERS) vki.destroyDebugUtilsMessengerEXT( self.instance, self.messenger, null, ); + var device_count: u32 = 0; + _ = try vki.enumeratePhysicalDevices(self.instance, &device_count, null); + const devices = try allocator.alloc(vk.PhysicalDevice, device_count); + defer allocator.free(devices); + _ = try vki.enumeratePhysicalDevices(self.instance, &device_count, devices.ptr); + + // todo some ranking strategy to find the most-suitable device + const Selection = struct { + device: vk.PhysicalDevice, + props: vk.PhysicalDeviceProperties, + feats: vk.PhysicalDeviceFeatures, + }; + const selected: Selection = for (devices) |device| { + const props = vki.getPhysicalDeviceProperties(device); + const feats = vki.getPhysicalDeviceFeatures(device); + + if (props.device_type != vk.PhysicalDeviceType.discrete_gpu) continue; + + // if (feats.geometry_shader == vk.FALSE) continue; + + break .{ + .device = device, + .props = props, + .feats = feats, + }; + } else { + return error.NoSuitablePhysicalDevice; + }; + + var queue_family_count: u32 = 0; + vki.getPhysicalDeviceQueueFamilyProperties(selected.device, &queue_family_count, null); + const queue_family_properties = try allocator.alloc(vk.QueueFamilyProperties, queue_family_count); + defer allocator.free(queue_family_properties); + vki.getPhysicalDeviceQueueFamilyProperties(selected.device, &queue_family_count, queue_family_properties.ptr); + + var indices = struct { + graphics: ?u32 = null, + }{}; + + for (queue_family_properties, 0..) |prop, idx| { + if (indices.graphics == null) { + if (prop.queue_flags.graphics_bit) { + indices.graphics = @intCast(idx); + } + } + + if (indices.graphics != null) { + break; + } + } + return self; } @@ -203,6 +256,10 @@ const InstanceDispatch = vk.InstanceWrapper(.{ .createDebugUtilsMessengerEXT = USE_DEBUG_LAYERS, .destroyDebugUtilsMessengerEXT = USE_DEBUG_LAYERS, .submitDebugUtilsMessageEXT = USE_DEBUG_LAYERS, + .enumeratePhysicalDevices = true, + .getPhysicalDeviceProperties = true, + .getPhysicalDeviceFeatures = true, + .getPhysicalDeviceQueueFamilyProperties = true, }); const DeviceDispatch = vk.DeviceWrapper(.{});