workaround: Force shm on Meteor/Arrow/Lunar Lake
This commit is contained in:
parent
b8780b9911
commit
9968b0e61f
5 changed files with 94 additions and 0 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1242,6 +1242,8 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aliasable",
|
"aliasable",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"ash",
|
||||||
|
"bytemuck",
|
||||||
"calloop 0.14.3",
|
"calloop 0.14.3",
|
||||||
"calloop-wayland-source 0.4.1",
|
"calloop-wayland-source 0.4.1",
|
||||||
"clap",
|
"clap",
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ aliasable = "0.1.3"
|
||||||
futures-executor = { version = "0.3.31", features = ["thread-pool"] }
|
futures-executor = { version = "0.3.31", features = ["thread-pool"] }
|
||||||
zbus = "5.9.0"
|
zbus = "5.9.0"
|
||||||
tokio-stream = { version = "0.1.17", features = ["sync"] }
|
tokio-stream = { version = "0.1.17", features = ["sync"] }
|
||||||
|
ash = { version = "0.38.0", features = ["loaded"] }
|
||||||
|
bytemuck = "1.23.2"
|
||||||
|
|
||||||
[dependencies.i18n-embed]
|
[dependencies.i18n-embed]
|
||||||
version = "0.16"
|
version = "0.16"
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,14 @@ impl AppData {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
let drm_dev = drm_dev.unwrap_or(feedback.main_device() as u64);
|
let drm_dev = drm_dev.unwrap_or(feedback.main_device() as u64);
|
||||||
|
if let Some(vulkan) = &mut self.vulkan {
|
||||||
|
if let Ok(Some(name)) = vulkan.device_name(drm_dev) {
|
||||||
|
// TODO Workaround: force shm on Meteor/Arrow/Lunar Lake
|
||||||
|
if name.contains("MTL") || name.contains("ARL") || name.contains("LNL") {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let Some((_dev_path, gbm)) = self.gbm_devices.gbm_device(drm_dev)? else {
|
let Some((_dev_path, gbm)) = self.gbm_devices.gbm_device(drm_dev)? else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ use gbm_devices::GbmDevices;
|
||||||
mod screencopy;
|
mod screencopy;
|
||||||
use screencopy::{ScreencopySession, SessionData};
|
use screencopy::{ScreencopySession, SessionData};
|
||||||
mod toplevel;
|
mod toplevel;
|
||||||
|
mod vulkan;
|
||||||
mod workspace;
|
mod workspace;
|
||||||
|
|
||||||
use super::{CaptureFilter, CaptureImage, Cmd, Event};
|
use super::{CaptureFilter, CaptureImage, Cmd, Event};
|
||||||
|
|
@ -63,6 +64,7 @@ pub struct AppData {
|
||||||
dmabuf_feedback: Option<DmabufFeedback>,
|
dmabuf_feedback: Option<DmabufFeedback>,
|
||||||
gbm_devices: GbmDevices,
|
gbm_devices: GbmDevices,
|
||||||
thread_pool: futures_executor::ThreadPool,
|
thread_pool: futures_executor::ThreadPool,
|
||||||
|
vulkan: Option<vulkan::Vulkan>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppData {
|
impl AppData {
|
||||||
|
|
@ -308,6 +310,7 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
||||||
dmabuf_feedback: None,
|
dmabuf_feedback: None,
|
||||||
gbm_devices: GbmDevices::default(),
|
gbm_devices: GbmDevices::default(),
|
||||||
thread_pool,
|
thread_pool,
|
||||||
|
vulkan: vulkan::Vulkan::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (cmd_sender, cmd_channel) = calloop::channel::channel();
|
let (cmd_sender, cmd_channel) = calloop::channel::channel();
|
||||||
|
|
|
||||||
79
src/backend/wayland/vulkan.rs
Normal file
79
src/backend/wayland/vulkan.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
use ash::{prelude::VkResult, vk};
|
||||||
|
use std::{collections::HashMap, ffi::CStr};
|
||||||
|
|
||||||
|
pub struct Vulkan {
|
||||||
|
instance: ash::Instance,
|
||||||
|
// TODO purge cache at some point
|
||||||
|
device_name_cache: HashMap<u64, VkResult<Option<String>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vulkan {
|
||||||
|
pub fn new() -> Option<Self> {
|
||||||
|
let entry = unsafe { ash::Entry::load().ok()? };
|
||||||
|
let app_info = vk::ApplicationInfo {
|
||||||
|
api_version: vk::make_api_version(0, 1, 1, 0),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let create_info = vk::InstanceCreateInfo {
|
||||||
|
p_application_info: &app_info,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let instance = unsafe { entry.create_instance(&create_info, None).ok()? };
|
||||||
|
Some(Self {
|
||||||
|
instance,
|
||||||
|
device_name_cache: HashMap::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn device_name(&mut self, dev: u64) -> VkResult<Option<&str>> {
|
||||||
|
if !self.device_name_cache.contains_key(&dev) {
|
||||||
|
let value = self.device_name_uncached(dev);
|
||||||
|
self.device_name_cache.insert(dev, value);
|
||||||
|
}
|
||||||
|
self.device_name_cache
|
||||||
|
.get(&dev)
|
||||||
|
.unwrap()
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| x.as_deref())
|
||||||
|
.map_err(|err| err.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn device_name_uncached(&mut self, dev: u64) -> VkResult<Option<String>> {
|
||||||
|
let devices = unsafe { self.instance.enumerate_physical_devices()? };
|
||||||
|
for device in devices {
|
||||||
|
// Check extension is supported
|
||||||
|
let supported = unsafe {
|
||||||
|
self.instance
|
||||||
|
.enumerate_device_extension_properties(device)?
|
||||||
|
};
|
||||||
|
if !supported.iter().any(|ext| {
|
||||||
|
CStr::from_bytes_until_nul(bytemuck::cast_slice(&ext.extension_name))
|
||||||
|
== Ok(ash::ext::physical_device_drm::NAME)
|
||||||
|
}) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut drm_props = vk::PhysicalDeviceDrmPropertiesEXT::default();
|
||||||
|
let mut props = vk::PhysicalDeviceProperties2::default().push_next(&mut drm_props);
|
||||||
|
unsafe {
|
||||||
|
self.instance
|
||||||
|
.get_physical_device_properties2(device, &mut props)
|
||||||
|
};
|
||||||
|
|
||||||
|
let device_name =
|
||||||
|
CStr::from_bytes_until_nul(bytemuck::cast_slice(&props.properties.device_name));
|
||||||
|
|
||||||
|
let major = rustix::fs::major(dev) as _;
|
||||||
|
let minor = rustix::fs::minor(dev) as _;
|
||||||
|
if (drm_props.primary_major, drm_props.primary_minor) == (major, minor)
|
||||||
|
|| (drm_props.render_major, drm_props.render_minor) == (major, minor)
|
||||||
|
{
|
||||||
|
return Ok(device_name
|
||||||
|
.ok()
|
||||||
|
.and_then(|x| Some(x.to_str().ok()?.to_owned())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue