mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 23:21:08 +03:00
add some config options to influence webgpu selection
This commit is contained in:
parent
883e2d11d7
commit
783b39aae1
@ -22,8 +22,9 @@ use crate::unix::UnixDomain;
|
||||
use crate::wsl::WslDomain;
|
||||
use crate::{
|
||||
default_config_with_overrides_applied, default_one_point_oh, default_one_point_oh_f64,
|
||||
default_true, KeyMapPreference, LoadedConfig, MouseEventTriggerMods, RgbaColor, CONFIG_DIR,
|
||||
CONFIG_FILE_OVERRIDE, CONFIG_OVERRIDES, CONFIG_SKIP, HOME_DIR,
|
||||
default_true, GpuInfo, KeyMapPreference, LoadedConfig, MouseEventTriggerMods, RgbaColor,
|
||||
WebGpuPowerPreference, CONFIG_DIR, CONFIG_FILE_OVERRIDE, CONFIG_OVERRIDES, CONFIG_SKIP,
|
||||
HOME_DIR,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use luahelper::impl_lua_conversion_dynamic;
|
||||
@ -262,6 +263,18 @@ pub struct Config {
|
||||
#[dynamic(default)]
|
||||
pub front_end: FrontEndSelection,
|
||||
|
||||
/// Whether to select the higher powered discrete GPU when
|
||||
/// the system has a choice of integrated or discrete.
|
||||
/// Defaults to low power.
|
||||
#[dynamic(default)]
|
||||
pub webgpu_power_preference: WebGpuPowerPreference,
|
||||
|
||||
#[dynamic(default)]
|
||||
pub webgpu_force_fallback_adapater: bool,
|
||||
|
||||
#[dynamic(default)]
|
||||
pub webgpu_preferred_adapter: Option<GpuInfo>,
|
||||
|
||||
#[dynamic(default = "WslDomain::default_domains")]
|
||||
pub wsl_domains: Vec<WslDomain>,
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
use luahelper::impl_lua_conversion_dynamic;
|
||||
use wezterm_dynamic::{FromDynamic, ToDynamic};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromDynamic, ToDynamic)]
|
||||
@ -12,3 +13,50 @@ impl Default for FrontEndSelection {
|
||||
FrontEndSelection::OpenGL
|
||||
}
|
||||
}
|
||||
|
||||
/// Corresponds to <https://docs.rs/wgpu/latest/wgpu/struct.AdapterInfo.html>
|
||||
#[derive(Debug, Clone, FromDynamic, ToDynamic)]
|
||||
pub struct GpuInfo {
|
||||
pub name: String,
|
||||
pub device_type: String,
|
||||
pub backend: String,
|
||||
pub driver: Option<String>,
|
||||
pub driver_info: Option<String>,
|
||||
pub vendor: Option<usize>,
|
||||
pub device: Option<usize>,
|
||||
}
|
||||
impl_lua_conversion_dynamic!(GpuInfo);
|
||||
|
||||
impl ToString for GpuInfo {
|
||||
fn to_string(&self) -> String {
|
||||
let mut result = format!(
|
||||
"name={}, device_type={}, backend={}",
|
||||
self.name, self.device_type, self.backend
|
||||
);
|
||||
if let Some(driver) = &self.driver {
|
||||
result.push_str(&format!(", driver={driver}"));
|
||||
}
|
||||
if let Some(driver_info) = &self.driver_info {
|
||||
result.push_str(&format!(", driver_info={driver_info}"));
|
||||
}
|
||||
if let Some(vendor) = &self.vendor {
|
||||
result.push_str(&format!(", vendor={vendor}"));
|
||||
}
|
||||
if let Some(device) = &self.device {
|
||||
result.push_str(&format!(", device={device}"));
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromDynamic, ToDynamic)]
|
||||
pub enum WebGpuPowerPreference {
|
||||
LowPower,
|
||||
HighPerformance,
|
||||
}
|
||||
|
||||
impl Default for WebGpuPowerPreference {
|
||||
fn default() -> Self {
|
||||
Self::LowPower
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::glyphcache::GlyphCache;
|
||||
use super::quad::*;
|
||||
use super::utilsprites::{RenderMetrics, UtilSprites};
|
||||
use crate::termwindow::webgpu::{WebGpuState, WebGpuTexture};
|
||||
use crate::termwindow::webgpu::{adapter_info_to_gpu_info, WebGpuState, WebGpuTexture};
|
||||
use ::window::bitmaps::atlas::OutOfTextureSpace;
|
||||
use ::window::bitmaps::Texture2d;
|
||||
use ::window::glium::backend::Context as GliumContext;
|
||||
@ -114,11 +114,8 @@ impl RenderContext {
|
||||
ctx.get_opengl_version_string()
|
||||
),
|
||||
Self::WebGpu(state) => {
|
||||
let info = &state.adapter_info;
|
||||
format!(
|
||||
"WebGPU: adapter={}, device_type={:?}, driver={}, driver_info={}, backend={:?}",
|
||||
info.name, info.device_type, info.driver, info.driver_info, info.backend
|
||||
)
|
||||
let info = adapter_info_to_gpu_info(state.adapter_info.clone());
|
||||
format!("WebGPU: {}", info.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::inputmap::InputMap;
|
||||
use config::keyassignment::KeyTable;
|
||||
use config::lua::get_or_create_sub_module;
|
||||
use config::lua::mlua::{self, Lua};
|
||||
use config::{DeferredKeyCode, Key, KeyNoAction};
|
||||
use config::{DeferredKeyCode, GpuInfo, Key, KeyNoAction};
|
||||
use luahelper::dynamic_to_lua_value;
|
||||
use mux::window::WindowId as MuxWindowId;
|
||||
use std::collections::HashMap;
|
||||
@ -69,5 +69,21 @@ pub fn register(lua: &Lua) -> anyhow::Result<()> {
|
||||
})?,
|
||||
)?;
|
||||
|
||||
window_mod.set(
|
||||
"enumerate_gpus",
|
||||
lua.create_function(|_, _: ()| {
|
||||
let backends = wgpu::Backends::all();
|
||||
let instance = wgpu::Instance::new(backends);
|
||||
let gpus: Vec<GpuInfo> = instance
|
||||
.enumerate_adapters(backends)
|
||||
.map(|adapter| {
|
||||
let info = adapter.get_info();
|
||||
crate::termwindow::webgpu::adapter_info_to_gpu_info(info)
|
||||
})
|
||||
.collect();
|
||||
Ok(gpus)
|
||||
})?,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -811,9 +811,9 @@ impl TermWindow {
|
||||
{
|
||||
let mut myself = tw.borrow_mut();
|
||||
let webgpu = match config.front_end {
|
||||
FrontEndSelection::WebGpu => {
|
||||
Some(Rc::new(WebGpuState::new(&window, dimensions).await?))
|
||||
}
|
||||
FrontEndSelection::WebGpu => Some(Rc::new(
|
||||
WebGpuState::new(&window, dimensions, &config).await?,
|
||||
)),
|
||||
_ => None,
|
||||
};
|
||||
myself.config_subscription.replace(config_subscription);
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::quad::Vertex;
|
||||
use anyhow::anyhow;
|
||||
use config::{ConfigHandle, GpuInfo, WebGpuPowerPreference};
|
||||
use std::cell::RefCell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::sync::Arc;
|
||||
@ -141,24 +142,114 @@ impl WebGpuTexture {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn adapter_info_to_gpu_info(info: wgpu::AdapterInfo) -> GpuInfo {
|
||||
GpuInfo {
|
||||
name: info.name,
|
||||
vendor: Some(info.vendor),
|
||||
device: Some(info.device),
|
||||
device_type: format!("{:?}", info.device_type),
|
||||
driver: if info.driver.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(info.driver)
|
||||
},
|
||||
driver_info: if info.driver_info.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(info.driver_info)
|
||||
},
|
||||
backend: format!("{:?}", info.backend),
|
||||
}
|
||||
}
|
||||
|
||||
impl WebGpuState {
|
||||
pub async fn new(window: &Window, dimensions: Dimensions) -> anyhow::Result<Self> {
|
||||
pub async fn new(
|
||||
window: &Window,
|
||||
dimensions: Dimensions,
|
||||
config: &ConfigHandle,
|
||||
) -> anyhow::Result<Self> {
|
||||
let handle = RawHandlePair::new(window);
|
||||
Self::new_impl(handle, dimensions).await
|
||||
Self::new_impl(handle, dimensions, config).await
|
||||
}
|
||||
|
||||
pub async fn new_impl(handle: RawHandlePair, dimensions: Dimensions) -> anyhow::Result<Self> {
|
||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||
pub async fn new_impl(
|
||||
handle: RawHandlePair,
|
||||
dimensions: Dimensions,
|
||||
config: &ConfigHandle,
|
||||
) -> anyhow::Result<Self> {
|
||||
let backends = wgpu::Backends::all();
|
||||
let instance = wgpu::Instance::new(backends);
|
||||
let surface = unsafe { instance.create_surface(&handle) };
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
compatible_surface: Some(&surface),
|
||||
force_fallback_adapter: false,
|
||||
})
|
||||
.await
|
||||
.ok_or_else(|| anyhow!("no matching adapter found"))?;
|
||||
|
||||
let mut adapter: Option<wgpu::Adapter> = None;
|
||||
|
||||
if let Some(preference) = &config.webgpu_preferred_adapter {
|
||||
for a in instance.enumerate_adapters(backends) {
|
||||
if !a.is_surface_supported(&surface) {
|
||||
let info = adapter_info_to_gpu_info(a.get_info());
|
||||
log::warn!("{} is not compatible with surface", info.to_string());
|
||||
continue;
|
||||
}
|
||||
|
||||
let info = a.get_info();
|
||||
|
||||
if preference.name != info.name {
|
||||
continue;
|
||||
}
|
||||
|
||||
if preference.device_type != format!("{:?}", info.device_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if preference.backend != format!("{:?}", info.backend) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(driver) = &preference.driver {
|
||||
if *driver != info.driver {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(vendor) = &preference.vendor {
|
||||
if *vendor != info.vendor {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(device) = &preference.device {
|
||||
if *device != info.device {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
adapter.replace(a);
|
||||
break;
|
||||
}
|
||||
|
||||
if adapter.is_none() {
|
||||
log::warn!(
|
||||
"Your webgpu preferred adapter '{}' was either not \
|
||||
found or is not compatible with your display",
|
||||
preference.to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if adapter.is_none() {
|
||||
adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: match config.webgpu_power_preference {
|
||||
WebGpuPowerPreference::HighPerformance => {
|
||||
wgpu::PowerPreference::HighPerformance
|
||||
}
|
||||
WebGpuPowerPreference::LowPower => wgpu::PowerPreference::LowPower,
|
||||
},
|
||||
compatible_surface: Some(&surface),
|
||||
force_fallback_adapter: config.webgpu_force_fallback_adapater,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
let adapter = adapter.ok_or_else(|| anyhow!("no matching adapter found"))?;
|
||||
let adapter_info = adapter.get_info();
|
||||
log::trace!("Using adapter: {adapter_info:?}");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user