1use std::time::Duration;
2use std::path::PathBuf;
3
4use num_enum::{IntoPrimitive, TryFromPrimitive};
5
6pub use libdrm_amdgpu_sys::*;
7use libdrm_amdgpu_sys::AMDGPU::{
8 CHIP_CLASS,
9 DeviceHandle,
10 drm_amdgpu_memory_info,
11 HW_IP::{HW_IP_TYPE, HwIpInfo},
12};
13
14mod app_device_info;
15pub use app_device_info::*;
16
17pub mod stat;
18pub mod app;
19pub mod xdna;
20
21mod device_path;
22pub use device_path::{DeviceType, DevicePath};
23
24mod drm_mode;
25pub use drm_mode::*;
26
27mod ppfeaturemask;
28pub use ppfeaturemask::*;
29
30#[derive(Debug, Copy, Clone, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
31#[repr(u8)]
32pub enum GuiMode {
33 Auto,
34 Single,
35 Tab,
36}
37
38impl GuiMode {
39 pub fn is_tab_mode(&self) -> bool {
40 *self == Self::Tab
41 }
42}
43
44#[derive(Debug, Copy, Clone, Eq, PartialEq)]
45pub enum GuiWgpuBackend {
46 Gl,
47 Vulkan,
48}
49
50#[derive(Debug, Clone)]
51pub struct UiArgs {
52 pub selected_device_path: DevicePath,
53 pub device_path_list: Vec<DevicePath>,
54 pub update_process_index: u64,
55 pub no_pc: bool,
56 pub is_dark_mode: Option<bool>, pub hide_fdinfo: bool, pub gui_wgpu_backend: GuiWgpuBackend, pub gui_mode: GuiMode, }
61
62pub struct Sampling {
63 pub count: usize,
64 pub delay: Duration,
65}
66
67impl Default for Sampling {
68 fn default() -> Self {
69 Self::low()
70 }
71}
72
73impl Sampling {
74 pub const fn low() -> Self {
75 Self {
76 count: 100,
77 delay: Duration::from_millis(10),
78 }
79 }
80
81 pub const fn high() -> Self {
82 Self {
83 count: 100,
84 delay: Duration::from_millis(1),
85 }
86 }
87
88 pub fn to_duration(&self) -> Duration {
89 self.delay * self.count as u32
90 }
91}
92
93#[derive(Debug, Clone)]
94pub struct VramUsage(pub drm_amdgpu_memory_info);
95
96impl VramUsage {
97 pub fn new(memory_info: &drm_amdgpu_memory_info) -> Self {
98 Self(*memory_info)
99 }
100
101 pub fn update_usage(&mut self, amdgpu_dev: &DeviceHandle) {
102 if let [Ok(vram), Ok(vis_vram), Ok(gtt)] = [
103 amdgpu_dev.vram_usage_info(),
104 amdgpu_dev.vis_vram_usage_info(),
105 amdgpu_dev.gtt_usage_info(),
106 ] {
107 self.0.vram.heap_usage = vram;
108 self.0.cpu_accessible_vram.heap_usage = vis_vram;
109 self.0.gtt.heap_usage = gtt;
110 }
111 }
112
113 pub fn update_usable_heap_size(&mut self, amdgpu_dev: &DeviceHandle) {
114 let Ok(info) = amdgpu_dev.vram_gtt_info() else { return };
115
116 self.0.vram.usable_heap_size = info.vram_size;
117 self.0.cpu_accessible_vram.usable_heap_size = info.vram_cpu_accessible_size;
118 self.0.gtt.usable_heap_size = info.gtt_size;
119 }
120}
121
122pub fn get_hw_ip_info_list(
123 amdgpu_dev: &DeviceHandle,
124 chip_class: CHIP_CLASS,
125) -> Vec<HwIpInfo> {
126 const HW_IP_LIST: &[HW_IP_TYPE] = &[
127 HW_IP_TYPE::DMA,
130 HW_IP_TYPE::UVD,
131 HW_IP_TYPE::VCE,
132 HW_IP_TYPE::UVD_ENC,
133 HW_IP_TYPE::VCN_DEC,
134 HW_IP_TYPE::VCN_ENC,
135 HW_IP_TYPE::VCN_JPEG,
136 HW_IP_TYPE::VPE,
137 ];
138
139 let mut hw_ip_list: Vec<HwIpInfo> = Vec::with_capacity(10);
140
141 {
142 for ip_type in [HW_IP_TYPE::GFX, HW_IP_TYPE::COMPUTE] {
143 let Ok(mut ip_info) = amdgpu_dev.get_hw_ip_info(ip_type) else { continue };
144
145 match chip_class {
148 CHIP_CLASS::GFX10 => ip_info.info.hw_ip_version_minor = 1,
149 CHIP_CLASS::GFX10_3 => ip_info.info.hw_ip_version_minor = 3,
150 _ => {},
151 }
152
153 if ip_info.count != 0 {
154 hw_ip_list.push(ip_info);
155 }
156 }
157 }
158
159 for ip_type in HW_IP_LIST {
160 let Ok(ip_info) = amdgpu_dev.get_hw_ip_info(*ip_type) else { continue };
161
162 if ip_info.count != 0 {
163 hw_ip_list.push(ip_info);
164 }
165 }
166
167 hw_ip_list
168}
169
170pub fn get_rocm_version() -> Option<String> {
171 let rocm_path = std::env::var("ROCM_PATH").unwrap_or("/opt/rocm".to_string());
172 let rocm_path = PathBuf::from(rocm_path);
173
174 let s = std::fs::read_to_string(rocm_path.join(".info/version")).ok()?;
175 let s = s.trim_end();
176
177 if let Some((ver, _)) = s.split_once('-') {
178 Some(ver.to_string())
179 } else {
180 Some(s.to_string())
181 }
182}