Kill GPU apps for AMD, Optimus fix

This commit is contained in:
Serge
2023-06-04 01:25:39 +02:00
parent acb2efdd00
commit d5b098335b
7 changed files with 146 additions and 31 deletions

View File

@@ -5,6 +5,32 @@ namespace AmdAdl2;
#region Export Struct
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADLSGApplicationInfo
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strFilePath;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string strVersion;
public long timeStamp;
public uint iProfileExists;
public uint iGPUAffinity;
public ADLBdf GPUBdf;
}
[StructLayout(LayoutKind.Sequential)]
public struct ADLBdf
{
public int iBus;
public int iDevice;
public int iFunction;
}
[StructLayout(LayoutKind.Sequential)]
public struct ADLSingleSensorData {
public int Supported;
@@ -481,5 +507,14 @@ public class Adl2 {
[DllImport(Atiadlxx_FileName)]
public static extern int ADL2_Adapter_ASICFamilyType_Get(IntPtr adlContextHandle, int adapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids);
[DllImport(Atiadlxx_FileName)]
public static extern int ADL2_SwitchableGraphics_Applications_Get(
IntPtr context,
int iListType,
out int lpNumApps,
out IntPtr lppAppList);
}
}

View File

@@ -1,10 +1,12 @@
using System.Runtime.InteropServices;
using AmdAdl2;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace GHelper.Gpu;
// Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs
public class AmdGpuControl : IGpuControl {
public class AmdGpuControl : IGpuControl
{
private bool _isReady;
private IntPtr _adlContextHandle;
private readonly ADLAdapterInfo _internalDiscreteAdapter;
@@ -12,7 +14,8 @@ public class AmdGpuControl : IGpuControl {
public bool IsNvidia => false;
public string FullName => _internalDiscreteAdapter!.AdapterName;
public AmdGpuControl() {
public AmdGpuControl()
{
if (!Adl2.Load())
return;
@@ -37,7 +40,8 @@ public class AmdGpuControl : IGpuControl {
// Determine which GPU is internal discrete AMD GPU
ADLAdapterInfo internalDiscreteAdapter =
osAdapterInfoData.ADLAdapterInfo
.FirstOrDefault(adapter => {
.FirstOrDefault(adapter =>
{
if (adapter.Exist == 0 || adapter.Present == 0)
return false;
@@ -62,7 +66,8 @@ public class AmdGpuControl : IGpuControl {
public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero;
public int? GetCurrentTemperature() {
public int? GetCurrentTemperature()
{
if (!IsValid)
return null;
@@ -79,8 +84,7 @@ public class AmdGpuControl : IGpuControl {
public int? GetGpuUse()
{
if (!IsValid)
return null;
if (!IsValid) return null;
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
return null;
@@ -93,21 +97,93 @@ public class AmdGpuControl : IGpuControl {
}
public void KillGPUApps()
{
private void ReleaseUnmanagedResources() {
if (_adlContextHandle != IntPtr.Zero) {
if (!IsValid) return;
IntPtr appInfoPtr = IntPtr.Zero;
int appCount = 0;
try
{
// Get switchable graphics applications information
var result = Adl2.NativeMethods.ADL2_SwitchableGraphics_Applications_Get(_adlContextHandle, 2, out appCount, out appInfoPtr);
if (result != 0)
{
throw new Exception("Failed to get switchable graphics applications. Error code: " + result);
}
// Convert the application data pointers to an array of structs
var appInfoArray = new ADLSGApplicationInfo[appCount];
IntPtr currentPtr = appInfoPtr;
for (int i = 0; i < appCount; i++)
{
appInfoArray[i] = Marshal.PtrToStructure<ADLSGApplicationInfo>(currentPtr);
currentPtr = IntPtr.Add(currentPtr, Marshal.SizeOf<ADLSGApplicationInfo>());
}
var appNames = new List<string>();
for (int i = 0; i < appCount; i++)
{
if (appInfoArray[i].iGPUAffinity == 1)
{
Logger.WriteLine(appInfoArray[i].strFileName + ":" + appInfoArray[i].iGPUAffinity + "(" + appInfoArray[i].timeStamp + ")");
appNames.Add(Path.GetFileNameWithoutExtension(appInfoArray[i].strFileName));
}
}
foreach (string kill in appNames)
foreach (var process in Process.GetProcessesByName(kill))
{
try
{
process.Kill();
Logger.WriteLine($"Stopped: {process.ProcessName}");
}
catch (Exception ex)
{
Logger.WriteLine($"Failed to stop: {process.ProcessName} {ex.Message}");
}
}
} catch (Exception ex)
{
Logger.WriteLine(ex.Message);
}
finally
{
// Clean up resources
if (appInfoPtr != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(appInfoPtr);
}
}
}
private void ReleaseUnmanagedResources()
{
if (_adlContextHandle != IntPtr.Zero)
{
Adl2.NativeMethods.ADL2_Main_Control_Destroy(_adlContextHandle);
_adlContextHandle = IntPtr.Zero;
_isReady = false;
}
}
public void Dispose() {
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
~AmdGpuControl() {
~AmdGpuControl()
{
ReleaseUnmanagedResources();
}
}

View File

@@ -6,4 +6,7 @@ public interface IGpuControl : IDisposable {
public string FullName { get; }
int? GetCurrentTemperature();
int? GetGpuUse();
void KillGPUApps();
}

View File

@@ -210,10 +210,9 @@ public static class HardwareControl
}
}
if (AppConfig.isConfig("kill_gpu_apps") && GpuControl is not null && GpuControl.IsNvidia)
if (AppConfig.isConfig("kill_gpu_apps") && GpuControl is not null)
{
NvidiaGpuControl nvControl = (NvidiaGpuControl)GpuControl;
nvControl.KillGPUApps();
GpuControl.KillGPUApps();
}
}
}

View File

@@ -600,12 +600,16 @@ public class NativeMethods
var devices = GetAllDevices().ToArray();
int count = 0, displayNum = -1;
string internalName = AppConfig.getConfigString("internal_display");
foreach (var device in devices)
{
if (device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL ||
device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED)
device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED ||
device.monitorFriendlyDeviceName == internalName)
{
displayNum = count;
AppConfig.setConfig("internal_display", device.monitorFriendlyDeviceName);
}
count++;
//Logger.WriteLine(device.monitorFriendlyDeviceName + ":" + device.outputTechnology.ToString());

View File

@@ -100,8 +100,6 @@ namespace GHelper
SettingsToggle(action);
}
Application.Run();
}

View File

@@ -6,7 +6,6 @@ using System.Net;
using System.Reflection;
using System.Text.Json;
using System.Timers;
using Tools;
namespace GHelper
{
@@ -368,7 +367,8 @@ namespace GHelper
string url = null;
for (int i = 0; i < assets.GetArrayLength(); i++) {
for (int i = 0; i < assets.GetArrayLength(); i++)
{
if (assets[i].GetProperty("browser_download_url").ToString().Contains(".zip"))
url = assets[i].GetProperty("browser_download_url").ToString();
}