Skip to content

Commit

Permalink
3rdparty: add amd_ags
Browse files Browse the repository at this point in the history
  • Loading branch information
CarterLi committed Dec 21, 2023
1 parent c569554 commit dfb0eec
Show file tree
Hide file tree
Showing 6 changed files with 1,478 additions and 14 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,7 @@ elseif(WIN32)
src/detection/gpu/gpu_windows.c
src/detection/gpu/gpu_nvidia.c
src/detection/gpu/gpu_intel.c
src/detection/gpu/gpu_amd.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
Expand Down
1,355 changes: 1,355 additions & 0 deletions src/3rdparty/ags/amd_ags.h

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/3rdparty/ags/repo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK",
"license": "MIT (embeded in source)",
"version": "AGS v6.2.0",
"author": "Advanced Micro Devices, Inc"
}
67 changes: 67 additions & 0 deletions src/detection/gpu/gpu_amd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "gpu_driver_specific.h"

// Everything detected in this file is static.
// The real time monitoring requires ADLX, whose interface is much more complicated than AGS
// Whoever has AMD graphic cards interested in this may contribute
// * ADLX (AMD Device Library eXtra): https://github.com/GPUOpen-LibrariesAndSDKs/ADLX

#include "3rdparty/ags/amd_ags.h"
#include "common/library.h"
#include "util/mallocHelper.h"

const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName)
{
static bool inited = false;
static AGSGPUInfo gpuInfo;

if (!inited)
{
inited = true;
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsDeInitialize)

struct AGSContext* apiHandle;
if (ffagsInitialize(AGS_CURRENT_VERSION, NULL, &apiHandle, &gpuInfo) != AGS_SUCCESS)
return "loading ags library failed";

ffagsDeInitialize(apiHandle);
}

if (!gpuInfo.numDevices == 0)
return "loading ags library failed or no AMD gpus found";

AGSDeviceInfo* device = NULL;

for (int iDev = 0; iDev < gpuInfo.numDevices; iDev++)
{
if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID)
{
if (
cond->pciDeviceId.deviceId == (uint32_t) gpuInfo.devices[iDev].deviceId &&
cond->pciDeviceId.vendorId == (uint32_t) gpuInfo.devices[iDev].vendorId &&
cond->pciDeviceId.revId == (uint32_t) gpuInfo.devices[iDev].revisionId)
{
device = &gpuInfo.devices[iDev];
break;
}
}
}

if (!device)
return "Device not found";

if (result.coreCount)
*result.coreCount = (uint32_t) device->numCUs;

if (result.memory)
{
result.memory->total = device->localMemoryInBytes;
result.memory->used = FF_GPU_VMEM_SIZE_UNSET;
}

if (result.frequency)
*result.frequency = device->coreClock / 1000.; // Maximum frequency

return NULL;
}
1 change: 1 addition & 0 deletions src/detection/gpu/gpu_driver_specific.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ typedef struct FFGpuDriverResult

const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
62 changes: 48 additions & 14 deletions src/detection/gpu/gpu_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,41 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
return ffStrbufEqual(&gpu->name, name);
}

static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&ffDetectNvidiaGpuInfo)* pDetectFn, const char** pDllName)
{
if (vendor == FF_GPU_VENDOR_NAME_NVIDIA)
{
*pDetectFn = ffDetectNvidiaGpuInfo;
*pDllName = "nvml.dll";
}
else if (vendor == FF_GPU_VENDOR_NAME_INTEL)
{
*pDetectFn = ffDetectIntelGpuInfo;
#ifdef _WIN64
*pDllName = "ControlLib.dll";
#else
*pDllName = "ControlLib32.dll";
#endif
}
else if (vendor == FF_GPU_VENDOR_NAME_AMD)
{
*pDetectFn = ffDetectAmdGpuInfo;
#ifdef _WIN64
*pDllName = "amd_ags_x64.dll";
#else
*pDllName = "amd_ags_x86.dll";
#endif
}
else
{
*pDetectFn = NULL;
*pDllName = NULL;
return false;
}

return true;
}

const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
{
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) };
Expand Down Expand Up @@ -55,12 +90,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);

if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
if (ffStrbufContainS(&gpu->vendor, "Intel"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
else if (ffStrbufContainS(&gpu->vendor, "NVIDIA"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
else if (ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);

wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, strlen("00000000-0000-0000-0000-000000000000}"));
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
Expand Down Expand Up @@ -89,15 +124,17 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
}
}

if ((gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA || gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL) &&
(options->temp || options->driverSpecific))
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
const char* dllName;

if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
{
uint32_t vendorId, deviceId, subSystemId, revId;
// See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html
// displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1"
if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId) == 4)
{
(gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA ? ffDetectNvidiaGpuInfo : ffDetectIntelGpuInfo)(
detectFn(
&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID | FF_GPU_DRIVER_CONDITION_TYPE_LUID,
.pciDeviceId = {
Expand All @@ -107,18 +144,15 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
.revId = revId,
},
.luid = gpu->deviceId,
}, (FFGpuDriverResult) {
},
(FFGpuDriverResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
}, gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA ? "nvml.dll" :
#ifdef _WIN64
"ControlLib.dll"
#else
"ControlLib32.dll"
#endif
},
dllName
);
}
}
Expand Down

0 comments on commit dfb0eec

Please sign in to comment.