From 008cf3b83dcb4c5fa2b04ae10402afdfbb6be66a Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 5 Jun 2022 00:18:40 +0200 Subject: [PATCH] OpenCL module --- .github/workflows/pull_request.yml | 2 +- .github/workflows/push.yml | 2 +- CMakeLists.txt | 12 ++++ README.md | 33 +++++------ completions/bash | 9 ++- presets/all | 2 +- presets/verbose | 2 + src/common/init.c | 6 ++ src/data/config.txt | 3 + src/data/help.txt | 3 + src/data/modules.txt | 1 + src/fastfetch.c | 16 ++++++ src/fastfetch.h | 4 ++ src/modules/opencl.c | 91 ++++++++++++++++++++++++++++++ 14 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 src/modules/opencl.c diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index b12b77e2e..3edcddd7c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev + run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev - name: Initialize CodeQL uses: github/codeql-action/init@v1 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 9b7898743..bee9cdb13 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v2 - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev + run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev - name: Initialize CodeQL uses: github/codeql-action/init@v1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 005437906..e87e175e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ OPTION(ENABLE_CHAFA "Enable chafa" ON) OPTION(ENABLE_EGL "Enable egl" ON) OPTION(ENABLE_GLX "Enable glx" ON) OPTION(ENABLE_OSMESA "Enable osmesa" ON) +OPTION(ENABLE_OPENCL "Enable opencl" ON) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) @@ -172,6 +173,7 @@ add_library(libfastfetch STATIC src/modules/time.c src/modules/colors.c src/modules/opengl.c + src/modules/opencl.c ) if(ENABLE_LIBPCI) @@ -378,6 +380,15 @@ if(ENABLE_OSMESA) endif() endif() +if(ENABLE_OPENCL) + pkg_check_modules(OPENCL OpenCL) + if(OPENCL_FOUND) + target_compile_definitions(libfastfetch PRIVATE FF_HAVE_OPENCL=1) + else() + message(WARNING "Package opencl not found. Building without support.") + endif() +endif() + target_include_directories(libfastfetch PUBLIC ${PROJECT_BINARY_DIR} PUBLIC ${PROJECT_SOURCE_DIR}/src @@ -403,6 +414,7 @@ target_include_directories(libfastfetch PRIVATE ${EGL_INCLUDE_DIRS} PRIVATE ${GLX_INCLUDE_DIRS} PRIVATE ${OSMESA_INCLUDE_DIRS} + PRIVATE ${OPENCL_INCLUDE_DIRS} ) target_link_libraries(libfastfetch diff --git a/README.md b/README.md index d589619e5..c76ea359d 100644 --- a/README.md +++ b/README.md @@ -19,32 +19,33 @@ There are some presets defined for fastfech in [`presets`](presets), you can can Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and `libpthread`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it. The following libraries are used if present at runtime: -* [`libpci`](https://github.com/pciutils/pciutils): GPU output. -* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output. -* [`libxcb-randr`](https://xcb.freedesktop.org/), +* [`libpci`](https://github.com/pciutils/pciutils): GPU output. +* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output. +* [`libxcb-randr`](https://xcb.freedesktop.org/), [`libXrandr`](https://gitlab.freedesktop.org/xorg/lib/libxrandr), [`libxcb`](https://xcb.freedesktop.org/), - [`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better resolution detection and faster WM detection. The `*randr` ones provide multi monitor support. The `libxcb*` ones usually have better performance. -* [`libwayland-client`](https://wayland.freedesktop.org/): Better resolution performance and output in wayland sessions. Supports different refresh rates per monitor. -* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings. -* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings. -* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol. -* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. -* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol. -* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Needed for detecting current media player and song. -* [`libEGL`](https://www.khronos.org/registry/EGL/), + [`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better resolution detection and faster WM detection. The `*randr` ones provide multi monitor support The `libxcb*` ones usually have better performance. +* [`libwayland-client`](https://wayland.freedesktop.org/): Better resolution performance and output in wayland sessions. Supports different refresh rates per monitor. +* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings. +* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings. +* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol. +* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. +* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol. +* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Needed for detecting current media player and song. +* [`libEGL`](https://www.khronos.org/registry/EGL/), [`libGLX`](https://dri.freedesktop.org/wiki/GLX/), [`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation. -* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. -* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for rpm package count. -* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. +* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module +* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. +* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for rpm package count. +* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE. ## Support status All categories not listed here should work without needing a specific implementation. ##### Available Modules ``` -Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Disk, Battery, Player, Song, Vulkan, OpenGL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom +Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Disk, Battery, Player, Song, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom ``` ##### Logos diff --git a/completions/bash b/completions/bash index cf8873a85..ea897c308 100644 --- a/completions/bash +++ b/completions/bash @@ -153,6 +153,7 @@ __fastfetch_completion() "-s" "--structure" "--set" + "--gl" "--os-format" "--os-key" "--host-format" @@ -217,7 +218,12 @@ __fastfetch_completion() "--date-key" "--time-format" "--time-key" - "--gl" + "--vulkan-key" + "--vulkan-format" + "--opengl-key" + "--opengl-format" + "--opencl-key" + "--opencl-format" ) local FF_OPTIONS_PATH=( @@ -241,6 +247,7 @@ __fastfetch_completion() "--lib-egl" "--lib-glx" "--lib-osmesa" + "--lib-opencl" "--battery-dir" "--load-config" ) diff --git a/presets/all b/presets/all index dac0b9c1b..8f42521dc 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:Break:Colors +--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Break:Colors diff --git a/presets/verbose b/presets/verbose index d402c011c..1b6865d1e 100644 --- a/presets/verbose +++ b/presets/verbose @@ -27,3 +27,5 @@ --song-format "Song: {}; Artist: {}; Album: {}" --datetime-format "year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}" --vulkan-format "driver: {}; Api Version: {}; Conformance Version: {}" +--opengl-format "version: {}; renderer: {}; vendor: {}" +--opencl-format "version: {}; device: {}; vendor: {}" diff --git a/src/common/init.c b/src/common/init.c index 2330fc824..17faaf42c 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -193,6 +193,8 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.vulkanFormat, 0); ffStrbufInitA(&instance->config.openGLKey, 0); ffStrbufInitA(&instance->config.openGLFormat, 0); + ffStrbufInitA(&instance->config.openCLKey, 0); + ffStrbufInitA(&instance->config.openCLFormat, 0); ffStrbufInitA(&instance->config.libPCI, 0); ffStrbufInitA(&instance->config.libVulkan, 0); @@ -213,6 +215,7 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.libEGL, 0); ffStrbufInitA(&instance->config.libGLX, 0); ffStrbufInitA(&instance->config.libOSMesa, 0); + ffStrbufInitA(&instance->config.libOpenCL, 0); ffStrbufInitA(&instance->config.diskFolders, 0); @@ -353,6 +356,9 @@ void ffListFeatures() #ifdef FF_HAVE_OSMESA "osmesa\n" #endif + #ifdef FF_HAVE_OPENCL + "opencl\n" + #endif "" , stdout); } diff --git a/src/data/config.txt b/src/data/config.txt index e5681286c..9dbe8af97 100644 --- a/src/data/config.txt +++ b/src/data/config.txt @@ -197,6 +197,7 @@ #--datetime-key Date Time #--vulkan-key Vulkan #--opengl-key OpenGL +#--opencl-key OpenCL # Format options: # Sets the format string for module values. @@ -234,6 +235,7 @@ #--datetime-format #--vulkan-format #--opengl-format +#--opencl-format # Library options: # Sets an user specific path to a library to load. @@ -257,3 +259,4 @@ #--lib-egl /usr/lib/libEGL.so #--lib-glx /usr/lib/libGLX.so #--lib-osmesa /usr/lib/libOSMesa.so +#--lib-opencl /usr/lib/libOpenCL.so \ No newline at end of file diff --git a/src/data/help.txt b/src/data/help.txt index 51ad5f725..9dfe911a3 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -79,6 +79,7 @@ Format options: Provide the format string for custom output. Use fastfetch --hel --date-format --vulkan-format --opengl-format + --opencl-format Key options: Provide a custom key for an output --os-key @@ -114,6 +115,7 @@ Key options: Provide a custom key for an output --date-key --vulkan-key --opengl-key + --opencl-key Library options: Set the path of a library to load --lib-PCI @@ -135,6 +137,7 @@ Library options: Set the path of a library to load --lib-egl --lib-glx --lib-osmesa + --lib-opencl Module specific options: --separator-string : Set the string printed by the separator module diff --git a/src/data/modules.txt b/src/data/modules.txt index 80073f7d9..60101764e 100644 --- a/src/data/modules.txt +++ b/src/data/modules.txt @@ -17,6 +17,7 @@ Locale LocalIP Memory OS +OpenCL OpenGL Packages Player diff --git a/src/fastfetch.c b/src/fastfetch.c index 5d0ea3459..39c3645f2 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -362,6 +362,14 @@ static inline void printCommandHelp(const char* command) "shading language version" ); } + else if(strcasecmp(command, "opencl-format") == 0) + { + constructAndPrintCommandHelpFormat("opencl", "{}", 3, + "version", + "device", + "vendor" + ); + } else fprintf(stderr, "No specific help for command %s provided\n", command); } @@ -993,6 +1001,10 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.openGLKey); else if(strcasecmp(key, "--opengl-format") == 0) optionParseString(key, value, &instance->config.openGLFormat); + else if(strcasecmp(key, "--opencl-key") == 0) + optionParseString(key, value, &instance->config.openCLKey); + else if(strcasecmp(key, "--opencl-format") == 0) + optionParseString(key, value, &instance->config.openCLFormat); /////////////////// //Library options// @@ -1036,6 +1048,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.libGLX); else if(strcasecmp(key, "--lib-osmesa") == 0) optionParseString(key, value, &instance->config.libOSMesa); + else if(strcasecmp(key, "--lib-opencl") == 0) + optionParseString(key, value, &instance->config.libOpenCL); ////////////////// //Module options// @@ -1226,6 +1240,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintVulkan(instance); else if(strcasecmp(line, "opengl") == 0) ffPrintOpenGL(instance); + else if(strcasecmp(line, "opencl") == 0) + ffPrintOpenCL(instance); else ffPrintError(instance, line, 0, NULL, NULL, 0, ""); } diff --git a/src/fastfetch.h b/src/fastfetch.h index af2f41d2a..711c57f68 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -139,6 +139,8 @@ typedef struct FFconfig FFstrbuf vulkanFormat; FFstrbuf openGLKey; FFstrbuf openGLFormat; + FFstrbuf openCLKey; + FFstrbuf openCLFormat; FFstrbuf libPCI; FFstrbuf libVulkan; @@ -159,6 +161,7 @@ typedef struct FFconfig FFstrbuf libEGL; FFstrbuf libGLX; FFstrbuf libOSMesa; + FFstrbuf libOpenCL; FFstrbuf diskFolders; @@ -612,5 +615,6 @@ void ffPrintPublicIp(FFinstance* instance); void ffPrintColors(FFinstance* instance); void ffPrintVulkan(FFinstance* instance); void ffPrintOpenGL(FFinstance* instance); +void ffPrintOpenCL(FFinstance* instance); #endif diff --git a/src/modules/opencl.c b/src/modules/opencl.c new file mode 100644 index 000000000..212b36771 --- /dev/null +++ b/src/modules/opencl.c @@ -0,0 +1,91 @@ +#include "fastfetch.h" + +#define FF_OPENCL_MODULE_NAME "OpenCL" +#define FF_OPENCL_NUM_FORMAT_ARGS 3 + +#ifdef FF_HAVE_OPENCL +#define CL_TARGET_OPENCL_VERSION 100 +#include + +typedef struct OpenCLData +{ + FF_LIBRARY_SYMBOL(clGetPlatformIDs); + FF_LIBRARY_SYMBOL(clGetDeviceIDs); + FF_LIBRARY_SYMBOL(clGetDeviceInfo); +} OpenCLData; + +static const char* openCLHandelData(FFinstance* instance, OpenCLData* data) +{ + cl_platform_id platformID; + cl_uint numPlatforms; + data->ffclGetPlatformIDs(1, &platformID, &numPlatforms); + + if(numPlatforms == 0) + return "clGetPlatformIDs returned 0 platforms"; + + cl_device_id deviceID; + cl_uint numDevices; + data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_GPU, 1, &deviceID, &numDevices); + + if(numDevices == 0) + data->ffclGetDeviceIDs(platformID, CL_DEVICE_TYPE_ALL, 1, &deviceID, &numDevices); + + if(numDevices == 0) + return "clGetDeviceIDs returned 0 devices"; + + char version[64]; + data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VERSION, sizeof(version), version, NULL); + if(!ffStrSet(version)) + return "clGetDeviceInfo returned NULL or empty string"; + + char device[128]; + data->ffclGetDeviceInfo(deviceID, CL_DEVICE_NAME, sizeof(device), device, NULL); + + char vendor[32]; + data->ffclGetDeviceInfo(deviceID, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL); + + if(instance->config.openCLFormat.length == 0) + { + ffPrintLogoAndKey(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCLKey); + puts(version); + } + else + { + ffPrintFormatString(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCLKey, &instance->config.openCLFormat, NULL, FF_OPENCL_NUM_FORMAT_ARGS, (FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRING, version}, + {FF_FORMAT_ARG_TYPE_STRING, device}, + {FF_FORMAT_ARG_TYPE_STRING, vendor} + }); + } + + return NULL; +} + +static const char* printOpenCL(FFinstance* instance) +{ + OpenCLData data; + + FF_LIBRARY_LOAD(opencl, instance->config.libOpenCL, "dlopen libOpenCL.so failed", "libOpenCL.so", 1); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(opencl, data.ffclGetPlatformIDs, clGetPlatformIDs, "dlsym clGetPlatformIDs failed"); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(opencl, data.ffclGetDeviceIDs, clGetDeviceIDs, "dlsym clGetDeviceIDs failed"); + FF_LIBRARY_LOAD_SYMBOL_ADRESS(opencl, data.ffclGetDeviceInfo, clGetDeviceInfo, "dlsym clGetDeviceInfo failed"); + + const char* error = openCLHandelData(instance, &data); + dlclose(opencl); + return error; +} +#endif + +void ffPrintOpenCL(FFinstance* instance) +{ + const char* error; + + #ifdef FF_HAVE_OPENCL + error = printOpenCL(instance); + #else + error = "Fastfetch was build without OpenCL support"; + #endif + + if(error != NULL) + ffPrintError(instance, FF_OPENCL_MODULE_NAME, 0, &instance->config.openCLKey, &instance->config.openCLFormat, FF_OPENCL_NUM_FORMAT_ARGS, error); +}