diff --git a/src/backend/kms/device.rs b/src/backend/kms/device.rs index 3d3dfc28..3c8665c7 100644 --- a/src/backend/kms/device.rs +++ b/src/backend/kms/device.rs @@ -95,6 +95,7 @@ pub struct Device { pub drm: GbmDrmOutputManager, supports_atomic: bool, + pub texture_formats: FormatSet, event_token: Option, pub socket: Option, } @@ -285,7 +286,7 @@ impl State { .with_context(|| format!("Failed to add drm device to event loop: {}", dev))?; let socket = match (!is_software) - .then(|| self.create_socket(dh, render_node, texture_formats)) + .then(|| self.create_socket(dh, render_node, texture_formats.clone())) .transpose() { Ok(socket) => socket, @@ -349,6 +350,7 @@ impl State { }, supports_atomic, + texture_formats, event_token: Some(token), socket, }; diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 3737901b..ae887c30 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -14,7 +14,7 @@ use indexmap::IndexMap; use render::gles::GbmGlowBackend; use smithay::{ backend::{ - allocator::{dmabuf::Dmabuf, format::FormatSet}, + allocator::{Buffer, dmabuf::Dmabuf, format::FormatSet}, drm::{DrmDeviceFd, DrmNode, NodeType, VrrSupport, output::DrmOutputRenderElements}, egl::{EGLContext, EGLDevice, EGLDisplay}, input::InputEvent, @@ -491,7 +491,7 @@ impl KmsState { global: &DmabufGlobal, dmabuf: Dmabuf, ) -> Result { - let device = self + let mut device = self .drm_devices .values_mut() .find(|device| { @@ -503,6 +503,21 @@ impl KmsState { }) .context("Couldn't find gpu for dmabuf global")?; + // If device advertised to client doesn't support format/modifier, select + // first device that does. This is needed for image-copy from + // output/toplevel on a different node. + // + // TODO: After + // https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/268, + // only try the device specified explicitly by the client, if set. + if !device.texture_formats.contains(&dmabuf.format()) { + device = self + .drm_devices + .values_mut() + .find(|device| device.texture_formats.contains(&dmabuf.format())) + .context("Dmabuf cannot be imported on any gpu")?; + } + let new_client = if let Some(client) = client { let new = device.inner.active_clients.insert(client.id()); device.inner.update_egl(