Files
ADOFAIRenderer/Util/GPUUtil.cs
T

93 lines
3.6 KiB
C#

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using ADOFAIRenderer.Util.FFmpeg;
using MelonLoader;
namespace ADOFAIRenderer.Util
{
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum GPUVendor
{
Unknown, NVIDIA, AMD, Intel
}
public static class GPUUtil
{
private const string NvidiaPattern =
@"^NVIDIA GeForce [RG]TX [0-9]+(?> SUPER| Ti(?> SUPER)?)?(?> [0-9]+GB)?(?> Laptop GPU)?/PCIe/SSE2$";
private const string IntelPattern =
@"^Intel(?>\(R\))? (?>U?HD Graphics [0-9]+$|Arc\(TM\) [A-C][0-9]+ Graphics)$";
// ReSharper disable once InconsistentNaming
private const string AMDPattern =
@"^AMD Radeon RX [0-9]+(?> XT)?$";
private static readonly Dictionary<Codec, List<(GPUVendor, string)>> CodecMap = new()
{
[Codec.H264] = new List<(GPUVendor, string)> { (GPUVendor.NVIDIA, "h264_nvenc"), (GPUVendor.Intel, "h264_qsv"), (GPUVendor.AMD, "h264_amf"), (GPUVendor.Unknown, "libx264") },
[Codec.H265] = new List<(GPUVendor, string)> { (GPUVendor.NVIDIA, "hevc_nvenc"), (GPUVendor.Intel, "hevc_qsv"), (GPUVendor.AMD, "hevc_amf"), (GPUVendor.Unknown, "libx265") },
[Codec.VP9] = new List<(GPUVendor, string)> { (GPUVendor.NVIDIA, "vp9_nvenc"), (GPUVendor.Intel, "vp9_qsv"), (GPUVendor.Unknown, "libvpx-vp9") },
[Codec.AV1] = new List<(GPUVendor, string)> { (GPUVendor.NVIDIA, "av1_nvenc"), (GPUVendor.Intel, "av1_qsv"), (GPUVendor.AMD, "av1_amf"), (GPUVendor.Unknown, "libsvtav1"), (GPUVendor.Unknown, "libaom-av1") },
[Codec.VVC] = new List<(GPUVendor, string)> { (GPUVendor.Unknown, "libvvenc") }
};
private static GPUVendor _cachedVendor = GPUVendor.Unknown;
private static bool _hasCachedVendor = false;
private static GPUVendor GetActiveGPUVendor()
{
if (_hasCachedVendor) return _cachedVendor;
var gpuName = UnityEngine.SystemInfo.graphicsDeviceName;
Melon<RenderMod>.Logger.Msg($"Active GPU: {gpuName}");
_cachedVendor = GPUVendor.Unknown;
foreach (Match unused in Regex.Matches(gpuName, NvidiaPattern))
{
_cachedVendor = GPUVendor.NVIDIA;
break;
}
if (_cachedVendor == GPUVendor.Unknown)
{
foreach (Match unused in Regex.Matches(gpuName, IntelPattern))
{
_cachedVendor = GPUVendor.Intel;
break;
}
}
if (_cachedVendor == GPUVendor.Unknown)
{
foreach (Match unused in Regex.Matches(gpuName, AMDPattern))
{
_cachedVendor = GPUVendor.AMD;
break;
}
}
_hasCachedVendor = true;
return _cachedVendor;
}
public static List<string> GetPrioritizedEncoderCandidates(Codec codec)
{
if (!CodecMap.TryGetValue(codec, out var list)) return new List<string>();
var vendor = GetActiveGPUVendor();
var prioritized = new List<string>();
var others = new List<string>();
foreach (var item in list)
{
if (item.Item1 == vendor) prioritized.Add(item.Item2);
else others.Add(item.Item2);
}
prioritized.AddRange(others);
return prioritized;
}
}
}