SHA256
153 lines
5.8 KiB
C#
153 lines
5.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using ADOFAIRenderer.Util.FFmpeg;
|
|
using MelonLoader;
|
|
using UnityEngine;
|
|
|
|
namespace ADOFAIRenderer.Util
|
|
{
|
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
public enum GPUVendor
|
|
{
|
|
Unknown, NVIDIA, AMD, Intel, Apple
|
|
}
|
|
|
|
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 GPUVendor _cachedVendor = GPUVendor.Unknown;
|
|
private static bool _hasCachedVendor;
|
|
|
|
private static GPUVendor GetActiveGPUVendor()
|
|
{
|
|
if (_hasCachedVendor) return _cachedVendor;
|
|
|
|
var gpuName = 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;
|
|
}
|
|
}
|
|
|
|
if (_cachedVendor == GPUVendor.Unknown && Application.platform == RuntimePlatform.OSXPlayer)
|
|
{
|
|
_cachedVendor = GPUVendor.Apple;
|
|
}
|
|
|
|
_hasCachedVendor = true;
|
|
return _cachedVendor;
|
|
}
|
|
|
|
private static double? _cachedNvidiaVersion;
|
|
private static bool _hasCachedNvidiaVersion;
|
|
|
|
public static double? GetNvidiaDriverVersion()
|
|
{
|
|
if (_hasCachedNvidiaVersion) return _cachedNvidiaVersion;
|
|
|
|
_hasCachedNvidiaVersion = true;
|
|
_cachedNvidiaVersion = null;
|
|
|
|
if (GetActiveGPUVendor() != GPUVendor.NVIDIA) return null;
|
|
|
|
// 1. Try parsing from UnityEngine.SystemInfo.graphicsDeviceVersion
|
|
var deviceVersion = SystemInfo.graphicsDeviceVersion;
|
|
if (!string.IsNullOrEmpty(deviceVersion))
|
|
{
|
|
var match = Regex.Match(deviceVersion, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
|
if (match.Success)
|
|
{
|
|
if (int.TryParse(match.Groups[3].Value, out var sub) && int.TryParse(match.Groups[4].Value, out int build))
|
|
{
|
|
var nvidiaVerInt = sub % 10 * 10000 + build;
|
|
_cachedNvidiaVersion = nvidiaVerInt / 100.0;
|
|
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from SystemInfo: {_cachedNvidiaVersion:F2}");
|
|
return _cachedNvidiaVersion;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. Fallback to Windows Registry (only on Windows NT platforms via RegistryUtil)
|
|
if (System.Environment.OSVersion.Platform != System.PlatformID.Win32NT) return null;
|
|
const string classKey = @"SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}";
|
|
var subkeys = RegistryUtil.GetHKLMSubKeyNames(classKey);
|
|
if (subkeys == null) return null;
|
|
|
|
foreach (var subkey in subkeys)
|
|
{
|
|
var subkeyPath = classKey + "\\" + subkey;
|
|
var provider = RegistryUtil.GetHKLMValue(subkeyPath, "ProviderName");
|
|
if (provider == null || !provider.Contains("NVIDIA")) continue;
|
|
|
|
var driverVersionStr = RegistryUtil.GetHKLMValue(subkeyPath, "DriverVersion");
|
|
if (string.IsNullOrEmpty(driverVersionStr)) continue;
|
|
|
|
var regMatch = Regex.Match(driverVersionStr, @"\b(\d+)\.(\d+)\.(\d+)\.(\d+)\b");
|
|
if (!regMatch.Success) continue;
|
|
if (!int.TryParse(regMatch.Groups[3].Value, out var sub) ||
|
|
!int.TryParse(regMatch.Groups[4].Value, out var build)) continue;
|
|
|
|
var nvidiaVerInt = sub % 10 * 10000 + build;
|
|
_cachedNvidiaVersion = nvidiaVerInt / 100f;
|
|
Melon<RenderMod>.Logger.Msg($"Parsed NVIDIA Driver Version from Registry (RegistryUtil): {_cachedNvidiaVersion:F2}");
|
|
return _cachedNvidiaVersion;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static List<VideoEncoder> GetPrioritizedEncoders(Codec codec, bool forceSoftware = false)
|
|
{
|
|
var encoders = VideoEncoder.All.Where(e => e.Codec == codec).ToList();
|
|
if (forceSoftware)
|
|
{
|
|
return encoders.Where(e => !e.IsHardware).ToList();
|
|
}
|
|
|
|
var vendor = GetActiveGPUVendor();
|
|
var prioritized = new List<VideoEncoder>();
|
|
var others = new List<VideoEncoder>();
|
|
|
|
foreach (var item in encoders)
|
|
{
|
|
if (item.Vendor == vendor) prioritized.Add(item);
|
|
else others.Add(item);
|
|
}
|
|
|
|
prioritized.AddRange(others);
|
|
return prioritized;
|
|
}
|
|
}
|
|
} |