Skip to content

Commit

Permalink
compositor: Add code to extract adapter from x11
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Jul 16, 2024
1 parent fdb4e9a commit 4439c05
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
3 changes: 3 additions & 0 deletions wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ wayland-protocols.workspace = true
wayland-backend = { version = "0.3.3", features = ["client_system"] }
wayland-client = { version = "0.31.2" }
wayland-sys = { version = "0.31.1", features = ["dlopen"] }
as-raw-xcb-connection = "1.0.1"
tiny-xlib = "0.2.3"
x11rb = { version = "0.13.1", features = ["allow-unsafe-code", "dl-libxcb", "dri3"] }
2 changes: 2 additions & 0 deletions wgpu/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pub mod compositor;
#[cfg(all(unix, not(target_os = "macos")))]
mod wayland;
#[cfg(all(unix, not(target_os = "macos")))]
mod x11;

pub use compositor::Compositor;
pub use wgpu::Surface;
Expand Down
7 changes: 6 additions & 1 deletion wgpu/src/window/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::{Backend, Primitive, Renderer, Settings};

#[cfg(all(unix, not(target_os = "macos")))]
use super::wayland::get_wayland_device_ids;
#[cfg(all(unix, not(target_os = "macos")))]
use super::x11::get_x11_device_ids;

/// A window graphics backend for iced powered by `wgpu`.
#[allow(missing_debug_implementations)]
Expand All @@ -29,7 +31,10 @@ impl Compositor {
compatible_window: Option<W>,
) -> Option<Self> {
#[cfg(all(unix, not(target_os = "macos")))]
let ids = compatible_window.as_ref().and_then(get_wayland_device_ids);
let ids = compatible_window.as_ref().and_then(|window| {
get_wayland_device_ids(window)
.or_else(|| get_x11_device_ids(window))
});

// HACK:
// 1. If we specifically didn't select an nvidia gpu
Expand Down
77 changes: 77 additions & 0 deletions wgpu/src/window/x11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use as_raw_xcb_connection::AsRawXcbConnection;
use raw_window_handle::{
RawDisplayHandle, XcbDisplayHandle, XlibDisplayHandle,
};
use rustix::fs::{fstat, major, minor};
use tiny_xlib::Display;
use x11rb::{
connection::RequestConnection,
protocol::extensions::dri3::{

Check failure on line 9 in wgpu/src/window/x11.rs

View workflow job for this annotation

GitHub Actions / all

failed to resolve: could not find `extensions` in `protocol`
ConnectionExt as _, X11_EXTENSION_NAME as DRI3_NAME,
},
xcb_ffi::XCBConnection,
};

pub fn get_x11_device_ids<W: Window>(window: &W) -> Option<(u16, u16)> {

Check failure on line 15 in wgpu/src/window/x11.rs

View workflow job for this annotation

GitHub Actions / all

cannot find trait `Window` in this scope
x11rb::xcb_ffi::load_libxcb().ok()?;

let (conn, screen) = match window
.display_handle()
.map(|handle| handle.as_raw())
{
#[allow(unsafe_code)]
Ok(RawDisplayHandle::Xlib(XlibDisplayHandle {
display,
screen,
..
})) => match display {
Some(ptr) => unsafe {
let xlib_display =
tiny_xlib::Display::from_ptr(ptr.as_ptr()).ok()?;
let conn = XCBConnection::from_raw_xcb_connection(
xlib.as_raw_xcb_connection(),

Check failure on line 32 in wgpu/src/window/x11.rs

View workflow job for this annotation

GitHub Actions / all

cannot find value `xlib` in this scope
false,
)
.ok();
// intentially leak the display, we don't want to close the connection
std::mem::forget(xlib_display);

(conn?, screen)
},
None => (XCBConnection::connect(None), screen),
},
Ok(RawDisplayHandle::Xcb(XcbDisplayHandle {
connection,
screen,
..
})) => match connection {
Some(ptr) => (
unsafe {
XCBConnection::from_raw_xcb_connection(ptr.as_ptr(), false)
.ok()?
},
screen,
),
None => (XCBConnection::connect(None), screen),
},
_ => {
return None;
}
};

// check for DRI3
let _ = conn.extension_information(DRI3_NAME).ok()??;
// we have dri3, dri3_open exists on any version, so lets skip version checks.

// provider being NONE tells the X server to use the RandR provider.
let screen = &conn.setup().roots[screen];
let dri3 = connection

Check failure on line 68 in wgpu/src/window/x11.rs

View workflow job for this annotation

GitHub Actions / all

cannot find value `connection` in this scope
.dri3_open(screen.root, x11rb::NONE)?
.reply()
.ok()?;
let device_fd = dri3.device_fd;
let stat = fstat(file).ok()?;

Check failure on line 73 in wgpu/src/window/x11.rs

View workflow job for this annotation

GitHub Actions / all

expected value, found macro `file`
let dev = stat.st_rdev;

super::ids_from_dev(dev)
}

0 comments on commit 4439c05

Please sign in to comment.