1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::time::Duration;
pub use libdrm_amdgpu_sys::*;
use libdrm_amdgpu_sys::AMDGPU::{
    DeviceHandle,
    drm_amdgpu_memory_info,
    HW_IP::{HW_IP_TYPE, HwIpInfo},
};

mod app_device_info;
pub use app_device_info::*;

pub mod stat;

mod device_path;
pub use device_path::DevicePath;

pub struct Sampling {
    pub count: usize,
    pub delay: Duration,
}

impl Default for Sampling {
    fn default() -> Self {
        Self::low()
    }
}

impl Sampling {
    pub const fn low() -> Self {
        Self {
            count: 100,
            delay: Duration::from_millis(10),
        }
    }

    pub const fn high() -> Self {
        Self {
            count: 100,
            delay: Duration::from_millis(1),
        }
    }

    pub fn to_duration(&self) -> Duration {
        self.delay * self.count as u32
    }
}

#[derive(Debug, Clone)]
pub struct VramUsage(pub drm_amdgpu_memory_info);

impl VramUsage {
    pub fn new(memory_info: &drm_amdgpu_memory_info) -> Self {
        Self(*memory_info)
    }

    pub fn update_usage(&mut self, amdgpu_dev: &DeviceHandle) {
        if let [Ok(vram), Ok(vis_vram), Ok(gtt)] = [
            amdgpu_dev.vram_usage_info(),
            amdgpu_dev.vis_vram_usage_info(),
            amdgpu_dev.gtt_usage_info(),
        ] {
            self.0.vram.heap_usage = vram;
            self.0.cpu_accessible_vram.heap_usage = vis_vram;
            self.0.gtt.heap_usage = gtt;
        }
    }
}

pub fn has_vcn(amdgpu_dev: &DeviceHandle) -> bool {
    amdgpu_dev.get_hw_ip_info(HW_IP_TYPE::VCN_DEC).is_ok()
}

pub fn has_vcn_unified(amdgpu_dev: &DeviceHandle) -> bool {
    let Ok(ip) = amdgpu_dev.get_hw_ip_info(HW_IP_TYPE::VCN_ENC) else { return false };

    4 <= ip.info.hw_ip_version_major
}

pub fn get_hw_ip_info_list(amdgpu_dev: &DeviceHandle) -> Vec<HwIpInfo> {
    const HW_IP_LIST: &[HW_IP_TYPE] = &[
        HW_IP_TYPE::GFX,
        HW_IP_TYPE::COMPUTE,
        HW_IP_TYPE::DMA,
        HW_IP_TYPE::UVD,
        HW_IP_TYPE::VCE,
        HW_IP_TYPE::UVD_ENC,
        HW_IP_TYPE::VCN_DEC,
        HW_IP_TYPE::VCN_ENC,
        HW_IP_TYPE::VCN_JPEG,
    ];

    HW_IP_LIST.iter()
        .filter_map(|ip_type| amdgpu_dev.get_hw_ip_info(*ip_type).ok())
        .filter(|hw_ip_info| hw_ip_info.count != 0).collect()
}