Skip to content

Commit b8e25bd

Browse files
committed
GPU: support embedding amdgpu.ids into fastfetch
1 parent 379c39d commit b8e25bd

File tree

8 files changed

+116
-28
lines changed

8 files changed

+116
-28
lines changed

CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by gith
9494
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
9595
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
9696
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
97+
option(ENABLE_EMBEDDED_AMDGPUIDS "Embed amdgpu.ids into fastfetch, requires `python`" OFF)
9798

9899
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
99100
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
@@ -289,6 +290,26 @@ if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids
289290
endif()
290291
endif()
291292

293+
if(ENABLE_EMBEDDED_AMDGPUIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc")
294+
if(Python_FOUND)
295+
if(NOT EXISTS "${PROJECT_BINARY_DIR}/amdgpu.ids")
296+
message(STATUS "'${PROJECT_BINARY_DIR}/amdgpu.ids' is missing, downloading...")
297+
file(DOWNLOAD "https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids" "${PROJECT_BINARY_DIR}/amdgpu.ids")
298+
endif()
299+
message(STATUS "Generating 'fastfetch_amdgpuids.c.inc'")
300+
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-amdgpuids.py" "${PROJECT_BINARY_DIR}/amdgpu.ids"
301+
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc"
302+
RESULT_VARIABLE PYTHON_AMDGPUIDS_RETCODE)
303+
if(NOT PYTHON_AMDGPUIDS_RETCODE EQUAL 0)
304+
file(REMOVE "${PROJECT_BINARY_DIR}/fastfetch_amdgpuids.c.inc")
305+
message(FATAL_ERROR "Failed to generate 'fastfetch_amdgpuids.c.inc'")
306+
endif()
307+
else()
308+
message(WARNING "Python3 is not found, 'fastfetch_amdgpuids.c.inc' will not be generated")
309+
set(ENABLE_EMBEDDED_AMDGPUIDS OFF)
310+
endif()
311+
endif()
312+
292313
if(Python_FOUND)
293314
message(STATUS "Generating 'fastfetch.1'")
294315
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py"
@@ -1517,6 +1538,9 @@ endif()
15171538
if(ENABLE_EMBEDDED_PCIIDS)
15181539
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_PCIIDS=1)
15191540
endif()
1541+
if(ENABLE_EMBEDDED_AMDGPUIDS)
1542+
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_AMDGPUIDS=1)
1543+
endif()
15201544

15211545
if(LINUX)
15221546
target_link_libraries(libfastfetch

scripts/gen-amdgpuids.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python3
2+
3+
import sys
4+
5+
def main(amdgpu_ids_path: str):
6+
with open(amdgpu_ids_path, 'r') as f:
7+
full_text = f.read()
8+
9+
products = []
10+
for line in full_text.split('\n'):
11+
if not line or line[0] == '#' or not ',\t' in line:
12+
continue
13+
device, revision, name = line.split(',\t', maxsplit=2)
14+
products.append((device, revision, name))
15+
16+
code = """\
17+
// SPDX-License-Identifier: MIT
18+
// https://opensource.org/license/mit
19+
// Generated from https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids
20+
21+
#include <stdint.h>
22+
#include <stddef.h>
23+
24+
typedef struct FFArmGpuProduct
25+
{
26+
const uint32_t id; // device << 8 | revision
27+
const char* name;
28+
} FFArmGpuProduct;
29+
30+
const FFArmGpuProduct ffAmdGpuProducts[] = {
31+
"""
32+
33+
for device, revision, name in products:
34+
code += f" {{ 0x{device} << 8 | 0x{revision}, \"{name.replace('"', '\\"')}\" }},\n"
35+
36+
code += "};\n"
37+
38+
print(code)
39+
40+
if __name__ == '__main__':
41+
len(sys.argv) == 2 or sys.exit('Usage: gen-amdgpuids.py </path/to/amdgpu.ids>')
42+
43+
main(sys.argv[1])

src/detection/gpu/gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ const char* ffGPUGetVendorString(unsigned vendorId);
5050

5151
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
5252
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
53+
void ffGPUQueryAmdGpuName(uint16_t deviceId, uint8_t revisionId, FFGPUResult* gpu);
5354
#endif

src/detection/gpu/gpu_bsd.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "gpu_driver_specific.h"
22

33
#include "common/io/io.h"
4-
#include "common/properties.h"
54

65
#include <sys/pciio.h>
76
#include <fcntl.h>
@@ -76,11 +75,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
7675
if (gpu->name.length == 0)
7776
{
7877
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
79-
{
80-
char query[32];
81-
snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) pc->pc_device, (unsigned) pc->pc_revid);
82-
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
83-
}
78+
ffGPUQueryAmdGpuName(pc->pc_device, pc->pc_revid, gpu);
8479
if (gpu->name.length == 0)
8580
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
8681
}

