mirror of
https://github.com/n00mkrad/flowframes.git
synced 2026-02-25 04:31:47 +01:00
Use Vulkan API directly to check Vk devices and compute queue count
This commit is contained in:
@@ -309,6 +309,12 @@
|
||||
<Reference Include="Tulpep.NotificationWindow, Version=1.1.38.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Tulpep.NotificationWindow.1.1.38\lib\net40\Tulpep.NotificationWindow.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Vulkan, Version=0.0.6850.37785, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\VulkanSharp.0.1.10\lib\net452\Vulkan.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Vulkan.Windows, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\VulkanSharp.0.1.10\lib\net452\Vulkan.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Win32Interop.Dwmapi, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Win32Interop.Dwmapi.1.0.1\lib\Win32Interop.Dwmapi.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -475,6 +481,7 @@
|
||||
<Compile Include="Os\StartupChecks.cs" />
|
||||
<Compile Include="Os\Updater.cs" />
|
||||
<Compile Include="Os\VapourSynthUtils.cs" />
|
||||
<Compile Include="Os\VulkanUtils.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="MiscUtils\FormatUtils.cs" />
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace Flowframes.Forms.Main
|
||||
|
||||
Program.mainForm = this;
|
||||
Logger.textbox = logBox;
|
||||
VulkanUtils.Init();
|
||||
NvApi.Init();
|
||||
InterpolationProgress.preview = previewPicturebox;
|
||||
RemovePreviewIfDisabled();
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace Flowframes.Os
|
||||
string ttaStr = Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
|
||||
rifeNcnn.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnn.PkgDir).Wrap()} & rife-ncnn-vulkan.exe " +
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} {frames} -m {mdl.ToLowerInvariant()} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {await NcnnUtils.GetNcnnThreads(Implementations.rifeNcnn)}";
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} {frames} -m {mdl.ToLowerInvariant()} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {NcnnUtils.GetNcnnThreads(Implementations.rifeNcnn)}";
|
||||
|
||||
Logger.Log("cmd.exe " + rifeNcnn.StartInfo.Arguments, true);
|
||||
|
||||
@@ -386,7 +386,7 @@ namespace Flowframes.Os
|
||||
Res = res,
|
||||
Uhd = InterpolateUtils.UseUhd(res),
|
||||
GpuId = gpuId,
|
||||
GpuThreads = await NcnnUtils.GetRifeNcnnGpuThreads(res, gpuId, Implementations.rifeNcnnVs),
|
||||
GpuThreads = NcnnUtils.GetRifeNcnnGpuThreads(res, gpuId, Implementations.rifeNcnnVs),
|
||||
SceneDetectSensitivity = Config.GetBool(Config.Key.scnDetect) ? Config.GetFloat(Config.Key.scnDetectValue) * 0.7f : 0f,
|
||||
Loop = Config.GetBool(Config.Key.enableLoop),
|
||||
MatchDuration = Config.GetBool(Config.Key.fixOutputDuration),
|
||||
@@ -580,7 +580,7 @@ namespace Flowframes.Os
|
||||
string ttaStr = ""; // Config.GetBool(Config.Key.rifeNcnnUseTta, false) ? "-x" : "";
|
||||
|
||||
ifrnetNcnn.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.ifrnetNcnn.PkgDir).Wrap()} & ifrnet-ncnn-vulkan.exe " +
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {await NcnnUtils.GetNcnnThreads(Implementations.ifrnetNcnn)}";
|
||||
$" -v -i {inPath.Wrap()} -o {outPath.Wrap()} -m {mdl} {ttaStr} {uhdStr} -g {Config.Get(Config.Key.ncnnGpus)} -f {NcnnUtils.GetNcnnPattern()} -j {NcnnUtils.GetNcnnThreads(Implementations.ifrnetNcnn)}";
|
||||
|
||||
Logger.Log("cmd.exe " + ifrnetNcnn.StartInfo.Arguments, true);
|
||||
|
||||
|
||||
66
Code/Os/VulkanUtils.cs
Normal file
66
Code/Os/VulkanUtils.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
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>();
|
||||
Instance vkInstance = new Instance(new InstanceCreateInfo());
|
||||
PhysicalDevice[] physicalDevices = vkInstance.EnumeratePhysicalDevices();
|
||||
|
||||
for (int idx = 0; idx < physicalDevices.Length; idx++)
|
||||
{
|
||||
PhysicalDevice device = physicalDevices[idx];
|
||||
|
||||
// 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;
|
||||
|
||||
string name = device.GetProperties().DeviceName;
|
||||
VkDevices.Add(new VkDevice { Id = idx, Name = name, ComputeQueueCount = compQueues });
|
||||
Logger.Log($"[VK] Found Vulkan device: {VkDevices.Last()}", true);
|
||||
}
|
||||
|
||||
// Clean up Vulkan resources
|
||||
vkInstance.Destroy();
|
||||
Logger.Log($"[VK] Vulkan device check took {sw.ElapsedMs} ms", true);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,51 +14,13 @@ namespace Flowframes.Utilities
|
||||
{
|
||||
class NcnnUtils
|
||||
{
|
||||
public static Dictionary<int, int> GpuIdsQueueCounts = null;
|
||||
|
||||
/// <summary> Get amount of GPU Compute Queues (VK) for each GPU </summary>
|
||||
public static async Task<Dictionary<int, int>> GetNcnnGpuComputeQueueCounts ()
|
||||
{
|
||||
if(GpuIdsQueueCounts != null)
|
||||
return GpuIdsQueueCounts;
|
||||
|
||||
Dictionary<int, int> queueCounts = new Dictionary<int, int>(); // int gpuId, int queueCount
|
||||
|
||||
Process rifeNcnn = OsUtils.NewProcess(true);
|
||||
rifeNcnn.StartInfo.Arguments = $"{OsUtils.GetCmdArg()} cd /D {Path.Combine(Paths.GetPkgPath(), Implementations.rifeNcnn.PkgDir)} & rife-ncnn-vulkan.exe -i dummydir -o dummydir";
|
||||
|
||||
string output = await Task.Run(() => OsUtils.GetProcStdOut(rifeNcnn, true));
|
||||
var queueLines = output.SplitIntoLines().Where(x => x.MatchesWildcard(@"*queueC=*queue*"));
|
||||
|
||||
foreach (var line in queueLines)
|
||||
{
|
||||
int gpuId = line.Split(' ')[0].GetInt();
|
||||
int queueCount = line.Split("queue")[1].Split('[')[1].Split(']')[0].GetInt();
|
||||
Logger.Log($"NCNN: Found GPU {gpuId} with compute queue count {queueCount}", true);
|
||||
queueCounts[gpuId] = queueCount;
|
||||
}
|
||||
|
||||
GpuIdsQueueCounts = queueCounts;
|
||||
return queueCounts;
|
||||
}
|
||||
|
||||
public static async Task<int> GetRifeNcnnGpuThreads(Size res, int gpuId, AI ai)
|
||||
public static int GetRifeNcnnGpuThreads(Size res, int gpuId, AI ai)
|
||||
{
|
||||
int threads = Config.GetInt(Config.Key.ncnnThreads);
|
||||
//if (res.Width * res.Height > 2560 * 1440) threads = 4;
|
||||
// if (res.Width * res.Height > 3840 * 2160) threads = 1;
|
||||
int maxThreads = VulkanUtils.GetMaxNcnnThreads(gpuId);
|
||||
|
||||
if (threads != 1)
|
||||
{
|
||||
var queueDict = await GetNcnnGpuComputeQueueCounts();
|
||||
int maxThreads = queueDict.ContainsKey(gpuId) ? queueDict[gpuId] : 1;
|
||||
threads = threads.Clamp(1, maxThreads); // To avoid exceeding the max queue count
|
||||
Logger.Log($"Using {threads}/{maxThreads} GPU threads.", true, false, ai.LogFilename);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log($"Using {threads} GPU thread.", true, false, ai.LogFilename);
|
||||
}
|
||||
threads = threads.Clamp(1, maxThreads); // To avoid exceeding the max queue count
|
||||
Logger.Log($"Using {threads}/{maxThreads} GPU compute threads.", true, false, ai.LogFilename);
|
||||
|
||||
return threads;
|
||||
}
|
||||
@@ -79,15 +41,11 @@ namespace Flowframes.Utilities
|
||||
return tilesizeStr;
|
||||
}
|
||||
|
||||
public static async Task<string> GetNcnnThreads(AI ai)
|
||||
public static string GetNcnnThreads(AI ai)
|
||||
{
|
||||
int gpusAmount = Config.Get(Config.Key.ncnnGpus).Split(',').Length;
|
||||
int threads = await GetRifeNcnnGpuThreads(new Size(), Config.Get(Config.Key.ncnnGpus).Split(',')[0].GetInt(), ai);
|
||||
string progThreadsStr = $"{threads}";
|
||||
|
||||
for (int i = 1; i < gpusAmount; i++)
|
||||
progThreadsStr += $",{threads}";
|
||||
|
||||
List<int> enabledGpuIds = Config.Get(Config.Key.ncnnGpus).Split(',').Select(s => s.GetInt()).ToList(); // Get GPU IDs
|
||||
List<int> gpuThreadCounts = enabledGpuIds.Select(g => GetRifeNcnnGpuThreads(new Size(), g, ai)).ToList(); // Get max thread count for each GPU
|
||||
string progThreadsStr = string.Join(",", gpuThreadCounts);
|
||||
return $"{(Interpolate.currentlyUsingAutoEnc ? 2 : 4)}:{progThreadsStr}:4"; // Read threads: 1 for singlethreaded, 2 for autoenc, 4 if order is irrelevant
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
|
||||
<package id="TabControl" version="2.1.2" targetFramework="net472" />
|
||||
<package id="Tulpep.NotificationWindow" version="1.1.38" targetFramework="net472" />
|
||||
<package id="VulkanSharp" version="0.1.10" targetFramework="net472" />
|
||||
<package id="Win32Interop.Dwmapi" version="1.0.1" targetFramework="net472" />
|
||||
<package id="Win32Interop.Gdi32" version="1.0.1" targetFramework="net472" />
|
||||
<package id="Win32Interop.Kernel32" version="1.0.1" targetFramework="net472" />
|
||||
|
||||
Reference in New Issue
Block a user