mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
Kill GPU apps for AMD, Optimus fix
This commit is contained in:
@@ -5,6 +5,32 @@ namespace AmdAdl2;
|
|||||||
|
|
||||||
#region Export Struct
|
#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)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct ADLSingleSensorData {
|
public struct ADLSingleSensorData {
|
||||||
public int Supported;
|
public int Supported;
|
||||||
@@ -481,5 +507,14 @@ public class Adl2 {
|
|||||||
|
|
||||||
[DllImport(Atiadlxx_FileName)]
|
[DllImport(Atiadlxx_FileName)]
|
||||||
public static extern int ADL2_Adapter_ASICFamilyType_Get(IntPtr adlContextHandle, int adapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids);
|
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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using System.Runtime.InteropServices;
|
|
||||||
using AmdAdl2;
|
using AmdAdl2;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace GHelper.Gpu;
|
namespace GHelper.Gpu;
|
||||||
|
|
||||||
// Reference: https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample-Managed/Program.cs
|
// 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 bool _isReady;
|
||||||
private IntPtr _adlContextHandle;
|
private IntPtr _adlContextHandle;
|
||||||
private readonly ADLAdapterInfo _internalDiscreteAdapter;
|
private readonly ADLAdapterInfo _internalDiscreteAdapter;
|
||||||
@@ -12,7 +14,8 @@ public class AmdGpuControl : IGpuControl {
|
|||||||
public bool IsNvidia => false;
|
public bool IsNvidia => false;
|
||||||
|
|
||||||
public string FullName => _internalDiscreteAdapter!.AdapterName;
|
public string FullName => _internalDiscreteAdapter!.AdapterName;
|
||||||
public AmdGpuControl() {
|
public AmdGpuControl()
|
||||||
|
{
|
||||||
if (!Adl2.Load())
|
if (!Adl2.Load())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -30,29 +33,30 @@ public class AmdGpuControl : IGpuControl {
|
|||||||
if (Adl2.NativeMethods.ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS)
|
if (Adl2.NativeMethods.ADL2_Adapter_AdapterInfo_Get(_adlContextHandle, AdapterBuffer, osAdapterInfoDataSize) != Adl2.ADL_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
osAdapterInfoData = (ADLAdapterInfoArray) Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!;
|
osAdapterInfoData = (ADLAdapterInfoArray)Marshal.PtrToStructure(AdapterBuffer, osAdapterInfoData.GetType())!;
|
||||||
|
|
||||||
const int amdVendorId = 1002;
|
const int amdVendorId = 1002;
|
||||||
|
|
||||||
// Determine which GPU is internal discrete AMD GPU
|
// Determine which GPU is internal discrete AMD GPU
|
||||||
ADLAdapterInfo internalDiscreteAdapter =
|
ADLAdapterInfo internalDiscreteAdapter =
|
||||||
osAdapterInfoData.ADLAdapterInfo
|
osAdapterInfoData.ADLAdapterInfo
|
||||||
.FirstOrDefault(adapter => {
|
.FirstOrDefault(adapter =>
|
||||||
|
{
|
||||||
if (adapter.Exist == 0 || adapter.Present == 0)
|
if (adapter.Exist == 0 || adapter.Present == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (adapter.VendorID != amdVendorId)
|
if (adapter.VendorID != amdVendorId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Adl2.NativeMethods.ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS)
|
if (Adl2.NativeMethods.ADL2_Adapter_ASICFamilyType_Get(_adlContextHandle, adapter.AdapterIndex, out ADLAsicFamilyType asicFamilyType, out int asicFamilyTypeValids) != Adl2.ADL_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
asicFamilyType = (ADLAsicFamilyType) ((int) asicFamilyType & asicFamilyTypeValids);
|
asicFamilyType = (ADLAsicFamilyType)((int)asicFamilyType & asicFamilyTypeValids);
|
||||||
|
|
||||||
// FIXME: is this correct for G14 2022?
|
// FIXME: is this correct for G14 2022?
|
||||||
return (asicFamilyType & ADLAsicFamilyType.Discrete) != 0;
|
return (asicFamilyType & ADLAsicFamilyType.Discrete) != 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (internalDiscreteAdapter.Exist == 0)
|
if (internalDiscreteAdapter.Exist == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -62,14 +66,15 @@ public class AmdGpuControl : IGpuControl {
|
|||||||
|
|
||||||
public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero;
|
public bool IsValid => _isReady && _adlContextHandle != IntPtr.Zero;
|
||||||
|
|
||||||
public int? GetCurrentTemperature() {
|
public int? GetCurrentTemperature()
|
||||||
|
{
|
||||||
if (!IsValid)
|
if (!IsValid)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int) ADLSensorType.PMLOG_TEMPERATURE_EDGE];
|
ADLSingleSensorData temperatureSensor = adlpmLogDataOutput.Sensors[(int)ADLSensorType.PMLOG_TEMPERATURE_EDGE];
|
||||||
if (temperatureSensor.Supported == 0)
|
if (temperatureSensor.Supported == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -79,8 +84,7 @@ public class AmdGpuControl : IGpuControl {
|
|||||||
|
|
||||||
public int? GetGpuUse()
|
public int? GetGpuUse()
|
||||||
{
|
{
|
||||||
if (!IsValid)
|
if (!IsValid) return null;
|
||||||
return null;
|
|
||||||
|
|
||||||
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
if (Adl2.NativeMethods.ADL2_New_QueryPMLogData_Get(_adlContextHandle, _internalDiscreteAdapter.AdapterIndex, out ADLPMLogDataOutput adlpmLogDataOutput) != Adl2.ADL_SUCCESS)
|
||||||
return null;
|
return null;
|
||||||
@@ -93,21 +97,93 @@ public class AmdGpuControl : IGpuControl {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void KillGPUApps()
|
||||||
|
{
|
||||||
|
|
||||||
private void ReleaseUnmanagedResources() {
|
if (!IsValid) return;
|
||||||
if (_adlContextHandle != IntPtr.Zero) {
|
|
||||||
|
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);
|
Adl2.NativeMethods.ADL2_Main_Control_Destroy(_adlContextHandle);
|
||||||
_adlContextHandle = IntPtr.Zero;
|
_adlContextHandle = IntPtr.Zero;
|
||||||
_isReady = false;
|
_isReady = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
ReleaseUnmanagedResources();
|
ReleaseUnmanagedResources();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AmdGpuControl() {
|
~AmdGpuControl()
|
||||||
|
{
|
||||||
ReleaseUnmanagedResources();
|
ReleaseUnmanagedResources();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,7 @@ public interface IGpuControl : IDisposable {
|
|||||||
public string FullName { get; }
|
public string FullName { get; }
|
||||||
int? GetCurrentTemperature();
|
int? GetCurrentTemperature();
|
||||||
int? GetGpuUse();
|
int? GetGpuUse();
|
||||||
|
|
||||||
|
void KillGPUApps();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
GpuControl.KillGPUApps();
|
||||||
nvControl.KillGPUApps();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -600,12 +600,16 @@ public class NativeMethods
|
|||||||
var devices = GetAllDevices().ToArray();
|
var devices = GetAllDevices().ToArray();
|
||||||
int count = 0, displayNum = -1;
|
int count = 0, displayNum = -1;
|
||||||
|
|
||||||
|
string internalName = AppConfig.getConfigString("internal_display");
|
||||||
|
|
||||||
foreach (var device in devices)
|
foreach (var device in devices)
|
||||||
{
|
{
|
||||||
if (device.outputTechnology == DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY.DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL ||
|
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;
|
displayNum = count;
|
||||||
|
AppConfig.setConfig("internal_display", device.monitorFriendlyDeviceName);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
//Logger.WriteLine(device.monitorFriendlyDeviceName + ":" + device.outputTechnology.ToString());
|
//Logger.WriteLine(device.monitorFriendlyDeviceName + ":" + device.outputTechnology.ToString());
|
||||||
|
|||||||
@@ -100,8 +100,6 @@ namespace GHelper
|
|||||||
SettingsToggle(action);
|
SettingsToggle(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Application.Run();
|
Application.Run();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Net;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using Tools;
|
|
||||||
|
|
||||||
namespace GHelper
|
namespace GHelper
|
||||||
{
|
{
|
||||||
@@ -368,7 +367,8 @@ namespace GHelper
|
|||||||
|
|
||||||
string url = null;
|
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"))
|
if (assets[i].GetProperty("browser_download_url").ToString().Contains(".zip"))
|
||||||
url = assets[i].GetProperty("browser_download_url").ToString();
|
url = assets[i].GetProperty("browser_download_url").ToString();
|
||||||
}
|
}
|
||||||
@@ -1301,7 +1301,7 @@ namespace GHelper
|
|||||||
public void AutoKeyboard()
|
public void AutoKeyboard()
|
||||||
{
|
{
|
||||||
InputDispatcher.SetBacklightAuto(true);
|
InputDispatcher.SetBacklightAuto(true);
|
||||||
if (AppConfig.ContainsModel("X16") || AppConfig.ContainsModel("X13")) InputDispatcher.TabletMode();
|
if (AppConfig.ContainsModel("X16") || AppConfig.ContainsModel("X13")) InputDispatcher.TabletMode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user