src/detection/gpu/gpu_general.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#ifdef FF_HAVE_PCIACCESS
44

5-
#include "common/properties.h"
65
#include "common/io/io.h"
76
#include "common/library.h"
87

@@ -43,11 +42,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
4342
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
4443

4544
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
46-
{
47-
char query[32];
48-
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) dev->device_id, (unsigned) dev->revision);
49-
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
50-
}
45+
ffGPUQueryAmdGpuName(dev->device_id, dev->revision, gpu);
5146

5247
if (gpu->name.length == 0)
5348
{

src/detection/gpu/gpu_linux.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include "detection/gpu/gpu_driver_specific.h"
55
#include "common/io/io.h"
66
#include "common/library.h"
7-
#include "common/properties.h"
87
#include "util/stringUtils.h"
98
#include "util/mallocHelper.h"
109

@@ -491,15 +490,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
491490
char* pend;
492491
uint64_t revision = strtoul(buffer->chars, &pend, 16);
493492
if (pend != buffer->chars)
494-
{
495-
char query[32];
496-
snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
497-
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
498-
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
499-
#else
500-
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
501-
#endif
502-
}
493+
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
503494
}
504495
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
505496
}

src/detection/gpu/gpu_pci.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "gpu.h"
22
#include "common/io/io.h"
3+
#include "common/properties.h"
34

45
#include <stdlib.h>
56
#ifdef __FreeBSD__
@@ -16,6 +17,9 @@
1617
#if FF_HAVE_EMBEDDED_PCIIDS
1718
#include "fastfetch_pciids.c.inc"
1819
#endif
20+
#if FF_HAVE_EMBEDDED_AMDGPUIDS
21+
#include "fastfetch_amdgpuids.c.inc"
22+
#endif
1923

2024
#define FF_STR_INDIR(x) #x
2125
#define FF_STR(x) FF_STR_INDIR(x)
@@ -191,3 +195,43 @@ void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device,
191195
#endif
192196
return parsePciIdsFile(loadPciIds(), subclass, vendor, device, gpu);
193197
}
198+
199+
#if FF_HAVE_EMBEDDED_AMDGPUIDS
200+
static inline int amdGpuCmp(const uint32_t* key, const FFArmGpuProduct* element)
201+
{
202+
// Maximum value of *key is 0x00FFFFFF. `(int) *key` should never overflow
203+
return (int) *key - (int) element->id;
204+
}
205+
206+
static bool loadAmdGpuIdsInc(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu)
207+
{
208+
uint32_t key = (deviceId << 8u) | revision;
209+
FFArmGpuProduct* product = bsearch(&key, ffAmdGpuProducts, ARRAY_SIZE(ffAmdGpuProducts), sizeof(*ffAmdGpuProducts), (void*) amdGpuCmp);
210+
if (product)
211+
{
212+
ffStrbufSetS(&gpu->name, product->name);
213+
return true;
214+
}
215+
return false;
216+
}
217+
#endif
218+
219+
static void parseAmdGpuIdsFile(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu)
220+
{
221+
char query[32];
222+
snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
223+
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
224+
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
225+
#else
226+
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
227+
#endif
228+
}
229+
230+
void ffGPUQueryAmdGpuName(uint16_t deviceId, uint8_t revisionId, FFGPUResult* gpu)
231+
{
232+
#if FF_HAVE_EMBEDDED_AMDGPUIDS
233+
bool ok = loadAmdGpuIdsInc(deviceId, revisionId, gpu);
234+
if (ok) return;
235+
#endif
236+
return parseAmdGpuIdsFile(deviceId, revisionId, gpu);
237+
}

src/detection/gpu/gpu_sunos.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "gpu.h"
2-
#include "common/properties.h"
32
#include "common/io/io.h"
43
#include "common/processing.h"
54

@@ -65,11 +64,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
6564
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
6665

6766
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
68-
{
69-
char query[32];
70-
snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
71-
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
72-
}
67+
ffGPUQueryAmdGpuName((uint16_t) deviceId, (uint8_t) revision, gpu);
7368

7469
if (gpu->name.length == 0)
7570
{

0 commit comments

Comments
 (0)