Skip to content

Commit 3d97292

Browse files
committed
feat(gpu-temp): add GPU temperature reading via ADL library
Add AMD Display Library (ADL) integration for querying GPU temperatures. Includes dynamic library loading with libloading and FFI bindings to core ADL functions for adapter detection and temperature retrieval.
1 parent 8efd97e commit 3d97292

3 files changed

Lines changed: 82 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ name = "hotamd"
33
version = "0.1.0"
44
edition = "2024"
55

6-
[dependencies]
6+
[dependencies]
7+
libc = "0.2.183"
8+
libloading = "0.9.0"

src/main.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1-
fn main() {
2-
println!("Hello, world!");
1+
#![allow(non_camel_case_types)]
2+
use libloading::{Library, Symbol};
3+
use std::ffi::c_void;
4+
5+
#[repr(C)]
6+
struct ADLTemperature { size: i32, temperature: i32 }
7+
unsafe extern "C" fn adl_malloc(size: i32) -> *mut c_void { unsafe { libc::malloc(size as usize) } }
8+
type ADL_MAIN_CONTROL_CREATE = unsafe extern "C" fn(unsafe extern "C" fn(i32) -> *mut c_void, i32) -> i32;
9+
type ADL_MAIN_CONTROL_DESTROY = unsafe extern "C" fn() -> i32;
10+
type ADL_ADAPTER_NUMBER_OF_ADAPTERS_GET = unsafe extern "C" fn(*mut i32) -> i32;
11+
type ADL_OVERDRIVE5_TEMPERATURE_GET = unsafe extern "C" fn(i32, i32, *mut ADLTemperature) -> i32;
12+
13+
struct ADLManager<'a> { adl_destroy: Symbol<'a, ADL_MAIN_CONTROL_DESTROY> }
14+
impl Drop for ADLManager<'_> {
15+
fn drop(&mut self) {
16+
unsafe { (*self.adl_destroy)(); }
17+
}
18+
}
19+
20+
fn main() -> Result<(), Box<dyn std::error::Error>> {
21+
unsafe {
22+
let lib = Library::new("atiadlxx.dll").expect("Failed to load atiadlxx.dll");
23+
24+
let adl_create: Symbol<ADL_MAIN_CONTROL_CREATE> = lib.get(b"ADL_Main_Control_Create")?;
25+
let adl_destroy: Symbol<ADL_MAIN_CONTROL_DESTROY> = lib.get(b"ADL_Main_Control_Destroy")?;
26+
let get_adapters: Symbol<ADL_ADAPTER_NUMBER_OF_ADAPTERS_GET> = lib.get(b"ADL_Adapter_NumberOfAdapters_Get")?;
27+
let get_temp: Symbol<ADL_OVERDRIVE5_TEMPERATURE_GET> = lib.get(b"ADL_Overdrive5_Temperature_Get")?;
28+
29+
adl_create(adl_malloc, 1);
30+
let _manager = ADLManager { adl_destroy };
31+
32+
let mut adapters = 0;
33+
get_adapters(&mut adapters);
34+
if adapters == 0 { return Err("No adapters found".into()) }
35+
println!("Adapters found: {adapters}");
36+
37+
let mut temp = ADLTemperature {
38+
size: std::mem::size_of::<ADLTemperature>() as i32,
39+
temperature: 0,
40+
};
41+
match get_temp(0, 0, &mut temp) {
42+
0 => println!("GPU Temperature: {}°C", temp.temperature / 1000),
43+
_ => println!("Temperature read failed"),
44+
}
45+
46+
Ok(())
47+
}
348
}

0 commit comments

Comments
 (0)