libamdgpu_top/stat/
gfxoff_state.rsuse std::io::{self, Read};
use std::path::PathBuf;
use std::fs;
use crate::PCI;
const BASE: &str = "/sys/kernel/debug/dri";
#[derive(Debug, Clone)]
pub struct GfxoffMonitor {
debug_dri_path: PathBuf,
pub mode: GfxoffMode,
pub status: GfxoffStatus,
}
impl GfxoffMonitor {
pub fn new(pci_bus: PCI::BUS_INFO) -> io::Result<Self> {
let debug_dri_path = pci_bus.get_debug_dri_path()?;
let mode = GfxoffMode::get_with_debug_dri_path(&debug_dri_path)?;
let status = GfxoffStatus::get_with_debug_dri_path(&debug_dri_path)?;
Ok(Self { debug_dri_path, mode, status })
}
pub fn update(&mut self) -> io::Result<()> {
self.mode = GfxoffMode::get_with_debug_dri_path(&self.debug_dri_path)?;
self.status = if self.mode.is_disabled() {
GfxoffStatus::NotInGFXOFF
} else {
GfxoffStatus::get_with_debug_dri_path(&self.debug_dri_path)?
};
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum GfxoffMode {
Disable,
Enable,
Unknown(u32),
}
impl GfxoffMode {
pub fn get(instance: u32) -> io::Result<Self> {
Self::get_with_debug_dri_path(format!("{BASE}/{instance}/"))
}
pub fn get_with_debug_dri_path<P: Into<PathBuf>>(path: P) -> io::Result<Self> {
let mode = read_gfxoff(path.into().join("amdgpu_gfxoff"))?;
Ok(Self::from(mode))
}
pub fn is_disabled(&self) -> bool {
*self == Self::Disable
}
pub fn is_enabled(&self) -> bool {
*self == Self::Enable
}
}
impl From<u32> for GfxoffMode {
fn from(val: u32) -> Self {
match val {
0 => Self::Disable,
1 => Self::Enable,
_ => Self::Unknown(val),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum GfxoffStatus {
InGFXOFF = 0, OutGFXOFF = 1, NotInGFXOFF = 2,
IntoGFXOFF = 3, Unknown(u32),
}
impl GfxoffStatus {
pub fn get(instance: u32) -> io::Result<Self> {
Self::get_with_debug_dri_path(format!("{BASE}/{instance}/"))
}
pub fn get_with_debug_dri_path<P: Into<PathBuf>>(path: P) -> io::Result<Self> {
let status= read_gfxoff(path.into().join("amdgpu_gfxoff_status"))?;
Ok(Self::from(status))
}
}
impl From<u32> for GfxoffStatus {
fn from(val: u32) -> Self {
match val {
0 => Self::InGFXOFF,
1 => Self::OutGFXOFF,
2 => Self::NotInGFXOFF,
3 => Self::IntoGFXOFF,
_ => Self::Unknown(val),
}
}
}
fn read_gfxoff<P: Into<PathBuf>>(path: P) -> io::Result<u32> {
let mut buf = [0xFFu8; 4];
let mut f = fs::File::open(path.into())?;
f.read_exact(&mut buf)?;
Ok(u32::from_le_bytes(buf))
}