@@ -9,7 +9,8 @@ use crate::{
9
9
ffi:: {
10
10
ctl_3d_feature_getset_t, ctl_3d_feature_t, ctl_adapter_bdf_t, ctl_device_adapter_handle_t,
11
11
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,
13
14
} ,
14
15
} ;
15
16
@@ -240,4 +241,180 @@ impl DeviceAdapter {
240
241
241
242
Ok ( flip_mode)
242
243
}
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],
243
420
}
0 commit comments