Add vulkan feature list

This commit is contained in:
Ilya Zlobintsev
2021-01-31 11:26:09 +02:00
parent 197c8e8bfa
commit 3b4bbcc4c6
3 changed files with 100 additions and 23 deletions

View File

@@ -1,12 +1,11 @@
use crate::config::{GpuConfig, GpuIdentifier};
use crate::hw_mon::{HWMon, HWMonError};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::fs;
use std::num::ParseIntError;
use std::path::PathBuf;
use vendor_data::VendorData;
use std::{collections::BTreeMap, fs};
use std::{
num::ParseIntError,
path::{Path, PathBuf},
};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
pub mod vendor_data;
@@ -54,7 +53,9 @@ impl PowerProfile {
"auto" | "Automatic" => Ok(PowerProfile::Auto),
"high" | "Highest Clocks" => Ok(PowerProfile::High),
"low" | "Lowest Clocks" => Ok(PowerProfile::Low),
_ => Err(GpuControllerError::ParseError("unrecognized GPU power profile".to_string())),
_ => Err(GpuControllerError::ParseError(
"unrecognized GPU power profile".to_string(),
)),
}
}
@@ -121,7 +122,7 @@ pub struct GpuController {
pub struct VulkanInfo {
pub device_name: String,
pub api_version: String,
pub features: String,
pub features: HashMap<String, bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
@@ -267,11 +268,12 @@ impl GpuController {
Ok(t) => Some(t),
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(),
};
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);
@@ -500,9 +502,19 @@ impl GpuController {
while let Some(line) = lines_iter.next() {
let mut split = line.split_whitespace();
let name = split.next().ok_or_else(|| GpuControllerError::ParseError("failed to get range name".to_string()))?;
let min = split.next().ok_or_else(|| GpuControllerError::ParseError("failed to get range minimal value".to_string()))?;
let max = split.next().ok_or_else(|| GpuControllerError::ParseError("failed to get range maximum value".to_string()))?;
let name = split.next().ok_or_else(|| {
GpuControllerError::ParseError("failed to get range name".to_string())
})?;
let min = split.next().ok_or_else(|| {
GpuControllerError::ParseError(
"failed to get range minimal value".to_string(),
)
})?;
let max = split.next().ok_or_else(|| {
GpuControllerError::ParseError(
"failed to get range maximum value".to_string(),
)
})?;
match name {
"SCLK:" => {
@@ -523,11 +535,19 @@ impl GpuController {
clocks_table.voltage_range = (min_voltage, max_voltage);
}
_ => return Err(GpuControllerError::ParseError("unrecognized voltage range type".to_string())),
_ => {
return Err(GpuControllerError::ParseError(
"unrecognized voltage range type".to_string(),
))
}
}
}
}
_ => return Err(GpuControllerError::ParseError("unrecognized line type".to_string())),
_ => {
return Err(GpuControllerError::ParseError(
"unrecognized line type".to_string(),
))
}
}
}
@@ -598,7 +618,7 @@ impl GpuController {
fn get_vulkan_info(pci_id: &str) -> VulkanInfo {
let mut device_name = String::from("Not supported");
let mut api_version = String::new();
let mut features = String::new();
let mut features = HashMap::new();
match Instance::new(None, &InstanceExtensions::none(), None) {
Ok(instance) => {
@@ -606,7 +626,22 @@ impl GpuController {
if format!("{:x}", physical.pci_device_id()) == pci_id.to_lowercase() {
api_version = physical.api_version().to_string();
device_name = physical.name().to_string();
features = format!("{:?}", physical.supported_features());
let features_string = format!("{:?}", physical.supported_features());
let features_string = features_string
.replace("Features", "")
.replace("{", "")
.replace("}", "");
for feature in features_string.split(',') {
let (name, supported) = feature.split_once(':').unwrap();
let name = name.trim();
let supported: bool = supported.trim().parse().unwrap();
features.insert(name.to_string(), supported);
}
break;
}
}
}
@@ -691,12 +726,12 @@ mod tests {
GpuController::parse_clocks_table(pp_od_clk_voltage).unwrap();
}
// pp_od_clk_voltage taken from a Vega 56
#[test]
fn parse_clocks_table_vega() {
init();
let pp_od_clk_voltage = r#"
OD_SCLK:
0: 852Mhz 800mV

View File

@@ -1,3 +1,5 @@
#![feature(str_split_once)]
pub mod config;
pub mod daemon_connection;
pub mod gpu_controller;

View File

@@ -6,12 +6,13 @@ pub struct VulkanInfoFrame {
pub container: Frame,
device_name_label: Label,
version_label: Label,
features_box: Box,
}
impl VulkanInfoFrame {
pub fn new() -> Self {
let container = Frame::new(None);
container.set_label_widget(Some(&{
let label = Label::new(None);
label.set_markup("<span font_desc='11'><b>Vulkan Information</b></span>");
@@ -64,15 +65,37 @@ impl VulkanInfoFrame {
let version_label = Label::new(None);
version_label.set_halign(Align::Start);
grid.attach(&version_label, 2, 1, 3, 1);
let features_expander = Expander::new(Some("Feature support"));
grid.attach(&features_expander, 0, 2, 5, 1);
let features_scrolled_window = ScrolledWindow::new(NONE_ADJUSTMENT, NONE_ADJUSTMENT);
features_scrolled_window.set_vexpand(true);
let features_box = Box::new(Orientation::Vertical, 5);
features_box.set_halign(Align::Center);
features_scrolled_window.add(&features_box);
features_expander.add(&features_scrolled_window);
container.add(&grid);
Self {
container,
device_name_label,
version_label,
features_box,
}
}
@@ -81,5 +104,22 @@ impl VulkanInfoFrame {
.set_markup(&format!("<b>{}</b>", vulkan_info.device_name));
self.version_label
.set_markup(&format!("<b>{}</b>", vulkan_info.api_version));
for (feature, supported) in vulkan_info.features.iter() {
let vbox = Box::new(Orientation::Horizontal, 5);
let feature_name_label = Label::new(Some(feature));
vbox.pack_start(&feature_name_label, false, false, 0);
let feature_supported_checkbutton = CheckButton::new();
feature_supported_checkbutton.set_sensitive(false);
feature_supported_checkbutton.set_active(*supported);
vbox.pack_start(&feature_supported_checkbutton, false, false, 0);
self.features_box.pack_end(&vbox, false, false, 0);
}
}
}