Skip to content

Commit e4ca034

Browse files
Merge pull request #7 from Traverse-Research/add-power-telemetry
🪫 Add power information queries
2 parents ccd1319 + 3ab258f commit e4ca034

File tree

4 files changed

+906
-10403
lines changed

4 files changed

+906
-10403
lines changed

Diff for: api_gen/src/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ fn main() {
77

88
let bindings = bindgen::Builder::default()
99
.header(header_path.to_string_lossy())
10+
.derive_debug(true)
11+
.layout_tests(false)
12+
.impl_debug(true)
13+
.derive_default(true)
1014
.clang_arg(format!(
1115
"-I{}",
1216
crate_root

Diff for: src/device_adapter.rs

+178-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use crate::{
99
ffi::{
1010
ctl_3d_feature_getset_t, ctl_3d_feature_t, ctl_adapter_bdf_t, ctl_device_adapter_handle_t,
1111
ctl_device_adapter_properties_t, ctl_device_type_t, ctl_gaming_flip_mode_flag_t,
12-
ctl_property_value_type_t, ControlLib, _ctl_result_t, ctl_endurance_gaming_t, ctl_result_t,
12+
ctl_property_value_type_t, ControlLib, _ctl_result_t, ctl_endurance_gaming_t,
13+
ctl_oc_telemetry_item_t, ctl_power_telemetry_t, ctl_result_t,
1314
},
1415
};
1516

@@ -240,4 +241,180 @@ impl DeviceAdapter {
240241

241242
Ok(flip_mode)
242243
}
244+
245+
pub fn power_telemetry(&self) -> Result<Telemetry> {
246+
let mut telemetry = ctl_power_telemetry_t {
247+
Size: std::mem::size_of::<ctl_power_telemetry_t>() as u32,
248+
..Default::default()
249+
};
250+
251+
let result = unsafe {
252+
self.control_lib
253+
.ctlPowerTelemetryGet(self.device_adapter_handle, &mut telemetry)
254+
};
255+
256+
Error::from_result(result)?;
257+
258+
Ok(Telemetry {
259+
time_stamp: telemetry.timeStamp.into(),
260+
gpu_energy_counter: telemetry.gpuEnergyCounter.into(),
261+
gpu_voltage: telemetry.gpuVoltage.into(),
262+
gpu_current_clock_frequency: telemetry.gpuCurrentClockFrequency.into(),
263+
gpu_current_temperature: telemetry.gpuCurrentTemperature.into(),
264+
global_activity_counter: telemetry.globalActivityCounter.into(),
265+
render_compute_activity_counter: telemetry.renderComputeActivityCounter.into(),
266+
media_activity_counter: telemetry.mediaActivityCounter.into(),
267+
vram_energy_counter: telemetry.vramEnergyCounter.into(),
268+
vram_voltage: telemetry.vramVoltage.into(),
269+
vram_current_clock_frequency: telemetry.vramCurrentClockFrequency.into(),
270+
vram_current_effective_frequency: telemetry.vramCurrentEffectiveFrequency.into(),
271+
vram_read_bandwidth_counter: telemetry.vramReadBandwidthCounter.into(),
272+
vram_write_bandwidth_counter: telemetry.vramWriteBandwidthCounter.into(),
273+
vram_current_temperature: telemetry.vramCurrentTemperature.into(),
274+
total_card_energy_counter: telemetry.totalCardEnergyCounter.into(),
275+
fan_speed: [
276+
telemetry.fanSpeed[0].into(),
277+
telemetry.fanSpeed[1].into(),
278+
telemetry.fanSpeed[2].into(),
279+
telemetry.fanSpeed[3].into(),
280+
telemetry.fanSpeed[4].into(),
281+
],
282+
})
283+
}
284+
}
285+
286+
#[derive(Debug)]
287+
pub enum Value {
288+
I8(i8),
289+
U8(u8),
290+
I16(i16),
291+
U16(u16),
292+
I32(i32),
293+
U32(u32),
294+
I64(i64),
295+
U64(u64),
296+
F32(f32),
297+
F64(f64),
298+
}
299+
300+
#[derive(Debug)]
301+
pub enum Unit {
302+
FrequencyMhz(Value),
303+
OperationsGts(Value),
304+
OperationsMts(Value),
305+
VoltageVolts(Value),
306+
PowerWatts(Value),
307+
TemperatureCelsius(Value),
308+
EnergyJoules(Value),
309+
TimeSeconds(Value),
310+
MemoryBytes(Value),
311+
AngularSpeedRpm(Value),
312+
PowerMilliwatts(Value),
313+
Percent(Value),
314+
MemSpeedGbps(Value),
315+
VoltageMillivolts(Value),
316+
}
317+
318+
#[derive(Debug)]
319+
pub struct TelemetryItem(pub Option<Unit>);
320+
321+
impl From<ctl_oc_telemetry_item_t> for TelemetryItem {
322+
fn from(item: ctl_oc_telemetry_item_t) -> Self {
323+
TelemetryItem(if item.bSupported {
324+
let value = match item.type_ {
325+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_INT8 => {
326+
Value::I8(unsafe { item.value.data8 })
327+
}
328+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_UINT8 => {
329+
Value::U8(unsafe { item.value.datau8 })
330+
}
331+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_INT16 => {
332+
Value::I16(unsafe { item.value.data16 })
333+
}
334+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_UINT16 => {
335+
Value::U16(unsafe { item.value.datau16 })
336+
}
337+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_INT32 => {
338+
Value::I32(unsafe { item.value.data32 })
339+
}
340+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_UINT32 => {
341+
Value::U32(unsafe { item.value.datau32 })
342+
}
343+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_INT64 => {
344+
Value::I64(unsafe { item.value.data64 })
345+
}
346+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_UINT64 => {
347+
Value::U64(unsafe { item.value.datau64 })
348+
}
349+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_FLOAT => {
350+
Value::F32(unsafe { item.value.datafloat })
351+
}
352+
crate::ffi::ctl_data_type_t::CTL_DATA_TYPE_DOUBLE => {
353+
Value::F64(unsafe { item.value.datadouble })
354+
}
355+
_ => return TelemetryItem(None),
356+
};
357+
358+
Some(match item.units {
359+
crate::ffi::_ctl_units_t::CTL_UNITS_FREQUENCY_MHZ => Unit::FrequencyMhz(value),
360+
crate::ffi::_ctl_units_t::CTL_UNITS_OPERATIONS_GTS => Unit::OperationsGts(value),
361+
crate::ffi::_ctl_units_t::CTL_UNITS_OPERATIONS_MTS => Unit::OperationsMts(value),
362+
crate::ffi::_ctl_units_t::CTL_UNITS_VOLTAGE_VOLTS => Unit::VoltageVolts(value),
363+
crate::ffi::_ctl_units_t::CTL_UNITS_POWER_WATTS => Unit::PowerWatts(value),
364+
crate::ffi::_ctl_units_t::CTL_UNITS_TEMPERATURE_CELSIUS => {
365+
Unit::TemperatureCelsius(value)
366+
}
367+
crate::ffi::_ctl_units_t::CTL_UNITS_ENERGY_JOULES => Unit::EnergyJoules(value),
368+
crate::ffi::_ctl_units_t::CTL_UNITS_TIME_SECONDS => Unit::TimeSeconds(value),
369+
crate::ffi::_ctl_units_t::CTL_UNITS_MEMORY_BYTES => Unit::MemoryBytes(value),
370+
crate::ffi::_ctl_units_t::CTL_UNITS_ANGULAR_SPEED_RPM => {
371+
Unit::AngularSpeedRpm(value)
372+
}
373+
crate::ffi::_ctl_units_t::CTL_UNITS_POWER_MILLIWATTS => {
374+
Unit::PowerMilliwatts(value)
375+
}
376+
crate::ffi::_ctl_units_t::CTL_UNITS_PERCENT => Unit::Percent(value),
377+
crate::ffi::_ctl_units_t::CTL_UNITS_MEM_SPEED_GBPS => Unit::MemSpeedGbps(value),
378+
crate::ffi::_ctl_units_t::CTL_UNITS_VOLTAGE_MILLIVOLTS => {
379+
Unit::VoltageMillivolts(value)
380+
}
381+
_ => return TelemetryItem(None),
382+
})
383+
} else {
384+
None
385+
})
386+
}
387+
}
388+
389+
#[derive(Debug)]
390+
pub struct Telemetry {
391+
pub time_stamp: TelemetryItem,
392+
pub gpu_energy_counter: TelemetryItem,
393+
pub gpu_voltage: TelemetryItem,
394+
pub gpu_current_clock_frequency: TelemetryItem,
395+
pub gpu_current_temperature: TelemetryItem,
396+
pub global_activity_counter: TelemetryItem,
397+
pub render_compute_activity_counter: TelemetryItem,
398+
pub media_activity_counter: TelemetryItem,
399+
pub vram_energy_counter: TelemetryItem,
400+
pub vram_voltage: TelemetryItem,
401+
pub vram_current_clock_frequency: TelemetryItem,
402+
pub vram_current_effective_frequency: TelemetryItem,
403+
pub vram_read_bandwidth_counter: TelemetryItem,
404+
pub vram_write_bandwidth_counter: TelemetryItem,
405+
pub vram_current_temperature: TelemetryItem,
406+
pub total_card_energy_counter: TelemetryItem,
407+
pub fan_speed: [TelemetryItem; 5],
408+
// pub gpuPowerLimited: bool,
409+
// pub gpuTemperatureLimited: bool,
410+
// pub gpuCurrentLimited: bool,
411+
// pub gpuVoltageLimited: bool,
412+
// pub gpuUtilizationLimited: bool,
413+
// pub vramPowerLimited: bool,
414+
// pub vramTemperatureLimited: bool,
415+
// pub vramCurrentLimited: bool,
416+
// pub vramVoltageLimited: bool,
417+
// pub vramUtilizationLimited: bool,
418+
// pub psu: [ctl_psu_info_t; 5usize],
419+
// pub fanSpeed: [ctl_oc_telemetry_item_t; 5usize],
243420
}

0 commit comments

Comments
 (0)