mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
Reworked the pci.ids parser
This commit is contained in:
parent
2449cc9ee3
commit
b7da2cbad5
@ -67,8 +67,8 @@ fn main() {
|
|||||||
|
|
||||||
fn print_info(d: &DaemonConnection, gpu_id: u32) {
|
fn print_info(d: &DaemonConnection, gpu_id: u32) {
|
||||||
let gpu_info = d.get_gpu_info(gpu_id).unwrap();
|
let gpu_info = d.get_gpu_info(gpu_id).unwrap();
|
||||||
println!("{} {}", "GPU Model:".blue(), gpu_info.card_model.bold());
|
println!("{} {}", "GPU Model:".blue(), gpu_info.vendor_data.card_model.unwrap_or_default().bold());
|
||||||
println!("{} {}", "GPU Vendor:".blue(), gpu_info.gpu_vendor.bold());
|
println!("{} {}", "GPU Vendor:".blue(), gpu_info.vendor_data.gpu_vendor.unwrap_or_default().bold());
|
||||||
println!("{} {}", "Driver in use:".blue(), gpu_info.driver.bold());
|
println!("{} {}", "Driver in use:".blue(), gpu_info.driver.bold());
|
||||||
println!("{} {}", "VBIOS Version:".blue(), gpu_info.vbios_version.bold());
|
println!("{} {}", "VBIOS Version:".blue(), gpu_info.vbios_version.bold());
|
||||||
println!("{} {}", "VRAM Size:".blue(), gpu_info.vram_size.to_string().bold());
|
println!("{} {}", "VRAM Size:".blue(), gpu_info.vram_size.to_string().bold());
|
||||||
|
@ -24,8 +24,8 @@ impl From<serde_json::Error> for ConfigError {
|
|||||||
#[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq)]
|
#[derive(Deserialize, Serialize, Debug, Clone, Hash, Eq)]
|
||||||
pub struct GpuIdentifier {
|
pub struct GpuIdentifier {
|
||||||
pub pci_id: String,
|
pub pci_id: String,
|
||||||
pub card_model: String,
|
pub card_model: Option<String>,
|
||||||
pub gpu_model: String,
|
pub gpu_model: Option<String>,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ impl DaemonConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_gpus(&self) -> Result<HashMap<u32, String>, DaemonError> {
|
pub fn get_gpus(&self) -> Result<HashMap<u32, Option<String>>, DaemonError> {
|
||||||
log::trace!("sending request");
|
log::trace!("sending request");
|
||||||
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
|
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
|
||||||
s.write_all(&bincode::serialize(&Action::GetGpus).unwrap())
|
s.write_all(&bincode::serialize(&Action::GetGpus).unwrap())
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::config::{GpuConfig, GpuIdentifier};
|
use crate::config::{GpuConfig, GpuIdentifier};
|
||||||
use crate::hw_mon::{HWMon, HWMonError};
|
use crate::hw_mon::{HWMon, HWMonError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use vendor_data::VendorData;
|
||||||
use std::{collections::BTreeMap, fs};
|
use std::{collections::BTreeMap, fs};
|
||||||
use std::{
|
use std::{
|
||||||
num::ParseIntError,
|
num::ParseIntError,
|
||||||
@ -8,6 +9,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||||
|
|
||||||
|
pub mod vendor_data;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum GpuControllerError {
|
pub enum GpuControllerError {
|
||||||
NotSupported,
|
NotSupported,
|
||||||
@ -123,10 +126,7 @@ pub struct VulkanInfo {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
pub struct GpuInfo {
|
pub struct GpuInfo {
|
||||||
pub gpu_vendor: String,
|
pub vendor_data: VendorData,
|
||||||
pub gpu_model: String,
|
|
||||||
pub card_model: String,
|
|
||||||
pub card_vendor: String,
|
|
||||||
pub model_id: String,
|
pub model_id: String,
|
||||||
pub vendor_id: String,
|
pub vendor_id: String,
|
||||||
pub driver: String,
|
pub driver: String,
|
||||||
@ -190,8 +190,8 @@ impl GpuController {
|
|||||||
let gpu_info = self.get_info();
|
let gpu_info = self.get_info();
|
||||||
GpuIdentifier {
|
GpuIdentifier {
|
||||||
pci_id: gpu_info.pci_slot.clone(),
|
pci_id: gpu_info.pci_slot.clone(),
|
||||||
card_model: gpu_info.card_model.clone(),
|
card_model: gpu_info.vendor_data.card_model.clone(),
|
||||||
gpu_model: gpu_info.gpu_model.clone(),
|
gpu_model: gpu_info.vendor_data.gpu_model.clone(),
|
||||||
path: self.hw_path.clone(),
|
path: self.hw_path.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,54 +234,6 @@ impl GpuController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vendor = "AMD".to_string();
|
|
||||||
let mut model = String::new();
|
|
||||||
let mut card_vendor = String::new();
|
|
||||||
let mut card_model = String::new();
|
|
||||||
|
|
||||||
let mut full_hwid_list = String::new();
|
|
||||||
if Path::exists(&PathBuf::from("/usr/share/hwdata/pci.ids")) {
|
|
||||||
full_hwid_list = fs::read_to_string("/usr/share/hwdata/pci.ids").unwrap();
|
|
||||||
} else if Path::exists(&PathBuf::from("/usr/share/misc/pci.ids")) {
|
|
||||||
full_hwid_list = fs::read_to_string("/usr/share/misc/pci.ids").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !full_hwid_list.is_empty() {
|
|
||||||
//some weird space character, don't touch
|
|
||||||
let pci_id_line = format!(" {}", model_id.to_lowercase());
|
|
||||||
let card_ids_line = format!(
|
|
||||||
" {} {}",
|
|
||||||
card_vendor_id.to_lowercase(),
|
|
||||||
card_model_id.to_lowercase()
|
|
||||||
);
|
|
||||||
log::trace!("identifying {} \n {}", pci_id_line, card_ids_line);
|
|
||||||
|
|
||||||
let lines: Vec<&str> = full_hwid_list.split('\n').collect();
|
|
||||||
|
|
||||||
//for line in full_hwid_list.split('\n') {
|
|
||||||
for i in 0..lines.len() {
|
|
||||||
let line = lines[i];
|
|
||||||
|
|
||||||
if line.len() > card_vendor_id.len() {
|
|
||||||
if line[0..card_vendor_id.len()] == card_vendor_id.to_lowercase() {
|
|
||||||
card_vendor = line
|
|
||||||
.splitn(2, ' ')
|
|
||||||
.collect::<Vec<&str>>()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.trim_start()
|
|
||||||
.to_string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if line.contains(&pci_id_line) {
|
|
||||||
model = line[pci_id_line.len()..].trim_start().to_string();
|
|
||||||
}
|
|
||||||
if line.contains(&card_ids_line) {
|
|
||||||
card_model = line[card_ids_line.len()..].trim_start().to_string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let vbios_version = match fs::read_to_string(self.hw_path.join("vbios_version")) {
|
let vbios_version = match fs::read_to_string(self.hw_path.join("vbios_version")) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => "".to_string(),
|
Err(_) => "".to_string(),
|
||||||
@ -316,11 +268,15 @@ impl GpuController {
|
|||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let vendor_data = match VendorData::from_ids(&vendor_id, &model_id, &card_vendor_id, &card_model_id) {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(e) => VendorData::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info!("Vendor data: {:?}", vendor_data);
|
||||||
|
|
||||||
GpuInfo {
|
GpuInfo {
|
||||||
gpu_vendor: vendor,
|
vendor_data,
|
||||||
gpu_model: model,
|
|
||||||
card_vendor,
|
|
||||||
card_model,
|
|
||||||
model_id,
|
model_id,
|
||||||
vendor_id,
|
vendor_id,
|
||||||
driver,
|
driver,
|
||||||
|
221
daemon/src/gpu_controller/vendor_data.rs
Normal file
221
daemon/src/gpu_controller/vendor_data.rs
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum VendorDataError {
|
||||||
|
MissingIdsFile,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct VendorData {
|
||||||
|
pub gpu_vendor: Option<String>,
|
||||||
|
pub gpu_model: Option<String>,
|
||||||
|
pub card_vendor: Option<String>,
|
||||||
|
pub card_model: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VendorData {
|
||||||
|
pub fn from_ids(
|
||||||
|
vendor_id: &str,
|
||||||
|
model_id: &str,
|
||||||
|
subsys_vendor_id: &str,
|
||||||
|
subsys_model_id: &str,
|
||||||
|
) -> Result<VendorData, VendorDataError> {
|
||||||
|
let vendor_id = vendor_id.to_lowercase();
|
||||||
|
let model_id = model_id.to_lowercase();
|
||||||
|
let subsys_vendor_id = subsys_vendor_id.to_lowercase();
|
||||||
|
let subsys_model_id = subsys_model_id.to_lowercase();
|
||||||
|
|
||||||
|
match PciDatabase::read() {
|
||||||
|
Ok(db) => {
|
||||||
|
let mut gpu_vendor = None;
|
||||||
|
let mut gpu_model = None;
|
||||||
|
let mut card_vendor = None;
|
||||||
|
let mut card_model = None;
|
||||||
|
|
||||||
|
log::trace!("Seacrhing vendor {}", vendor_id);
|
||||||
|
if let Some(vendor) = db.vendors.get(&vendor_id) {
|
||||||
|
log::trace!("Found vendor {}", vendor.name);
|
||||||
|
gpu_vendor = Some(vendor.name.clone());
|
||||||
|
|
||||||
|
log::trace!("Searching device {}", model_id);
|
||||||
|
if let Some(model) = vendor.devices.get(&model_id) {
|
||||||
|
log::trace!("Found device {}", model.name);
|
||||||
|
gpu_model = Some(model.name.clone());
|
||||||
|
|
||||||
|
log::trace!("Searching subdevice {} {}", subsys_vendor_id, subsys_model_id);
|
||||||
|
if let Some(subvendor) = db.vendors.get(&subsys_vendor_id) {
|
||||||
|
log::trace!("Found subvendor {}", subvendor.name);
|
||||||
|
card_vendor = Some(subvendor.name.clone());
|
||||||
|
}
|
||||||
|
if let Some(subdevice) = model.subdevices.get(&(subsys_vendor_id, subsys_model_id)) {
|
||||||
|
log::trace!("Found subdevice {}", subdevice);
|
||||||
|
card_model = Some(subdevice.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(VendorData { gpu_vendor, gpu_model, card_vendor, card_model })
|
||||||
|
},
|
||||||
|
Err(_) => Err(VendorDataError::MissingIdsFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum PciDatabaseError {
|
||||||
|
FileNotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PciDatabase {
|
||||||
|
pub vendors: HashMap<String, PciVendor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PciDatabase {
|
||||||
|
pub fn read<'a>() -> Result<Self, PciDatabaseError> {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
|
match Self::read_pci_db() {
|
||||||
|
Some(pci_ids) => {
|
||||||
|
log::trace!("Parsing pci.ids");
|
||||||
|
|
||||||
|
let mut vendors: HashMap<String, PciVendor> = HashMap::new();
|
||||||
|
|
||||||
|
let mut lines = pci_ids.split("\n").into_iter();
|
||||||
|
|
||||||
|
let mut current_vendor_id: Option<String> = None;
|
||||||
|
let mut current_device_id: Option<String> = None;
|
||||||
|
|
||||||
|
while let Some(line) = lines.next() {
|
||||||
|
if line.starts_with("#") | line.is_empty() {
|
||||||
|
continue;
|
||||||
|
} else if line.starts_with("\t\t") {
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
|
||||||
|
let vendor_id = split.next().unwrap().to_owned();
|
||||||
|
let device_id = split.next().unwrap().to_owned();
|
||||||
|
let name = split.collect::<Vec<&str>>().join(" ");
|
||||||
|
|
||||||
|
if let Some(current_vendor_id) = ¤t_vendor_id {
|
||||||
|
if let Some(current_device_id) = ¤t_device_id {
|
||||||
|
vendors
|
||||||
|
.get_mut(current_vendor_id)
|
||||||
|
.unwrap()
|
||||||
|
.devices
|
||||||
|
.get_mut(current_device_id)
|
||||||
|
.unwrap()
|
||||||
|
.subdevices
|
||||||
|
.insert((vendor_id, device_id), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if line.starts_with("\t") {
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
|
||||||
|
let id = split.next().unwrap().to_owned();
|
||||||
|
let name = split.collect::<Vec<&str>>().join(" ");
|
||||||
|
|
||||||
|
let device = PciDevice::new(name);
|
||||||
|
|
||||||
|
current_device_id = Some(id.clone());
|
||||||
|
|
||||||
|
if let Some(current_vendor_id) = ¤t_vendor_id {
|
||||||
|
vendors
|
||||||
|
.get_mut(current_vendor_id)
|
||||||
|
.unwrap()
|
||||||
|
.devices
|
||||||
|
.insert(id, device);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut split = line.split_whitespace();
|
||||||
|
|
||||||
|
let id = split.next().unwrap().to_owned();
|
||||||
|
let name = split.collect::<Vec<&str>>().join(" ");
|
||||||
|
|
||||||
|
current_vendor_id = Some(id.clone());
|
||||||
|
|
||||||
|
let vendor = PciVendor::new(name);
|
||||||
|
vendors.insert(id, vendor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(PciDatabase { vendors })
|
||||||
|
}
|
||||||
|
None => Err(PciDatabaseError::FileNotFound),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_pci_db() -> Option<String> {
|
||||||
|
let paths = ["/usr/share/hwdata/pci.ids", "/usr/share/misc/pci.ids"];
|
||||||
|
|
||||||
|
if let Some(path) = paths.iter().find(|path| Path::exists(&PathBuf::from(path))) {
|
||||||
|
let all_ids = fs::read_to_string(path).unwrap();
|
||||||
|
|
||||||
|
Some(all_ids)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PciVendor {
|
||||||
|
pub name: String,
|
||||||
|
pub devices: HashMap<String, PciDevice>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PciVendor {
|
||||||
|
pub fn new(name: String) -> Self {
|
||||||
|
PciVendor {
|
||||||
|
name,
|
||||||
|
devices: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct PciDevice {
|
||||||
|
pub name: String,
|
||||||
|
pub subdevices: HashMap<(String, String), String>, // <(vendor_id, device_id), name>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PciDevice {
|
||||||
|
pub fn new(name: String) -> Self {
|
||||||
|
PciDevice {
|
||||||
|
name,
|
||||||
|
subdevices: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn init() {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_polaris() {
|
||||||
|
init();
|
||||||
|
let data = VendorData::from_ids("1002", "67DF", "1DA2", "E387").unwrap();
|
||||||
|
|
||||||
|
assert_eq!(data.gpu_vendor, Some("Advanced Micro Devices, Inc. [AMD/ATI]".to_string()));
|
||||||
|
assert_eq!(data.gpu_model, Some("Ellesmere [Radeon RX 470/480/570/570X/580/580X/590]".to_string()));
|
||||||
|
assert_eq!(data.card_vendor, Some("Sapphire Technology Limited".to_string()));
|
||||||
|
assert_eq!(data.card_model, Some("Radeon RX 570 Pulse 4GB".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_vega() {
|
||||||
|
let data = VendorData::from_ids("1002", "687F", "1043", "0555").unwrap();
|
||||||
|
|
||||||
|
assert_eq!(data.gpu_vendor, Some("Advanced Micro Devices, Inc. [AMD/ATI]".to_string()));
|
||||||
|
assert_eq!(data.gpu_model, Some("Vega 10 XL/XT [Radeon RX Vega 56/64]".to_string()));
|
||||||
|
assert_eq!(data.card_vendor, Some("ASUSTeK Computer Inc.".to_string()));
|
||||||
|
assert_eq!(data.card_model, None);
|
||||||
|
}
|
||||||
|
}
|
@ -95,7 +95,7 @@ impl Daemon {
|
|||||||
let gpu_info = controller.get_info();
|
let gpu_info = controller.get_info();
|
||||||
|
|
||||||
for (id, (gpu_identifier, gpu_config)) in &config.gpu_configs {
|
for (id, (gpu_identifier, gpu_config)) in &config.gpu_configs {
|
||||||
if gpu_info.pci_slot == gpu_identifier.pci_id && gpu_info.card_model == gpu_identifier.card_model && gpu_info.gpu_model == gpu_identifier.gpu_model {
|
if gpu_info.pci_slot == gpu_identifier.pci_id && gpu_info.vendor_data.card_model == gpu_identifier.card_model && gpu_info.vendor_data.gpu_model == gpu_identifier.gpu_model {
|
||||||
controller.load_config(gpu_config.clone());
|
controller.load_config(gpu_config.clone());
|
||||||
gpu_controllers.insert(id.clone(), controller);
|
gpu_controllers.insert(id.clone(), controller);
|
||||||
log::info!("already known");
|
log::info!("already known");
|
||||||
@ -155,9 +155,9 @@ impl Daemon {
|
|||||||
let response: Result<DaemonResponse, DaemonError> = match action {
|
let response: Result<DaemonResponse, DaemonError> = match action {
|
||||||
Action::CheckAlive => Ok(DaemonResponse::OK),
|
Action::CheckAlive => Ok(DaemonResponse::OK),
|
||||||
Action::GetGpus => {
|
Action::GetGpus => {
|
||||||
let mut gpus: HashMap<u32, String> = HashMap::new();
|
let mut gpus: HashMap<u32, Option<String>> = HashMap::new();
|
||||||
for (id, controller) in &self.gpu_controllers {
|
for (id, controller) in &self.gpu_controllers {
|
||||||
gpus.insert(*id, controller.get_info().gpu_model.clone());
|
gpus.insert(*id, controller.get_info().vendor_data.gpu_model.clone());
|
||||||
}
|
}
|
||||||
Ok(DaemonResponse::Gpus(gpus))
|
Ok(DaemonResponse::Gpus(gpus))
|
||||||
},
|
},
|
||||||
@ -336,7 +336,7 @@ pub enum DaemonResponse {
|
|||||||
OK,
|
OK,
|
||||||
GpuInfo(gpu_controller::GpuInfo),
|
GpuInfo(gpu_controller::GpuInfo),
|
||||||
GpuStats(gpu_controller::GpuStats),
|
GpuStats(gpu_controller::GpuStats),
|
||||||
Gpus(HashMap<u32, String>),
|
Gpus(HashMap<u32, Option<String>>),
|
||||||
PowerCap((i64, i64)),
|
PowerCap((i64, i64)),
|
||||||
FanControlInfo(gpu_controller::FanControlInfo),
|
FanControlInfo(gpu_controller::FanControlInfo),
|
||||||
}
|
}
|
||||||
|
@ -105,8 +105,8 @@ fn build_ui(application: >k::Application) {
|
|||||||
|
|
||||||
let gpus = d.get_gpus().unwrap();
|
let gpus = d.get_gpus().unwrap();
|
||||||
|
|
||||||
for gpu in &gpus {
|
for (id, gpu) in &gpus {
|
||||||
gpu_select_comboboxtext.append(Some(&gpu.0.to_string()), &gpu.1);
|
gpu_select_comboboxtext.append(Some(&id.to_string()), &gpu.clone().unwrap_or_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
//limits the length of gpu names in combobox
|
//limits the length of gpu names in combobox
|
||||||
@ -408,8 +408,8 @@ fn set_info(builder: &Builder, d: DaemonConnection, gpu_id: u32, gpu_power_level
|
|||||||
|
|
||||||
let gpu_info = d.get_gpu_info(gpu_id).unwrap();
|
let gpu_info = d.get_gpu_info(gpu_id).unwrap();
|
||||||
|
|
||||||
gpu_model_text_buffer.set_text(&gpu_info.card_model);
|
gpu_model_text_buffer.set_text(&gpu_info.vendor_data.card_model.unwrap_or_default());
|
||||||
manufacturer_text_buffer.set_text(&gpu_info.card_vendor);
|
manufacturer_text_buffer.set_text(&gpu_info.vendor_data.card_vendor.unwrap_or_default());
|
||||||
vbios_version_text_buffer.set_text(&gpu_info.vbios_version);
|
vbios_version_text_buffer.set_text(&gpu_info.vbios_version);
|
||||||
driver_text_buffer.set_text(&gpu_info.driver);
|
driver_text_buffer.set_text(&gpu_info.driver);
|
||||||
vram_size_text_buffer.set_text(&format!("{} MiB", &gpu_info.vram_size));
|
vram_size_text_buffer.set_text(&format!("{} MiB", &gpu_info.vram_size));
|
||||||
|
Loading…
Reference in New Issue
Block a user