mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
101 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bcc8f6d0b8 | |||
| 90ca6ee3cd | |||
| b679185c87 | |||
| 6bbed12083 | |||
| f04851891e | |||
| f94d9ca3bd | |||
| f833dda3b9 | |||
| ceecb39bc5 | |||
| c957ca7230 | |||
| 5dfd2676c2 | |||
| d650f67ece | |||
| 760e82913a | |||
| e64a44a3e6 | |||
| be9cf00b05 | |||
| 52fdabeb2e | |||
| 846f4c003e | |||
| dc5f2ac577 | |||
| 663650cb61 | |||
| 45aecae221 | |||
| 3d3669ae3a | |||
| ac2aba0faf | |||
| d0ca944b9c | |||
| 3d7c631abd | |||
| abe78823b6 | |||
| 7e03b03cb7 | |||
| 27fe997dc3 | |||
| fe46159e40 | |||
| 031aa985f1 | |||
| 07c61f70d9 | |||
| 71b05d2594 | |||
| 98665d1b82 | |||
| da0eedf888 | |||
| 1133cb619b | |||
| a091d209cf | |||
| 47c658815b | |||
| b0d0c74073 | |||
| 9535b4d480 | |||
| c64cbf57d8 | |||
| d11235bbe2 | |||
| 3054c6618e | |||
| f34d51dddc | |||
| e05ac797cc | |||
| 187059deef | |||
| 5c9f184314 | |||
| 49725c2cc6 | |||
| eec9a26952 | |||
| 88d616e978 | |||
| 4fccad5d10 | |||
| ec18363f51 | |||
| b87a36785b | |||
| 1d7b212d8d | |||
| 4b6f2a9efa | |||
| bdaf303da4 | |||
| 3fb773eedd | |||
| e73647973d | |||
| d2b3a075b2 | |||
| f139148745 | |||
| e2ec2c695c | |||
| ba4ec47a8c | |||
| de5ef3842c | |||
| 1129ed9be4 | |||
| 0d4f1544c7 | |||
| e68a9476b5 | |||
| 17556c7a95 | |||
| eca9f626a5 | |||
| 7562e05123 | |||
| bf17f2b4b9 | |||
| 88e193e9fd | |||
| e474a47fad | |||
| c77fb71a69 | |||
| 48dd5976e1 | |||
| 093f7e438b | |||
| 0a0c1745b3 | |||
| 7b5dc58140 | |||
| 8681d2f74a | |||
| 2b20ed873c | |||
| ae3c15b7fd | |||
| 8dafd8f300 | |||
| c9a1765f29 | |||
| cc246ea239 | |||
| 0ae5fceb07 | |||
| 6dd18050be | |||
| 9eca6e0b48 | |||
| 4d58d1be66 | |||
| 6694388969 | |||
| f7058cd125 | |||
| 80033b656f | |||
| 1c719fa743 | |||
| a9f5722fd9 | |||
| 0952d7917f | |||
| a3f50f32bf | |||
| ab1bfffbd4 | |||
| 41d6187f11 | |||
| d4b175b146 | |||
| 8905962389 | |||
| d9d34ccbbb | |||
| d21048c165 | |||
| 8b0c32a35f | |||
| db269d29e8 | |||
| f9f628eae6 | |||
| 92e9fbf2eb |
@@ -520,41 +520,6 @@ jobs:
|
||||
name: fastfetch-freebsd-amd64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
dragonfly-amd64:
|
||||
name: DragonFly-amd64
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/dragonflybsd-vm@v1
|
||||
with:
|
||||
usesh: yes
|
||||
prepare: |
|
||||
uname -a
|
||||
pkg update
|
||||
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa libelf
|
||||
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-dragonfly-amd64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
openbsd-amd64:
|
||||
name: OpenBSD-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -659,9 +624,6 @@ jobs:
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: download amd_ags
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x64.dll
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
@@ -709,7 +671,6 @@ jobs:
|
||||
- freebsd-amd64
|
||||
- openbsd-amd64
|
||||
- netbsd-amd64
|
||||
- dragonfly-amd64
|
||||
- sunos-amd64
|
||||
- windows-amd64
|
||||
permissions:
|
||||
|
||||
+54
-1
@@ -1,3 +1,56 @@
|
||||
# 2.40.1
|
||||
|
||||
Bugfixes:
|
||||
* Fix compiling error on old intel platform (TPM, macOS)
|
||||
* Fix `--file-raw -` no longer working (Logo, #1659)
|
||||
* Regression of v2.40.0
|
||||
|
||||
# 2.40.0
|
||||
|
||||
Changes:
|
||||
* In `key-format` of `LocalIP` module, `{name}` has been renamed to `{ifname}` for consistency (LocalIP, #1639)
|
||||
|
||||
Features:
|
||||
* Support Warp Terminal font detection (TerminalFont, Windows)
|
||||
* Support more AMD GPU information using ADL SDK, including memory type detection (GPU, Windows)
|
||||
* Support Intel dGPU memory type detection (GPU, Windows)
|
||||
* Support Nvidia VMEM type detection via NVAPI (GPU, Windows, #993)
|
||||
* Support Boot manager detection for OpenBSD and NetBSD (Bootmgr, OpenBSD / NetBSD)
|
||||
* Use `SystemConfiguration` for DNS entries detection (DNS, macOS)
|
||||
* Add `systemd-resolved` support for DNS module (DNS, Linux, #1646)
|
||||
* Improve performance and accuracy of Wifi detection on FreeBSD using ioctl (Wifi, FreeBSD)
|
||||
* Support remaining time reporting for batteries on NetBSD (Battery, NetBSD)
|
||||
* Add new Mac models support (Host, macOS)
|
||||
* Load config from fastfetch binary path with `--config` option (#1649)
|
||||
* Support TPM detection on macOS (TPM, macOS)
|
||||
* Support IPv6 client address report (Users, Linux / Windows)
|
||||
* Support default route detection for IPv6 (LocalIP, Linux)
|
||||
* Round seconds to the nearest minute to match the behavior of `uptime` command (Uptime)
|
||||
|
||||
Bugfixes:
|
||||
* Fix `outputColor` not working when `length` is set in Separator module (#1644)
|
||||
* Fix CPU detection on PowerPC platforms (#1640, CPU, Linux)
|
||||
* Fix battery manufacture date detection (Battery, macOS)
|
||||
* Fix battery critical state detection (Battery, Linux)
|
||||
* Fix Warp Terminal PID detection (Terminal, macOS)
|
||||
* Remove disk creation time detection support on SunOS as ctim is file status change timestamp, not creation time (Disk, SunOS)
|
||||
* Fall back to KDGKBINFO if `usbhid` fails (Keyboard, FreeBSD)
|
||||
* Fix multiple paging file support (Swap, Windows)
|
||||
* Fix memleaks, code smells in multiple modules
|
||||
* Fix boot time calculation on NetBSD (Uptime, NetBSD)
|
||||
* Temporarily fix Hyprland version detection (WM, Linux, #1657)
|
||||
|
||||
Logo:
|
||||
* Fix opensuse-tumbleweed_small (#1636)
|
||||
* Change WiiLinuxNgx to more generic name with aliases Wii-Linux and WiiLinux (#1633)
|
||||
* Change name of Xray-OS to Ada (#1651)
|
||||
* Change Nexa Linux logo (#1653)
|
||||
|
||||
# 2.39.1
|
||||
|
||||
Bugfixes:
|
||||
* Fix a regression that PublicIP detection fails randomly (PublicIP, #1629)
|
||||
|
||||
# 2.39.0
|
||||
|
||||
Changes:
|
||||
@@ -331,7 +384,7 @@ Features:
|
||||
* Support tilix version detection (Terminal, Linux)
|
||||
* Support percent type config in module level. Example:
|
||||
|
||||
```json
|
||||
```jsonc
|
||||
{
|
||||
"type": "memory",
|
||||
"percent": {
|
||||
|
||||
+13
-11
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.39.0
|
||||
VERSION 2.40.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -708,7 +708,6 @@ elseif(FreeBSD)
|
||||
src/detection/uptime/uptime_bsd.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_bsd.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
@@ -720,10 +719,12 @@ elseif(FreeBSD)
|
||||
if(DragonFly)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/wifi/wifi_nosupport.c
|
||||
)
|
||||
else()
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/bluetooth/bluetooth_bsd.c
|
||||
src/detection/wifi/wifi_bsd.c
|
||||
)
|
||||
endif()
|
||||
elseif(NetBSD)
|
||||
@@ -739,7 +740,7 @@ elseif(NetBSD)
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/board/board_nbsd.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/bootmgr/bootmgr_bsd.c
|
||||
src/detection/brightness/brightness_nbsd.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nbsd.c
|
||||
@@ -817,22 +818,22 @@ elseif(OpenBSD)
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_obsd.c
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/bios/bios_windows.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/bluetoothradio/bluetoothradio_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/bootmgr/bootmgr_bsd.c
|
||||
src/detection/brightness/brightness_obsd.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/chassis/chassis_windows.c
|
||||
src/detection/cpu/cpu_obsd.c
|
||||
src/detection/cpucache/cpucache_nosupport.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
src/detection/cpuusage/cpuusage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_obsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
@@ -889,6 +890,7 @@ elseif(OpenBSD)
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
src/util/smbiosHelper.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -911,7 +913,7 @@ elseif(APPLE)
|
||||
src/detection/cpuusage/cpuusage_apple.c
|
||||
src/detection/cursor/cursor_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/dns/dns_apple.c
|
||||
src/detection/physicaldisk/physicaldisk_apple.c
|
||||
src/detection/physicalmemory/physicalmemory_apple.m
|
||||
src/detection/diskio/diskio_apple.c
|
||||
@@ -945,7 +947,7 @@ elseif(APPLE)
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/terminalsize/terminalsize_linux.c
|
||||
src/detection/theme/theme_nosupport.c
|
||||
src/detection/tpm/tpm_nosupport.c
|
||||
src/detection/tpm/tpm_apple.c
|
||||
src/detection/uptime/uptime_bsd.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_apple.m
|
||||
|
||||
Vendored
+24
@@ -1,3 +1,27 @@
|
||||
fastfetch (2.40.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.40.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 03 Apr 2025 08:46:54 +0800
|
||||
|
||||
fastfetch (2.39.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.39.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 21 Mar 2025 11:02:19 +0800
|
||||
|
||||
fastfetch (2.39.0ubuntu1) jammy; urgency=medium
|
||||
|
||||
* Remove unwanted debugging code
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 20 Mar 2025 10:39:22 +0800
|
||||
|
||||
fastfetch (2.39.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.39.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 20 Mar 2025 10:35:18 +0800
|
||||
|
||||
fastfetch (2.38.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.38.0
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.38.0_source.buildinfo universe/utils optional
|
||||
fastfetch_2.40.0_source.buildinfo universe/utils optional
|
||||
|
||||
+11
-11
@@ -28,38 +28,38 @@
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}{$1}│ {#92}User {#90}│",
|
||||
"format": "{$2}{$3}{user-name} {#2}[{home-dir}]"
|
||||
"format": "{$2}{$3}{user-name} {#2}[{home-dir}]"
|
||||
},
|
||||
{
|
||||
"type": "users",
|
||||
"key": "{#90}{$1}│ {#92}Users {#90}│",
|
||||
"myselfOnly": false,
|
||||
"format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} {#2}[Login time: {login-time}]",
|
||||
"format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} [Login time: {login-time}]"
|
||||
},
|
||||
{
|
||||
"type": "datetime",
|
||||
"key": "{#90}{$1}│ {#92}Datetime {#90}│",
|
||||
"format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}{weekday} {#2}[W{week}] {#2}[UTC{offset-from-utc}]"
|
||||
"format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} [{weekday}] [W{week}] [UTC{offset-from-utc}]"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}{$1}│ {#93}Host: {#90}│",
|
||||
"format": "{$2}{$3}{#1}{#36}{host-name}"
|
||||
"key": "{#90}{$1}│ {#93}Host {#90}│",
|
||||
"format": "{$2}{$3}{host-name}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "{#90}{$1}│ {#93}Machine {#90}│",
|
||||
"format": "{$2}{$3}{name} {#2}{version}"
|
||||
"format": "{$2}{$3}{name} {#2}{version}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "{#90}{$1}│ {#93}OS {#90}│",
|
||||
"format": "{$2}{$3}{pretty-name} {codename} {#2}[v{version}] {#2}[{arch}]"
|
||||
"format": "{$2}{$3}{?pretty-name}{pretty-name}{?}{/pretty-name}{name}{/} {codename} {#2}[v{version}] [{arch}]"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "{#90}{$1}│ {#93}Kernel {#90}│",
|
||||
"format": "{$2}{$3}{sysname} {#2}[v{release}]"
|
||||
"format": "{$2}{$3}{sysname} {#2}[v{release}]"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
@@ -71,14 +71,14 @@
|
||||
"key": "{#90}{$1}│ {#91}CPU {#90}│",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true,
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-types}] {#2}[{freq-max}]"
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-types}] [{freq-max}]"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "{#90}{$1}│ {#91}GPU {#90}│",
|
||||
"detectionMethod": "auto",
|
||||
"driverSpecific": true,
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-count}] {#2}[{type}]"
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-count}]{?frequency} [{frequency}]{?} [{type}]"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
@@ -98,7 +98,7 @@
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "{#90}{$1}│ {#95}Terminal {#90}│",
|
||||
"format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||
"format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
// Modified from: 24.jsonc
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"padding": {
|
||||
"top": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": "",
|
||||
"constants": [
|
||||
// CONSTANT {$1} - VERTICAL BARS AT START AND 75th CHARACTERS FORWARD AND BACKWARD
|
||||
"\u001b[90m│ │\u001b[60D\u001b[39m"
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
// CUSTOM - Top UI bar
|
||||
{
|
||||
"type": "custom",
|
||||
"key": "{#90}╭ Keys ───────╮",
|
||||
"format": "{#90}╭ Values ────────────────────────────────────────────────────╮",
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}│ {#92}User {#90}│",
|
||||
"format": "{$1}{user-name} {#2}[{home-dir}]"
|
||||
},
|
||||
{
|
||||
"type": "users",
|
||||
"key": "{#90}│ {#92}Users {#90}│",
|
||||
"myselfOnly": false,
|
||||
"format": "{$1}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} [Login time: {login-time}]"
|
||||
},
|
||||
{
|
||||
"type": "datetime",
|
||||
"key": "{#90}│ {#92}Datetime {#90}│",
|
||||
"format": "{$1}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}[{weekday}] [W{week}] [UTC{offset-from-utc}]"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}│ {#93}Host {#90}│",
|
||||
"format": "{$1}{host-name}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "{#90}│ {#93}Machine {#90}│",
|
||||
"format": "{$1}{name} {#2}{version}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "{#90}│ {#93}OS {#90}│",
|
||||
"format": "{$1}{?pretty-name}{pretty-name}{?}{/pretty-name}{name}{/} {codename} {#2}[v{version}] [{arch}]"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "{#90}│ {#93}Kernel {#90}│",
|
||||
"format": "{$1}{sysname} {#2}[v{release}]"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "{#90}│ {#93}Uptime {#90}│",
|
||||
"format": "{$1}{?days}{days} Days + {?}{hours}:{minutes}:{seconds}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "{#90}│ {#91}CPU {#90}│",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true,
|
||||
"format": "{$1}{name} {#2}[C:{core-types}] [{freq-max}]"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "{#90}│ {#91}GPU {#90}│",
|
||||
"detectionMethod": "auto",
|
||||
"driverSpecific": true,
|
||||
"format": "{$1}{name} {#2}[C:{core-count}]{?frequency} [{frequency}]{?} {#2}[{type}]"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "{#90}│ {#91}Memory {#90}│",
|
||||
"format": "{$1}{used} / {total} ({percentage})"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "{#90}│ {#91}Disk {#90}│",
|
||||
"format": "{$1}{size-used} / {size-total} ({size-percentage})"
|
||||
},
|
||||
{
|
||||
"type": "poweradapter",
|
||||
"key": "{#90}│ {#91}Power {#90}│",
|
||||
"format": "{$1}{name}"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "{#90}│ {#95}Terminal {#90}│",
|
||||
"format": "{$1}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": "{#90}│ {#95}Font {#90}│",
|
||||
"format": "{$1}{name} {#2}[{size}]"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "{#90}│ {#95}Shell {#90}│",
|
||||
"format": "{$1}{pretty-name} {#2}[v{version}] [PID:{pid}]"
|
||||
},
|
||||
{
|
||||
// localip IPv4
|
||||
"type": "localip",
|
||||
"key": "{#90}│ {#94}Local IPv4 {#90}│",
|
||||
"showPrefixLen": true,
|
||||
"showIpv4": true,
|
||||
"showIpv6": false,
|
||||
"showMtu": true,
|
||||
"format": "{$1}{ifname}: {ipv4} {#2}[MTU:{mtu}]"
|
||||
},
|
||||
{
|
||||
// localip IPv6
|
||||
"type": "localip",
|
||||
"key": "{#90}│ {#94}Local IPv6 {#90}│",
|
||||
"showPrefixLen": true,
|
||||
"showIpv4": false,
|
||||
"showIpv6": true,
|
||||
"showMtu": true,
|
||||
"format": "{$1}{ifname}: {ipv6} {#2}[MTU:{mtu}]"
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "{#90}│ {#94}Public IPv4 {#90}│",
|
||||
"ipv6": false,
|
||||
"format": "{$1}{ip} {#2}[{location}]"
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "{#90}│ {#94}Public IPv6 {#90}│",
|
||||
"ipv6": true,
|
||||
"format": "{$1}{ip} {#2}[{location}]"
|
||||
},
|
||||
// CUSTOM - Button UI bar
|
||||
{
|
||||
"type": "custom",
|
||||
"key": "{#90}╰─────────────╯",
|
||||
"format": "{#90}╰────────────────────────────────────────────────────────────╯",
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "custom",
|
||||
"key": " ",
|
||||
"format": "{#90}╭ Colors ───────────────────────────────────────────────────────────────────╮",
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "{#90}│ {#40} {#41} {#42} {#43} {#44} {#45} {#46} {#47} {#} {#90}│",
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "{#90}│ {#100} {#101} {#102} {#103} {#104} {#105} {#106} {#107} {#} {#90}│",
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "{#90}╰───────────────────────────────────────────────────────────────────────────╯",
|
||||
},
|
||||
]
|
||||
}
|
||||
Vendored
-383
@@ -1,383 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
/// \file
|
||||
/// \mainpage
|
||||
/// AGS Library Overview
|
||||
/// --------------------
|
||||
/// This document provides an overview of the AGS (AMD GPU Services) library. The AGS library provides software developers with the ability to query
|
||||
/// AMD GPU software and hardware state information that is not normally available through standard operating systems or graphic APIs.
|
||||
///
|
||||
/// The latest version of the API is publicly hosted here: https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/.
|
||||
/// It is also worth checking http://gpuopen.com/gaming-product/amd-gpu-services-ags-library/ for any updates and articles on AGS.
|
||||
/// \internal
|
||||
/// Online documentation is publicly hosted here: http://gpuopen-librariesandsdks.github.io/ags/
|
||||
/// \endinternal
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 6.2 since version 6.1
|
||||
/// ---------------------------------------
|
||||
/// AGS 6.2 includes the following updates:
|
||||
/// * Shader clock intrinsics
|
||||
/// * Minor improvements and fixes
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 6.1 since version 6.0
|
||||
/// ---------------------------------------
|
||||
/// AGS 6.1 includes the following updates:
|
||||
/// * RDNA3 detection
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 6.0 since version 5.4.2
|
||||
/// ---------------------------------------
|
||||
/// AGS 6.0 includes the following updates:
|
||||
/// * DX12 ray tracing hit token for RDNA2 hardware.
|
||||
/// * Shader intrinsic that exposes ReadLaneAt in DX12.
|
||||
/// * Shader intrinsics that expose explicit float conversions in DX12.
|
||||
/// * Refactored and revised API to minimize user error.
|
||||
/// * Added agsGetVersionNumber.
|
||||
/// * Detection for external GPUs.
|
||||
/// * Detection of RDNA2 architecture.
|
||||
/// * Grouped the more established intrinsics together into per year support.
|
||||
/// * Function pointer typedefs for the API
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 5.4.2 since version 5.4.1
|
||||
/// ---------------------------------------
|
||||
/// AGS 5.4.2 includes the following updates:
|
||||
/// * sharedMemoryInBytes has been reinstated.
|
||||
/// * Clock speed returned for APUs.
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 5.4.1 since version 5.4.0
|
||||
/// ---------------------------------------
|
||||
/// AGS 5.4.1 includes the following updates:
|
||||
/// * AsicFamily_Count to help with code maintenance.
|
||||
/// * Visual Studio 2019 support.
|
||||
/// * x86 support
|
||||
/// * BaseInstance and BaseVertex intrinsics along with corresponding caps bits.
|
||||
/// * GetWaveSize intrinsic along with corresponding caps bits.
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 5.4 since version 5.3
|
||||
/// ---------------------------------------
|
||||
/// AGS 5.4 includes the following updates:
|
||||
/// * A more detailed description of the GPU architecture, now including RDNA GPUs.
|
||||
/// * Radeon 7 core and memory speeds returned.
|
||||
/// * Draw index and Atomic U64 intrinsics for both DX11 and DX12.
|
||||
///
|
||||
/// ---------------------------------------
|
||||
/// What's new in AGS 5.3 since version 5.2
|
||||
/// ---------------------------------------
|
||||
/// AGS 5.3 includes the following updates:
|
||||
/// * DX11 deferred context support for Multi Draw Indirect and UAV Overlap extensions.
|
||||
/// * A Radeon Software Version helper to determine whether the installed driver meets your game's minimum driver version requirements.
|
||||
/// * Freesync HDR Gamma 2.2 mode which uses a 1010102 swapchain and can be considered as an alternative to using the 64 bit swapchain required for Freesync HDR scRGB.
|
||||
///
|
||||
/// Using the AGS library
|
||||
/// ---------------------
|
||||
/// It is recommended to take a look at the source code for the samples that come with the AGS SDK:
|
||||
/// * AGSSample
|
||||
/// * CrossfireSample
|
||||
/// * EyefinitySample
|
||||
/// The AGSSample application is the simplest of the three examples and demonstrates the code required to initialize AGS and use it to query the GPU and Eyefinity state.
|
||||
/// The CrossfireSample application demonstrates the use of the new API to transfer resources on GPUs in Crossfire mode. Lastly, the EyefinitySample application provides a more
|
||||
/// extensive example of Eyefinity setup than the basic example provided in AGSSample.
|
||||
/// There are other samples on Github that demonstrate the DirectX shader extensions, such as the Barycentrics11 and Barycentrics12 samples.
|
||||
///
|
||||
/// To add AGS support to an existing project, follow these steps:
|
||||
/// * Link your project against the correct import library. Choose from either the 32 bit or 64 bit version.
|
||||
/// * Copy the AGS dll into the same directory as your game executable.
|
||||
/// * Include the amd_ags.h header file from your source code.
|
||||
/// * Include the AGS hlsl files if you are using the shader intrinsics.
|
||||
/// * Declare a pointer to an AGSContext and make this available for all subsequent calls to AGS.
|
||||
/// * On game initialization, call \ref agsInitialize passing in the address of the context. On success, this function will return a valid context pointer.
|
||||
///
|
||||
/// Don't forget to cleanup AGS by calling \ref agsDeInitialize when the app exits, after the device has been destroyed.
|
||||
|
||||
#ifndef AMD_AGS_H
|
||||
#define AMD_AGS_H
|
||||
|
||||
#define AMD_AGS_VERSION_MAJOR 6 ///< AGS major version
|
||||
#define AMD_AGS_VERSION_MINOR 2 ///< AGS minor version
|
||||
#define AMD_AGS_VERSION_PATCH 0 ///< AGS patch version
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// \defgroup Defines AGS defines
|
||||
/// @{
|
||||
#if defined (AGS_GCC)
|
||||
#define AMD_AGS_API
|
||||
#else
|
||||
#define AMD_AGS_API __declspec(dllexport) ///< AGS exported functions
|
||||
#endif
|
||||
|
||||
#define AGS_MAKE_VERSION( major, minor, patch ) ( ( major << 22 ) | ( minor << 12 ) | patch ) ///< Macro to create the app and engine versions for the fields in \ref AGSDX12ExtensionParams and \ref AGSDX11ExtensionParams and the Radeon Software Version
|
||||
#define AGS_UNSPECIFIED_VERSION 0xFFFFAD00 ///< Use this to specify no version
|
||||
#define AGS_CURRENT_VERSION AGS_MAKE_VERSION( AMD_AGS_VERSION_MAJOR, AMD_AGS_VERSION_MINOR, AMD_AGS_VERSION_PATCH ) ///< Macro to return the current AGS version as defined by the AGS header file
|
||||
/// @}
|
||||
|
||||
/// \defgroup enums General enumerations
|
||||
/// @{
|
||||
|
||||
/// The return codes
|
||||
typedef enum AGSReturnCode
|
||||
{
|
||||
AGS_SUCCESS, ///< Successful function call
|
||||
AGS_FAILURE, ///< Failed to complete call for some unspecified reason
|
||||
AGS_INVALID_ARGS, ///< Invalid arguments into the function
|
||||
AGS_OUT_OF_MEMORY, ///< Out of memory when allocating space internally
|
||||
AGS_MISSING_D3D_DLL, ///< Returned when a D3D dll fails to load
|
||||
AGS_LEGACY_DRIVER, ///< Returned if a feature is not present in the installed driver
|
||||
AGS_NO_AMD_DRIVER_INSTALLED, ///< Returned if the AMD GPU driver does not appear to be installed
|
||||
AGS_EXTENSION_NOT_SUPPORTED, ///< Returned if the driver does not support the requested driver extension
|
||||
AGS_ADL_FAILURE, ///< Failure in ADL (the AMD Display Library)
|
||||
AGS_DX_FAILURE, ///< Failure from DirectX runtime
|
||||
AGS_D3DDEVICE_NOT_CREATED ///< Failure due to not creating the D3D device successfully via AGS.
|
||||
} AGSReturnCode;
|
||||
|
||||
/// @}
|
||||
|
||||
typedef struct AGSContext AGSContext; ///< All function calls in AGS require a pointer to a context. This is generated via \ref agsInitialize
|
||||
|
||||
/// The rectangle struct used by AGS.
|
||||
typedef struct AGSRect
|
||||
{
|
||||
int offsetX; ///< Offset on X axis
|
||||
int offsetY; ///< Offset on Y axis
|
||||
int width; ///< Width of rectangle
|
||||
int height; ///< Height of rectangle
|
||||
} AGSRect;
|
||||
|
||||
/// The display info struct used to describe a display enumerated by AGS
|
||||
typedef struct AGSDisplayInfo
|
||||
{
|
||||
char name[ 256 ]; ///< The name of the display
|
||||
char displayDeviceName[ 32 ]; ///< The display device name, i.e. DISPLAY_DEVICE::DeviceName
|
||||
|
||||
unsigned int isPrimaryDisplay : 1; ///< Whether this display is marked as the primary display
|
||||
unsigned int HDR10 : 1; ///< HDR10 is supported on this display
|
||||
unsigned int dolbyVision : 1; ///< Dolby Vision is supported on this display
|
||||
unsigned int freesync : 1; ///< Freesync is supported on this display
|
||||
unsigned int freesyncHDR : 1; ///< Freesync HDR is supported on this display
|
||||
unsigned int eyefinityInGroup : 1; ///< The display is part of the Eyefinity group
|
||||
unsigned int eyefinityPreferredDisplay : 1; ///< The display is the preferred display in the Eyefinity group for displaying the UI
|
||||
unsigned int eyefinityInPortraitMode : 1; ///< The display is in the Eyefinity group but in portrait mode
|
||||
unsigned int reservedPadding : 24; ///< Reserved for future use
|
||||
|
||||
int maxResolutionX; ///< The maximum supported resolution of the unrotated display
|
||||
int maxResolutionY; ///< The maximum supported resolution of the unrotated display
|
||||
float maxRefreshRate; ///< The maximum supported refresh rate of the display
|
||||
|
||||
AGSRect currentResolution; ///< The current resolution and position in the desktop, ignoring Eyefinity bezel compensation
|
||||
AGSRect visibleResolution; ///< The visible resolution and position. When Eyefinity bezel compensation is enabled this will
|
||||
///< be the sub region in the Eyefinity single large surface (SLS)
|
||||
float currentRefreshRate; ///< The current refresh rate
|
||||
|
||||
int eyefinityGridCoordX; ///< The X coordinate in the Eyefinity grid. -1 if not in an Eyefinity group
|
||||
int eyefinityGridCoordY; ///< The Y coordinate in the Eyefinity grid. -1 if not in an Eyefinity group
|
||||
|
||||
double chromaticityRedX; ///< Red display primary X coord
|
||||
double chromaticityRedY; ///< Red display primary Y coord
|
||||
|
||||
double chromaticityGreenX; ///< Green display primary X coord
|
||||
double chromaticityGreenY; ///< Green display primary Y coord
|
||||
|
||||
double chromaticityBlueX; ///< Blue display primary X coord
|
||||
double chromaticityBlueY; ///< Blue display primary Y coord
|
||||
|
||||
double chromaticityWhitePointX; ///< White point X coord
|
||||
double chromaticityWhitePointY; ///< White point Y coord
|
||||
|
||||
double screenDiffuseReflectance; ///< Percentage expressed between 0 - 1
|
||||
double screenSpecularReflectance; ///< Percentage expressed between 0 - 1
|
||||
|
||||
double minLuminance; ///< The minimum luminance of the display in nits
|
||||
double maxLuminance; ///< The maximum luminance of the display in nits
|
||||
double avgLuminance; ///< The average luminance of the display in nits
|
||||
|
||||
int logicalDisplayIndex; ///< The internally used index of this display
|
||||
int adlAdapterIndex; ///< The internally used ADL adapter index
|
||||
int reserved; ///< reserved field
|
||||
} AGSDisplayInfo;
|
||||
|
||||
/// The ASIC family
|
||||
typedef enum AsicFamily
|
||||
{
|
||||
AsicFamily_Unknown, ///< Unknown architecture, potentially from another IHV. Check \ref AGSDeviceInfo::vendorId
|
||||
AsicFamily_PreGCN, ///< Pre GCN architecture.
|
||||
AsicFamily_GCN1, ///< AMD GCN 1 architecture: Oland, Cape Verde, Pitcairn & Tahiti.
|
||||
AsicFamily_GCN2, ///< AMD GCN 2 architecture: Hawaii & Bonaire. This also includes APUs Kaveri and Carrizo.
|
||||
AsicFamily_GCN3, ///< AMD GCN 3 architecture: Tonga & Fiji.
|
||||
AsicFamily_GCN4, ///< AMD GCN 4 architecture: Polaris.
|
||||
AsicFamily_Vega, ///< AMD Vega architecture, including Raven Ridge (ie AMD Ryzen CPU + AMD Vega GPU).
|
||||
AsicFamily_RDNA, ///< AMD RDNA architecture
|
||||
AsicFamily_RDNA2, ///< AMD RDNA2 architecture
|
||||
AsicFamily_RDNA3, ///< AMD RDNA3 architecture
|
||||
|
||||
AsicFamily_Count ///< Number of enumerated ASIC families
|
||||
} AsicFamily;
|
||||
|
||||
/// The device info struct used to describe a physical GPU enumerated by AGS
|
||||
typedef struct AGSDeviceInfo
|
||||
{
|
||||
const char* adapterString; ///< The adapter name string
|
||||
AsicFamily asicFamily; ///< Set to Unknown if not AMD hardware
|
||||
unsigned int isAPU : 1; ///< Whether this device is an APU
|
||||
unsigned int isPrimaryDevice : 1; ///< Whether this device is marked as the primary device
|
||||
unsigned int isExternal :1; ///< Whether this device is a detachable, external device
|
||||
unsigned int reservedPadding : 29; ///< Reserved for future use
|
||||
|
||||
int vendorId; ///< The vendor id
|
||||
int deviceId; ///< The device id
|
||||
int revisionId; ///< The revision id
|
||||
|
||||
int numCUs; ///< Number of compute units
|
||||
int numWGPs; ///< Number of RDNA Work Group Processors. Only valid if ASIC is RDNA onwards.
|
||||
|
||||
int numROPs; ///< Number of ROPs
|
||||
int coreClock; ///< Core clock speed at 100% power in MHz
|
||||
int memoryClock; ///< Memory clock speed at 100% power in MHz
|
||||
int memoryBandwidth; ///< Memory bandwidth in MB/s
|
||||
float teraFlops; ///< Teraflops of GPU. Zero if not GCN onwards. Calculated from iCoreClock * iNumCUs * 64 Pixels/clk * 2 instructions/MAD
|
||||
|
||||
unsigned long long localMemoryInBytes; ///< The size of local memory in bytes. 0 for non AMD hardware.
|
||||
unsigned long long sharedMemoryInBytes; ///< The size of system memory available to the GPU in bytes. It is important to factor this into your VRAM budget for APUs
|
||||
///< as the reported local memory will only be a small fraction of the total memory available to the GPU.
|
||||
|
||||
int numDisplays; ///< The number of active displays found to be attached to this adapter.
|
||||
AGSDisplayInfo* displays; ///< List of displays allocated by AGS to be numDisplays in length.
|
||||
|
||||
int eyefinityEnabled; ///< Indicates if Eyefinity is active
|
||||
int eyefinityGridWidth; ///< Contains width of the multi-monitor grid that makes up the Eyefinity Single Large Surface.
|
||||
int eyefinityGridHeight; ///< Contains height of the multi-monitor grid that makes up the Eyefinity Single Large Surface.
|
||||
int eyefinityResolutionX; ///< Contains width in pixels of the multi-monitor Single Large Surface.
|
||||
int eyefinityResolutionY; ///< Contains height in pixels of the multi-monitor Single Large Surface.
|
||||
int eyefinityBezelCompensated; ///< Indicates if bezel compensation is used for the current SLS display area. 1 if enabled, and 0 if disabled.
|
||||
|
||||
int adlAdapterIndex; ///< Internally used index into the ADL list of adapters
|
||||
int reserved; ///< reserved field
|
||||
} AGSDeviceInfo;
|
||||
|
||||
/// \defgroup general General API functions
|
||||
/// API for initialization, cleanup, HDR display modes and Crossfire GPU count
|
||||
/// @{
|
||||
|
||||
typedef void* (__stdcall *AGS_ALLOC_CALLBACK)( size_t allocationSize ); ///< AGS user defined allocation prototype
|
||||
typedef void (__stdcall *AGS_FREE_CALLBACK)( void* allocationPtr ); ///< AGS user defined free prototype
|
||||
|
||||
/// The configuration options that can be passed in to \ref agsInitialize
|
||||
typedef struct AGSConfiguration
|
||||
{
|
||||
AGS_ALLOC_CALLBACK allocCallback; ///< Optional memory allocation callback. If not supplied, malloc() is used
|
||||
AGS_FREE_CALLBACK freeCallback; ///< Optional memory freeing callback. If not supplied, free() is used
|
||||
} AGSConfiguration;
|
||||
|
||||
/// The top level GPU information returned from \ref agsInitialize
|
||||
typedef struct AGSGPUInfo
|
||||
{
|
||||
const char* driverVersion; ///< The AMD driver package version
|
||||
const char* radeonSoftwareVersion; ///< The Radeon Software Version
|
||||
|
||||
int numDevices; ///< Number of GPUs in the system
|
||||
AGSDeviceInfo* devices; ///< List of GPUs in the system
|
||||
} AGSGPUInfo;
|
||||
|
||||
/// The struct to specify the display settings to the driver.
|
||||
typedef struct AGSDisplaySettings AGSDisplaySettings;
|
||||
|
||||
|
||||
/// The result returned from \ref agsCheckDriverVersion
|
||||
typedef enum AGSDriverVersionResult
|
||||
{
|
||||
AGS_SOFTWAREVERSIONCHECK_OK, ///< The reported Radeon Software Version is newer or the same as the required version
|
||||
AGS_SOFTWAREVERSIONCHECK_OLDER, ///< The reported Radeon Software Version is older than the required version
|
||||
AGS_SOFTWAREVERSIONCHECK_UNDEFINED ///< The check could not determine as result. This could be because it is a private or custom driver or just invalid arguments.
|
||||
} AGSDriverVersionResult;
|
||||
|
||||
///
|
||||
/// Helper function to check the installed software version against the required software version.
|
||||
///
|
||||
/// \param [in] radeonSoftwareVersionReported The Radeon Software Version returned from \ref AGSGPUInfo::radeonSoftwareVersion.
|
||||
/// \param [in] radeonSoftwareVersionRequired The Radeon Software Version to check against. This is specificed using \ref AGS_MAKE_VERSION.
|
||||
/// \return The result of the check.
|
||||
///
|
||||
AMD_AGS_API AGSDriverVersionResult agsCheckDriverVersion( const char* radeonSoftwareVersionReported, unsigned int radeonSoftwareVersionRequired );
|
||||
|
||||
///
|
||||
/// Function to return the AGS version number.
|
||||
///
|
||||
/// \return The version number made using AGS_MAKE_VERSION( AMD_AGS_VERSION_MAJOR, AMD_AGS_VERSION_MINOR, AMD_AGS_VERSION_PATCH ).
|
||||
///
|
||||
AMD_AGS_API int agsGetVersionNumber();
|
||||
|
||||
///
|
||||
/// Function used to initialize the AGS library.
|
||||
/// agsVersion must be specified as AGS_CURRENT_VERSION or the call will return \ref AGS_INVALID_ARGS.
|
||||
/// Must be called prior to any of the subsequent AGS API calls.
|
||||
/// Must be called prior to ID3D11Device or ID3D12Device creation.
|
||||
/// \note The caller of this function should handle the possibility of the call failing in the cases below. One option is to do a vendor id check and only call \ref agsInitialize if there is an AMD GPU present.
|
||||
/// \note This function will fail with \ref AGS_NO_AMD_DRIVER_INSTALLED if there is no AMD driver found on the system.
|
||||
/// \note This function will fail with \ref AGS_LEGACY_DRIVER in Catalyst versions before 12.20.
|
||||
///
|
||||
/// \param [in] agsVersion The API version specified using the \ref AGS_CURRENT_VERSION macro. If this does not match the version in the binary this initialization call will fail.
|
||||
/// \param [in] config Optional pointer to a AGSConfiguration struct to override the default library configuration.
|
||||
/// \param [out] context Address of a pointer to a context. This function allocates a context on the heap which is then required for all subsequent API calls.
|
||||
/// \param [out] gpuInfo Optional pointer to a AGSGPUInfo struct which will get filled in for all the GPUs in the system.
|
||||
///
|
||||
AMD_AGS_API AGSReturnCode agsInitialize( int agsVersion, const AGSConfiguration* config, AGSContext** context, AGSGPUInfo* gpuInfo );
|
||||
|
||||
///
|
||||
/// Function used to clean up the AGS library.
|
||||
///
|
||||
/// \param [in] context Pointer to a context. This function will deallocate the context from the heap.
|
||||
///
|
||||
AMD_AGS_API AGSReturnCode agsDeInitialize( AGSContext* context );
|
||||
|
||||
///
|
||||
/// Function used to set a specific display into HDR mode
|
||||
/// \note Setting all of the values apart from color space and transfer function to zero will cause the display to use defaults.
|
||||
/// \note Call this function after each mode change (switch to fullscreen, any change in swapchain etc).
|
||||
/// \note HDR10 PQ mode requires a 1010102 swapchain.
|
||||
/// \note HDR10 scRGB mode requires an FP16 swapchain.
|
||||
/// \note Freesync HDR scRGB mode requires an FP16 swapchain.
|
||||
/// \note Freesync HDR Gamma 2.2 mode requires a 1010102 swapchain.
|
||||
/// \note Dolby Vision requires a 8888 UNORM swapchain.
|
||||
///
|
||||
/// \param [in] context Pointer to a context. This is generated by \ref agsInitialize
|
||||
/// \param [in] deviceIndex The index of the device listed in \ref AGSGPUInfo::devices.
|
||||
/// \param [in] displayIndex The index of the display listed in \ref AGSDeviceInfo::displays.
|
||||
/// \param [in] settings Pointer to the display settings to use.
|
||||
///
|
||||
AMD_AGS_API AGSReturnCode agsSetDisplayMode( AGSContext* context, int deviceIndex, int displayIndex, const AGSDisplaySettings* settings );
|
||||
|
||||
/// @}
|
||||
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // AMD_AGS_H
|
||||
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK",
|
||||
"license": "MIT (embeded in source)",
|
||||
"version": "AGS v6.2.0",
|
||||
"author": "Advanced Micro Devices, Inc",
|
||||
"modified": "CarterLi"
|
||||
}
|
||||
+2596
File diff suppressed because it is too large
Load Diff
+46
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// MIT LICENSE:
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
/// \file adl_sdk.h
|
||||
/// \brief Contains the definition of the Memory Allocation Callback.\n <b>Included in ADL SDK</b>
|
||||
///
|
||||
/// \n\n
|
||||
/// This file contains the definition of the Memory Allocation Callback.\n
|
||||
/// It also includes definitions of the respective structures and constants.\n
|
||||
/// <b> This is the only header file to be included in a C/C++ project using ADL </b>
|
||||
|
||||
#ifndef ADL_SDK_H_
|
||||
#define ADL_SDK_H_
|
||||
|
||||
#include "adl_structures.h"
|
||||
|
||||
#if defined (LINUX)
|
||||
#define __stdcall
|
||||
#endif /* (LINUX) */
|
||||
|
||||
/// Memory Allocation Call back
|
||||
typedef void* ( __stdcall *ADL_MAIN_MALLOC_CALLBACK )( int );
|
||||
|
||||
#define ADL_SDK_MAJOR_VERSION 17
|
||||
#define ADL_SDK_MINOR_VERSION 1
|
||||
|
||||
#endif /* ADL_SDK_H_ */
|
||||
+4289
File diff suppressed because it is too large
Load Diff
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/GPUOpen-LibrariesAndSDKs/display-library",
|
||||
"license": "MIT (embeded in source)",
|
||||
"version": "ADL SDK 17.1",
|
||||
"author": "Advanced Micro Devices, Inc"
|
||||
}
|
||||
@@ -119,7 +119,6 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (__APPLE__ || __HAIKU__) // #1395
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
@@ -131,24 +130,6 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
|
||||
|
||||
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
#else
|
||||
size_t len = strlen(path);
|
||||
assert(len < PATH_MAX);
|
||||
if (len == 0) return false;
|
||||
|
||||
int ret;
|
||||
if (path[len - 1] != '/')
|
||||
{
|
||||
char buf[PATH_MAX + 1];
|
||||
memcpy(buf, path, len);
|
||||
buf[len] = '/';
|
||||
buf[len + 1] = 0;
|
||||
ret = access(buf, F_OK);
|
||||
}
|
||||
else
|
||||
ret = access(path, F_OK);
|
||||
return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -256,6 +256,11 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (instance.config.display.debugMode)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
static bool init = false;
|
||||
static int origOut = -1;
|
||||
static int origErr = -1;
|
||||
|
||||
@@ -159,6 +159,11 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (instance.config.display.debugMode)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
static bool init = false;
|
||||
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
static bool getDefaultRouteIPv4(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r");
|
||||
if (!netRoute) return false;
|
||||
@@ -15,12 +15,38 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
// skip first line
|
||||
FF_UNUSED(fscanf(netRoute, "%*[^\n]\n"));
|
||||
|
||||
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
|
||||
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu, ...
|
||||
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
|
||||
{
|
||||
if (destination != 0) continue;
|
||||
*ifIndex = if_nametoindex(iface);
|
||||
return true;
|
||||
}
|
||||
iface[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getDefaultRouteIPv6(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/ipv6_route", "r");
|
||||
if (!netRoute) return false;
|
||||
|
||||
uint32_t prefixLen;
|
||||
//destination, dest_prefix_len, source, src_prefix_len, next hop, metric, ref counter, use counter, flags, iface
|
||||
while (fscanf(netRoute, "%*s %x %*s %*s %*s %*s %*s %*s %*s %" FF_STR(IF_NAMESIZE) "s", &prefixLen, iface) == 2)
|
||||
{
|
||||
if (prefixLen != 0) continue;
|
||||
*ifIndex = if_nametoindex(iface);
|
||||
return true;
|
||||
}
|
||||
iface[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
{
|
||||
if (getDefaultRouteIPv4(iface, ifIndex))
|
||||
return true;
|
||||
|
||||
return getDefaultRouteIPv6(iface, ifIndex);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ static const char* initNetworkingState(FFNetworkingState* state, const char* hos
|
||||
ffStrbufInitA(&state->command, 64);
|
||||
ffStrbufAppendS(&state->command, "GET ");
|
||||
ffStrbufAppendS(&state->command, path);
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.0\nHost: ");
|
||||
ffStrbufAppendS(&state->command, host);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
@@ -476,7 +476,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
||||
return "Content length mismatch";
|
||||
}
|
||||
|
||||
if (ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
||||
FF_DEBUG("Received valid HTTP 200 response, content %u bytes, total %u bytes", contentLength, buffer->length);
|
||||
} else {
|
||||
FF_DEBUG("Invalid response: %.40s...", buffer->chars);
|
||||
|
||||
@@ -151,7 +151,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, " HTTP/1.0\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, "Connection: close\r\n"); // Explicitly request connection closure
|
||||
@@ -314,7 +314,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
||||
return "No HTTP header end found";
|
||||
}
|
||||
|
||||
if (ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n")) {
|
||||
if (ffStrbufStartsWithS(buffer, "HTTP/1.0 200 OK\r\n")) {
|
||||
FF_DEBUG("Received valid HTTP 200 response, content length: %u bytes, total length: %u bytes",
|
||||
contentLength, buffer->length);
|
||||
} else {
|
||||
|
||||
@@ -198,6 +198,12 @@ void ffParseDuration(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t s
|
||||
return;
|
||||
}
|
||||
|
||||
if(seconds >= 30)
|
||||
{
|
||||
minutes++;
|
||||
seconds = 0;
|
||||
}
|
||||
|
||||
if(days > 0)
|
||||
{
|
||||
ffStrbufAppendF(result, "%u day", days);
|
||||
|
||||
+2
-2
@@ -65,8 +65,8 @@
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
|
||||
{
|
||||
ts.tv_sec += ts.tv_sec / 1000;
|
||||
ts.tv_nsec += (ts.tv_nsec % 1000) * 1000000;
|
||||
ts.tv_sec += timeout / 1000;
|
||||
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
|
||||
{
|
||||
pthread_kill(thread, SIGTERM);
|
||||
|
||||
@@ -98,7 +98,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
// https://github.com/AsahiLinux/linux/blob/b5c05cbffb0488c7618106926d522cc3b43d93d5/drivers/power/supply/macsmc_power.c#L410-L419
|
||||
int year = (manufactureDate[0] - '0') * 10 + (manufactureDate[1] - '0') + 2000 - 8;
|
||||
int month = (manufactureDate[2] - '0') * 10 + (manufactureDate[3] - '0');
|
||||
int day = (manufactureDate[4] - '0') * 10 + (manufactureDate[3] - '5');
|
||||
int day = (manufactureDate[4] - '0') * 10 + (manufactureDate[3] - '0');
|
||||
ffStrbufSetF(&battery->manufactureDate, "%.4d-%.2d-%.2d", year, month, day);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ static void parseBattery(int dfd, const char* id, FFBatteryOptions* options, FFl
|
||||
|
||||
if (ffReadFileBufferRelative(dfd, "capacity_level", &tmpBuffer))
|
||||
{
|
||||
ffStrbufTrimRightSpace(&result->manufacturer);
|
||||
ffStrbufTrimRightSpace(&tmpBuffer);
|
||||
if (ffStrbufEqualS(&tmpBuffer, "Critical"))
|
||||
{
|
||||
if (result->status.length)
|
||||
|
||||
@@ -70,9 +70,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
||||
critical = true;
|
||||
}
|
||||
else if (ffStrEquals(desc, "discharge rate"))
|
||||
{
|
||||
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
|
||||
}
|
||||
}
|
||||
|
||||
if (max > 0)
|
||||
@@ -92,7 +90,10 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
||||
if (charging)
|
||||
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||
else if (dischargeRate)
|
||||
{
|
||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||
battery->timeRemaining = (int32_t)((double)curr / dischargeRate * 3600);
|
||||
}
|
||||
if (critical)
|
||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||
if (acConnected)
|
||||
@@ -100,8 +101,11 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
||||
ffStrbufTrimRight(&battery->status, ' ');
|
||||
ffStrbufTrimRight(&battery->status, ',');
|
||||
}
|
||||
|
||||
prop_object_iterator_release(iter);
|
||||
}
|
||||
prop_object_iterator_release(itKey);
|
||||
prop_object_release(root);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ const char* ffDetectBios(FFBiosResult* result)
|
||||
{
|
||||
ffStrbufSetStatic(&result->type,
|
||||
ffPathExists("/dev/efi" /*efidev*/, FF_PATHTYPE_FILE) ||
|
||||
ffPathExists("/boot/efi/efi/" /*efi partition*/, FF_PATHTYPE_DIRECTORY)
|
||||
ffPathExists("/boot/efi/efi/" /*efi partition. Note /boot/efi exists on BIOS system*/, FF_PATHTYPE_DIRECTORY)
|
||||
? "UEFI" : "BIOS");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
const char *ffDetectBios(FFBiosResult *bios)
|
||||
const char* ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->date);
|
||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
|
||||
|
||||
@@ -27,6 +27,11 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
||||
};
|
||||
};
|
||||
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||
#elif __OpenBSD__
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
typedef struct FFSmbiosBios
|
||||
@@ -89,8 +94,8 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#elif __HAIKU__
|
||||
// Currently SMBIOS detection is supported in legency BIOS only
|
||||
#elif __HAIKU__ || __OpenBSD__
|
||||
// Currently SMBIOS detection is supported in legancy BIOS only
|
||||
ffStrbufSetStatic(&bios->type, "BIOS");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -21,5 +21,5 @@ const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MA
|
||||
if (bt_devenum((void*) enumDev, devices) < 0)
|
||||
return "bt_devenum() failed";
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#import <IOBluetooth/IOBluetooth.h>
|
||||
|
||||
// For some reason the official declaration of IOBluetoothHostController don't include property `controllers`
|
||||
// For some reason the official declaration of IOBluetoothHostController doesn't include property `controllers`
|
||||
@interface IOBluetoothHostController()
|
||||
+ (id)controllers;
|
||||
@end
|
||||
|
||||
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothResult */)
|
||||
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||
{
|
||||
NSArray<IOBluetoothHostController*>* ctrls = IOBluetoothHostController.controllers;
|
||||
if(!ctrls)
|
||||
|
||||
@@ -83,7 +83,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||
ffStrbufInitS(&device->name, blri.localInfo.name);
|
||||
|
||||
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
|
||||
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
addr.rgBytes[5],
|
||||
addr.rgBytes[4],
|
||||
addr.rgBytes[3],
|
||||
@@ -97,6 +97,8 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||
device->enabled = true;
|
||||
device->connectable = ffBluetoothIsConnectable(hRadio);
|
||||
device->discoverable = ffBluetoothIsDiscoverable(hRadio);
|
||||
|
||||
CloseHandle(hRadio);
|
||||
} while (ffBluetoothFindNextRadio(hFind, &hRadio));
|
||||
|
||||
ffBluetoothFindRadioClose(hFind);
|
||||
|
||||
@@ -6,6 +6,7 @@ typedef struct FFBootmgrResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf firmware;
|
||||
uint16_t order;
|
||||
bool secureBoot;
|
||||
} FFBootmgrResult;
|
||||
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
#include "efi_helper.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <sys/efiio.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <dev/efi/efiio.h>
|
||||
#else
|
||||
#include <sys/efiio.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
typedef uint16_t efi_char;
|
||||
#endif
|
||||
|
||||
#ifndef EFI_GLOBAL_VARIABLE
|
||||
#define EFI_GLOBAL_VARIABLE { 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, { 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } }
|
||||
#endif
|
||||
|
||||
const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int efifd = open("/dev/efi", O_RDWR);
|
||||
@@ -13,7 +25,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
|
||||
uint8_t buffer[2048];
|
||||
struct efi_var_ioc ioc = {
|
||||
.vendor = { 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, { 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c } },
|
||||
.vendor = EFI_GLOBAL_VARIABLE,
|
||||
.data = buffer,
|
||||
};
|
||||
|
||||
@@ -23,8 +35,10 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
if (ioctl(efifd, EFIIOC_VAR_GET, &ioc) < 0 || ioc.datasize != 2)
|
||||
return "ioctl(EFIIOC_VAR_GET, BootCurrent) failed";
|
||||
|
||||
result->order = *(uint16_t*)buffer;
|
||||
|
||||
unsigned char hex[5];
|
||||
snprintf((char*) hex, sizeof(hex), "%04X", *(uint16_t*)buffer);
|
||||
snprintf((char*) hex, sizeof(hex), "%04X", result->order);
|
||||
ioc.datasize = sizeof(buffer);
|
||||
ioc.name = (efi_char[]){ 'B', 'o', 'o', 't', hex[0], hex[1], hex[2], hex[3], '\0' };
|
||||
ioc.namesize = sizeof("Boot####") * 2;
|
||||
|
||||
@@ -11,8 +11,10 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
if (ffReadFileData(FF_EFIVARS_PATH_PREFIX "BootCurrent-" FF_EFI_GLOBAL_GUID, sizeof(buffer), buffer) != 6)
|
||||
return "Failed to read efivar: BootCurrent";
|
||||
|
||||
uint16_t value = *(uint16_t *)&buffer[4];
|
||||
snprintf((char*) buffer, sizeof(buffer), FF_EFIVARS_PATH_PREFIX "Boot%04X-" FF_EFI_GLOBAL_GUID, value);
|
||||
|
||||
result->order = *(uint16_t *)&buffer[4];
|
||||
|
||||
snprintf((char*) buffer, sizeof(buffer), FF_EFIVARS_PATH_PREFIX "Boot%04X-" FF_EFI_GLOBAL_GUID, result->order);
|
||||
|
||||
ssize_t size = ffReadFileData((const char*) buffer, sizeof(buffer), buffer);
|
||||
if (size < 5 + (int) sizeof(FFEfiLoadOption) || size == (ssize_t) sizeof(buffer))
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "bootmgr.h"
|
||||
#include "efi_helper.h"
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
const char* enablePrivilege(const wchar_t* privilege)
|
||||
{
|
||||
HANDLE token;
|
||||
FF_AUTO_CLOSE_FD HANDLE token = NULL;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
|
||||
return "OpenProcessToken() failed";
|
||||
|
||||
@@ -32,13 +33,12 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
if (enablePrivilege(L"SeSystemEnvironmentPrivilege") != NULL)
|
||||
return "Failed to enable SeSystemEnvironmentPrivilege";
|
||||
|
||||
uint16_t value;
|
||||
if (GetFirmwareEnvironmentVariableW(L"BootCurrent", L"{" FF_EFI_GLOBAL_GUID L"}", &value, sizeof(value)) != 2)
|
||||
if (GetFirmwareEnvironmentVariableW(L"BootCurrent", L"{" FF_EFI_GLOBAL_GUID L"}", &result->order, sizeof(result->order)) != 2)
|
||||
return "GetFirmwareEnvironmentVariableW(BootCurrent) failed";
|
||||
|
||||
uint8_t buffer[2048];
|
||||
wchar_t key[16];
|
||||
swprintf(key, ARRAY_SIZE(key), L"Boot%04X", value);
|
||||
swprintf(key, ARRAY_SIZE(key), L"Boot%04X", result->order);
|
||||
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
|
||||
if (size < sizeof(FFEfiLoadOption) || size == ARRAY_SIZE(buffer))
|
||||
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
|
||||
|
||||
@@ -8,24 +8,35 @@
|
||||
|
||||
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int devfd = open("/dev/ttyC0", O_RDONLY);
|
||||
char path[] = "/dev/ttyCX";
|
||||
for (char i = '0'; i <= '9'; ++i) {
|
||||
path[strlen("/dev/ttyC")] = i;
|
||||
|
||||
if (devfd < 0) return "open(dev/ttyC0, O_RDONLY) failed";
|
||||
FF_AUTO_CLOSE_FD int devfd = open(path, O_RDONLY);
|
||||
|
||||
struct wsdisplay_param param = {
|
||||
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
|
||||
};
|
||||
if (devfd < 0) {
|
||||
if (errno == EACCES && i == '0')
|
||||
return "Permission denied when opening tty device";
|
||||
if (errno == ENOENT)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
|
||||
return "ioctl(WSDISPLAYIO_GETPARAM) failed";
|
||||
struct wsdisplay_param param = {
|
||||
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
|
||||
};
|
||||
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufInitStatic(&brightness->name, "wsdisplay");
|
||||
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, ¶m) < 0)
|
||||
continue;
|
||||
|
||||
brightness->max = param.max;
|
||||
brightness->min = param.min;
|
||||
brightness->current = param.curval;
|
||||
brightness->builtin = true;
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
ffStrbufInitF(&brightness->name, "ttyC%c", i);
|
||||
|
||||
brightness->max = param.max;
|
||||
brightness->min = param.min;
|
||||
brightness->current = param.curval;
|
||||
brightness->builtin = true;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
|
||||
FF_LIBRARY_LOAD(dxva2, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, DestroyPhysicalMonitor)
|
||||
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||
{
|
||||
@@ -64,6 +65,8 @@ static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, F
|
||||
brightness->current = curr;
|
||||
brightness->builtin = false;
|
||||
}
|
||||
|
||||
ffDestroyPhysicalMonitor(physicalMonitor.hPhysicalMonitor);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@@ -12,7 +12,10 @@ static const char* enumerateDevices(FFBtrfsResult* item, int dfd, FFstrbuf* buff
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = fdopendir(subfd);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
close(subfd);
|
||||
return "fdopendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
|
||||
@@ -37,7 +37,7 @@ const char* ffDetectCamera(FFlist* result)
|
||||
{
|
||||
case V4L2_COLORSPACE_SMPTE170M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 170M"); break;
|
||||
case V4L2_COLORSPACE_SMPTE240M: ffStrbufInitStatic(&camera->colorspace, "SMPTE 240M"); break;
|
||||
case V4L2_COLORSPACE_BT878: ffStrbufInitStatic(&camera->colorspace, "BT.808"); break;
|
||||
case V4L2_COLORSPACE_BT878: ffStrbufInitStatic(&camera->colorspace, "BT.878"); break;
|
||||
case V4L2_COLORSPACE_470_SYSTEM_M: ffStrbufInitStatic(&camera->colorspace, "NTSC"); break;
|
||||
case V4L2_COLORSPACE_470_SYSTEM_BG: ffStrbufInitStatic(&camera->colorspace, "EBU 3213"); break;
|
||||
case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break;
|
||||
|
||||
@@ -48,7 +48,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
IMFActivate* device = devices[i];
|
||||
IMFActivate* FF_AUTO_RELEASE_COM_OBJECT device = devices[i];
|
||||
|
||||
wchar_t buffer[256];
|
||||
uint32_t length = 0;
|
||||
@@ -90,9 +90,11 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
continue;
|
||||
|
||||
// Assume first type is the maximum resolution
|
||||
IMFMediaType* FF_AUTO_RELEASE_COM_OBJECT type = NULL;
|
||||
IMFMediaType* type = NULL;
|
||||
for (DWORD idx = 0; SUCCEEDED(handler->GetMediaTypeByIndex(idx, &type)); ++idx)
|
||||
{
|
||||
on_scope_exit destroyType([=] { type->Release(); });
|
||||
|
||||
GUID majorType;
|
||||
if (FAILED(type->GetMajorType(&majorType)) || majorType != MFMediaType_Video)
|
||||
continue;
|
||||
@@ -123,7 +125,7 @@ const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
}
|
||||
}
|
||||
|
||||
CoTaskMemFree(devices);
|
||||
if (devices) CoTaskMemFree(devices);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ const char* ffChassisTypeToString(uint32_t type)
|
||||
case 0x1A: return "Compact PCI";
|
||||
case 0x1B: return "Advanced TCA";
|
||||
case 0x1C: return "Blade";
|
||||
case 0x1D: return "Mobile Workstation";
|
||||
case 0x1E: return "Tablet";
|
||||
case 0x1F: return "Convertible";
|
||||
case 0x20: return "Detachable";
|
||||
|
||||
@@ -17,10 +17,11 @@ const char* ffDetectChassis(FFChassisResult* result)
|
||||
|
||||
if (ffStrbufStartsWithS(&host.name, "MacBook "))
|
||||
ffStrbufSetStatic(&result->type, "Laptop");
|
||||
else if (ffStrbufStartsWithS(&host.name, "Mac mini "))
|
||||
else if (ffStrbufStartsWithS(&host.name, "Mac mini ") ||
|
||||
ffStrbufStartsWithS(&host.name, "Mac Studio "))
|
||||
ffStrbufSetStatic(&result->type, "Mini PC");
|
||||
else if (ffStrbufStartsWithS(&host.name, "iMac "))
|
||||
ffStrbufSetStatic(&result->type, "All-in-One");
|
||||
ffStrbufSetStatic(&result->type, "All in One");
|
||||
else
|
||||
ffStrbufSetStatic(&result->type, "Desktop");
|
||||
|
||||
|
||||
@@ -430,7 +430,6 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
|
||||
|
||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
|
||||
{
|
||||
if (!p) break;
|
||||
p += strlen("\nphysical id\t:");
|
||||
char* pend;
|
||||
unsigned long id = strtoul(p, &pend, 10);
|
||||
@@ -586,7 +585,6 @@ FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const c
|
||||
|
||||
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen)))
|
||||
{
|
||||
if (!p) break;
|
||||
p += keylen;
|
||||
char* pend;
|
||||
unsigned long id = strtoul(p, &pend, 10);
|
||||
@@ -608,7 +606,7 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options,
|
||||
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#else
|
||||
#elif !__powerpc__ && !__powerpc
|
||||
detectSocName(cpu);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,12 +9,19 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static void freePropDict(prop_dictionary_t* pdict)
|
||||
{
|
||||
assert(pdict != NULL);
|
||||
if (*pdict == NULL) return;
|
||||
prop_object_release(*pdict);
|
||||
}
|
||||
|
||||
static const char* detectCpuTemp(double* current)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
|
||||
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
|
||||
|
||||
prop_dictionary_t root = NULL;
|
||||
__attribute__((__cleanup__(freePropDict))) prop_dictionary_t root = NULL;
|
||||
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
|
||||
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
||||
|
||||
|
||||
@@ -23,22 +23,24 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
||||
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "brand");
|
||||
ffStrbufSetNS(&cpu->name, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
if (kn) ffStrbufSetNS(&cpu->name, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
if (kn) ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
if (kn->value.ui32 > cpu->frequencyBase)
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
if (kn && kn->value.ui32 > cpu->frequencyBase)
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "ncpus");
|
||||
cpu->coresLogical = cpu->coresPhysical = cpu->coresOnline = (uint16_t) kn->value.ui32;
|
||||
if (kn) cpu->coresLogical = cpu->coresPhysical = cpu->coresOnline = (uint16_t) kn->value.ui32;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -128,9 +128,13 @@ static const char* detectByRegistry(FFCPUResult* cpu)
|
||||
|
||||
if (cpu->coresLogical == 0)
|
||||
{
|
||||
DWORD cores;
|
||||
if (RegQueryInfoKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", NULL, NULL, &cores, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
|
||||
FF_HKEY_AUTO_DESTROY hProcsKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", &hProcsKey, NULL))
|
||||
{
|
||||
uint32_t cores;
|
||||
if (ffRegGetNSubKeys(hProcsKey, &cores, NULL))
|
||||
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mhz;
|
||||
|
||||
@@ -26,6 +26,8 @@ const char* detectThermalTemp(double* current, double* critical)
|
||||
else
|
||||
*critical = 0.0/0.0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return "No WMI result returned";
|
||||
|
||||
@@ -31,7 +31,7 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
||||
case CacheInstruction: cacheType = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
|
||||
case CacheData: cacheType = FF_CPU_CACHE_TYPE_DATA; break;
|
||||
case CacheTrace: cacheType = FF_CPU_CACHE_TYPE_TRACE; break;
|
||||
default: __builtin_unreachable(); break;
|
||||
default: break;
|
||||
}
|
||||
ffCPUCacheAddItem(result, ptr->Cache.Level, ptr->Cache.CacheSize, ptr->Cache.LineSize, cacheType);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <mach/processor_info.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/vm_map.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
@@ -28,5 +29,7 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
.totalAll = (uint64_t)total,
|
||||
};
|
||||
}
|
||||
|
||||
vm_deallocate(mach_task_self(), (vm_address_t) cpuInfo, numCpuInfo * sizeof(integer_t));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
|
||||
return "geom_gettree() failed";
|
||||
}
|
||||
|
||||
for (cLabels = geomTree.lg_class.lh_first; !ffStrEquals(cLabels->lg_name, "LABEL"); cLabels = cLabels->lg_class.le_next);
|
||||
for (cLabels = geomTree.lg_class.lh_first; cLabels && !ffStrEquals(cLabels->lg_name, "LABEL"); cLabels = cLabels->lg_class.le_next);
|
||||
if (!cLabels)
|
||||
return "Class LABEL is not found";
|
||||
}
|
||||
@@ -165,7 +165,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs->f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree);
|
||||
disk->filesUsed = (uint32_t) (fs->f_files - fs->f_ffree);
|
||||
|
||||
ffStrbufInitS(&disk->mountFrom, fs->f_mntfromname);
|
||||
ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
|
||||
@@ -185,7 +185,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
#ifndef __DragonFly__
|
||||
struct stat st;
|
||||
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
|
||||
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
|
||||
disk->createTime = (uint64_t)(((uint64_t) st.st_birthtimespec.tv_sec * 1000) + ((uint64_t) st.st_birthtimespec.tv_nsec / 1000000));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
for (dev_t dev; (dev = next_dev(&pos)) >= B_OK;)
|
||||
{
|
||||
fs_info fs;
|
||||
if (fs_stat_dev(dev, &fs) < -1) continue;
|
||||
if (fs_stat_dev(dev, &fs) < 0) continue;
|
||||
|
||||
node_ref node(fs.dev, fs.root);
|
||||
BDirectory dir(&node);
|
||||
@@ -32,10 +32,10 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
disk->bytesTotal = (uint64_t)fs.total_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesFree = (uint64_t)fs.free_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesAvailable = disk->bytesFree;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk. c
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.total_nodes;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs.free_nodes);
|
||||
disk->filesUsed = (uint32_t) (fs.total_nodes - fs.free_nodes);
|
||||
|
||||
ffStrbufInitS(&disk->mountFrom, fs.device_name);
|
||||
ffStrbufInitS(&disk->mountpoint, path.Path());
|
||||
|
||||
@@ -209,7 +209,10 @@ static bool isRemovable(FFDisk* currentDisk)
|
||||
char sysBlockVolume[PATH_MAX]; // /sys/devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
if (realpath(sysBlockPartition, sysBlockVolume) == NULL)
|
||||
return false;
|
||||
strcpy(strrchr(sysBlockVolume, '/') + 1, "removable");
|
||||
char* lastSlash = strrchr(sysBlockVolume, '/');
|
||||
if (lastSlash == NULL)
|
||||
return false;
|
||||
strcpy(lastSlash + 1, "removable");
|
||||
|
||||
char removableChar = '0';
|
||||
return ffReadFileData(sysBlockVolume, 1, &removableChar) > 0 && removableChar == '1';
|
||||
|
||||
@@ -99,9 +99,6 @@ static void detectStats(FFDisk* disk)
|
||||
ffStrbufSetS(&disk->name, fs.f_fstr);
|
||||
|
||||
disk->createTime = 0;
|
||||
struct stat deviceStat;
|
||||
if(stat(disk->mountpoint.chars, &deviceStat) == 0)
|
||||
disk->createTime = (uint64_t) deviceStat.st_ctim.tv_sec * 1000 + (uint64_t) deviceStat.st_ctim.tv_nsec / 1000000000;
|
||||
}
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
|
||||
@@ -69,10 +69,15 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
|
||||
uint64_t temp = *currValue;
|
||||
*currValue -= *prevValue;
|
||||
*currValue /= (time2 - time1) / 1000 /* seconds */;
|
||||
|
||||
// For next function call
|
||||
*prevValue = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// For next function call
|
||||
time1 = time2;
|
||||
// Leak ioCounters1 here
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
struct gmesh geomTree;
|
||||
__attribute__((__cleanup__(geom_deletetree)))
|
||||
struct gmesh geomTree = {};
|
||||
if (geom_gettree(&geomTree) < 0)
|
||||
return "geom_gettree() failed";
|
||||
|
||||
@@ -21,6 +22,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
return "geom_stats_open() failed";
|
||||
|
||||
void* snap = geom_stats_snapshot_get();
|
||||
if (!snap)
|
||||
return "geom_stats_snapshot_get() failed";
|
||||
|
||||
struct devstat* snapIter;
|
||||
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
||||
{
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options)
|
||||
static const char* parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
||||
if (devfd < 0) return; // virtual device
|
||||
if (devfd < 0) return "virtual device";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
@@ -49,7 +49,7 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
return;
|
||||
return "ignored";
|
||||
}
|
||||
|
||||
// I/Os merges sectors ticks ...
|
||||
@@ -57,10 +57,10 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
||||
{
|
||||
char sysBlockStat[PROC_FILE_BUFFSIZ];
|
||||
ssize_t fileSize = ffReadFileDataRelative(dfd, "stat", ARRAY_SIZE(sysBlockStat) - 1, sysBlockStat);
|
||||
if (fileSize <= 0) return;
|
||||
if (fileSize <= 0) return "failed to read stat file";
|
||||
sysBlockStat[fileSize] = '\0';
|
||||
if (sscanf(sysBlockStat, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
|
||||
return;
|
||||
return "invalid stat file format";
|
||||
}
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
@@ -70,6 +70,8 @@ static void parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FF
|
||||
device->bytesWritten = sectorWritten * 512;
|
||||
device->readCount = nRead;
|
||||
device->writeCount = nWritten;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
@@ -83,7 +85,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
const char* const devName = sysBlockEntry->d_name;
|
||||
|
||||
if (devName[0] == '.') continue;;
|
||||
if (devName[0] == '.') continue;
|
||||
|
||||
FF_AUTO_CLOSE_FD int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
|
||||
if (dfd > 0) parseDiskIOCounters(dfd, devName, result, options);
|
||||
|
||||
@@ -12,12 +12,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
|
||||
return "sysctl({HW_IOSTATS}, NULL) failed";
|
||||
uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl));
|
||||
|
||||
struct io_sysctl* stats = malloc(len);
|
||||
|
||||
FF_AUTO_FREE struct io_sysctl* stats = malloc(len);
|
||||
|
||||
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
||||
return "sysctl({HW_IOSTATS}, stats) failed";
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < nDrive; ++i)
|
||||
{
|
||||
struct io_sysctl* st = &stats[i];
|
||||
|
||||
@@ -13,7 +13,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
return "sysctl({HW_DISKSTATS}, NULL) failed";
|
||||
uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats));
|
||||
|
||||
struct diskstats* stats = malloc(len);
|
||||
FF_AUTO_FREE struct diskstats* stats = malloc(len);
|
||||
|
||||
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
|
||||
return "sysctl({HW_DISKSTATS}, stats) failed";
|
||||
|
||||
@@ -27,7 +27,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->devPath);
|
||||
ffStrbufInit(&device->devPath); // unlike other platforms, `/dev/ks_name` is not available
|
||||
ffStrbufInitS(&device->name, ks->ks_name);
|
||||
device->bytesRead = kio.nread;
|
||||
device->readCount = kio.reads;
|
||||
|
||||
@@ -56,8 +56,6 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFDiskIO
|
||||
return true;
|
||||
}
|
||||
|
||||
ffStrbufInitWS(&device->devPath, szDevice);
|
||||
|
||||
DISK_PERFORMANCE dp = {};
|
||||
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
|
||||
{
|
||||
@@ -72,6 +70,8 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFDiskIO
|
||||
result->length--;
|
||||
}
|
||||
|
||||
ffStrbufInitWS(&device->devPath, szDevice);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,33 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static bool checkHdrStatus(FFDisplayResult* display)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
|
||||
if (ffSettingsGetAndroidProperty("ro.surface_flinger.has_HDR_display", &buffer))
|
||||
{
|
||||
if (ffStrbufIgnCaseEqualS(&buffer, "true"))
|
||||
{
|
||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
|
||||
|
||||
if (ffSettingsGetAndroidProperty("persist.sys.hdr_mode", &buffer) &&
|
||||
ffStrbufToUInt(&buffer, 0) > 0)
|
||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
@@ -54,7 +81,7 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
}
|
||||
|
||||
ffStrbufRecalculateLength(&name);
|
||||
ffdsAppendDisplay(ds,
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
(uint32_t)width,
|
||||
(uint32_t)height,
|
||||
refreshRate,
|
||||
@@ -72,6 +99,7 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
0,
|
||||
"dumpsys"
|
||||
);
|
||||
if (display) display->hdrStatus = checkHdrStatus(display);
|
||||
}
|
||||
|
||||
index = nextIndex + 1;
|
||||
@@ -92,7 +120,7 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
||||
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
|
||||
return ffdsAppendDisplay(ds,
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
@@ -110,6 +138,8 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
0,
|
||||
"getprop"
|
||||
);
|
||||
if (display) display->hdrStatus = checkHdrStatus(display);
|
||||
return !!display;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -68,7 +68,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
if(ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames) == NULL)
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &buffer);
|
||||
|
||||
// CGDisplayScreenSize reports invalid result for external displays on old Intel MacBook Pro
|
||||
|
||||
@@ -273,7 +273,7 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result)
|
||||
FF_LIST_FOR_EACH(FFstrbuf, basePath, instance.state.platform.configDirs)
|
||||
{
|
||||
char path[1024];
|
||||
snprintf(path, ARRAY_SIZE(path) - 1, "%s%s", basePath->chars, fileName);
|
||||
snprintf(path, ARRAY_SIZE(path), "%s%s", basePath->chars, fileName);
|
||||
if (ffReadFileBuffer(path, &monitorsXml))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||
ffStrbufAppendS(&procPath, dirent->d_name);
|
||||
uint32_t procFolderPathLength = procPath.length;
|
||||
|
||||
//Don't check for processes not owend by the current user.
|
||||
//Don't check for processes not owned by the current user.
|
||||
ffStrbufAppendS(&procPath, "/loginuid");
|
||||
ffReadFileBuffer(procPath.chars, &loginuid);
|
||||
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
|
||||
|
||||
@@ -26,7 +26,7 @@ typedef struct XcbPropertyData
|
||||
FF_LIBRARY_SYMBOL(xcb_get_atom_name_reply)
|
||||
} XcbPropertyData;
|
||||
|
||||
static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyData)
|
||||
static bool xcbInitPropertyData(FF_MAYBE_UNUSED void* libraryHandle, XcbPropertyData* propertyData)
|
||||
{
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom_reply, false)
|
||||
@@ -333,7 +333,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
|
||||
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcbRandr, "dlopen lbxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD(xcbRandr, "dlopen libxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_connect)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_get_setup)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_setup_roots_iterator)
|
||||
@@ -369,7 +369,7 @@ const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
|
||||
data.connection = ffxcb_connect(NULL, NULL);
|
||||
if(data.connection == NULL)
|
||||
return "xcb_connect failed";
|
||||
return "xcb_connect() failed";
|
||||
|
||||
|
||||
data.result = result;
|
||||
|
||||
@@ -17,7 +17,7 @@ typedef struct X11PropertyData
|
||||
FF_LIBRARY_SYMBOL(XFree)
|
||||
} X11PropertyData;
|
||||
|
||||
static bool x11InitPropertyData(void* libraryHandle, X11PropertyData* propertyData)
|
||||
static bool x11InitPropertyData(FF_MAYBE_UNUSED void* libraryHandle, X11PropertyData* propertyData)
|
||||
{
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XInternAtom, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XGetWindowProperty, false)
|
||||
@@ -147,7 +147,7 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
||||
"xlib-randr-crtc"
|
||||
);
|
||||
|
||||
if (edidLength)
|
||||
if (item && edidLength)
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
@@ -231,7 +231,7 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
|
||||
if(monitorInfos == NULL)
|
||||
return false;
|
||||
|
||||
bool foundAMonitor;
|
||||
bool foundAMonitor = false;
|
||||
|
||||
for(int i = 0; i < numberOfMonitors; i++)
|
||||
{
|
||||
@@ -272,7 +272,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
0,
|
||||
(uint32_t) WidthMMOfScreen(screen),
|
||||
(uint32_t) HeightMMOfScreen(screen),
|
||||
"xlib_randr_screen"
|
||||
"xlib-randr-screen"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "detection/dns/dns.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
#include <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
static const char* detectDnsFromConf(const char* path, FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
FF_DEBUG("Attempting to read DNS config from %s", path);
|
||||
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(path, "r");
|
||||
if (!file)
|
||||
{
|
||||
FF_DEBUG("Failed to open %s: %m", path);
|
||||
return "fopen(path, r) failed";
|
||||
}
|
||||
|
||||
if (results->length > 0)
|
||||
{
|
||||
FF_DEBUG("Clearing existing DNS entries (%u entries)", results->length);
|
||||
FF_LIST_FOR_EACH(FFstrbuf, item, *results)
|
||||
ffStrbufDestroy(item);
|
||||
ffListClear(results);
|
||||
}
|
||||
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while (getline(&line, &len, file) != -1)
|
||||
{
|
||||
if (ffStrStartsWith(line, "nameserver"))
|
||||
{
|
||||
char* nameserver = line + strlen("nameserver");
|
||||
while (*nameserver == ' ' || *nameserver == '\t')
|
||||
nameserver++;
|
||||
if (*nameserver == '\0') continue;
|
||||
|
||||
char* comment = strchr(nameserver, '#');
|
||||
if (comment) *comment = '\0';
|
||||
|
||||
if ((ffStrContainsC(nameserver, ':') && !(options->showType & FF_DNS_TYPE_IPV6_BIT)) ||
|
||||
(ffStrContainsC(nameserver, '.') && !(options->showType & FF_DNS_TYPE_IPV4_BIT)))
|
||||
continue;
|
||||
|
||||
FFstrbuf* item = (FFstrbuf*) ffListAdd(results);
|
||||
ffStrbufInitS(item, nameserver);
|
||||
ffStrbufTrimRightSpace(item);
|
||||
FF_DEBUG("Found DNS server: %s", item->chars);
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("Found %u DNS servers in %s", results->length, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
// Handle macOS-specific DNS configurations
|
||||
FF_DEBUG("Using SystemConfiguration framework for macOS");
|
||||
|
||||
// Create a reference to the dynamic store
|
||||
FF_CFTYPE_AUTO_RELEASE SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("fastfetch"), NULL, NULL);
|
||||
if (store)
|
||||
{
|
||||
// Get the network global IPv4 and IPv6 configuration
|
||||
FF_CFTYPE_AUTO_RELEASE CFStringRef key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetDNS);
|
||||
if (key)
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef dict = SCDynamicStoreCopyValue(store, key);
|
||||
if (dict)
|
||||
{
|
||||
// Get the DNS server addresses array
|
||||
CFArrayRef dnsServers = CFDictionaryGetValue(dict, kSCPropNetDNSServerAddresses);
|
||||
|
||||
if (dnsServers)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(dnsServers); i++)
|
||||
{
|
||||
if (ffCfStrGetString(CFArrayGetValueAtIndex(dnsServers, i), &buffer) == NULL)
|
||||
{
|
||||
// Check if the address matches our filter
|
||||
if ((ffStrbufContainC(&buffer, ':') && !(options->showType & FF_DNS_TYPE_IPV6_BIT)) ||
|
||||
(ffStrbufContainC(&buffer, '.') && !(options->showType & FF_DNS_TYPE_IPV4_BIT)))
|
||||
continue;
|
||||
|
||||
// Add to results
|
||||
FFstrbuf* item = (FFstrbuf*) ffListAdd(results);
|
||||
ffStrbufInitMove(item, &buffer);
|
||||
FF_DEBUG("Found DNS server on macOS: %s", item->chars);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find any servers, try resolv.conf as fallback
|
||||
if (results->length > 0)
|
||||
return NULL;
|
||||
|
||||
FF_DEBUG("No DNS servers found via SystemConfiguration, trying resolv.conf");
|
||||
// Try standard resolv.conf location on macOS as a fallback
|
||||
return detectDnsFromConf("/var/run/resolv.conf", options, results);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/io/io.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#define RESOLV_CONF "/system/settings/network/resolv.conf"
|
||||
@@ -10,11 +11,24 @@
|
||||
#define RESOLV_CONF "/etc/resolv.conf"
|
||||
#endif
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
static const char* detectDnsFromConf(const char* path, FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT RESOLV_CONF, "r");
|
||||
FF_DEBUG("Attempting to read DNS config from %s", path);
|
||||
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(path, "r");
|
||||
if (!file)
|
||||
return "fopen (" FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf) failed";
|
||||
{
|
||||
FF_DEBUG("Failed to open %s: %m", path);
|
||||
return "fopen(path, r) failed";
|
||||
}
|
||||
|
||||
if (results->length > 0)
|
||||
{
|
||||
FF_DEBUG("Clearing existing DNS entries (%u entries)", results->length);
|
||||
FF_LIST_FOR_EACH(FFstrbuf, item, *results)
|
||||
ffStrbufDestroy(item);
|
||||
ffListClear(results);
|
||||
}
|
||||
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
@@ -38,7 +52,90 @@ const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
FFstrbuf* item = (FFstrbuf*) ffListAdd(results);
|
||||
ffStrbufInitS(item, nameserver);
|
||||
ffStrbufTrimRightSpace(item);
|
||||
FF_DEBUG("Found DNS server: %s", item->chars);
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("Found %u DNS servers in %s", results->length, path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
FF_DEBUG("Starting DNS detection");
|
||||
|
||||
const char* error = detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT RESOLV_CONF, options, results);
|
||||
if (error != NULL)
|
||||
{
|
||||
FF_DEBUG("Error detecting DNS: %s", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
#if __linux__ && !__ANDROID__
|
||||
// Handle different DNS management services
|
||||
if (results->length == 1)
|
||||
{
|
||||
const FFstrbuf* firstEntry = FF_LIST_GET(FFstrbuf, *results, 0);
|
||||
|
||||
if (ffStrbufEqualS(firstEntry, "127.0.0.53"))
|
||||
{
|
||||
FF_DEBUG("Detected systemd-resolved (127.0.0.53), checking actual DNS servers");
|
||||
// Managed by systemd-resolved
|
||||
if (detectDnsFromConf("/run/systemd/resolve/resolv.conf", options, results) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else if (ffStrbufEqualS(firstEntry, "127.0.0.1"))
|
||||
{
|
||||
FF_DEBUG("Detected possible NetworkManager (127.0.0.1), checking actual DNS servers");
|
||||
// Managed by NetworkManager
|
||||
if (detectDnsFromConf("/var/run/NetworkManager/resolv.conf", options, results) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Check other possible DNS configuration files
|
||||
if (results->length == 0)
|
||||
{
|
||||
FF_DEBUG("No DNS servers found, trying alternative config files");
|
||||
|
||||
// Try resolvconf
|
||||
FF_DEBUG("Trying resolvconf configuration");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/run/resolvconf/resolv.conf", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
|
||||
// Try dnsmasq
|
||||
FF_DEBUG("Trying dnsmasq configuration");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/var/run/dnsmasq/resolv.conf", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
|
||||
// Try openresolv
|
||||
FF_DEBUG("Trying openresolv configuration");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf.openresolv", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
// Handle BSD-specific DNS configurations
|
||||
if (results->length == 0)
|
||||
{
|
||||
FF_DEBUG("No DNS servers found, trying BSD-specific config files");
|
||||
|
||||
// FreeBSD and other BSDs may use resolvconf service
|
||||
FF_DEBUG("Trying BSD resolvconf configuration");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/var/run/resolvconf/resolv.conf", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
|
||||
// Some BSDs store DNS configuration here
|
||||
FF_DEBUG("Trying BSD nameserver configuration");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/var/run/nameserver", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
|
||||
// Try common BSD paths
|
||||
FF_DEBUG("Trying BSD common paths");
|
||||
if (detectDnsFromConf(FASTFETCH_TARGET_DIR_ROOT "/etc/nameserver", options, results) == NULL && results->length > 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
FF_DEBUG("DNS detection completed with %u servers found", results->length);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifdef _WIN32
|
||||
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
|
||||
{
|
||||
assert(resolved_name != NULL);
|
||||
return _fullpath(resolved_name, file_name, _MAX_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,8 +20,12 @@ const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */)
|
||||
{
|
||||
snprintf(path, ARRAY_SIZE(path), "/dev/uhid%d", i);
|
||||
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) continue;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
break; // No more devices
|
||||
continue; // Device not found
|
||||
}
|
||||
report_desc_t repDesc = hid_get_report_desc(fd);
|
||||
if (!repDesc) continue;
|
||||
|
||||
@@ -53,6 +57,7 @@ const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */)
|
||||
device->battery = 0;
|
||||
}
|
||||
}
|
||||
hid_end_parse(hData);
|
||||
}
|
||||
|
||||
hid_dispose_report_desc(repDesc);
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include "3rdparty/display-library/adl_sdk.h"
|
||||
|
||||
// https://gpuopen-librariesandsdks.github.io/adl/modules.html
|
||||
|
||||
// Function to initialize the ADL2 interface and to obtain client's context handle.
|
||||
extern int ADL2_Main_Control_Create(ADL_MAIN_MALLOC_CALLBACK callback, int iEnumConnectedAdapters, ADL_CONTEXT_HANDLE* context);
|
||||
|
||||
// Destroy client's ADL context.
|
||||
extern int ADL2_Main_Control_Destroy(ADL_CONTEXT_HANDLE context);
|
||||
|
||||
// Retrieves adapter information for given adapter or all OS-known adapters.
|
||||
// Return ADL_OK on success, DESPITE THE OFFICIAL DOCUMENT SAYS IT RETURNS 1 FOR SUCCESS!
|
||||
extern int ADL2_Adapter_AdapterInfoX3_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* numAdapters, AdapterInfo** lppAdapterInfo);
|
||||
|
||||
// Function to retrieve Graphic Core Info.
|
||||
extern int ADL2_Adapter_Graphic_Core_Info_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLGraphicCoreInfo* pGraphicCoreInfo);
|
||||
|
||||
// Function to retrieve memory information from the adapter. Version 2
|
||||
extern int ADL2_Adapter_MemoryInfo2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLMemoryInfo2* lpMemoryInfo2);
|
||||
|
||||
// This function retrieves the VRAM usage of given adapter.
|
||||
extern int ADL2_Adapter_VRAMUsage_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iVRAMUsageInMB);
|
||||
|
||||
// This function retrieves the Dedicated VRAM usage of given adapter.
|
||||
extern int ADL2_Adapter_DedicatedVRAMUsage_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iVRAMUsageInMB);
|
||||
|
||||
// Function to get the ASICFamilyType from the adapter.
|
||||
extern int ADL2_Adapter_ASICFamilyType_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpAsicTypes, int* lpValids);
|
||||
|
||||
|
||||
// Function to retrieve current power management capabilities.
|
||||
extern int ADL2_Overdrive_Caps(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* iSupported, int* iEnabled, int* iVersion);
|
||||
|
||||
|
||||
/////////// Overdrive 6 functions
|
||||
|
||||
// Function to retrieve current Overdrive and performance-related activity.
|
||||
extern int ADL2_Overdrive6_CurrentStatus_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD6CurrentStatus* lpCurrentStatus);
|
||||
|
||||
// Function to retrieve GPU temperature from the thermal controller.
|
||||
extern int ADL2_Overdrive6_Temperature_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int* lpTemperature);
|
||||
|
||||
// Function to retrieve the current or default Overdrive clock ranges.
|
||||
extern int ADL2_Overdrive6_StateInfo_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iStateType, ADLOD6StateInfo* lpStateInfo);
|
||||
|
||||
|
||||
/// Overdrive N functions
|
||||
|
||||
// Despite the name (N means Next), this is actually Overdrive7 API
|
||||
// https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Sample/OverdriveN/OverdriveN.cpp#L209
|
||||
|
||||
// Function to retrieve the OverdriveN capabilities.
|
||||
extern int ADL2_OverdriveN_CapabilitiesX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNCapabilitiesX2* lpODCapabilities);
|
||||
|
||||
// Function to retrieve the current OD performance status.
|
||||
extern int ADL2_OverdriveN_PerformanceStatus_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceStatus *lpODPerformanceStatus);
|
||||
|
||||
// Function to retrieve the current temperature.
|
||||
extern int ADL2_OverdriveN_Temperature_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, int iTemperatureType, int *iTemperature);
|
||||
|
||||
// Function to retrieve the current GPU clocks settings.
|
||||
extern int ADL2_OverdriveN_SystemClocksX2_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLODNPerformanceLevelsX2 *lpODPerformanceLevels);
|
||||
|
||||
|
||||
/// Overdrive 8 functions
|
||||
|
||||
// Function to retrieve the Overdrive8 current settings.
|
||||
extern int ADL2_Overdrive8_Current_Setting_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLOD8CurrentSetting *lpCurrentSetting);
|
||||
|
||||
// Function to retrieve the Overdrive8 current settings.
|
||||
extern int ADL2_New_QueryPMLogData_Get(ADL_CONTEXT_HANDLE context, int iAdapterIndex, ADLPMLogDataOutput *lpDataOutput);
|
||||
@@ -55,6 +55,7 @@ const char* detectByOpenGL(FFlist* gpus)
|
||||
ffStrbufInitMove(&gpu->name, &result.renderer);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef struct FFGPUResult
|
||||
FFstrbuf name;
|
||||
FFstrbuf driver;
|
||||
FFstrbuf platformApi;
|
||||
FFstrbuf memoryType;
|
||||
double temperature;
|
||||
double coreUsage;
|
||||
int32_t coreCount;
|
||||
|
||||
+505
-35
@@ -1,75 +1,545 @@
|
||||
#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 "adl.h"
|
||||
#include "common/library.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
// Helper function to convert ADL status code to string
|
||||
FF_MAYBE_UNUSED static const char* ffAdlStatusToString(int status) {
|
||||
switch (status) {
|
||||
#define FF_ADL_STATUS_CASE(name) case name: return #name;
|
||||
FF_ADL_STATUS_CASE(ADL_OK)
|
||||
FF_ADL_STATUS_CASE(ADL_OK_WARNING)
|
||||
FF_ADL_STATUS_CASE(ADL_OK_MODE_CHANGE)
|
||||
FF_ADL_STATUS_CASE(ADL_OK_RESTART)
|
||||
FF_ADL_STATUS_CASE(ADL_OK_WAIT)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_NOT_INIT)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_PARAM)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_PARAM_SIZE)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_ADL_IDX)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_CONTROLLER_IDX)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_DIPLAY_IDX)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_NOT_SUPPORTED)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_NULL_POINTER)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_DISABLED_ADAPTER)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_CALLBACK)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_RESOURCE_CONFLICT)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_SET_INCOMPLETE)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_NO_XDISPLAY)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_CALL_TO_INCOMPATIABLE_DRIVER)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_NO_ADMINISTRATOR_PRIVILEGES)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_FEATURESYNC_NOT_STARTED)
|
||||
FF_ADL_STATUS_CASE(ADL_ERR_INVALID_POWER_STATE)
|
||||
#undef FF_ADL_STATUS_CASE
|
||||
default: return "Unknown ADL error";
|
||||
}
|
||||
}
|
||||
|
||||
// Memory allocation function
|
||||
static void* __attribute__((__stdcall__)) ffAdlMainMemoryAlloc(int iSize)
|
||||
{
|
||||
return malloc((size_t) iSize);
|
||||
}
|
||||
|
||||
struct FFAdlData {
|
||||
FF_LIBRARY_SYMBOL(ADL2_Main_Control_Destroy)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_AdapterInfoX3_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_Graphic_Core_Info_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_MemoryInfo2_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_DedicatedVRAMUsage_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_VRAMUsage_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Adapter_ASICFamilyType_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive_Caps)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_CapabilitiesX2_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_SystemClocksX2_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_PerformanceStatus_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_OverdriveN_Temperature_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive8_Current_Setting_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_New_QueryPMLogData_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive6_CurrentStatus_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive6_Temperature_Get)
|
||||
FF_LIBRARY_SYMBOL(ADL2_Overdrive6_StateInfo_Get)
|
||||
|
||||
bool inited;
|
||||
ADL_CONTEXT_HANDLE apiHandle;
|
||||
} adlData;
|
||||
|
||||
static void shutdownAdl()
|
||||
{
|
||||
if (adlData.apiHandle)
|
||||
{
|
||||
FF_DEBUG("Destroying ADL context");
|
||||
adlData.ffADL2_Main_Control_Destroy(adlData.apiHandle);
|
||||
adlData.apiHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName)
|
||||
{
|
||||
static bool inited = false;
|
||||
static AGSGPUInfo gpuInfo;
|
||||
FF_DEBUG("Attempting to detect AMD GPU info using '%s'", soName);
|
||||
|
||||
if (!inited)
|
||||
if (!adlData.inited)
|
||||
{
|
||||
inited = true;
|
||||
FF_LIBRARY_LOAD(libags, "dlopen amd_ags failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
|
||||
adlData.inited = true;
|
||||
FF_DEBUG("Initializing ADL library");
|
||||
FF_LIBRARY_LOAD(atiadl, "dlopen atiadlxx failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(atiadl, ADL2_Main_Control_Create)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Main_Control_Destroy)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_AdapterInfoX3_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_Graphic_Core_Info_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_MemoryInfo2_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_DedicatedVRAMUsage_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_VRAMUsage_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Adapter_ASICFamilyType_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive_Caps)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_CapabilitiesX2_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_SystemClocksX2_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_PerformanceStatus_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive8_Current_Setting_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_New_QueryPMLogData_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_OverdriveN_Temperature_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive6_CurrentStatus_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive6_Temperature_Get)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(atiadl, adlData, ADL2_Overdrive6_StateInfo_Get)
|
||||
FF_DEBUG("ADL library loaded");
|
||||
|
||||
struct AGSContext* apiHandle;
|
||||
if (ffagsInitialize(AGS_CURRENT_VERSION, NULL, &apiHandle, &gpuInfo) != AGS_SUCCESS)
|
||||
return "loading ags library failed";
|
||||
int result = ffADL2_Main_Control_Create(ffAdlMainMemoryAlloc, 1 /*iEnumConnectedAdapters*/, &adlData.apiHandle);
|
||||
FF_DEBUG("ADL2_Main_Control_Create returned %s (%d)", ffAdlStatusToString(result), result);
|
||||
if (result != ADL_OK)
|
||||
return "ffADL2_Main_Control_Create() failed";
|
||||
|
||||
// agsDeInitialize will free pointers allocated in gpuInfo. Just leak them.
|
||||
atexit(shutdownAdl);
|
||||
atiadl = NULL; // don't close atiadl
|
||||
FF_DEBUG("ADL initialization complete");
|
||||
}
|
||||
|
||||
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 (!adlData.apiHandle)
|
||||
{
|
||||
if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID)
|
||||
FF_DEBUG("ADL context not initialized");
|
||||
return "ffADL2_Main_Control_Create() failed";
|
||||
}
|
||||
|
||||
FF_AUTO_FREE AdapterInfo* devices = NULL;
|
||||
int numDevices = 0;
|
||||
int adapterResult = adlData.ffADL2_Adapter_AdapterInfoX3_Get(adlData.apiHandle, -1, &numDevices, &devices);
|
||||
FF_DEBUG("ADL2_Adapter_AdapterInfoX3_Get returned %s (%d)", ffAdlStatusToString(adapterResult), adapterResult);
|
||||
|
||||
if (adapterResult == ADL_OK)
|
||||
{
|
||||
FF_DEBUG("found %d adapters", numDevices);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("ffADL2_Adapter_AdapterInfoX3_Get() failed");
|
||||
return "ffADL2_Adapter_AdapterInfoX3_Get() failed";
|
||||
}
|
||||
|
||||
const AdapterInfo* device = NULL;
|
||||
for (int iDev = 0; iDev < numDevices; iDev++)
|
||||
{
|
||||
if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID)
|
||||
{
|
||||
FF_DEBUG("Checking device %d: bus=%d, device=%d, func=%d against requested bus=%u, device=%u, func=%u",
|
||||
iDev, devices[iDev].iBusNumber, devices[iDev].iDeviceNumber, devices[iDev].iFunctionNumber,
|
||||
cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func);
|
||||
|
||||
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)
|
||||
cond->pciBusId.bus == (uint32_t) devices[iDev].iBusNumber &&
|
||||
cond->pciBusId.device == (uint32_t) devices[iDev].iDeviceNumber &&
|
||||
cond->pciBusId.func == (uint32_t) devices[iDev].iFunctionNumber)
|
||||
{
|
||||
device = &gpuInfo.devices[iDev];
|
||||
device = &devices[iDev];
|
||||
FF_DEBUG("Found matching device: %s (index: %d)", device->strAdapterName, device->iAdapterIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!device)
|
||||
{
|
||||
FF_DEBUG("Device not found");
|
||||
return "Device not found";
|
||||
}
|
||||
|
||||
if (result.coreCount)
|
||||
*result.coreCount = (uint32_t) device->numCUs;
|
||||
{
|
||||
ADLGraphicCoreInfo coreInfo;
|
||||
int status = adlData.ffADL2_Adapter_Graphic_Core_Info_Get(adlData.apiHandle, device->iAdapterIndex, &coreInfo);
|
||||
FF_DEBUG("ADL2_Adapter_Graphic_Core_Info_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
FF_DEBUG("Core info - NumCUs: %d, NumPEsPerCU: %d", coreInfo.iNumCUs, coreInfo.iNumPEsPerCU);
|
||||
*result.coreCount = (uint32_t) coreInfo.iNumCUs * (uint32_t) coreInfo.iNumPEsPerCU;
|
||||
FF_DEBUG("Got core count: %u", *result.coreCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get core count");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.memory)
|
||||
{
|
||||
result.memory->total = device->localMemoryInBytes;
|
||||
result.memory->used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
int vramUsage = 0;
|
||||
int status = adlData.ffADL2_Adapter_DedicatedVRAMUsage_Get(adlData.apiHandle, device->iAdapterIndex, &vramUsage);
|
||||
FF_DEBUG("ADL2_Adapter_DedicatedVRAMUsage_Get returned %s (%d), usage: %d MB",
|
||||
ffAdlStatusToString(status), status, vramUsage);
|
||||
|
||||
if (status == ADL_OK) {
|
||||
result.memory->used = (uint64_t) vramUsage * 1024 * 1024;
|
||||
FF_DEBUG("Dedicated VRAM usage: %llu bytes (%d MB)", result.memory->used, vramUsage);
|
||||
} else {
|
||||
FF_DEBUG("Failed to get dedicated VRAM usage");
|
||||
}
|
||||
|
||||
if (result.sharedMemory)
|
||||
{
|
||||
vramUsage = 0;
|
||||
status = adlData.ffADL2_Adapter_VRAMUsage_Get(adlData.apiHandle, device->iAdapterIndex, &vramUsage);
|
||||
FF_DEBUG("ADL2_Adapter_VRAMUsage_Get returned %s (%d), usage: %d MB",
|
||||
ffAdlStatusToString(status), status, vramUsage);
|
||||
|
||||
if (status == ADL_OK) {
|
||||
uint64_t totalUsage = (uint64_t) vramUsage * 1024 * 1024;
|
||||
result.sharedMemory->used = totalUsage - result.memory->used;
|
||||
FF_DEBUG("Total VRAM usage: %llu bytes, Shared VRAM usage: %llu bytes (%llu MB)",
|
||||
totalUsage, result.sharedMemory->used, result.sharedMemory->used / (1024 * 1024));
|
||||
} else {
|
||||
FF_DEBUG("Failed to get total VRAM usage");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.frequency)
|
||||
*result.frequency = (uint32_t) device->coreClock; // Maximum frequency
|
||||
if (result.memoryType)
|
||||
{
|
||||
ADLMemoryInfo2 memoryInfo;
|
||||
int status = adlData.ffADL2_Adapter_MemoryInfo2_Get(adlData.apiHandle, device->iAdapterIndex, &memoryInfo);
|
||||
FF_DEBUG("ADL2_Adapter_MemoryInfo2_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
FF_DEBUG("Memory info - Type: %s, Size: %lld MB", memoryInfo.strMemoryType, memoryInfo.iMemorySize / 1024 / 1024);
|
||||
ffStrbufSetS(result.memoryType, memoryInfo.strMemoryType);
|
||||
FF_DEBUG("Got memory type: %s", memoryInfo.strMemoryType);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get memory type");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.type)
|
||||
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
{
|
||||
int asicTypes = 0;
|
||||
int valids = 0;
|
||||
int status = adlData.ffADL2_Adapter_ASICFamilyType_Get(adlData.apiHandle, device->iAdapterIndex, &asicTypes, &valids);
|
||||
FF_DEBUG("ADL2_Adapter_ASICFamilyType_Get returned %s (%d), asicTypes: 0x%x, valids: 0x%x",
|
||||
ffAdlStatusToString(status), status, asicTypes, valids);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
asicTypes &= valids; // This design is strange
|
||||
*result.type = asicTypes & ADL_ASIC_INTEGRATED ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
FF_DEBUG("GPU type: %s (asicTypes: 0x%x, valids: 0x%x)",
|
||||
*result.type == FF_GPU_TYPE_INTEGRATED ? "Integrated" : "Discrete", asicTypes, valids);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get GPU type");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.index)
|
||||
*result.index = (uint32_t) device->adlAdapterIndex;
|
||||
{
|
||||
*result.index = (uint32_t) device->iAdapterIndex;
|
||||
FF_DEBUG("Setting adapter index: %u", *result.index);
|
||||
}
|
||||
|
||||
if (result.name)
|
||||
ffStrbufSetS(result.name, device->adapterString);
|
||||
{
|
||||
ffStrbufSetS(result.name, device->strAdapterName);
|
||||
FF_DEBUG("Setting adapter name: %s; UDID: %s, Present: %d, Exist: %d", device->strAdapterName, device->strUDID, device->iPresent, device->iExist);
|
||||
}
|
||||
|
||||
int odVersion = 0;
|
||||
|
||||
{
|
||||
int odSupported = 0;
|
||||
int odEnabled = 0;
|
||||
int status = adlData.ffADL2_Overdrive_Caps(adlData.apiHandle, device->iAdapterIndex, &odSupported, &odEnabled, &odVersion);
|
||||
FF_DEBUG("ADL2_Overdrive_Caps returned %s (%d); supported %d, enabled %d; version %d",
|
||||
ffAdlStatusToString(status), status, odSupported, odEnabled, odVersion);
|
||||
if (status != ADL_OK)
|
||||
{
|
||||
FF_DEBUG("Overdrive not supported, results may be inaccurate");
|
||||
// Note even if Overdrive is not supported, we can still get the OD version
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (odVersion == 8)
|
||||
{
|
||||
FF_DEBUG("Using Overdrive8 API (odVersion=%d)", odVersion);
|
||||
|
||||
if (result.frequency)
|
||||
{
|
||||
ADLOD8CurrentSetting currentSetting = { .count = OD8_COUNT };
|
||||
int status = adlData.ffADL2_Overdrive8_Current_Setting_Get(adlData.apiHandle, device->iAdapterIndex, ¤tSetting);
|
||||
FF_DEBUG("ADL2_Overdrive8_Current_Setting_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
FF_DEBUG("OD8 Settings count: %d", currentSetting.count);
|
||||
|
||||
*result.frequency = (uint32_t) currentSetting.Od8SettingTable[OD8_GFXCLK_FMAX];
|
||||
FF_DEBUG("Got max engine clock (OD8_GFXCLK_FMAX): %u MHz", *result.frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get max frequency information");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.temp || result.coreUsage)
|
||||
{
|
||||
ADLPMLogDataOutput pmLogDataOutput = {};
|
||||
int status = adlData.ffADL2_New_QueryPMLogData_Get(adlData.apiHandle, device->iAdapterIndex, &pmLogDataOutput);
|
||||
FF_DEBUG("ADL2_New_QueryPMLogData_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
if (result.temp)
|
||||
{
|
||||
ADLSingleSensorData* sensor = &pmLogDataOutput.sensors[ADL_PMLOG_TEMPERATURE_HOTSPOT];
|
||||
FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_TEMPERATURE_HOTSPOT, "ADL_PMLOG_TEMPERATURE_HOTSPOT", sensor->supported, sensor->value);
|
||||
if (sensor->supported)
|
||||
{
|
||||
*result.temp = sensor->value;
|
||||
FF_DEBUG("Temperature: %.1f°C (HOTSPOT)", *result.temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sensor = &pmLogDataOutput.sensors[ADL_PMLOG_TEMPERATURE_GFX];
|
||||
FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_TEMPERATURE_GFX, "ADL_PMLOG_TEMPERATURE_GFX", sensor->supported, sensor->value);
|
||||
if (sensor->supported)
|
||||
{
|
||||
*result.temp = sensor->value;
|
||||
FF_DEBUG("Temperature: %.1f°C (GFX)", *result.temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sensor = &pmLogDataOutput.sensors[ADL_PMLOG_TEMPERATURE_SOC];
|
||||
FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_TEMPERATURE_SOC, "ADL_PMLOG_TEMPERATURE_SOC", sensor->supported, sensor->value);
|
||||
if (sensor->supported)
|
||||
{
|
||||
*result.temp = sensor->value;
|
||||
FF_DEBUG("Temperature: %.1f°C (SOC)", *result.temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("No supported temp sensor found, temp detection failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.coreUsage)
|
||||
{
|
||||
ADLSingleSensorData* activity = &pmLogDataOutput.sensors[ADL_PMLOG_INFO_ACTIVITY_GFX];
|
||||
FF_DEBUG("Sensor %d: %s, supported: %d, value: %d", ADL_PMLOG_INFO_ACTIVITY_GFX, "ADL_PMLOG_INFO_ACTIVITY_GFX", activity->supported, activity->value);
|
||||
if (activity->supported)
|
||||
{
|
||||
*result.coreUsage = activity->value;
|
||||
FF_DEBUG("Core usage: %.1f%%", *result.coreUsage);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Sensor %d not supported, GPU usage detection failed", ADL_PMLOG_INFO_ACTIVITY_GFX);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get temperature / GPU activity");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (odVersion == 7)
|
||||
{
|
||||
FF_DEBUG("Using OverdriveN API (odVersion=%d)", odVersion);
|
||||
|
||||
if (result.frequency)
|
||||
{
|
||||
// https://github.com/MaynardMiner/odvii/blob/master/OverdriveN.cpp#L176
|
||||
ADLODNCapabilitiesX2 odCapabilities = {};
|
||||
int status = adlData.ffADL2_OverdriveN_CapabilitiesX2_Get(adlData.apiHandle, device->iAdapterIndex, &odCapabilities);
|
||||
FF_DEBUG("ADL2_OverdriveN_CapabilitiesX2_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
if (odCapabilities.iMaximumNumberOfPerformanceLevels == 0)
|
||||
{
|
||||
FF_DEBUG("ADL2_OverdriveN_CapabilitiesX2_Get: no performance levels available");
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("ODN Capabilities - MaxPerformanceLevels: %d, GPU Clock Range: [%d - %d]",
|
||||
odCapabilities.iMaximumNumberOfPerformanceLevels,
|
||||
odCapabilities.sEngineClockRange.iMin, odCapabilities.sEngineClockRange.iMax);
|
||||
|
||||
size_t size = sizeof(ADLODNPerformanceLevelsX2) + sizeof(ADLODNPerformanceLevelX2) * ((unsigned) odCapabilities.iMaximumNumberOfPerformanceLevels - 1);
|
||||
FF_AUTO_FREE ADLODNPerformanceLevelsX2* odPerfLevels = calloc(size, 1);
|
||||
odPerfLevels->iSize = (int) size;
|
||||
odPerfLevels->iNumberOfPerformanceLevels = odCapabilities.iMaximumNumberOfPerformanceLevels;
|
||||
odPerfLevels->iMode = ODNControlType_Current;
|
||||
|
||||
int status = adlData.ffADL2_OverdriveN_SystemClocksX2_Get(adlData.apiHandle, device->iAdapterIndex, odPerfLevels);
|
||||
FF_DEBUG("ADL2_OverdriveN_SystemClocksX2_Get returned %s (%d), levels: %d",
|
||||
ffAdlStatusToString(status), status, odPerfLevels->iNumberOfPerformanceLevels);
|
||||
|
||||
if (status != ADL_OK)
|
||||
{
|
||||
FF_DEBUG("Failed to get frequency information");
|
||||
}
|
||||
else
|
||||
{
|
||||
// lowest to highest
|
||||
for (int i = odPerfLevels->iNumberOfPerformanceLevels - 1; i >= 0 ; i--)
|
||||
{
|
||||
ADLODNPerformanceLevelX2* level = &odPerfLevels->aLevels[i];
|
||||
FF_DEBUG("Performance level %d: enabled: %d, engine clock = %d", i, level->iEnabled, level->iClock);
|
||||
if (level->iEnabled)
|
||||
{
|
||||
*result.frequency = (uint32_t) level->iClock / 100; // in 10 kHz
|
||||
FF_DEBUG("Got max engine clock: %u MHz", *result.frequency);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get frequency information");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.coreUsage)
|
||||
{
|
||||
ADLODNPerformanceStatus performanceStatus = {};
|
||||
int status = adlData.ffADL2_OverdriveN_PerformanceStatus_Get(adlData.apiHandle, device->iAdapterIndex, &performanceStatus);
|
||||
FF_DEBUG("ADL2_OverdriveN_PerformanceStatus_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
FF_DEBUG("Performance Status - Activity: %d%%, CoreClock: %dMHz, MemoryClock: %dMHz",
|
||||
performanceStatus.iGPUActivityPercent,
|
||||
performanceStatus.iCoreClock,
|
||||
performanceStatus.iMemoryClock);
|
||||
|
||||
*result.coreUsage = performanceStatus.iGPUActivityPercent;
|
||||
FF_DEBUG("Got GPU activity: %d%%", performanceStatus.iGPUActivityPercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get GPU activity");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.temp)
|
||||
{
|
||||
int milliDegrees = 0;
|
||||
int status = adlData.ffADL2_OverdriveN_Temperature_Get(adlData.apiHandle, device->iAdapterIndex, 1, &milliDegrees);
|
||||
FF_DEBUG("ADL2_OverdriveN_Temperature_Get returned %s (%d)", ffAdlStatusToString(status), status);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
*result.temp = milliDegrees / 1000.0;
|
||||
FF_DEBUG("Temperature: %.1f°C (raw: %d milliC)", *result.temp, milliDegrees);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get temperature");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (odVersion == 6)
|
||||
{
|
||||
FF_DEBUG("Using Overdrive6 API (odVersion=%d)", odVersion);
|
||||
|
||||
if (result.frequency)
|
||||
{
|
||||
FF_AUTO_FREE ADLOD6StateInfo* stateInfo = calloc(sizeof(ADLOD6StateInfo) + sizeof(ADLOD6PerformanceLevel), 1);
|
||||
stateInfo->iNumberOfPerformanceLevels = 2;
|
||||
|
||||
int status = adlData.ffADL2_Overdrive6_StateInfo_Get(adlData.apiHandle, device->iAdapterIndex, ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE, stateInfo);
|
||||
FF_DEBUG("ADL2_Overdrive6_StateInfo_Get returned %s (%d), performance levels: %d",
|
||||
ffAdlStatusToString(status), status, stateInfo->iNumberOfPerformanceLevels);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
// OD6 uses clock ranges instead of discrete performance levels.
|
||||
// iNumberOfPerformanceLevels is always 2.
|
||||
// The 1st level indicates the minimum clocks in the range.
|
||||
// The 2nd level indicates the maximum clocks in the range.
|
||||
if (stateInfo->iNumberOfPerformanceLevels != 2)
|
||||
{
|
||||
FF_DEBUG("ADL2_Overdrive6_StateInfo_Get: unexpected number of performance levels: %d", stateInfo->iNumberOfPerformanceLevels);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("OD6 Settings - MinPerformanceLevels: %d, MaxPerformanceLevels: %d",
|
||||
stateInfo->aLevels[0].iEngineClock, stateInfo->aLevels[1].iEngineClock);
|
||||
*result.frequency = (uint32_t) stateInfo->aLevels[1].iEngineClock / 100; // in 10 kHz
|
||||
FF_DEBUG("Got max engine clock: %u MHz", *result.frequency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get frequency information");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.coreUsage)
|
||||
{
|
||||
ADLOD6CurrentStatus status = {};
|
||||
int apiStatus = adlData.ffADL2_Overdrive6_CurrentStatus_Get(adlData.apiHandle, device->iAdapterIndex, &status);
|
||||
FF_DEBUG("ADL2_Overdrive6_CurrentStatus_Get returned %s (%d)", ffAdlStatusToString(apiStatus), apiStatus);
|
||||
|
||||
if (apiStatus == ADL_OK)
|
||||
{
|
||||
*result.coreUsage = status.iActivityPercent;
|
||||
FF_DEBUG("Got GPU activity: %d%%", status.iActivityPercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get GPU activity");
|
||||
}
|
||||
}
|
||||
|
||||
if (result.temp)
|
||||
{
|
||||
int milliDegrees = 0;
|
||||
int status = adlData.ffADL2_Overdrive6_Temperature_Get(adlData.apiHandle, device->iAdapterIndex, &milliDegrees);
|
||||
FF_DEBUG("ADL2_Overdrive6_Temperature_Get returned %s (%d), temperature: %d milliC",
|
||||
ffAdlStatusToString(status), status, milliDegrees);
|
||||
|
||||
if (status == ADL_OK)
|
||||
{
|
||||
*result.temp = milliDegrees / 1000.0;
|
||||
FF_DEBUG("Temperature: %.1f°C", *result.temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Failed to get temperature");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_DEBUG("Unknown Overdrive version: %d", odVersion);
|
||||
return "Unknown Overdrive version";
|
||||
}
|
||||
FF_DEBUG("AMD GPU detection complete - returning success");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,12 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
{
|
||||
switch (strtol(gpuName->chars + strlen("Apple M"), NULL, 10))
|
||||
{
|
||||
case 0: error = "Invalid Apple Silicon GPU"; break;
|
||||
case 1: error = ffDetectSmcTemps(FF_TEMP_GPU_M1X, &result); break;
|
||||
case 2: error = ffDetectSmcTemps(FF_TEMP_GPU_M2X, &result); break;
|
||||
case 3: error = ffDetectSmcTemps(FF_TEMP_GPU_M3X, &result); break;
|
||||
case 4: error = ffDetectSmcTemps(FF_TEMP_GPU_M4X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon GPU";
|
||||
default: error = "Unsupported Apple Silicon GPU"; break;
|
||||
}
|
||||
}
|
||||
else if (ffStrbufStartsWithS(gpuName, "Intel"))
|
||||
@@ -102,7 +103,8 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
}
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
@@ -112,7 +114,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
ffStrbufInit(&gpu->driver); // Ok for both Apple and Intel
|
||||
ffCfDictGetString(properties, CFSTR("CFBundleIdentifier"), &gpu->driver);
|
||||
|
||||
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount)) // For Apple
|
||||
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount) != NULL) // For Apple
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
@@ -131,9 +133,9 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
if (ffCfDictGetInt64(perfStatistics, CFSTR("In use system memory"), (int64_t*) &vramUsed) != NULL)
|
||||
vramTotal = 0;
|
||||
}
|
||||
else if (ffCfDictGetInt64(perfStatistics, CFSTR("vramUsedBytes"), (int64_t*) &vramTotal) == NULL)
|
||||
else if (ffCfDictGetInt64(perfStatistics, CFSTR("vramFreeBytes"), (int64_t*) &vramTotal) == NULL)
|
||||
{
|
||||
if (ffCfDictGetInt64(perfStatistics, CFSTR("vramFreeBytes"), (int64_t*) &vramUsed) == NULL)
|
||||
if (ffCfDictGetInt64(perfStatistics, CFSTR("vramUsedBytes"), (int64_t*) &vramUsed) == NULL)
|
||||
vramTotal += vramUsed;
|
||||
else
|
||||
vramTotal = 0;
|
||||
@@ -143,15 +145,15 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
ffStrbufInit(&gpu->name);
|
||||
//IOAccelerator returns model / vendor-id properties for Apple Silicon, but not for Intel Iris GPUs.
|
||||
//Still needs testing for AMD's
|
||||
if(ffCfDictGetString(properties, CFSTR("model"), &gpu->name))
|
||||
if(ffCfDictGetString(properties, CFSTR("model"), &gpu->name) != NULL)
|
||||
{
|
||||
CFRelease(properties);
|
||||
properties = NULL;
|
||||
|
||||
io_registry_entry_t parentEntry;
|
||||
IORegistryEntryGetParentEntry(registryEntry, kIOServicePlane, &parentEntry);
|
||||
if(IORegistryEntryCreateCFProperties(parentEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t parentEntry = 0;
|
||||
if(IORegistryEntryGetParentEntry(registryEntry, kIOServicePlane, &parentEntry) != kIOReturnSuccess ||
|
||||
IORegistryEntryCreateCFProperties(parentEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(parentEntry);
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
@@ -179,7 +181,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
gpu->shared.total = vramTotal;
|
||||
gpu->shared.used = vramUsed;
|
||||
}
|
||||
else
|
||||
else if (gpu->type == FF_GPU_TYPE_DISCRETE)
|
||||
{
|
||||
gpu->dedicated.total = vramTotal;
|
||||
gpu->dedicated.used = vramUsed;
|
||||
|
||||
@@ -29,6 +29,7 @@ const char* ffGpuDetectDriverVersion(FFlist* gpus)
|
||||
ffStrbufAppendS(&x->driver, version.UTF8String);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return "Unsupported macOS version";
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD int fd = open("/dev/pci", O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return "open(\"/dev/pci\", O_RDONLY, 0) failed";
|
||||
|
||||
struct pci_conf confs[128];
|
||||
struct pci_match_conf match = {
|
||||
.pc_class = PCIC_DISPLAY,
|
||||
@@ -40,7 +43,8 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(pc->pc_vendor));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInitS(&gpu->driver, pc->pd_name);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "/dev/pci");
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
@@ -77,7 +81,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
|
||||
ffGPUQueryAmdGpuName(pc->pc_device, pc->pc_revid, gpu);
|
||||
if (gpu->name.length == 0)
|
||||
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
|
||||
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
|
||||
}
|
||||
|
||||
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
|
||||
|
||||
@@ -41,6 +41,8 @@ typedef struct FFGpuDriverResult
|
||||
uint32_t* index;
|
||||
double* temp;
|
||||
FFGPUMemory* memory;
|
||||
FFstrbuf* memoryType;
|
||||
FFGPUMemory* sharedMemory;
|
||||
uint32_t* coreCount;
|
||||
double* coreUsage;
|
||||
FFGPUType* type;
|
||||
@@ -87,9 +89,9 @@ FF_MAYBE_UNUSED static inline bool getDriverSpecificDetectionFn(const char* vend
|
||||
{
|
||||
*pDetectFn = ffDetectAmdGpuInfo;
|
||||
#ifdef _WIN64
|
||||
*pDllName = "amd_ags_x64.dll";
|
||||
*pDllName = "atiadlxx.dll";
|
||||
#else
|
||||
*pDllName = "amd_ags_x86.dll";
|
||||
*pDllName = "atiadlxy.dll";
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(dev->vendor_id));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "libpciaccess");
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
@@ -46,9 +47,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
ffGPUQueryAmdGpuName(dev->device_id, dev->revision, gpu);
|
||||
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
ffGPUFillVendorAndName((dev->device_class >> 8) & 8, dev->vendor_id, dev->device_id, gpu);
|
||||
}
|
||||
ffGPUFillVendorAndName((dev->device_class >> 8) & 0xFF, dev->vendor_id, dev->device_id, gpu);
|
||||
}
|
||||
|
||||
ffpci_system_cleanup();
|
||||
|
||||
@@ -23,7 +23,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(dev.vendor_id));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInitStatic(&gpu->platformApi, POKE_DEVICE_FULLNAME);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
|
||||
@@ -12,6 +12,7 @@ struct FFIgclData {
|
||||
FF_LIBRARY_SYMBOL(ctlEnumTemperatureSensors)
|
||||
FF_LIBRARY_SYMBOL(ctlTemperatureGetState)
|
||||
FF_LIBRARY_SYMBOL(ctlEnumMemoryModules)
|
||||
FF_LIBRARY_SYMBOL(ctlMemoryGetProperties)
|
||||
FF_LIBRARY_SYMBOL(ctlMemoryGetState)
|
||||
FF_LIBRARY_SYMBOL(ctlEnumFrequencyDomains)
|
||||
FF_LIBRARY_SYMBOL(ctlFrequencyGetProperties)
|
||||
@@ -42,6 +43,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumTemperatureSensors)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlTemperatureGetState)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumMemoryModules)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlMemoryGetProperties)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlMemoryGetState)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumFrequencyDomains)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlFrequencyGetProperties)
|
||||
@@ -135,14 +137,56 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
result.memory->total = 0;
|
||||
for (uint32_t iMem = 0; iMem < memoryCount; iMem++)
|
||||
{
|
||||
ctl_mem_state_t memoryState = {
|
||||
.Size = sizeof(ctl_mem_state_t),
|
||||
ctl_mem_properties_t memoryProperties = {
|
||||
.Size = sizeof(memoryProperties),
|
||||
.Version = 0,
|
||||
};
|
||||
if (igclData.ffctlMemoryGetState(memoryModules[iMem], &memoryState) == CTL_RESULT_SUCCESS)
|
||||
if (igclData.ffctlMemoryGetProperties(memoryModules[iMem], &memoryProperties) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
result.memory->total += memoryState.size;
|
||||
result.memory->used += memoryState.size - memoryState.free;
|
||||
if (memoryProperties.location == CTL_MEM_LOC_DEVICE && result.memoryType)
|
||||
{
|
||||
switch (memoryProperties.type)
|
||||
{
|
||||
#define FF_ICTL_MEM_TYPE_CASE(type) case CTL_MEM_TYPE_##type: ffStrbufSetStatic(result.memoryType, #type); break
|
||||
FF_ICTL_MEM_TYPE_CASE(HBM);
|
||||
FF_ICTL_MEM_TYPE_CASE(DDR);
|
||||
FF_ICTL_MEM_TYPE_CASE(DDR3);
|
||||
FF_ICTL_MEM_TYPE_CASE(DDR4);
|
||||
FF_ICTL_MEM_TYPE_CASE(DDR5);
|
||||
FF_ICTL_MEM_TYPE_CASE(LPDDR);
|
||||
FF_ICTL_MEM_TYPE_CASE(LPDDR3);
|
||||
FF_ICTL_MEM_TYPE_CASE(LPDDR4);
|
||||
FF_ICTL_MEM_TYPE_CASE(LPDDR5);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR4);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR5);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR5X);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR6);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR6X);
|
||||
FF_ICTL_MEM_TYPE_CASE(GDDR7);
|
||||
#undef FF_ICTL_MEM_TYPE_CASE
|
||||
default:
|
||||
ffStrbufSetF(result.memoryType, "Unknown (%u)", memoryProperties.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctl_mem_state_t memoryState = {
|
||||
.Size = sizeof(ctl_mem_state_t),
|
||||
.Version = 0,
|
||||
};
|
||||
if (igclData.ffctlMemoryGetState(memoryModules[iMem], &memoryState) == CTL_RESULT_SUCCESS)
|
||||
{
|
||||
if (memoryProperties.location == CTL_MEM_LOC_DEVICE)
|
||||
{
|
||||
result.memory->total += memoryState.size;
|
||||
result.memory->used += memoryState.size - memoryState.free;
|
||||
}
|
||||
else if (result.sharedMemory && memoryProperties.location == CTL_MEM_LOC_SYSTEM)
|
||||
{
|
||||
result.sharedMemory->total += memoryState.size;
|
||||
result.sharedMemory->used += memoryState.size - memoryState.free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +215,8 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
availableCount++;
|
||||
}
|
||||
}
|
||||
*result.temp = sumValue / availableCount;
|
||||
if (availableCount > 0)
|
||||
*result.temp = sumValue / availableCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -426,7 +426,9 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
}
|
||||
else
|
||||
{
|
||||
pPciPath = memrchr(deviceDir->chars, '/', deviceDir->length) + 1;
|
||||
pPciPath = memrchr(deviceDir->chars, '/', deviceDir->length);
|
||||
assert(pPciPath);
|
||||
pPciPath++;
|
||||
}
|
||||
|
||||
uint32_t pciDomain, pciBus, pciDevice, pciFunc;
|
||||
@@ -438,6 +440,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
@@ -632,6 +635,7 @@ static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, co
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
+127
-15
@@ -21,6 +21,108 @@ struct FFNvmlData {
|
||||
bool inited;
|
||||
} nvmlData;
|
||||
|
||||
#if defined(_WIN32) && !defined(FF_DISABLE_DLOPEN)
|
||||
|
||||
#include "nvapi.h"
|
||||
|
||||
struct FFNvapiData {
|
||||
FF_LIBRARY_SYMBOL(nvapi_Unload)
|
||||
FF_LIBRARY_SYMBOL(nvapi_EnumPhysicalGPUs)
|
||||
FF_LIBRARY_SYMBOL(nvapi_GPU_GetRamType)
|
||||
|
||||
bool inited;
|
||||
} nvapiData;
|
||||
|
||||
static const char* detectMemTypeByNvapi(FFGpuDriverResult* result)
|
||||
{
|
||||
if (!nvapiData.inited)
|
||||
{
|
||||
nvapiData.inited = true;
|
||||
|
||||
FF_LIBRARY_LOAD(libnvapi, "dlopen nvapi failed",
|
||||
#ifdef _WIN64
|
||||
"nvapi64.dll"
|
||||
#else
|
||||
"nvapi.dll"
|
||||
#endif
|
||||
, 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvapi, nvapi_QueryInterface)
|
||||
#define FF_NVAPI_INTERFACE(iName, iOffset) \
|
||||
__typeof__(&iName) ff ## iName = ffnvapi_QueryInterface(iOffset); \
|
||||
if (ff ## iName == NULL) return "nvapi_QueryInterface " #iName " failed";
|
||||
|
||||
FF_NVAPI_INTERFACE(nvapi_Initialize, NVAPI_INTERFACE_OFFSET_INITIALIZE)
|
||||
FF_NVAPI_INTERFACE(nvapi_Unload, NVAPI_INTERFACE_OFFSET_UNLOAD)
|
||||
FF_NVAPI_INTERFACE(nvapi_EnumPhysicalGPUs, NVAPI_INTERFACE_OFFSET_ENUM_PHYSICAL_GPUS)
|
||||
FF_NVAPI_INTERFACE(nvapi_GPU_GetRamType, NVAPI_INTERFACE_OFFSET_GPU_GET_RAM_TYPE)
|
||||
#undef FF_NVAPI_INTERFACE
|
||||
|
||||
if (ffnvapi_Initialize() < 0)
|
||||
return "NvAPI_Initialize() failed";
|
||||
|
||||
nvapiData.ffnvapi_EnumPhysicalGPUs = ffnvapi_EnumPhysicalGPUs;
|
||||
nvapiData.ffnvapi_GPU_GetRamType = ffnvapi_GPU_GetRamType;
|
||||
nvapiData.ffnvapi_Unload = ffnvapi_Unload;
|
||||
|
||||
atexit((void*) ffnvapi_Unload);
|
||||
libnvapi = NULL; // don't close nvapi
|
||||
}
|
||||
|
||||
if (nvapiData.ffnvapi_EnumPhysicalGPUs == NULL)
|
||||
return "loading nvapi library failed";
|
||||
|
||||
NvPhysicalGpuHandle handles[32];
|
||||
int gpuCount = 0;
|
||||
|
||||
if (nvapiData.ffnvapi_EnumPhysicalGPUs(handles, &gpuCount) < 0)
|
||||
return "NvAPI_EnumPhysicalGPUs() failed";
|
||||
|
||||
uint32_t gpuIndex = *result->index;
|
||||
|
||||
if (gpuIndex >= (uint32_t) gpuCount)
|
||||
return "GPU index out of range";
|
||||
|
||||
// Not very sure. Need to check in multi-GPU system
|
||||
NvPhysicalGpuHandle gpuHandle = handles[gpuIndex];
|
||||
|
||||
NvApiGPUMemoryType memType;
|
||||
if (nvapiData.ffnvapi_GPU_GetRamType(gpuHandle, &memType) < 0)
|
||||
return "NvAPI_GPU_GetRamType() failed";
|
||||
|
||||
switch (memType)
|
||||
{
|
||||
#define FF_NVAPI_MEMORY_TYPE(type) \
|
||||
case NVAPI_GPU_MEMORY_TYPE_##type: \
|
||||
ffStrbufSetStatic(result->memoryType, #type); \
|
||||
break;
|
||||
FF_NVAPI_MEMORY_TYPE(UNKNOWN)
|
||||
FF_NVAPI_MEMORY_TYPE(SDRAM)
|
||||
FF_NVAPI_MEMORY_TYPE(DDR1)
|
||||
FF_NVAPI_MEMORY_TYPE(DDR2)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR2)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR3)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR4)
|
||||
FF_NVAPI_MEMORY_TYPE(DDR3)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR5)
|
||||
FF_NVAPI_MEMORY_TYPE(LPDDR2)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR5X)
|
||||
FF_NVAPI_MEMORY_TYPE(LPDDR3)
|
||||
FF_NVAPI_MEMORY_TYPE(LPDDR4)
|
||||
FF_NVAPI_MEMORY_TYPE(LPDDR5)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR6)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR6X)
|
||||
FF_NVAPI_MEMORY_TYPE(GDDR7)
|
||||
#undef FF_NVAPI_MEMORY_TYPE
|
||||
default:
|
||||
ffStrbufSetF(result->memoryType, "Unknown (%d)", memType);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName)
|
||||
{
|
||||
#ifndef FF_DISABLE_DLOPEN
|
||||
@@ -61,7 +163,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
if (cond->type & FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID)
|
||||
{
|
||||
char pciBusIdStr[32];
|
||||
snprintf(pciBusIdStr, ARRAY_SIZE(pciBusIdStr) - 1, "%04x:%02x:%02x.%d", cond->pciBusId.domain, cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func);
|
||||
snprintf(pciBusIdStr, ARRAY_SIZE(pciBusIdStr), "%04x:%02x:%02x.%d", cond->pciBusId.domain, cond->pciBusId.bus, cond->pciBusId.device, cond->pciBusId.func);
|
||||
|
||||
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(pciBusIdStr, &device);
|
||||
if (ret != NVML_SUCCESS)
|
||||
@@ -88,24 +190,28 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
|
||||
break;
|
||||
}
|
||||
if (!device) return "Device not found";
|
||||
}
|
||||
|
||||
nvmlBrandType_t brand;
|
||||
if (nvmlData.ffnvmlDeviceGetBrand(device, &brand) == NVML_SUCCESS)
|
||||
if (!device) return "Device not found";
|
||||
|
||||
if (result.type)
|
||||
{
|
||||
switch (brand)
|
||||
nvmlBrandType_t brand;
|
||||
if (nvmlData.ffnvmlDeviceGetBrand(device, &brand) == NVML_SUCCESS)
|
||||
{
|
||||
case NVML_BRAND_NVIDIA_RTX:
|
||||
case NVML_BRAND_QUADRO_RTX:
|
||||
case NVML_BRAND_GEFORCE:
|
||||
case NVML_BRAND_TITAN:
|
||||
case NVML_BRAND_TESLA:
|
||||
case NVML_BRAND_QUADRO:
|
||||
*result.type = FF_GPU_TYPE_DISCRETE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (brand)
|
||||
{
|
||||
case NVML_BRAND_NVIDIA_RTX:
|
||||
case NVML_BRAND_QUADRO_RTX:
|
||||
case NVML_BRAND_GEFORCE:
|
||||
case NVML_BRAND_TITAN:
|
||||
case NVML_BRAND_TESLA:
|
||||
case NVML_BRAND_QUADRO:
|
||||
*result.type = FF_GPU_TYPE_DISCRETE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +219,13 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
{
|
||||
unsigned int value;
|
||||
if (nvmlData.ffnvmlDeviceGetIndex(device, &value) == NVML_SUCCESS)
|
||||
{
|
||||
*result.index = value;
|
||||
#ifdef _WIN32
|
||||
if (result.memoryType)
|
||||
detectMemTypeByNvapi(&result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
|
||||
"scanpci",
|
||||
"/usr/bin/scanpci",
|
||||
"-v",
|
||||
NULL,
|
||||
});
|
||||
@@ -35,8 +35,14 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
{
|
||||
// find the start of device entry
|
||||
const char* pstart = memrchr(buffer.chars, '\n', (size_t) (pclass - buffer.chars));
|
||||
if (pstart == NULL)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
while (pstart[1] != 'p')
|
||||
{
|
||||
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
|
||||
if (pstart == NULL)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
}
|
||||
++pstart;
|
||||
|
||||
uint32_t vendorId, deviceId;
|
||||
@@ -51,9 +57,10 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "/usr/bin/scanpci");
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
@@ -37,6 +37,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "SetupAPI");
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
@@ -47,13 +48,14 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
gpu->deviceId = 0;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
uint32_t pciBus = 0, pciAddr = UINT32_MAX, pciDev = 0, pciFunc = 0;
|
||||
uint32_t pciBus = 0, pciAddr = 0, pciDev = 0, pciFunc = 0;
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
|
||||
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
|
||||
{
|
||||
pciDev = (pciAddr >> 16) & 0xFFFF;
|
||||
pciFunc = pciAddr & 0xFFFF;
|
||||
gpu->deviceId = (pciBus * 1000ull) + (pciDev * 10ull) + pciFunc;
|
||||
pciAddr = 1; // Set to 1 to indicate that the device is a PCI device
|
||||
}
|
||||
|
||||
wchar_t buffer[256];
|
||||
@@ -173,6 +175,8 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
.index = &gpu->index,
|
||||
.temp = options->temp ? &gpu->temperature : NULL,
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.sharedMemory = options->driverSpecific ? &gpu->shared : NULL,
|
||||
.memoryType = options->driverSpecific ? &gpu->memoryType : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
|
||||
.type = &gpu->type,
|
||||
|
||||
@@ -70,6 +70,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
|
||||
ffStrbufInitS(&gpu->name, desc);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
|
||||
@@ -141,6 +141,50 @@ typedef struct ctl_mem_state_t
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv417ctlMemoryGetState16ctl_mem_handle_tP15ctl_mem_state_t
|
||||
extern ctl_result_t ctlMemoryGetState(ctl_mem_handle_t hMemory, ctl_mem_state_t *pState);
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv414ctl_mem_type_t
|
||||
typedef enum ctl_mem_type_t
|
||||
{
|
||||
CTL_MEM_TYPE_HBM = 0,
|
||||
CTL_MEM_TYPE_DDR = 1,
|
||||
CTL_MEM_TYPE_DDR3 = 2,
|
||||
CTL_MEM_TYPE_DDR4 = 3,
|
||||
CTL_MEM_TYPE_DDR5 = 4,
|
||||
CTL_MEM_TYPE_LPDDR = 5,
|
||||
CTL_MEM_TYPE_LPDDR3 = 6,
|
||||
CTL_MEM_TYPE_LPDDR4 = 7,
|
||||
CTL_MEM_TYPE_LPDDR5 = 8,
|
||||
CTL_MEM_TYPE_GDDR4 = 9,
|
||||
CTL_MEM_TYPE_GDDR5 = 10,
|
||||
CTL_MEM_TYPE_GDDR5X = 11,
|
||||
CTL_MEM_TYPE_GDDR6 = 12,
|
||||
CTL_MEM_TYPE_GDDR6X = 13,
|
||||
CTL_MEM_TYPE_GDDR7 = 14,
|
||||
CTL_MEM_TYPE_MAX
|
||||
} ctl_mem_type_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv413ctl_mem_loc_t
|
||||
typedef enum ctl_mem_loc_t
|
||||
{
|
||||
CTL_MEM_LOC_SYSTEM = 0,
|
||||
CTL_MEM_LOC_DEVICE = 1,
|
||||
CTL_MEM_LOC_MAX
|
||||
} ctl_mem_loc_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv420ctl_mem_properties_t
|
||||
typedef struct ctl_mem_properties_t
|
||||
{
|
||||
uint32_t Size;
|
||||
uint8_t Version;
|
||||
ctl_mem_type_t type;
|
||||
ctl_mem_loc_t location;
|
||||
uint64_t physicalSize;
|
||||
int32_t busWidth;
|
||||
int32_t numChannels;
|
||||
} ctl_mem_properties_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#_CPPv422ctlMemoryGetProperties16ctl_mem_handle_tP20ctl_mem_properties_t
|
||||
extern ctl_result_t ctlMemoryGetProperties(ctl_mem_handle_t hMemory, ctl_mem_properties_t *pProperties);
|
||||
|
||||
typedef struct ctl_freq_handle_t* ctl_freq_handle_t;
|
||||
|
||||
// https://intel.github.io/drivers.gpu.control-library/Control/api.html#ctlenumfrequencydomains
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// References:
|
||||
// https://github.com/NVIDIA/nvapi (MIT License)
|
||||
// https://github.com/deathcamp/NVOC/blob/master/nvoc.c (Public Domain)
|
||||
|
||||
typedef enum NvApiGPUMemoryType
|
||||
{
|
||||
NVAPI_GPU_MEMORY_TYPE_UNKNOWN = 0,
|
||||
NVAPI_GPU_MEMORY_TYPE_SDRAM,
|
||||
NVAPI_GPU_MEMORY_TYPE_DDR1,
|
||||
NVAPI_GPU_MEMORY_TYPE_DDR2,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR2,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR3,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR4,
|
||||
NVAPI_GPU_MEMORY_TYPE_DDR3,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR5,
|
||||
NVAPI_GPU_MEMORY_TYPE_LPDDR2,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR5X,
|
||||
NVAPI_GPU_MEMORY_TYPE_LPDDR3,
|
||||
NVAPI_GPU_MEMORY_TYPE_LPDDR4,
|
||||
NVAPI_GPU_MEMORY_TYPE_LPDDR5,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR6,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR6X,
|
||||
NVAPI_GPU_MEMORY_TYPE_GDDR7,
|
||||
} NvApiGPUMemoryType;
|
||||
|
||||
typedef int NvAPI_Status; // 0 = success; < 0 = error
|
||||
typedef struct NvPhysicalGpuHandle* NvPhysicalGpuHandle;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NVAPI_INTERFACE_OFFSET_INITIALIZE = 0x0150E828,
|
||||
NVAPI_INTERFACE_OFFSET_UNLOAD = 0xD22BDD7E,
|
||||
NVAPI_INTERFACE_OFFSET_ENUM_PHYSICAL_GPUS = 0xE5AC921F,
|
||||
NVAPI_INTERFACE_OFFSET_GPU_GET_RAM_TYPE = 0x57F7CAAC,
|
||||
|
||||
NVAPI_INTERFACE_OFFSET_FORCE_UINT32 = 0xFFFFFFFF
|
||||
} NvApiInterfaceOffsets;
|
||||
|
||||
extern void* nvapi_QueryInterface(NvApiInterfaceOffsets offset);
|
||||
|
||||
extern NvAPI_Status nvapi_Initialize(void);
|
||||
extern NvAPI_Status nvapi_Unload(void);
|
||||
extern NvAPI_Status nvapi_EnumPhysicalGPUs(NvPhysicalGpuHandle* handles, int* count);
|
||||
extern NvAPI_Status nvapi_GPU_GetRamType(NvPhysicalGpuHandle handle, NvApiGPUMemoryType* memtype);
|
||||
@@ -14,7 +14,7 @@ typedef struct FFHostResult
|
||||
} FFHostResult;
|
||||
|
||||
const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel);
|
||||
#ifdef __x86_64__
|
||||
#if __x86_64__
|
||||
bool ffHostDetectMac(FFHostResult* host);
|
||||
#endif
|
||||
const char* ffDetectHost(FFHostResult* host);
|
||||
|
||||
@@ -107,6 +107,11 @@ const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
else if(ffStrbufStartsWithS(hwModel, "Mac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Mac");
|
||||
if(ffStrEquals(version, "16,13")) return "MacBook Air (15-inch, M4, 2025)";
|
||||
if(ffStrEquals(version, "16,12")) return "MacBook Air (13-inch, M4, 2025)";
|
||||
if(ffStrEquals(version, "16,11") ||
|
||||
ffStrEquals(version, "16,10")) return "Mac Mini (2024)";
|
||||
if(ffStrEquals(version, "16,9")) return "Mac Studio (M4 Max, 2025)";
|
||||
if(ffStrEquals(version, "16,3")) return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,2")) return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "16,1")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)";
|
||||
@@ -114,8 +119,7 @@ const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
ffStrEquals(version, "16,8")) return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)";
|
||||
if(ffStrEquals(version, "16,7") ||
|
||||
ffStrEquals(version, "16,5")) return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)";
|
||||
if(ffStrEquals(version, "16,15") ||
|
||||
ffStrEquals(version, "16,10")) return "Mac mini (2024)";
|
||||
if(ffStrEquals(version, "15,14")) return "Mac Studio (M3 Ultra, 2025)";
|
||||
if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)";
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
|
||||
|
||||
@@ -72,7 +72,7 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffCleanUpSmbiosValue(&host->family);
|
||||
}
|
||||
|
||||
#if _WIN32 && __x86_64__
|
||||
#if _WIN64 && __x86_64__ // aarch64 also defines _WIN64
|
||||
ffHostDetectMac(host);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
|
||||
ffStrbufSetStatic(&result->exe, path);
|
||||
ffStrbufSetStatic(&result->name, "launch_daemon");
|
||||
result->pid = 0;
|
||||
|
||||
team_info teamInfo;
|
||||
int32 cookie = 0;
|
||||
@@ -28,7 +29,8 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
}
|
||||
}
|
||||
|
||||
ffGetFileVersion(path, &result->version);
|
||||
if (instance.config.general.detectVersion)
|
||||
ffGetFileVersion(path, &result->version);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <usbhid.h>
|
||||
#include <sys/kbio.h>
|
||||
|
||||
#if __has_include(<dev/usb/usb_ioctl.h>)
|
||||
#include <dev/usb/usb_ioctl.h> // FreeBSD
|
||||
@@ -11,16 +12,47 @@
|
||||
#include <bus/u4b/usb_ioctl.h> // DragonFly
|
||||
#endif
|
||||
|
||||
#define MAX_UHID_JOYS 64
|
||||
static const char* detectByIoctl(FFlist* devices)
|
||||
{
|
||||
keyboard_info_t kbdInfo;
|
||||
if (ioctl(STDIN_FILENO, KDGKBINFO, &kbdInfo) != 0)
|
||||
return "ioctl(KDGKBINFO) failed";
|
||||
|
||||
const char* ffDetectKeyboard(FFlist* devices /* List of FFKeyboardDevice */)
|
||||
FFKeyboardDevice* device = (FFKeyboardDevice*) ffListAdd(devices);
|
||||
|
||||
switch (kbdInfo.kb_type) {
|
||||
case KB_84:
|
||||
ffStrbufInitS(&device->name, "AT 84-key keyboard");
|
||||
break;
|
||||
case KB_101:
|
||||
ffStrbufInitS(&device->name, "AT 101/102-key keyboard");
|
||||
break;
|
||||
default:
|
||||
ffStrbufInitS(&device->name, "Unknown keyboard");
|
||||
break;
|
||||
}
|
||||
|
||||
ffStrbufAppendF(&device->name, " (kbd%d)", kbdInfo.kb_index);
|
||||
|
||||
ffStrbufInit(&device->serial);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX_UHID_KBDS 64
|
||||
|
||||
static const char* detectByUsbhid(FFlist* devices)
|
||||
{
|
||||
char path[16];
|
||||
for (int i = 0; i < MAX_UHID_JOYS; i++)
|
||||
for (int i = 0; i < MAX_UHID_KBDS; i++)
|
||||
{
|
||||
snprintf(path, ARRAY_SIZE(path), "/dev/uhid%d", i);
|
||||
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) continue;
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
break; // No more devices
|
||||
continue; // Device not found
|
||||
}
|
||||
|
||||
report_desc_t repDesc = hid_get_report_desc(fd);
|
||||
if (!repDesc) continue;
|
||||
@@ -43,6 +75,7 @@ const char* ffDetectKeyboard(FFlist* devices /* List of FFKeyboardDevice */)
|
||||
ffStrbufInitS(&device->name, di.udi_product);
|
||||
}
|
||||
}
|
||||
hid_end_parse(hData);
|
||||
}
|
||||
|
||||
hid_dispose_report_desc(repDesc);
|
||||
@@ -50,3 +83,11 @@ const char* ffDetectKeyboard(FFlist* devices /* List of FFKeyboardDevice */)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectKeyboard(FFlist* devices /* List of FFKeyboardDevice */)
|
||||
{
|
||||
detectByUsbhid(devices);
|
||||
if (devices->length > 0)
|
||||
return NULL;
|
||||
return detectByIoctl(devices);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ extern void MRMediaRemoteGetNowPlayingInfo(dispatch_queue_t dispatcher, void(^ca
|
||||
extern void MRMediaRemoteGetNowPlayingClient(dispatch_queue_t dispatcher, void (^callback)(_Nullable id clientObj)) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
extern CFStringRef MRNowPlayingClientGetParentAppBundleIdentifier(id clientObj) __attribute__((weak_import));
|
||||
void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing));
|
||||
void MRMediaRemoteGetNowPlayingApplicationIsPlaying(dispatch_queue_t queue, void (^callback)(BOOL playing)) __attribute__((weak_import));
|
||||
|
||||
static const char* getMedia(FFMediaResult* result)
|
||||
{
|
||||
@@ -20,6 +20,7 @@ static const char* getMedia(FFMediaResult* result)
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingClient);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetBundleIdentifier);
|
||||
FF_TEST_FN_EXISTANCE(MRNowPlayingClientGetParentAppBundleIdentifier);
|
||||
FF_TEST_FN_EXISTANCE(MRMediaRemoteGetNowPlayingApplicationIsPlaying);
|
||||
#undef FF_TEST_FN_EXISTANCE
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
@@ -63,6 +64,7 @@ static const char* getMedia(FFMediaResult* result)
|
||||
});
|
||||
|
||||
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
||||
// Don't dispatch_release because we are using ARC
|
||||
|
||||
if(result->playerId.length > 0)
|
||||
{
|
||||
|
||||
@@ -129,9 +129,9 @@ static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResul
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[] = { fileName[1], fileName[2], 0 };
|
||||
if (str[0] == 0 || str[1] == 0)
|
||||
if (fileName[1] == 0 || fileName[2] == 0)
|
||||
break;
|
||||
char str[] = { fileName[1], fileName[2], 0 };
|
||||
ffStrbufAppendC(&result->song, (char) strtoul(str, NULL, 16));
|
||||
fileName += 2;
|
||||
}
|
||||
|
||||
@@ -32,15 +32,15 @@ const char* ffWinrtDetectMedia(FFWinrtMediaResult* result)
|
||||
{
|
||||
switch (playbackInfo.PlaybackStatus())
|
||||
{
|
||||
#define FF_MEDIA_SET_STATUS(status_code) \
|
||||
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: result->status = #status_code; break
|
||||
FF_MEDIA_SET_STATUS(Closed);
|
||||
FF_MEDIA_SET_STATUS(Opened);
|
||||
FF_MEDIA_SET_STATUS(Changing);
|
||||
FF_MEDIA_SET_STATUS(Stopped);
|
||||
FF_MEDIA_SET_STATUS(Playing);
|
||||
FF_MEDIA_SET_STATUS(Paused);
|
||||
#undef FF_MEDIA_SET_STATUS
|
||||
#define FF_MEDIA_SET_STATUS(status_code) \
|
||||
case GlobalSystemMediaTransportControlsSessionPlaybackStatus::status_code: result->status = #status_code; break;
|
||||
FF_MEDIA_SET_STATUS(Closed)
|
||||
FF_MEDIA_SET_STATUS(Opened)
|
||||
FF_MEDIA_SET_STATUS(Changing)
|
||||
FF_MEDIA_SET_STATUS(Stopped)
|
||||
FF_MEDIA_SET_STATUS(Playing)
|
||||
FF_MEDIA_SET_STATUS(Paused)
|
||||
#undef FF_MEDIA_SET_STATUS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,21 @@
|
||||
#include <bus/u4b/usb_ioctl.h> // DragonFly
|
||||
#endif
|
||||
|
||||
#define MAX_UHID_JOYS 64
|
||||
#define MAX_UHID_MICE 64
|
||||
|
||||
const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */)
|
||||
{
|
||||
char path[16];
|
||||
for (int i = 0; i < MAX_UHID_JOYS; i++)
|
||||
for (int i = 0; i < MAX_UHID_MICE; i++)
|
||||
{
|
||||
snprintf(path, ARRAY_SIZE(path), "/dev/uhid%d", i);
|
||||
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) continue;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
break; // No more devices
|
||||
continue; // Device not found
|
||||
}
|
||||
report_desc_t repDesc = hid_get_report_desc(fd);
|
||||
if (!repDesc) continue;
|
||||
|
||||
@@ -43,6 +47,7 @@ const char* ffDetectMouse(FFlist* devices /* List of FFMouseDevice */)
|
||||
ffStrbufInitS(&device->name, di.udi_product);
|
||||
}
|
||||
}
|
||||
hid_end_parse(hData);
|
||||
}
|
||||
|
||||
hid_dispose_report_desc(repDesc);
|
||||
|
||||
@@ -92,6 +92,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
ffStrbufInit(&gpu->memoryType);
|
||||
gpu->index = FF_GPU_INDEX_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
|
||||
@@ -123,67 +123,73 @@ const char* ffDetectPhysicalMemory(FFlist* result)
|
||||
else if (ldevice)
|
||||
ffStrbufSetS(&device->locator, ldevice);
|
||||
|
||||
switch (data->FormFactor)
|
||||
{
|
||||
case 0x01: ffStrbufSetStatic(&device->formFactor, "Other"); break;
|
||||
case 0x02: ffStrbufSetStatic(&device->formFactor, "Unknown"); break;
|
||||
case 0x03: ffStrbufSetStatic(&device->formFactor, "SIMM"); break;
|
||||
case 0x04: ffStrbufSetStatic(&device->formFactor, "SIP"); break;
|
||||
case 0x05: ffStrbufSetStatic(&device->formFactor, "Chip"); break;
|
||||
case 0x06: ffStrbufSetStatic(&device->formFactor, "DIP"); break;
|
||||
case 0x07: ffStrbufSetStatic(&device->formFactor, "ZIP"); break;
|
||||
case 0x08: ffStrbufSetStatic(&device->formFactor, "Proprietary Card"); break;
|
||||
case 0x09: ffStrbufSetStatic(&device->formFactor, "DIMM"); break;
|
||||
case 0x0A: ffStrbufSetStatic(&device->formFactor, "TSOP"); break;
|
||||
case 0x0B: ffStrbufSetStatic(&device->formFactor, "Row of chips"); break;
|
||||
case 0x0C: ffStrbufSetStatic(&device->formFactor, "RIMM"); break;
|
||||
case 0x0D: ffStrbufSetStatic(&device->formFactor, "SODIMM"); break;
|
||||
case 0x0E: ffStrbufSetStatic(&device->formFactor, "SRIMM"); break;
|
||||
case 0x0F: ffStrbufSetStatic(&device->formFactor, "FBDIMM"); break;
|
||||
case 0x10: ffStrbufSetStatic(&device->formFactor, "Die"); break;
|
||||
default: ffStrbufSetF(&device->formFactor, "Unknown (%d)", (int) data->FormFactor); break;
|
||||
}
|
||||
const char* formFactorNames[] = {
|
||||
NULL, // 0x00 (用于索引,实际上没有0x00的类型)
|
||||
"Other", // 0x01
|
||||
"Unknown", // 0x02
|
||||
"SIMM", // 0x03
|
||||
"SIP", // 0x04
|
||||
"Chip", // 0x05
|
||||
"DIP", // 0x06
|
||||
"ZIP", // 0x07
|
||||
"Proprietary Card",// 0x08
|
||||
"DIMM", // 0x09
|
||||
"TSOP", // 0x0A
|
||||
"Row of chips", // 0x0B
|
||||
"RIMM", // 0x0C
|
||||
"SODIMM", // 0x0D
|
||||
"SRIMM", // 0x0E
|
||||
"FBDIMM", // 0x0F
|
||||
"Die", // 0x10
|
||||
};
|
||||
if (data->FormFactor > 0 && data->FormFactor < ARRAY_SIZE(formFactorNames))
|
||||
ffStrbufSetS(&device->formFactor, formFactorNames[data->FormFactor]);
|
||||
else
|
||||
ffStrbufSetF(&device->formFactor, "Unknown (%d)", (int) data->FormFactor);
|
||||
|
||||
switch (data->MemoryType)
|
||||
{
|
||||
case 0x01: ffStrbufSetStatic(&device->type, "Other"); break;
|
||||
case 0x02: ffStrbufSetStatic(&device->type, "Unknown"); break;
|
||||
case 0x03: ffStrbufSetStatic(&device->type, "DRAM"); break;
|
||||
case 0x04: ffStrbufSetStatic(&device->type, "EDRAM"); break;
|
||||
case 0x05: ffStrbufSetStatic(&device->type, "VRAM"); break;
|
||||
case 0x06: ffStrbufSetStatic(&device->type, "SRAM"); break;
|
||||
case 0x07: ffStrbufSetStatic(&device->type, "RAM"); break;
|
||||
case 0x08: ffStrbufSetStatic(&device->type, "ROM"); break;
|
||||
case 0x09: ffStrbufSetStatic(&device->type, "FLASH"); break;
|
||||
case 0x0A: ffStrbufSetStatic(&device->type, "EEPROM"); break;
|
||||
case 0x0B: ffStrbufSetStatic(&device->type, "FEPROM"); break;
|
||||
case 0x0C: ffStrbufSetStatic(&device->type, "EPROM"); break;
|
||||
case 0x0D: ffStrbufSetStatic(&device->type, "CDRAM"); break;
|
||||
case 0x0E: ffStrbufSetStatic(&device->type, "3DRAM"); break;
|
||||
case 0x0F: ffStrbufSetStatic(&device->type, "SDRAM"); break;
|
||||
case 0x10: ffStrbufSetStatic(&device->type, "SGRAM"); break;
|
||||
case 0x11: ffStrbufSetStatic(&device->type, "RDRAM"); break;
|
||||
case 0x12: ffStrbufSetStatic(&device->type, "DDR"); break;
|
||||
case 0x13: ffStrbufSetStatic(&device->type, "DDR2"); break;
|
||||
case 0x14: ffStrbufSetStatic(&device->type, "DDR2 FB-DIMM"); break;
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x17: ffStrbufSetStatic(&device->type, "Reserved"); break;
|
||||
case 0x18: ffStrbufSetStatic(&device->type, "DDR3"); break;
|
||||
case 0x19: ffStrbufSetStatic(&device->type, "FBD2"); break;
|
||||
case 0x1A: ffStrbufSetStatic(&device->type, "DDR4"); break;
|
||||
case 0x1B: ffStrbufSetStatic(&device->type, "LPDDR"); break;
|
||||
case 0x1C: ffStrbufSetStatic(&device->type, "LPDDR2"); break;
|
||||
case 0x1D: ffStrbufSetStatic(&device->type, "LPDDR3"); break;
|
||||
case 0x1E: ffStrbufSetStatic(&device->type, "LPDDR4"); break;
|
||||
case 0x1F: ffStrbufSetStatic(&device->type, "Logical non-volatile device"); break;
|
||||
case 0x20: ffStrbufSetStatic(&device->type, "HBM"); break;
|
||||
case 0x21: ffStrbufSetStatic(&device->type, "HBM2"); break;
|
||||
case 0x22: ffStrbufSetStatic(&device->type, "DDR5"); break;
|
||||
case 0x23: ffStrbufSetStatic(&device->type, "LPDDR5"); break;
|
||||
case 0x24: ffStrbufSetStatic(&device->type, "HBM3"); break;
|
||||
default: ffStrbufSetF(&device->type, "Unknown (%d)", (int) data->MemoryType); break;
|
||||
}
|
||||
const char* memoryTypeNames[] = {
|
||||
NULL, // 0x00 (用于索引,实际上没有0x00的类型)
|
||||
"Other", // 0x01
|
||||
"Unknown", // 0x02
|
||||
"DRAM", // 0x03
|
||||
"EDRAM", // 0x04
|
||||
"VRAM", // 0x05
|
||||
"SRAM", // 0x06
|
||||
"RAM", // 0x07
|
||||
"ROM", // 0x08
|
||||
"FLASH", // 0x09
|
||||
"EEPROM", // 0x0A
|
||||
"FEPROM", // 0x0B
|
||||
"EPROM", // 0x0C
|
||||
"CDRAM", // 0x0D
|
||||
"3DRAM", // 0x0E
|
||||
"SDRAM", // 0x0F
|
||||
"SGRAM", // 0x10
|
||||
"RDRAM", // 0x11
|
||||
"DDR", // 0x12
|
||||
"DDR2", // 0x13
|
||||
"DDR2 FB-DIMM", // 0x14
|
||||
"Reserved", // 0x15
|
||||
"Reserved", // 0x16
|
||||
"Reserved", // 0x17
|
||||
"DDR3", // 0x18
|
||||
"FBD2", // 0x19
|
||||
"DDR4", // 0x1A
|
||||
"LPDDR", // 0x1B
|
||||
"LPDDR2", // 0x1C
|
||||
"LPDDR3", // 0x1D
|
||||
"LPDDR4", // 0x1E
|
||||
"Logical non-volatile device", // 0x1F
|
||||
"HBM", // 0x20
|
||||
"HBM2", // 0x21
|
||||
"DDR5", // 0x22
|
||||
"LPDDR5", // 0x23
|
||||
"HBM3", // 0x24
|
||||
};
|
||||
if (data->MemoryType > 0 && data->MemoryType < ARRAY_SIZE(memoryTypeNames))
|
||||
ffStrbufSetStatic(&device->type, memoryTypeNames[data->MemoryType]);
|
||||
else
|
||||
ffStrbufSetF(&device->type, "Unknown (%d)", (int) data->MemoryType);
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosMemoryDevice, Speed)) // 2.3+
|
||||
{
|
||||
|
||||
@@ -64,7 +64,7 @@ const char* ffDetectSound(FFlist* devices)
|
||||
return "sioctl_ondesc() failed";
|
||||
|
||||
if (bundle.iLevel != bundle.iMute || bundle.iLevel == 0)
|
||||
return "Unexpecd sioctl_ondesc() result";
|
||||
return "Unexpected sioctl_ondesc() result";
|
||||
|
||||
FFSoundDevice* device = ffListAdd(devices);
|
||||
ffStrbufInitS(&device->name, bundle.name);
|
||||
|
||||
@@ -9,6 +9,14 @@ extern "C" {
|
||||
#include <endpointvolume.h>
|
||||
#include <functiondiscoverykeys_devpkey.h>
|
||||
|
||||
static void ffCoTaskMemFreeWrapper(void* pptr)
|
||||
{
|
||||
assert(pptr != NULL);
|
||||
void* ptr = *(void**)pptr;
|
||||
if (ptr) CoTaskMemFree(ptr);
|
||||
}
|
||||
#define FF_COTASK_AUTO_FREE __attribute__((__cleanup__(ffCoTaskMemFreeWrapper)))
|
||||
|
||||
const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
|
||||
{
|
||||
const char* error = ffInitCom();
|
||||
@@ -20,7 +28,7 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
|
||||
if (FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&pEnum)))
|
||||
return "CoCreateInstance(CLSID_MMDeviceEnumerator) failed";
|
||||
|
||||
LPWSTR mainDeviceId = NULL;
|
||||
LPWSTR FF_COTASK_AUTO_FREE mainDeviceId = NULL;
|
||||
|
||||
{
|
||||
IMMDevice* FF_AUTO_RELEASE_COM_OBJECT pDefaultDevice = NULL;
|
||||
@@ -47,7 +55,7 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
|
||||
if (FAILED(pDevices->Item(deviceIdx, &immDevice)))
|
||||
continue;
|
||||
|
||||
LPWSTR immDeviceId = NULL;
|
||||
LPWSTR FF_COTASK_AUTO_FREE immDeviceId = NULL;
|
||||
if (FAILED(immDevice->GetId(&immDeviceId)))
|
||||
continue;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user