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 = [
|
||||
"aliasable",
|
||||
"anyhow",
|
||||
"ash",
|
||||
"bytemuck",
|
||||
"calloop 0.14.3",
|
||||
"calloop-wayland-source 0.4.1",
|
||||
"clap",
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ aliasable = "0.1.3"
|
|||
futures-executor = { version = "0.3.31", features = ["thread-pool"] }
|
||||
zbus = "5.9.0"
|
||||
tokio-stream = { version = "0.1.17", features = ["sync"] }
|
||||
ash = { version = "0.38.0", features = ["loaded"] }
|
||||
bytemuck = "1.23.2"
|
||||
|
||||
[dependencies.i18n-embed]
|
||||
version = "0.16"
|
||||
|
|
|
|||
|
|
@ -93,6 +93,14 @@ impl AppData {
|
|||
return Ok(None);
|
||||
};
|
||||
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 {
|
||||
return Ok(None);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ use gbm_devices::GbmDevices;
|
|||
mod screencopy;
|
||||
use screencopy::{ScreencopySession, SessionData};
|
||||
mod toplevel;
|
||||
mod vulkan;
|
||||
mod workspace;
|
||||
|
||||
use super::{CaptureFilter, CaptureImage, Cmd, Event};
|
||||
|
|
@ -63,6 +64,7 @@ pub struct AppData {
|
|||
dmabuf_feedback: Option<DmabufFeedback>,
|
||||
gbm_devices: GbmDevices,
|
||||
thread_pool: futures_executor::ThreadPool,
|
||||
vulkan: Option<vulkan::Vulkan>,
|
||||
}
|
||||
|
||||
impl AppData {
|
||||
|
|
@ -308,6 +310,7 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
|
|||
dmabuf_feedback: None,
|
||||
gbm_devices: GbmDevices::default(),
|
||||
thread_pool,
|
||||
vulkan: vulkan::Vulkan::new(),
|
||||
};
|
||||
|
||||
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