mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-11-03 12:50:31 -06:00
chore: use full device snapshot
This commit is contained in:
1 parent
2b24043d2b
commit
8ef367b46a
23 files changed
+5117
-186
No files matched your search
@@ -40,6 +40,8 @@ pub type DynGpuController = Box<dyn GpuController>;
|
||||
type FanControlHandle = (Rc<Notify>, JoinHandle<()>);
|
||||
|
||||
pub trait GpuController {
|
||||
fn controller_type(&self) -> &'static str;
|
||||
|
||||
fn controller_info(&self) -> &CommonControllerInfo;
|
||||
|
||||
fn device_type(&self) -> DeviceType;
|
||||
|
||||
@@ -767,6 +767,10 @@ impl AmdGpuController {
|
||||
}
|
||||
|
||||
impl GpuController for AmdGpuController {
|
||||
fn controller_type(&self) -> &'static str {
|
||||
"amd"
|
||||
}
|
||||
|
||||
fn controller_info(&self) -> &CommonControllerInfo {
|
||||
&self.common
|
||||
}
|
||||
|
||||
@@ -709,6 +709,10 @@ impl IntelGpuController {
|
||||
}
|
||||
|
||||
impl GpuController for IntelGpuController {
|
||||
fn controller_type(&self) -> &'static str {
|
||||
"intel"
|
||||
}
|
||||
|
||||
fn controller_info(&self) -> &CommonControllerInfo {
|
||||
&self.common
|
||||
}
|
||||
|
||||
@@ -1,38 +1,43 @@
|
||||
use super::{DrmProvider, VramInfo};
|
||||
use lact_schema::{DeviceStats, DrmInfo, IntelDrmInfo};
|
||||
use serde::de::DeserializeOwned;
|
||||
use crate::server::handler::SnapshotDeviceInfo;
|
||||
use lact_schema::IntelDrmInfo;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct MockDrmProvider {
|
||||
info: DrmInfo,
|
||||
stats: DeviceStats,
|
||||
snapshot: SnapshotDeviceInfo,
|
||||
}
|
||||
|
||||
impl MockDrmProvider {
|
||||
pub fn new(sysfs: &Path) -> Option<Self> {
|
||||
Some(Self {
|
||||
info: read_json(sysfs, "drm_info.json")?,
|
||||
stats: read_json(sysfs, "stats.json")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
let info_path = sysfs.parent()?.parent()?.join("info.json");
|
||||
let raw_snapshot = std::fs::read_to_string(info_path).ok()?;
|
||||
let snapshot = serde_json::from_str(&raw_snapshot).expect("could not parse snapshot");
|
||||
|
||||
fn read_json<T: DeserializeOwned>(sysfs: &Path, name: &str) -> Option<T> {
|
||||
std::fs::read_to_string(sysfs.join(name))
|
||||
.ok()
|
||||
.and_then(|contents| serde_json::from_str::<T>(&contents).ok())
|
||||
Some(Self { snapshot })
|
||||
}
|
||||
}
|
||||
|
||||
impl DrmProvider for MockDrmProvider {
|
||||
fn get_intel_info(&self) -> IntelDrmInfo {
|
||||
self.info.intel.clone()
|
||||
self.snapshot
|
||||
.info
|
||||
.drm_info
|
||||
.as_ref()
|
||||
.map(|info| info.intel.clone())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn get_vram_info(&self) -> VramInfo {
|
||||
VramInfo {
|
||||
total: self.stats.vram.total.unwrap_or(0),
|
||||
used: self.stats.vram.used.unwrap_or(0),
|
||||
mem_info: self.info.memory_info.clone().unwrap_or_default(),
|
||||
total: self.snapshot.stats.vram.total.unwrap_or(0),
|
||||
used: self.snapshot.stats.vram.used.unwrap_or(0),
|
||||
mem_info: self
|
||||
.snapshot
|
||||
.info
|
||||
.drm_info
|
||||
.as_ref()
|
||||
.and_then(|info| info.memory_info.clone())
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -744,6 +744,10 @@ fn apply_power_cap(device: &mut Device<'_>, power_cap: Option<f64>) -> anyhow::R
|
||||
}
|
||||
|
||||
impl GpuController for NvidiaGpuController {
|
||||
fn controller_type(&self) -> &'static str {
|
||||
"nvidia"
|
||||
}
|
||||
|
||||
fn controller_info(&self) -> &CommonControllerInfo {
|
||||
&self.common
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ use amdgpu_sysfs::gpu_handle::{
|
||||
use anyhow::{Context, anyhow, bail};
|
||||
use lact_schema::{
|
||||
ClocksInfo, DeviceApiInfo, DeviceInfo, DeviceListEntry, DeviceStats, DisplaysInfo,
|
||||
FanControlMode, FanOptions, PmfwOptions, PowerStates, ProcessList, ProfileRule,
|
||||
FanControlMode, FanOptions, GpuPciInfo, PmfwOptions, PowerStates, ProcessList, ProfileRule,
|
||||
ProfileWatcherState, ProfilesInfo,
|
||||
config::{
|
||||
FanControlSettings, FanCurve, GpuConfig, Profile, ProfileHooks, default_fan_static_speed,
|
||||
@@ -34,6 +34,7 @@ use libdrm_amdgpu_sys::LibDrmAmdgpu;
|
||||
use libflate::gzip;
|
||||
use nix::libc;
|
||||
use pciid_parser::Database;
|
||||
use serde::Serialize;
|
||||
use serde_json::json;
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
@@ -832,7 +833,7 @@ impl<'a> Handler {
|
||||
|
||||
pub(crate) async fn generate_snapshot_device_info(
|
||||
&self,
|
||||
) -> BTreeMap<String, serde_json::Value> {
|
||||
) -> BTreeMap<String, SnapshotDeviceInfo> {
|
||||
let controllers = self.gpu_controllers.read().await;
|
||||
let config = self.config.read().await;
|
||||
|
||||
@@ -843,14 +844,14 @@ impl<'a> Handler {
|
||||
|
||||
let unique_vendor = controller_vendor_is_unique(controller, id, &controllers);
|
||||
|
||||
let data = json!({
|
||||
"pci_info": controller.controller_info().pci_info.clone(),
|
||||
"info": controller.get_info(unique_vendor, true).await,
|
||||
"stats": controller.get_stats(gpu_config),
|
||||
"clocks_info": controller.get_clocks_info(gpu_config).ok(),
|
||||
"power_profile_modes": controller.get_power_profile_modes().ok(),
|
||||
"power_states": controller.get_power_states(gpu_config),
|
||||
});
|
||||
let data = SnapshotDeviceInfo {
|
||||
pci_info: controller.controller_info().pci_info.clone(),
|
||||
info: controller.get_info(unique_vendor, true).await,
|
||||
stats: controller.get_stats(gpu_config),
|
||||
clocks_info: controller.get_clocks_info(gpu_config).ok(),
|
||||
power_profile_modes: controller.get_power_profile_modes().ok(),
|
||||
power_states: controller.get_power_states(gpu_config),
|
||||
};
|
||||
|
||||
map.insert(id.clone(), data);
|
||||
}
|
||||
@@ -1317,6 +1318,18 @@ impl<'a> Handler {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[cfg_attr(feature = "mock", derive(serde::Deserialize))]
|
||||
pub(crate) struct SnapshotDeviceInfo {
|
||||
pub pci_info: GpuPciInfo,
|
||||
pub info: DeviceInfo,
|
||||
pub stats: DeviceStats,
|
||||
#[serde(default)]
|
||||
pub clocks_info: Option<ClocksInfo>,
|
||||
pub power_profile_modes: Option<PowerProfileModesTable>,
|
||||
pub power_states: PowerStates,
|
||||
}
|
||||
|
||||
async fn apply_config_to_controllers(
|
||||
controllers: &BTreeMap<String, Box<dyn GpuController>>,
|
||||
config: &Config,
|
||||
@@ -1445,7 +1458,7 @@ fn load_controllers(
|
||||
|
||||
info!(
|
||||
"initialized {} controller for GPU {id} at '{}' ({})",
|
||||
info.driver,
|
||||
controller.controller_type(),
|
||||
info.sysfs_path.display(),
|
||||
info.pci_info
|
||||
.device_pci_info
|
||||
|
||||
@@ -48,6 +48,7 @@ async fn snapshot_everything() {
|
||||
.into_values()
|
||||
.next()
|
||||
.unwrap();
|
||||
let device_info = serde_json::to_value(&device_info).unwrap();
|
||||
|
||||
assert_json_snapshot!(test_key, device_info);
|
||||
}
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
---
|
||||
source: lact-daemon/src/tests/mod.rs
|
||||
assertion_line: 123
|
||||
expression: write_commands
|
||||
---
|
||||
[]
|
||||
@@ -20,11 +20,13 @@ expression: device_info
|
||||
"info": {
|
||||
"driver": "i915",
|
||||
"drm_info": {
|
||||
"execution_units": 128,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"cpu_accessible_total": 6383730688,
|
||||
"cpu_accessible_used": 22360064,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 8,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
@@ -125,6 +127,9 @@ expression: device_info
|
||||
"gpu": 603,
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
"vram": {
|
||||
"total": 6383730688,
|
||||
"used": 22360064
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
---
|
||||
source: lact-daemon/src/tests/mod.rs
|
||||
assertion_line: 52
|
||||
expression: device_info
|
||||
---
|
||||
{
|
||||
"clocks_info": null,
|
||||
"info": {
|
||||
"driver": "i915",
|
||||
"drm_info": {
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [
|
||||
"DumpableVBios",
|
||||
"ConfigurableFanControl"
|
||||
],
|
||||
"link_info": {
|
||||
"current_speed": "2.5 GT/s PCIe",
|
||||
"current_width": "1"
|
||||
},
|
||||
"opencl_instances": [
|
||||
{
|
||||
"c_version": "OpenCL C 1.2 ",
|
||||
"compute_units": 128,
|
||||
"device_name": "Intel(R) Arc(TM) A380 Graphics",
|
||||
"driver_version": "25.48.36300",
|
||||
"global_memory": 6064541696,
|
||||
"local_memory": 65536,
|
||||
"platform_name": "Intel(R) OpenCL Graphics",
|
||||
"version": "OpenCL 3.0 NEO ",
|
||||
"workgroup_size": 1024
|
||||
}
|
||||
],
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "DG2 [Arc A380]",
|
||||
"model_id": "56A5",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model": "ASRock Challenger ITX Arc A380",
|
||||
"model_id": "6004",
|
||||
"vendor": "ASRock Incorporation",
|
||||
"vendor_id": "1849"
|
||||
}
|
||||
},
|
||||
"vulkan_instances": []
|
||||
},
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "DG2 [Arc A380]",
|
||||
"model_id": "56A5",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model": "ASRock Challenger ITX Arc A380",
|
||||
"model_id": "6004",
|
||||
"vendor": "ASRock Incorporation",
|
||||
"vendor_id": "1849"
|
||||
}
|
||||
},
|
||||
"power_profile_modes": null,
|
||||
"power_states": {
|
||||
"core": [],
|
||||
"vram": []
|
||||
},
|
||||
"stats": {
|
||||
"clockspeed": {
|
||||
"sensors": {}
|
||||
},
|
||||
"fan": {
|
||||
"control_enabled": false,
|
||||
"pmfw_info": {},
|
||||
"speed_current": 0
|
||||
},
|
||||
"power": {},
|
||||
"temps": {
|
||||
"1": {
|
||||
"crit": null,
|
||||
"crit_hyst": null,
|
||||
"current": 55.0,
|
||||
"display_only": false,
|
||||
"primary": true
|
||||
}
|
||||
},
|
||||
"voltage": {
|
||||
"gpu": 603,
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,13 @@ expression: device_info
|
||||
"info": {
|
||||
"driver": "xe",
|
||||
"drm_info": {
|
||||
"execution_units": 128,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"cpu_accessible_total": 6383730688,
|
||||
"cpu_accessible_used": 22360064,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 8,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
@@ -115,6 +117,9 @@ expression: device_info
|
||||
"gpu": 605,
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
"vram": {
|
||||
"total": 6383730688,
|
||||
"used": 22360064
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ expression: device_info
|
||||
"driver": "xe",
|
||||
"drm_info": {
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_total": 12809404416,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
@@ -112,6 +112,9 @@ expression: device_info
|
||||
"voltage": {
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
"vram": {
|
||||
"total": 12809404416,
|
||||
"used": 10781573120
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ expression: device_info
|
||||
"driver": "xe",
|
||||
"drm_info": {
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_total": 12809404416,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
@@ -227,6 +227,9 @@ expression: device_info
|
||||
"voltage": {
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
"vram": {
|
||||
"total": 12809404416,
|
||||
"used": 10781573120
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,13 @@ expression: device_info
|
||||
"info": {
|
||||
"driver": "i915",
|
||||
"drm_info": {
|
||||
"execution_units": 24,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 3,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
|
||||
@@ -20,11 +20,13 @@ expression: device_info
|
||||
"info": {
|
||||
"driver": "xe",
|
||||
"drm_info": {
|
||||
"execution_units": 24,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 3,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"execution_units": 128,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 6383730688,
|
||||
"cpu_accessible_used": 22360064,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 8,
|
||||
"vram_clock_ratio": 1.0
|
||||
}
|
||||
Executable
+1154
File diff suppressed because it is too large.
Load diff
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"clockspeed": {
|
||||
"gpu_clockspeed": 600,
|
||||
"sensors": {},
|
||||
"target_gpu_clockspeed": 600
|
||||
},
|
||||
"fan": {
|
||||
"control_enabled": false,
|
||||
"pmfw_info": {},
|
||||
"speed_current": 741
|
||||
},
|
||||
"power": {
|
||||
"cap_current": 65.0,
|
||||
"cap_default": 65.0,
|
||||
"cap_max": 400.0,
|
||||
"cap_min": 0.0,
|
||||
"current": 18.0
|
||||
},
|
||||
"temps": {
|
||||
"gpu": {
|
||||
"crit": null,
|
||||
"crit_hyst": null,
|
||||
"current": 54.0,
|
||||
"display_only": true,
|
||||
"primary": true
|
||||
}
|
||||
},
|
||||
"throttle_info": {},
|
||||
"voltage": {
|
||||
"gpu": 605,
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {
|
||||
"total": 6383730688,
|
||||
"used": 22360064
|
||||
}
|
||||
}
|
||||
Executable
+1154
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"clocks_info": {
|
||||
"table": {
|
||||
"type": "intel",
|
||||
"value": {
|
||||
"gt_freq": [300, 1150],
|
||||
"rp0_freq": 1150,
|
||||
"rpe_freq": 300,
|
||||
"rpn_freq": 300
|
||||
}
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"driver": "i915",
|
||||
"drm_info": {
|
||||
"execution_units": 24,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 3,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
"link_info": {},
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "CometLake-U GT2 [UHD Graphics]",
|
||||
"model_id": "9B41",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model_id": "22B1",
|
||||
"vendor": "Lenovo",
|
||||
"vendor_id": "17AA"
|
||||
}
|
||||
},
|
||||
"vulkan_instances": []
|
||||
},
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "CometLake-U GT2 [UHD Graphics]",
|
||||
"model_id": "9B41",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model_id": "22B1",
|
||||
"vendor": "Lenovo",
|
||||
"vendor_id": "17AA"
|
||||
}
|
||||
},
|
||||
"power_profile_modes": null,
|
||||
"power_states": {
|
||||
"core": [
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 1150
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 1150
|
||||
}
|
||||
],
|
||||
"vram": []
|
||||
},
|
||||
"stats": {
|
||||
"busy_percent": 0,
|
||||
"clockspeed": {
|
||||
"gpu_clockspeed": 300,
|
||||
"sensors": {},
|
||||
"target_gpu_clockspeed": 300
|
||||
},
|
||||
"fan": {
|
||||
"control_enabled": false,
|
||||
"pmfw_info": {}
|
||||
},
|
||||
"power": {
|
||||
"cap_min": 0.0
|
||||
},
|
||||
"temps": {},
|
||||
"throttle_info": {},
|
||||
"voltage": {
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"_comment": "This is not actually a matching snapshot, but i couldnt get anything better",
|
||||
"clocks_info": {
|
||||
"table": {
|
||||
"type": "intel",
|
||||
"value": {
|
||||
"gt_freq": [300, 1150],
|
||||
"rp0_freq": 1150,
|
||||
"rpe_freq": 300,
|
||||
"rpn_freq": 300
|
||||
}
|
||||
}
|
||||
},
|
||||
"info": {
|
||||
"driver": "i915",
|
||||
"drm_info": {
|
||||
"execution_units": 24,
|
||||
"memory_info": {
|
||||
"cpu_accessible_total": 0,
|
||||
"cpu_accessible_used": 0,
|
||||
"resizeable_bar": true
|
||||
},
|
||||
"subslices": 3,
|
||||
"vram_clock_ratio": 1.0
|
||||
},
|
||||
"flags": [],
|
||||
"link_info": {},
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "CometLake-U GT2 [UHD Graphics]",
|
||||
"model_id": "9B41",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model_id": "22B1",
|
||||
"vendor": "Lenovo",
|
||||
"vendor_id": "17AA"
|
||||
}
|
||||
},
|
||||
"vulkan_instances": []
|
||||
},
|
||||
"pci_info": {
|
||||
"device_pci_info": {
|
||||
"model": "CometLake-U GT2 [UHD Graphics]",
|
||||
"model_id": "9B41",
|
||||
"vendor": "Intel Corporation",
|
||||
"vendor_id": "8086"
|
||||
},
|
||||
"subsystem_pci_info": {
|
||||
"model_id": "22B1",
|
||||
"vendor": "Lenovo",
|
||||
"vendor_id": "17AA"
|
||||
}
|
||||
},
|
||||
"power_profile_modes": null,
|
||||
"power_states": {
|
||||
"core": [
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 1150
|
||||
},
|
||||
{
|
||||
"enabled": true,
|
||||
"value": 1150
|
||||
}
|
||||
],
|
||||
"vram": []
|
||||
},
|
||||
"stats": {
|
||||
"busy_percent": 0,
|
||||
"clockspeed": {
|
||||
"gpu_clockspeed": 300,
|
||||
"sensors": {},
|
||||
"target_gpu_clockspeed": 300
|
||||
},
|
||||
"fan": {
|
||||
"control_enabled": false,
|
||||
"pmfw_info": {}
|
||||
},
|
||||
"power": {
|
||||
"cap_min": 0.0
|
||||
},
|
||||
"temps": {},
|
||||
"throttle_info": {},
|
||||
"voltage": {
|
||||
"sensors": {}
|
||||
},
|
||||
"vram": {}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user