Skip to content

Commit 9968b0e

Browse files
committed
workaround: Force shm on Meteor/Arrow/Lunar Lake
1 parent b8780b9 commit 9968b0e

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ aliasable = "0.1.3"
3737
futures-executor = { version = "0.3.31", features = ["thread-pool"] }
3838
zbus = "5.9.0"
3939
tokio-stream = { version = "0.1.17", features = ["sync"] }
40+
ash = { version = "0.38.0", features = ["loaded"] }
41+
bytemuck = "1.23.2"
4042

4143
[dependencies.i18n-embed]
4244
version = "0.16"

src/backend/wayland/buffer.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ impl AppData {
9393
return Ok(None);
9494
};
9595
let drm_dev = drm_dev.unwrap_or(feedback.main_device() as u64);
96+
if let Some(vulkan) = &mut self.vulkan {
97+
if let Ok(Some(name)) = vulkan.device_name(drm_dev) {
98+
// TODO Workaround: force shm on Meteor/Arrow/Lunar Lake
99+
if name.contains("MTL") || name.contains("ARL") || name.contains("LNL") {
100+
return Ok(None);
101+
}
102+
}
103+
}
96104
let Some((_dev_path, gbm)) = self.gbm_devices.gbm_device(drm_dev)? else {
97105
return Ok(None);
98106
};

src/backend/wayland/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use gbm_devices::GbmDevices;
3939
mod screencopy;
4040
use screencopy::{ScreencopySession, SessionData};
4141
mod toplevel;
42+
mod vulkan;
4243
mod workspace;
4344

4445
use super::{CaptureFilter, CaptureImage, Cmd, Event};
@@ -63,6 +64,7 @@ pub struct AppData {
6364
dmabuf_feedback: Option<DmabufFeedback>,
6465
gbm_devices: GbmDevices,
6566
thread_pool: futures_executor::ThreadPool,
67+
vulkan: Option<vulkan::Vulkan>,
6668
}
6769

6870
impl AppData {
@@ -308,6 +310,7 @@ fn start(conn: Connection) -> mpsc::Receiver<Event> {
308310
dmabuf_feedback: None,
309311
gbm_devices: GbmDevices::default(),
310312
thread_pool,
313+
vulkan: vulkan::Vulkan::new(),
311314
};
312315

313316
let (cmd_sender, cmd_channel) = calloop::channel::channel();

src/backend/wayland/vulkan.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use ash::{prelude::VkResult, vk};
2+
use std::{collections::HashMap, ffi::CStr};
3+
4+
pub struct Vulkan {
5+
instance: ash::Instance,
6+
// TODO purge cache at some point
7+
device_name_cache: HashMap<u64, VkResult<Option<String>>>,
8+
}
9+
10+
impl Vulkan {
11+
pub fn new() -> Option<Self> {
12+
let entry = unsafe { ash::Entry::load().ok()? };
13+
let app_info = vk::ApplicationInfo {
14+
api_version: vk::make_api_version(0, 1, 1, 0),
15+
..Default::default()
16+
};
17+
let create_info = vk::InstanceCreateInfo {
18+
p_application_info: &app_info,
19+
..Default::default()
20+
};
21+
let instance = unsafe { entry.create_instance(&create_info, None).ok()? };
22+
Some(Self {
23+
instance,
24+
device_name_cache: HashMap::new(),
25+
})
26+
}
27+
28+
pub fn device_name(&mut self, dev: u64) -> VkResult<Option<&str>> {
29+
if !self.device_name_cache.contains_key(&dev) {
30+
let value = self.device_name_uncached(dev);
31+
self.device_name_cache.insert(dev, value);
32+
}
33+
self.device_name_cache
34+
.get(&dev)
35+
.unwrap()
36+
.as_ref()
37+
.map(|x| x.as_deref())
38+
.map_err(|err| err.clone())
39+
}
40+
41+
fn device_name_uncached(&mut self, dev: u64) -> VkResult<Option<String>> {
42+
let devices = unsafe { self.instance.enumerate_physical_devices()? };
43+
for device in devices {
44+
// Check extension is supported
45+
let supported = unsafe {
46+
self.instance
47+
.enumerate_device_extension_properties(device)?
48+
};
49+
if !supported.iter().any(|ext| {
50+
CStr::from_bytes_until_nul(bytemuck::cast_slice(&ext.extension_name))
51+
== Ok(ash::ext::physical_device_drm::NAME)
52+
}) {
53+
continue;
54+
}
55+
56+
let mut drm_props = vk::PhysicalDeviceDrmPropertiesEXT::default();
57+
let mut props = vk::PhysicalDeviceProperties2::default().push_next(&mut drm_props);
58+
unsafe {
59+
self.instance
60+
.get_physical_device_properties2(device, &mut props)
61+
};
62+
63+
let device_name =
64+
CStr::from_bytes_until_nul(bytemuck::cast_slice(&props.properties.device_name));
65+
66+
let major = rustix::fs::major(dev) as _;
67+
let minor = rustix::fs::minor(dev) as _;
68+
if (drm_props.primary_major, drm_props.primary_minor) == (major, minor)
69+
|| (drm_props.render_major, drm_props.render_minor) == (major, minor)
70+
{
71+
return Ok(device_name
72+
.ok()
73+
.and_then(|x| Some(x.to_str().ok()?.to_owned())));
74+
}
75+
}
76+
77+
Ok(None)
78+
}
79+
}

0 commit comments

Comments
 (0)