feature: Add GpuDriverVersion to GPU info logging

- The Vulkan backend now reports the driver name and version using VK_KHR_driver_properties when available, with fallbacks for raw Vulkan driverVersion parsing. Intel Windows drivers also get the full package-style version from the driver UUID when exposed by the driver.
  OpenGL now carries its existing OpenGL version string through HardwareInfo.GpuDriverVersion.
This commit is contained in:
Babib3l
2026-08-24 13:58:00 -05:00
committed by KeatonTheBot
parent 06f049b874
commit db4799e7ab
4 changed files with 69 additions and 5 deletions
+3 -1
View File
@@ -5,12 +5,14 @@ namespace Ryujinx.Graphics.GAL
public string GpuVendor { get; }
public string GpuModel { get; }
public string GpuDriver { get; }
public string GpuDriverVersion { get; }
public HardwareInfo(string gpuVendor, string gpuModel, string gpuDriver)
public HardwareInfo(string gpuVendor, string gpuModel, string gpuDriver, string gpuDriverVersion)
{
GpuVendor = gpuVendor;
GpuModel = gpuModel;
GpuDriver = gpuDriver;
GpuDriverVersion = gpuDriverVersion;
}
}
}
@@ -133,7 +133,7 @@ namespace Ryujinx.Graphics.OpenGL
public HardwareInfo GetHardwareInfo()
{
return new HardwareInfo(GpuVendor, GpuRenderer, GpuVendor); // OpenGL does not provide a driver name, vendor name is closest analogue.
return new HardwareInfo(GpuVendor, GpuRenderer, GpuVendor, GpuVersion); // OpenGL does not provide a driver name, vendor name is closest analogue.
}
public PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)
+3
View File
@@ -36,6 +36,9 @@ namespace Ryujinx.Graphics.Vulkan
[GeneratedRegex(@"Adreno (\(TM\) )?(8[0-9]\d)")]
public static partial Regex Adreno8xxRegex();
[GeneratedRegex(@"^\d+\.\d+\.\d+\.\d+$")]
internal static partial Regex IntelWindowsDriverVersionRegex();
public static Vendor FromId(uint id)
{
return id switch
+62 -3
View File
@@ -115,6 +115,7 @@ namespace Ryujinx.Graphics.Vulkan
public string GpuDriver { get; private set; }
public string GpuRenderer { get; private set; }
public string GpuVersion { get; private set; }
public string GpuDriverVersion { get; private set; }
public bool PreferThreading => true;
@@ -185,6 +186,14 @@ namespace Ryujinx.Graphics.Vulkan
SType = StructureType.PhysicalDeviceProperties2,
};
PhysicalDeviceIDProperties propertiesId = new()
{
SType = StructureType.PhysicalDeviceIDProperties,
PNext = properties2.PNext,
};
properties2.PNext = &propertiesId;
PhysicalDeviceSubgroupProperties propertiesSubgroup = new()
{
SType = StructureType.PhysicalDeviceSubgroupProperties,
@@ -374,13 +383,17 @@ namespace Ryujinx.Graphics.Vulkan
GpuVendor = VendorUtils.GetNameFromId(properties.VendorID);
GpuDriver = hasDriverProperties && !OperatingSystem.IsMacOS() ?
VendorUtils.GetFriendlyDriverName(driverProperties.DriverID) : GpuVendor; // Fallback to vendor name if driver is unavailable or on MacOS where vendor is preferred.
GpuDriverVersion = TryGetIntelWindowsDriverVersionFromUuid(ref propertiesId, out string intelDriverVersion) ? intelDriverVersion :
hasDriverProperties ?
GetDriverInfo(ref driverProperties) ?? ParseDriverVersion(ref properties) :
ParseDriverVersion(ref properties);
fixed (byte* deviceName = properties.DeviceName)
{
GpuRenderer = Marshal.PtrToStringAnsi((nint)deviceName);
}
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}";
IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer);
@@ -846,7 +859,7 @@ namespace Ryujinx.Graphics.Vulkan
public HardwareInfo GetHardwareInfo()
{
return new HardwareInfo(GpuVendor, GpuRenderer, GpuDriver);
return new HardwareInfo(GpuVendor, GpuRenderer, GpuDriver, GpuDriverVersion);
}
/// <summary>
@@ -896,9 +909,55 @@ namespace Ryujinx.Graphics.Vulkan
return $"{(driverVersionRaw >> 22) & 0x3FF}.{(driverVersionRaw >> 14) & 0xFF}.{(driverVersionRaw >> 6) & 0xFF}.{driverVersionRaw & 0x3F}";
}
// Intel's Windows Vulkan driver exposes the 101.xxxx build portion in a custom layout.
if (properties.VendorID == 0x8086 && OperatingSystem.IsWindows())
{
return $"{driverVersionRaw >> 14}.{driverVersionRaw & 0x3FFF}";
}
return ParseStandardVulkanVersion(driverVersionRaw);
}
private static unsafe string GetDriverInfo(ref PhysicalDeviceDriverPropertiesKHR driverProperties)
{
fixed (byte* driverInfo = driverProperties.DriverInfo)
{
string driverInfoString = Marshal.PtrToStringAnsi((nint)driverInfo);
return string.IsNullOrWhiteSpace(driverInfoString) ? null : driverInfoString;
}
}
private static unsafe bool TryGetIntelWindowsDriverVersionFromUuid(ref PhysicalDeviceIDProperties propertiesId, out string driverVersion)
{
driverVersion = null;
if (!OperatingSystem.IsWindows())
{
return false;
}
fixed (byte* driverUuid = propertiesId.DriverUuid)
{
string driverUuidString = Marshal.PtrToStringAnsi((nint)driverUuid, (int)Vk.UuidSize);
int terminatorIndex = driverUuidString.IndexOf('\0');
if (terminatorIndex >= 0)
{
driverUuidString = driverUuidString[..terminatorIndex];
}
if (VendorUtils.IntelWindowsDriverVersionRegex().IsMatch(driverUuidString))
{
driverVersion = driverUuidString;
return true;
}
}
return false;
}
internal PrimitiveTopology TopologyRemap(PrimitiveTopology topology)
{
return topology switch
@@ -924,7 +983,7 @@ namespace Ryujinx.Graphics.Vulkan
private void PrintGpuInformation()
{
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion}, Driver: {GpuDriver} {GpuDriverVersion})");
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
}