NYXGFX/src/rhi/vulkan/device.zig

99 lines
2.9 KiB
Zig
Raw Normal View History

2026-08-09 14:17:49 +01:00
//! ----------------------------------------------------
//! `🗲` 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;
}