diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 60d9e1ba6..ee5048503 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -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); diff --git a/src/detection/gpu/gpu_bsd.c b/src/detection/gpu/gpu_bsd.c index 5057fe05b..d2e000fd7 100644 --- a/src/detection/gpu/gpu_bsd.c +++ b/src/detection/gpu/gpu_bsd.c @@ -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")) diff --git a/src/detection/gpu/gpu_drm.c b/src/detection/gpu/gpu_drm.c index 35c10737f..93d9e87f0 100644 --- a/src/detection/gpu/gpu_drm.c +++ b/src/detection/gpu/gpu_drm.c @@ -12,6 +12,44 @@ #include "intel_drm.h" #include "asahi_drm.h" +#include + +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 diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 48ffe46a3..efa260fae 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -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; + } } }