99 lines
2.9 KiB
Zig
99 lines
2.9 KiB
Zig
|
|
//! ----------------------------------------------------
|
||
|
|
//! `🗲` 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;
|
||
|
|
}
|