//! ---------------------------------------------------- //! `🗲` Vulkan Device `🗲` //! ---------------------------------------------------- const gtl = @import("gtl"); const std = @import("std"); const vk = @import("vulkan"); const Instance = @import("instance.zig"); const Self = @This(); // // FIELDS // raw: *vk.VkDevice_T, /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn init( instance: *Instance, alloc: std.mem.Allocator, ) !Self { var physical: vk.VkPhysicalDevice = null; var count: u32 = 0; if (vk.vkEnumeratePhysicalDevices(instance.raw, &count, null) != vk.VK_SUCCESS) { return error.FailedToEnumeratePhysicalDevices; } if (count == 0) { return error.FailedToFindGPUWithVKSupport; } const devices = try alloc.alloc(vk.VkPhysicalDevice, count); defer alloc.free(devices); if (vk.vkEnumeratePhysicalDevices(instance.raw, &count, devices.ptr) != vk.VK_SUCCESS) { return error.FailedToEnumeratePhysicalDevices; } for (devices) |device| { if (try isDeviceSuitable(device)) { physical = device; break; } } var features: vk.VkPhysicalDeviceFeatures = .{}; var queue_create_info: vk.VkDeviceQueueCreateInfo = .{ .sType = vk.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, }; var create_info: vk.VkDeviceCreateInfo = .{ .sType = vk.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pQueueCreateInfos = &queue_create_info, .queueCreateInfoCount = 1, .pEnabledFeatures = &features, }; var device: vk.VkDevice = null; if (vk.vkCreateDevice(physical, &create_info, null, &device) != vk.VK_SUCCESS) { return error.FailedToCreateVulkanDevice; } return .{ .raw = device.?, }; } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn deinit(self: *Self) void { vk.vkDestroyDevice(self.raw, null); } /// ---------------------------------------------------- /// ---------------------------------------------------- fn isDeviceSuitable(device: vk.VkPhysicalDevice) !bool { var properties: vk.VkPhysicalDeviceProperties = .{}; vk.vkGetPhysicalDeviceProperties(device, &properties); var features: vk.VkPhysicalDeviceFeatures = .{}; vk.vkGetPhysicalDeviceFeatures(device, &features); if (gtl.log.print(.debug, "DEVICE", gtl.ansi.blue)) |v| { defer v.end(); v.write("Name: {s}", .{properties.deviceName}); v.write("Type: {s}", .{ switch (properties.deviceType) { vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU => "discrete", else => "idk", }, }); } return properties.deviceType == vk.VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU and features.geometryShader == 1; }