mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
refactor: use blueprint for the info page (#273)
* feat: use blueprint for hardware info * chore: unify padding * fix: opensuse libadwaita build
This commit is contained in:
parent
e91bc46a0f
commit
54370e9b22
@ -52,7 +52,7 @@ impl App {
|
||||
let window = ApplicationWindow::builder()
|
||||
.title("LACT")
|
||||
.default_width(600)
|
||||
.default_height(820)
|
||||
.default_height(830)
|
||||
.icon_name(APP_ID)
|
||||
.build();
|
||||
|
||||
|
174
lact-gui/src/app/root_stack/info_page/hardware_info.rs
Normal file
174
lact-gui/src/app/root_stack/info_page/hardware_info.rs
Normal file
@ -0,0 +1,174 @@
|
||||
use gtk::glib::{self, object::ObjectExt, subclass::object::DerivedObjectProperties, Object};
|
||||
use lact_client::schema::{DeviceInfo, DeviceStats};
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct HardwareInfoSection(ObjectSubclass<imp::HardwareInfoSection>)
|
||||
@extends gtk::Box, gtk::Widget,
|
||||
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||
}
|
||||
|
||||
impl HardwareInfoSection {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn set_info(&self, info: &DeviceInfo) {
|
||||
self.reset();
|
||||
|
||||
if let Some(pci_info) = &info.pci_info {
|
||||
if let Some(name) = pci_info
|
||||
.subsystem_pci_info
|
||||
.model
|
||||
.as_deref()
|
||||
.or(pci_info.device_pci_info.model.as_deref())
|
||||
{
|
||||
self.set_gpu_model(name);
|
||||
}
|
||||
|
||||
if let Some(manufacturer_name) = info.pci_info.as_ref().and_then(|pci_info| {
|
||||
pci_info
|
||||
.subsystem_pci_info
|
||||
.vendor
|
||||
.as_deref()
|
||||
.or(pci_info.device_pci_info.model.as_deref())
|
||||
}) {
|
||||
self.set_gpu_manufacturer(manufacturer_name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(drm_info) = &info.drm_info {
|
||||
self.set_gpu_family(drm_info.family_name.clone());
|
||||
self.set_asic_name(drm_info.asic_name.clone());
|
||||
self.set_compute_units(drm_info.compute_units.to_string());
|
||||
|
||||
self.set_vram_type(drm_info.vram_type.clone());
|
||||
self.set_peak_vram_bandwidth(format!("{} GiB/s", drm_info.vram_max_bw));
|
||||
self.set_l1_cache(format!("{} KiB", drm_info.l1_cache_per_cu / 1024));
|
||||
self.set_l2_cache(format!("{} KiB", drm_info.l2_cache / 1024));
|
||||
self.set_l3_cache(format!("{} MiB", drm_info.l3_cache_mb));
|
||||
|
||||
if let Some(memory_info) = &drm_info.memory_info {
|
||||
let rebar = if memory_info.resizeable_bar {
|
||||
"Enabled"
|
||||
} else {
|
||||
"Disabled"
|
||||
};
|
||||
self.set_rebar(rebar);
|
||||
|
||||
self.set_cpu_accessible_vram(format!(
|
||||
"{} MiB",
|
||||
memory_info.cpu_accessible_total / 1024 / 1024
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
self.set_driver_used(info.driver);
|
||||
|
||||
if let Some(vbios) = &info.vbios_version {
|
||||
self.set_vbios_version(vbios.clone());
|
||||
}
|
||||
|
||||
if let (Some(link_speed), Some(link_width)) =
|
||||
(&info.link_info.current_speed, &info.link_info.current_width)
|
||||
{
|
||||
self.set_link_speed(format!("{link_speed} x{link_width}",));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_stats(&self, stats: &DeviceStats) {
|
||||
if let Some(total_vram) = stats.vram.total {
|
||||
self.set_vram_size(format!("{} MiB", total_vram / 1024 / 1024));
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&self) {
|
||||
let properties = imp::HardwareInfoSection::derived_properties();
|
||||
for property in properties {
|
||||
self.set_property(property.name(), "Unknown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HardwareInfoSection {
|
||||
fn default() -> Self {
|
||||
Object::builder().build()
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
#![allow(clippy::enum_variant_names)]
|
||||
use crate::app::{info_row::InfoRow, page_section::PageSection};
|
||||
use glib::Properties;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject},
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
widget::{CompositeTemplateClass, WidgetImpl},
|
||||
},
|
||||
CompositeTemplate,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::HardwareInfoSection)]
|
||||
#[template(file = "ui/info_page/hardware_info_section.blp")]
|
||||
pub struct HardwareInfoSection {
|
||||
#[property(get, set)]
|
||||
gpu_model: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
gpu_manufacturer: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
gpu_family: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
asic_name: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
compute_units: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
vbios_version: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
driver_used: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
vram_size: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
vram_type: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
peak_vram_bandwidth: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
l1_cache: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
l2_cache: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
l3_cache: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
rebar: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
cpu_accessible_vram: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
link_speed: RefCell<String>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for HardwareInfoSection {
|
||||
const NAME: &'static str = "HardwareInfoSection";
|
||||
type Type = super::HardwareInfoSection;
|
||||
type ParentType = PageSection;
|
||||
|
||||
fn class_init(class: &mut Self::Class) {
|
||||
InfoRow::ensure_type();
|
||||
PageSection::ensure_type();
|
||||
|
||||
class.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for HardwareInfoSection {}
|
||||
|
||||
impl WidgetImpl for HardwareInfoSection {}
|
||||
impl BoxImpl for HardwareInfoSection {}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
mod hardware_info;
|
||||
mod vulkan_info;
|
||||
|
||||
use super::{label_row, values_grid};
|
||||
use self::hardware_info::HardwareInfoSection;
|
||||
|
||||
use super::values_grid;
|
||||
use crate::app::page_section::PageSection;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
@ -10,22 +13,7 @@ use vulkan_info::VulkanInfoFrame;
|
||||
#[derive(Clone)]
|
||||
pub struct InformationPage {
|
||||
pub container: ScrolledWindow,
|
||||
gpu_name_label: Label,
|
||||
gpu_manufacturer_label: Label,
|
||||
family_name: Label,
|
||||
asic_name: Label,
|
||||
vbios_version_label: Label,
|
||||
driver_label: Label,
|
||||
vram_size_label: Label,
|
||||
vram_type_label: Label,
|
||||
vram_peak_bw_label: Label,
|
||||
compute_units_label: Label,
|
||||
l1_cache_label: Label,
|
||||
l2_cache_label: Label,
|
||||
l3_cache_label: Label,
|
||||
resizable_bar_enabled: Label,
|
||||
cpu_accessible_vram_label: Label,
|
||||
link_speed_label: Label,
|
||||
hardware_info: HardwareInfoSection,
|
||||
vulkan_info_frame: VulkanInfoFrame,
|
||||
vulkan_unavailable_label: Label,
|
||||
}
|
||||
@ -39,42 +27,12 @@ impl InformationPage {
|
||||
.margin_end(20)
|
||||
.build();
|
||||
|
||||
let info_container = PageSection::new("Hardware Information");
|
||||
|
||||
let values_grid = values_grid();
|
||||
|
||||
// Dummy label to prevent the gpu name label from stealing focus
|
||||
let dummy_label = Label::builder().selectable(true).halign(Align::End).build();
|
||||
values_grid.attach(&dummy_label, 0, 0, 1, 1);
|
||||
|
||||
let mut row = 0;
|
||||
let gpu_name_label = sequential_label_row("GPU Model:", &values_grid, &mut row);
|
||||
let gpu_manufacturer_label =
|
||||
sequential_label_row("GPU Manufacturer:", &values_grid, &mut row);
|
||||
let family_name = sequential_label_row("GPU Family:", &values_grid, &mut row);
|
||||
let asic_name = sequential_label_row("ASIC Name:", &values_grid, &mut row);
|
||||
let compute_units_label = sequential_label_row("Compute Units:", &values_grid, &mut row);
|
||||
let vbios_version_label = sequential_label_row("VBIOS Version:", &values_grid, &mut row);
|
||||
let driver_label = sequential_label_row("Driver Used:", &values_grid, &mut row);
|
||||
|
||||
let vram_size_label = sequential_label_row("VRAM Size:", &values_grid, &mut row);
|
||||
let vram_type_label = sequential_label_row("VRAM Type:", &values_grid, &mut row);
|
||||
let vram_peak_bw_label =
|
||||
sequential_label_row("Peak VRAM Bandwidth:", &values_grid, &mut row);
|
||||
|
||||
let l1_cache_label = sequential_label_row("L1 Cache (Per CU):", &values_grid, &mut row);
|
||||
let l2_cache_label = sequential_label_row("L2 Cache:", &values_grid, &mut row);
|
||||
let l3_cache_label = sequential_label_row("L3 Cache:", &values_grid, &mut row);
|
||||
|
||||
let resizable_bar_enabled = sequential_label_row("Resizeable BAR:", &values_grid, &mut row);
|
||||
let cpu_accessible_vram_label =
|
||||
sequential_label_row("CPU Accessible VRAM:", &values_grid, &mut row);
|
||||
let link_speed_label = sequential_label_row("Link Speed:", &values_grid, &mut row);
|
||||
|
||||
info_container.append(&values_grid);
|
||||
vbox.append(&info_container);
|
||||
let hardware_info = HardwareInfoSection::new();
|
||||
vbox.append(&hardware_info);
|
||||
|
||||
let vulkan_container = PageSection::new("Vulkan Information");
|
||||
vulkan_container.set_spacing(10);
|
||||
vulkan_container.set_margin_start(15);
|
||||
|
||||
let vulkan_info_frame = VulkanInfoFrame::new();
|
||||
vulkan_container.append(&vulkan_info_frame.container);
|
||||
@ -97,129 +55,14 @@ impl InformationPage {
|
||||
|
||||
Self {
|
||||
container,
|
||||
gpu_name_label,
|
||||
gpu_manufacturer_label,
|
||||
vbios_version_label,
|
||||
driver_label,
|
||||
vram_size_label,
|
||||
link_speed_label,
|
||||
hardware_info,
|
||||
vulkan_info_frame,
|
||||
family_name,
|
||||
asic_name,
|
||||
vram_type_label,
|
||||
resizable_bar_enabled,
|
||||
cpu_accessible_vram_label,
|
||||
compute_units_label,
|
||||
vram_peak_bw_label,
|
||||
l1_cache_label,
|
||||
l2_cache_label,
|
||||
l3_cache_label,
|
||||
vulkan_unavailable_label,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_info(&self, gpu_info: &DeviceInfo) {
|
||||
let gpu_name = gpu_info
|
||||
.pci_info
|
||||
.as_ref()
|
||||
.and_then(|pci_info| {
|
||||
pci_info
|
||||
.subsystem_pci_info
|
||||
.model
|
||||
.as_deref()
|
||||
.or(pci_info.device_pci_info.model.as_deref())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
self.gpu_name_label
|
||||
.set_markup(&format!("<b>{gpu_name}</b>"));
|
||||
|
||||
let gpu_manufacturer = gpu_info
|
||||
.pci_info
|
||||
.as_ref()
|
||||
.and_then(|pci_info| {
|
||||
pci_info
|
||||
.subsystem_pci_info
|
||||
.vendor
|
||||
.as_deref()
|
||||
.or(pci_info.device_pci_info.model.as_deref())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
self.gpu_manufacturer_label
|
||||
.set_markup(&format!("<b>{gpu_manufacturer}</b>"));
|
||||
|
||||
let mut family_name = "Unknown";
|
||||
let mut asic_name = "Unknown";
|
||||
let mut compute_units = "Unknown".to_owned();
|
||||
let mut vram_type = "Unknown";
|
||||
let mut vram_max_bw = "Unknown";
|
||||
let mut cpu_accessible_vram = "Unknown".to_owned();
|
||||
let mut resizeable_bar_enabled = "Unknown";
|
||||
let mut l1_cache = "Unknown".to_owned();
|
||||
let mut l2_cache = "Unknown".to_owned();
|
||||
let mut l3_cache = "Unknown".to_owned();
|
||||
|
||||
if let Some(drm_info) = &gpu_info.drm_info {
|
||||
family_name = &drm_info.family_name;
|
||||
asic_name = &drm_info.asic_name;
|
||||
compute_units = drm_info.compute_units.to_string();
|
||||
vram_type = &drm_info.vram_type;
|
||||
vram_max_bw = &drm_info.vram_max_bw;
|
||||
l1_cache = format!("{} KiB", drm_info.l1_cache_per_cu / 1024);
|
||||
l2_cache = format!("{} KiB", drm_info.l2_cache / 1024);
|
||||
l3_cache = format!("{} MiB", drm_info.l3_cache_mb);
|
||||
|
||||
if let Some(memory_info) = &drm_info.memory_info {
|
||||
resizeable_bar_enabled = if memory_info.resizeable_bar {
|
||||
"Enabled"
|
||||
} else {
|
||||
"Disabled"
|
||||
};
|
||||
|
||||
cpu_accessible_vram = (memory_info.cpu_accessible_total / 1024 / 1024).to_string();
|
||||
}
|
||||
}
|
||||
|
||||
self.family_name
|
||||
.set_markup(&format!("<b>{family_name}</b>"));
|
||||
self.asic_name.set_markup(&format!("<b>{asic_name}</b>"));
|
||||
self.compute_units_label
|
||||
.set_markup(&format!("<b>{compute_units}</b>"));
|
||||
self.vram_type_label
|
||||
.set_markup(&format!("<b>{vram_type}</b>"));
|
||||
self.vram_peak_bw_label
|
||||
.set_markup(&format!("<b>{vram_max_bw} GiB/s</b>"));
|
||||
|
||||
self.l1_cache_label
|
||||
.set_markup(&format!("<b>{l1_cache}</b>"));
|
||||
self.l2_cache_label
|
||||
.set_markup(&format!("<b>{l2_cache}</b>"));
|
||||
self.l3_cache_label
|
||||
.set_markup(&format!("<b>{l3_cache}</b>"));
|
||||
|
||||
self.resizable_bar_enabled
|
||||
.set_markup(&format!("<b>{resizeable_bar_enabled}</b>"));
|
||||
self.cpu_accessible_vram_label
|
||||
.set_markup(&format!("<b>{cpu_accessible_vram} MiB</b>"));
|
||||
|
||||
let vbios_version = gpu_info.vbios_version.as_deref().unwrap_or("Unknown");
|
||||
self.vbios_version_label
|
||||
.set_markup(&format!("<b>{vbios_version}</b>"));
|
||||
|
||||
self.driver_label
|
||||
.set_markup(&format!("<b>{}</b>", gpu_info.driver));
|
||||
|
||||
let link_speed = gpu_info
|
||||
.link_info
|
||||
.current_speed
|
||||
.as_deref()
|
||||
.unwrap_or("Unknown");
|
||||
let link_width = gpu_info
|
||||
.link_info
|
||||
.current_width
|
||||
.as_deref()
|
||||
.unwrap_or("Unknown");
|
||||
self.link_speed_label
|
||||
.set_markup(&format!("<b>{link_speed} x{link_width}</b>",));
|
||||
self.hardware_info.set_info(gpu_info);
|
||||
|
||||
if let Some(vulkan_info) = &gpu_info.vulkan_info {
|
||||
self.vulkan_info_frame.set_info(vulkan_info);
|
||||
@ -232,17 +75,6 @@ impl InformationPage {
|
||||
}
|
||||
|
||||
pub fn set_stats(&self, stats: &DeviceStats) {
|
||||
let vram_size = stats.vram.total.map_or_else(
|
||||
|| "Unknown".to_owned(),
|
||||
|size| (size / 1024 / 1024).to_string(),
|
||||
);
|
||||
self.vram_size_label
|
||||
.set_markup(&format!("<b>{vram_size} MiB</b>"));
|
||||
self.hardware_info.set_stats(stats);
|
||||
}
|
||||
}
|
||||
|
||||
fn sequential_label_row(title: &str, parent: &Grid, row: &mut i32) -> Label {
|
||||
let label = label_row(title, parent, *row, 0, true);
|
||||
*row += 1;
|
||||
label
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ impl VulkanInfoFrame {
|
||||
let extensions_model = gio::ListStore::new::<VulkanFeature>();
|
||||
|
||||
let grid = values_grid();
|
||||
grid.set_margin_start(0);
|
||||
grid.set_margin_end(0);
|
||||
|
||||
let device_name_label = label_row("Device name", &grid, 0, 0, true);
|
||||
let version_label = label_row("Vulkan version:", &grid, 1, 0, true);
|
||||
|
103
lact-gui/ui/info_page/hardware_info_section.blp
Normal file
103
lact-gui/ui/info_page/hardware_info_section.blp
Normal file
@ -0,0 +1,103 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $HardwareInfoSection: $PageSection {
|
||||
name: "Hardware Information";
|
||||
spacing: 10;
|
||||
margin-start: 15;
|
||||
|
||||
$InfoRow {
|
||||
name: "GPU Model:";
|
||||
value: bind template.gpu_model;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "GPU Manufacturer:";
|
||||
value: bind template.gpu_manufacturer;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "GPU Family:";
|
||||
value: bind template.gpu_family;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "ASIC Name:";
|
||||
value: bind template.asic_name;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Compute Units:";
|
||||
value: bind template.compute_units;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "VBIOS Version:";
|
||||
value: bind template.vbios_version;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Driver Used:";
|
||||
value: bind template.driver_used;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "VRAM Size:";
|
||||
value: bind template.vram_size;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "VRAM Type:";
|
||||
value: bind template.vram_type;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Peak VRAM Bandwidth:";
|
||||
value: bind template.peak_vram_bandwidth;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "L1 Cache (Per CU):";
|
||||
value: bind template.l1_cache;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "L2 Cache:";
|
||||
value: bind template.l2_cache;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "L3 Cache:";
|
||||
value: bind template.l3_cache;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Resizeable BAR:";
|
||||
value: bind template.rebar;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "CPU Accessible VRAM:";
|
||||
value: bind template.cpu_accessible_vram;
|
||||
selectable: true;
|
||||
}
|
||||
|
||||
$InfoRow {
|
||||
name: "Link Speed:";
|
||||
value: bind template.link_speed;
|
||||
selectable: true;
|
||||
}
|
||||
}
|
@ -14,12 +14,12 @@ metadata:
|
||||
all: [ hwdata ]
|
||||
fedora-39: [ gtk4, libdrm, libadwaita ]
|
||||
arch: [ gtk4, libadwaita ]
|
||||
opensuse-tumbleweed: [ gtk4, libdrm, libadwaita ]
|
||||
opensuse-tumbleweed: [ libdrm, libadwaita ]
|
||||
build_depends:
|
||||
all: [ curl, make, clang ]
|
||||
fedora-39: [ gtk4-devel, gcc, libdrm-devel, blueprint-compiler, libadwaita-devel, dbus ]
|
||||
arch: [ gtk4, blueprint-compiler, libadwaita, dbus ]
|
||||
opensuse-tumbleweed: [ gtk4-devel, libdrm-devel, blueprint-compiler, libadwaita-devel ]
|
||||
opensuse-tumbleweed: [ libdrm-devel, blueprint-compiler, libadwaita-devel ]
|
||||
all_images: true
|
||||
env:
|
||||
RUSTUP_URL: https://sh.rustup.rs
|
||||
|
Loading…
Reference in New Issue
Block a user