Files
archived-g-helper/app/Gpu/NvidiaGpuControl.cs
2023-05-07 18:10:18 +02:00

166 lines
4.3 KiB
C#

using NvAPIWrapper.GPU;
using NvAPIWrapper.Native;
using NvAPIWrapper.Native.GPU;
using NvAPIWrapper.Native.GPU.Structures;
using NvAPIWrapper.Native.Interfaces.GPU;
using System.Diagnostics;
using static NvAPIWrapper.Native.GPU.Structures.PerformanceStates20InfoV1;
namespace GHelper.Gpu;
public class NvidiaGpuControl : IGpuControl
{
public const int MaxCoreOffset = 250;
public const int MaxMemoryOffset = 250;
public const int MinCoreOffset = -250;
public const int MinMemoryOffset = -250;
private static PhysicalGPU? _internalGpu;
public NvidiaGpuControl()
{
Create();
}
public static void Create()
{
try
{
_internalGpu = GetInternalDiscreteGpu();
}
catch (Exception ex)
{
Debug.WriteLine(ex);
_internalGpu = null;
}
}
public static void RecreateWithDelay(int delay = 5)
{
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(delay));
Create();
});
}
public bool IsValid => _internalGpu != null;
public bool IsNvidia => IsValid;
public int? GetCurrentTemperature()
{
if (!IsValid)
return null;
PhysicalGPU internalGpu = _internalGpu!;
IThermalSensor? gpuSensor =
GPUApi.GetThermalSettings(internalGpu.Handle).Sensors
.FirstOrDefault(s => s.Target == ThermalSettingsTarget.GPU);
return gpuSensor?.CurrentTemperature;
}
public void Dispose()
{
}
public void GetClocks(out int core, out int memory, out string gpu)
{
PhysicalGPU internalGpu = _internalGpu!;
gpu = internalGpu.FullName;
Logger.WriteLine(internalGpu.FullName);
Logger.WriteLine(internalGpu.ArchitectInformation.ToString());
IPerformanceStates20Info states = GPUApi.GetPerformanceStates20(internalGpu.Handle);
//Logger.WriteLine("IPerformanceStates20Info type : " + states.GetType());
core = states.Clocks[PerformanceStateId.P0_3DPerformance][0].FrequencyDeltaInkHz.DeltaValue / 1000;
memory = states.Clocks[PerformanceStateId.P0_3DPerformance][1].FrequencyDeltaInkHz.DeltaValue / 1000;
Logger.WriteLine($"GET GPU Clock offsets : {core}, {memory}");
}
public int SetClocksFromConfig()
{
int core = Program.config.getConfig("gpu_core");
int memory = Program.config.getConfig("gpu_memory");
int status = SetClocks(core, memory);
return status;
}
public int SetClocks(int core, int memory)
{
if (core < MinCoreOffset || core > MaxCoreOffset) return 0;
if (memory < MinMemoryOffset || memory > MaxMemoryOffset) return 0;
PhysicalGPU internalGpu = _internalGpu!;
var coreClock = new PerformanceStates20ClockEntryV1(PublicClockDomain.Graphics, new PerformanceStates20ParameterDelta(core * 1000));
var memoryClock = new PerformanceStates20ClockEntryV1(PublicClockDomain.Memory, new PerformanceStates20ParameterDelta(memory * 1000));
PerformanceStates20ClockEntryV1[] clocks = { coreClock , memoryClock};
PerformanceStates20BaseVoltageEntryV1[] voltages = { };
PerformanceState20[] performanceStates = { new PerformanceState20(PerformanceStateId.P0_3DPerformance, clocks, voltages) };
var overclock = new PerformanceStates20InfoV1(performanceStates, 2, 0);
try
{
GPUApi.SetPerformanceStates20(internalGpu.Handle, overclock);
Logger.WriteLine($"SET GPU Clock offsets : {core}, {memory}");
}
catch (Exception ex)
{
Logger.WriteLine(ex.Message);
return -1;
}
return 1;
}
private static PhysicalGPU? GetInternalDiscreteGpu()
{
try
{
return PhysicalGPU
.GetPhysicalGPUs()
.FirstOrDefault(gpu => gpu.SystemType == SystemType.Laptop);
}
catch (Exception ex)
{
Logger.WriteLine(ex.ToString());
return null;
}
}
public int? GetGpuUse()
{
if (!IsValid)
return null;
PhysicalGPU internalGpu = _internalGpu!;
IUtilizationDomainInfo? gpuUsage = GPUApi.GetUsages(internalGpu.Handle).GPU;
return (int?)gpuUsage?.Percentage;
}
}