Files
flowframes/CodeLegacy/Os/VulkanUtils.cs

86 lines
3.1 KiB
C#
Raw Normal View History

using Flowframes.IO;
using Flowframes.MiscUtils;
using System;
using System.Collections.Generic;
using System.Linq;
using Vulkan;
namespace Flowframes.Os
{
public class VulkanUtils
{
public class VkDevice
{
public int Id { get; set; } = -1;
public string Name { get; set; } = "";
public int ComputeQueueCount { get; set; } = 0;
public override string ToString()
{
return $"[{Id}] {Name} [{ComputeQueueCount} Compute Queues]";
}
}
public static List<VkDevice> VkDevices { get; private set; } = null;
public static void Init()
{
var sw = new NmkdStopwatch();
VkDevices = new List<VkDevice>();
2024-01-23 23:16:54 +01:00
try
{
2024-01-23 23:16:54 +01:00
Instance vkInstance = new Instance(new InstanceCreateInfo());
PhysicalDevice[] physicalDevices = vkInstance.EnumeratePhysicalDevices();
2024-01-23 23:16:54 +01:00
for (int idx = 0; idx < physicalDevices.Length; idx++)
{
PhysicalDevice device = physicalDevices[idx];
2024-01-23 23:16:54 +01:00
// Get queue families and find the one with Compute support but no Graphics support. This is the one that gives us the correct thread count to use for NCNN etc.
QueueFamilyProperties[] queueFamilies = device.GetQueueFamilyProperties();
var validQueueFamilies = queueFamilies.Where(q => q.QueueFlags.HasFlag(QueueFlags.Compute) && !q.QueueFlags.HasFlag(QueueFlags.Graphics));
int compQueues = validQueueFamilies.Any() ? (int)validQueueFamilies.First().QueueCount : 0;
if(compQueues <= 0)
continue;
2024-01-23 23:16:54 +01:00
string name = device.GetProperties().DeviceName;
VkDevices.Add(new VkDevice { Id = idx, Name = name, ComputeQueueCount = compQueues });
2024-10-16 10:26:05 +02:00
Logger.Log($"[VK] Found Vulkan device: {VkDevices.Last()}", true);
2024-01-23 23:16:54 +01:00
}
2024-01-23 23:16:54 +01:00
// Clean up Vulkan resources
vkInstance.Destroy();
Logger.Log($"[VK] Vulkan device check completed after {sw.ElapsedMs} ms", true);
if (VkDevices.Count == 0)
return;
// Set the device that has the most compute queues as default GPU
var maxQueuesDevice = VkDevices.OrderByDescending(d => d.ComputeQueueCount).First();
Config.Set(Config.Key.ncnnGpus, $"{maxQueuesDevice.Id}");
2024-01-23 23:16:54 +01:00
}
catch(Exception ex)
{
Logger.Log($"Vulkan Error: {ex.Message}", true);
Logger.Log($"Vulkan initialization failed. NCNN implementations might not work, or run on the CPU.");
}
}
public static int GetMaxNcnnThreads(int deviceId)
{
var matchingDevices = VkDevices.Where(d => d.Id == deviceId);
if (matchingDevices.Any())
return matchingDevices.First().ComputeQueueCount;
return 0;
}
public static int GetMaxNcnnThreads(VkDevice device)
{
return device.ComputeQueueCount;
}
}
}