diff --git a/data/resources/ui/pages/gpu.ui b/data/resources/ui/pages/gpu.ui index 8adb76b..45fa320 100644 --- a/data/resources/ui/pages/gpu.ui +++ b/data/resources/ui/pages/gpu.ui @@ -32,6 +32,9 @@ + + + GPU Frequency diff --git a/src/ui/pages/gpu.rs b/src/ui/pages/gpu.rs index bcf86aa..4dcca12 100644 --- a/src/ui/pages/gpu.rs +++ b/src/ui/pages/gpu.rs @@ -40,6 +40,8 @@ mod imp { #[template_child] pub vram_usage: TemplateChild, #[template_child] + pub gtt_usage: TemplateChild, + #[template_child] pub temperature: TemplateChild, #[template_child] pub power_usage: TemplateChild, @@ -103,6 +105,7 @@ mod imp { encode_decode_usage: Default::default(), encode_decode_combined_usage: Default::default(), vram_usage: Default::default(), + gtt_usage: Default::default(), temperature: Default::default(), power_usage: Default::default(), gpu_clockspeed: Default::default(), @@ -235,6 +238,9 @@ impl ResGPU { imp.vram_usage.set_title_label(&i18n("Video Memory Usage")); imp.vram_usage.graph().set_graph_color(0xc0, 0x1c, 0x28); + + imp.gtt_usage.set_title_label(&i18n("GTT Memory Usage")); + imp.gtt_usage.graph().set_graph_color(0xc0, 0x1c, 0x28); imp.temperature.set_title_label(&i18n("Temperature")); imp.temperature.graph().set_graph_color(0xa5, 0x1d, 0x2d); @@ -244,6 +250,9 @@ impl ResGPU { &gpu.get_vendor() .map_or_else(|_| i18n("N/A"), |vendor| vendor.name().to_string()), ); + + + match gpu.gpu_identifier() { GpuIdentifier::PciSlot(pci_slot) => { @@ -283,6 +292,8 @@ impl ResGPU { decode_fraction, total_vram, used_vram, + used_gtt_mem, + total_gtt_mem, clock_speed, vram_speed, temperature, @@ -380,6 +391,45 @@ impl ResGPU { None }; + + + let gtt_usage_string = if let (Some(total_gtt_mem), Some(used_gtt_mem)) = (total_gtt_mem, used_gtt_mem) + { + let used_gtt_fraction = (*used_gtt_mem as f64 / *total_gtt_mem as f64).finite_or_default(); + + let gtt_percentage_string = format!("{} %", (used_gtt_fraction * 100.0).round()); + + let gtt_subtitle = format!( + "{} / {} · {}", + convert_storage(*used_gtt_mem as f64, false), + convert_storage(*total_gtt_mem as f64, false), + gtt_percentage_string + ); + + imp.gtt_usage.set_subtitle(>t_subtitle); + imp.gtt_usage.graph().push_data_point(used_gtt_fraction); + imp.gtt_usage.graph().set_visible(true); + imp.gtt_usage.graph().set_locked_max_y(Some(1.0)); + + Some(gtt_percentage_string) + } else if let Some(used_gtt_mem) = used_gtt_mem { + let gtt_subtitle = convert_storage(*used_gtt_mem as f64, false); + + imp.gtt_usage.set_subtitle(>t_subtitle); + imp.gtt_usage.graph().push_data_point(*used_gtt_mem as f64); + imp.gtt_usage.graph().set_visible(true); + imp.gtt_usage.graph().set_locked_max_y(None); + + Some(gtt_subtitle) + } else { + imp.gtt_usage.set_subtitle(&i18n("N/A")); + + imp.gtt_usage.graph().set_visible(false); + + None + }; + + let mut power_string = power_usage.map_or_else(|| i18n("N/A"), convert_power); @@ -414,6 +464,11 @@ impl ResGPU { // shorter than) 'Memory' usage_percentage_string.push_str(&i18n_f("Memory: {}", &[&vram_usage_string])); } + + if let Some(gtt_usage_string) = gtt_usage_string { + usage_percentage_string.push_str(" · "); + usage_percentage_string.push_str(&i18n_f("Memory: {}", &[>t_usage_string])); + } imp.temperature.graph().set_visible(temperature.is_some()); diff --git a/src/utils/gpu/amd.rs b/src/utils/gpu/amd.rs index acaa835..540693d 100644 --- a/src/utils/gpu/amd.rs +++ b/src/utils/gpu/amd.rs @@ -164,10 +164,18 @@ impl GpuImpl for AmdGpu { fn used_vram(&self) -> Result { self.drm_used_vram().map(|usage| usage as u64) } - + fn total_vram(&self) -> Result { self.drm_total_vram().map(|usage| usage as u64) } + + fn used_gtt_mem(&self)-> Result { + self.drm_gtt_used_mem().map(|usage| usage as u64) + } + + fn total_gtt_mem(&self)-> Result { + self.drm_gtt_total_mem().map(|usage| usage as u64) + } fn temperature(&self) -> Result { self.hwmon_temperature() diff --git a/src/utils/gpu/intel.rs b/src/utils/gpu/intel.rs index 5d4b01f..2f000d4 100644 --- a/src/utils/gpu/intel.rs +++ b/src/utils/gpu/intel.rs @@ -114,6 +114,14 @@ impl GpuImpl for IntelGpu { fn total_vram(&self) -> Result { self.drm_total_vram().map(|usage| usage as u64) } + + fn used_gtt_mem(&self)-> Result { + self.drm_gtt_used_mem().map(|usage| usage as u64) + } + + fn total_gtt_mem(&self)-> Result { + self.drm_gtt_total_mem().map(|usage| usage as u64) + } fn temperature(&self) -> Result { match self.driver { diff --git a/src/utils/gpu/mod.rs b/src/utils/gpu/mod.rs index 521fed6..e2f577f 100644 --- a/src/utils/gpu/mod.rs +++ b/src/utils/gpu/mod.rs @@ -48,6 +48,9 @@ pub struct GpuData { pub total_vram: Option, pub used_vram: Option, + + pub used_gtt_mem: Option, + pub total_gtt_mem: Option, pub clock_speed: Option, pub vram_speed: Option, @@ -77,7 +80,9 @@ impl GpuData { let total_vram = gpu.total_vram().ok(); let used_vram = gpu.used_vram().ok(); - + + let used_gtt_mem = gpu.used_gtt_mem().ok(); + let total_gtt_mem = gpu.total_gtt_mem().ok(); let clock_speed = gpu.core_frequency().ok(); let vram_speed = gpu.vram_frequency().ok(); @@ -98,6 +103,8 @@ impl GpuData { decode_fraction, total_vram, used_vram, + used_gtt_mem, + total_gtt_mem, clock_speed, vram_speed, temperature, @@ -143,6 +150,8 @@ pub trait GpuImpl { fn combined_media_engine(&self) -> Result; fn used_vram(&self) -> Result; fn total_vram(&self) -> Result; + fn used_gtt_mem(&self) -> Result; + fn total_gtt_mem(&self) -> Result; fn temperature(&self) -> Result; fn power_usage(&self) -> Result; fn core_frequency(&self) -> Result; @@ -168,6 +177,14 @@ pub trait GpuImpl { fn drm_total_vram(&self) -> Result { read_parsed(self.sysfs_path().join("device/mem_info_vram_total")) } + + fn drm_gtt_used_mem(&self) -> Result { + read_parsed(self.sysfs_path().join("device/mem_info_gtt_used")) + } + + fn drm_gtt_total_mem(&self) -> Result { + read_parsed(self.sysfs_path().join("device/mem_info_gtt_total")) + } fn hwmon_path(&self) -> Result<&Path> { self.first_hwmon().context("no hwmon found") diff --git a/src/utils/gpu/nvidia.rs b/src/utils/gpu/nvidia.rs index 38f3f42..5bf8558 100644 --- a/src/utils/gpu/nvidia.rs +++ b/src/utils/gpu/nvidia.rs @@ -154,6 +154,14 @@ impl GpuImpl for NvidiaGpu { .map(|memory_info| memory_info.total) .or_else(|_| self.drm_total_vram().map(|usage| usage as u64)) } + + fn used_gtt_mem(&self)-> Result { + self.drm_gtt_used_mem().map(|usage| usage as u64) + } + + fn total_gtt_mem(&self)-> Result { + self.drm_gtt_total_mem().map(|usage| usage as u64) + } fn temperature(&self) -> Result { Self::nvml_device(&self.pci_slot_string) diff --git a/src/utils/gpu/other.rs b/src/utils/gpu/other.rs index 8a80da9..45af230 100644 --- a/src/utils/gpu/other.rs +++ b/src/utils/gpu/other.rs @@ -83,6 +83,14 @@ impl GpuImpl for OtherGpu { fn total_vram(&self) -> Result { self.drm_total_vram().map(|usage| usage as u64) } + + fn used_gtt_mem(&self)-> Result { + self.drm_gtt_used_mem().map(|usage| usage as u64) + } + + fn total_gtt_mem(&self)-> Result { + self.drm_gtt_total_mem().map(|usage| usage as u64) + } fn temperature(&self) -> Result { self.hwmon_temperature() diff --git a/src/utils/gpu/v3d.rs b/src/utils/gpu/v3d.rs index f4411cd..4b38a6b 100644 --- a/src/utils/gpu/v3d.rs +++ b/src/utils/gpu/v3d.rs @@ -83,6 +83,14 @@ impl GpuImpl for V3dGpu { fn total_vram(&self) -> Result { self.drm_total_vram().map(|usage| usage as u64) } + + fn used_gtt_mem(&self)-> Result { + self.drm_gtt_used_mem().map(|usage| usage as u64) + } + + fn total_gtt_mem(&self)-> Result { + self.drm_gtt_total_mem().map(|usage| usage as u64) + } fn temperature(&self) -> Result { self.hwmon_temperature()