GPU (Linux / FreeBSD): add DRM detection support for old radeon driver

Ref: #1810
This commit is contained in:
Carter Li
2025-06-18 16:37:04 +08:00
parent 8559cc45eb
commit 6917f9479e
4 changed files with 80 additions and 31 deletions
+1
View File
@@ -54,6 +54,7 @@ void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device,
void ffGPUQueryAmdGpuName(uint16_t deviceId, uint8_t revisionId, FFGPUResult* gpu);
#if FF_HAVE_DRM
const char* ffDrmDetectRadeon(const FFGPUOptions* options, FFGPUResult* gpu, const char* renderPath);
const char* ffDrmDetectAmdgpu(const FFGPUOptions* options, FFGPUResult* gpu, const char* renderPath);
const char* ffDrmDetectI915(FFGPUResult* gpu, int fd);
const char* ffDrmDetectXe(FFGPUResult* gpu, int fd);
+2
View File
@@ -109,6 +109,8 @@ static const char* detectByDrm(const FFGPUOptions* options, FFlist* gpus)
ffDrmDetectI915(gpu, fd);
else if (ffStrStartsWith(driverName, "amdgpu"))
ffDrmDetectAmdgpu(options, gpu, dev->nodes[DRM_NODE_RENDER]);
else if (ffStrStartsWith(driverName, "radeon"))
ffDrmDetectRadeon(options, gpu, dev->nodes[DRM_NODE_RENDER]);
else if (ffStrStartsWith(driverName, "xe"))
ffDrmDetectXe(gpu, fd);
else if (ffStrStartsWith(driverName, "asahi"))
+38
View File
@@ -12,6 +12,44 @@
#include "intel_drm.h"
#include "asahi_drm.h"
#include <radeon_drm.h>
const char* ffDrmDetectRadeon(const FFGPUOptions* options, FFGPUResult* gpu, const char* renderPath)
{
FF_AUTO_CLOSE_FD int fd = open(renderPath, O_RDONLY);
if (fd < 0) return "Failed to open DRM render device";
struct drm_radeon_info info;
info.request = RADEON_INFO_ACTIVE_CU_COUNT;
if (ioctl(fd, DRM_IOCTL_RADEON_INFO, &info) >= 0)
gpu->coreCount = (int32_t) info.value;
if (options->temp)
{
info.request = RADEON_INFO_CURRENT_GPU_TEMP; // millidegrees C
if (ioctl(fd, DRM_IOCTL_RADEON_INFO, &info) >= 0)
gpu->temperature = (double) info.value / 1000.0;
}
info.request = RADEON_INFO_MAX_SCLK; // MHz
if (ioctl(fd, DRM_IOCTL_RADEON_INFO, &info) >= 0)
gpu->frequency = (uint32_t) (info.value / 1000u);
struct drm_radeon_gem_info gemInfo;
if (ioctl(fd, DRM_IOCTL_RADEON_GEM_INFO, &gemInfo) >= 0 && gemInfo.vram_visible > 0)
{
gpu->type = FF_GPU_TYPE_DISCRETE;
if (options->driverSpecific)
{
gpu->dedicated.total = gemInfo.vram_visible;
info.request = RADEON_INFO_VRAM_USAGE;
if (ioctl(fd, DRM_IOCTL_RADEON_INFO, &info) >= 0)
gpu->dedicated.used = info.value;
}
}
return NULL;
}
#ifdef FF_HAVE_DRM_AMDGPU
#include <amdgpu.h>
+39 -31
View File
@@ -105,14 +105,19 @@ FF_MAYBE_UNUSED static const char* drmFindRenderFromCard(const char* drmCardKey,
static const char* drmDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, const char* drmKey, FFstrbuf* buffer)
{
#if FF_HAVE_DRM_AMDGPU
const char* error = drmFindRenderFromCard(drmKey, buffer);
if (error) return error;
return ffDrmDetectAmdgpu(options, gpu, buffer->chars);
#else
FF_UNUSED(options, gpu, drmKey, buffer);
return "Fastfetch is not compiled with libdrm_amdgpu support";
if (ffStrbufEqualS(&gpu->driver, "radeon"))
return ffDrmDetectRadeon(options, gpu, buffer->chars);
else
{
#if FF_HAVE_DRM_AMDGPU
return ffDrmDetectAmdgpu(options, gpu, buffer->chars);
#else
FF_UNUSED(options, gpu, drmKey, buffer);
return "Fastfetch is not compiled with libdrm_amdgpu support";
#endif
}
}
static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
@@ -135,47 +140,50 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
ffStrbufAppendC(pciDir, '/');
const uint32_t hwmonLen = pciDir->length;
ffStrbufAppendS(pciDir, "in1_input"); // Northbridge voltage in millivolts (APUs only)
if (ffPathExists(pciDir->chars, FF_PATHTYPE_ANY))
gpu->type = FF_GPU_TYPE_INTEGRATED;
else
gpu->type = FF_GPU_TYPE_DISCRETE;
uint64_t value = 0;
if (options->temp)
{
ffStrbufSubstrBefore(pciDir, hwmonLen);
ffStrbufAppendS(pciDir, "temp1_input"); // The on die GPU temperature in millidegrees Celsius
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
gpu->temperature = (double) value / 1000;
}
if (options->driverSpecific)
if (ffStrbufEqualS(&gpu->driver, "amdgpu")) // Ancient radeon drivers don't have these files
{
ffStrbufSubstrBefore(pciDir, pciDirLen);
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_total");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
gpu->dedicated.total = value;
else
gpu->shared.total = value;
ffStrbufSubstrBefore(pciDir, hwmonLen);
ffStrbufAppendS(pciDir, "in1_input"); // Northbridge voltage in millivolts (APUs only)
if (ffPathExists(pciDir->chars, FF_PATHTYPE_ANY))
gpu->type = FF_GPU_TYPE_INTEGRATED;
else
gpu->type = FF_GPU_TYPE_DISCRETE;
ffStrbufSubstrBefore(pciDir, pciDir->length - (uint32_t) strlen("/mem_info_vis_vram_total"));
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_used");
if (options->driverSpecific)
{
ffStrbufSubstrBefore(pciDir, pciDirLen);
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_total");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
gpu->dedicated.used = value;
gpu->dedicated.total = value;
else
gpu->shared.used = value;
}
}
gpu->shared.total = value;
ffStrbufSubstrBefore(pciDir, pciDirLen);
ffStrbufAppendS(pciDir, "/gpu_busy_percent");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
gpu->coreUsage = (double) value;
ffStrbufSubstrBefore(pciDir, pciDir->length - (uint32_t) strlen("/mem_info_vis_vram_total"));
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_used");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
gpu->dedicated.used = value;
else
gpu->shared.used = value;
}
}
ffStrbufSubstrBefore(pciDir, pciDirLen);
ffStrbufAppendS(pciDir, "/gpu_busy_percent");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
gpu->coreUsage = (double) value;
}
}
}