backend: Don't attempt dma-copies from newer intel chips

This commit is contained in:
Victoria Brekenfeld 2026-06-29 17:31:44 +02:00 committed by Victoria Brekenfeld
parent ccc4f36065
commit bb584aab7f

View file

@ -1,21 +1,30 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use smithay::backend::{ use clap_lex::OsStrExt;
SwapBuffersError, use rustix::path::Arg;
allocator::{ use smithay::{
Allocator, backend::{
dmabuf::{AnyError, Dmabuf, DmabufAllocator}, SwapBuffersError,
gbm::GbmAllocator, allocator::{
}, Allocator,
drm::{CreateDrmNodeError, DrmNode}, dmabuf::{AnyError, Dmabuf, DmabufAllocator},
renderer::{ gbm::GbmAllocator,
RendererSuper, },
gles::{GlesError, GlesRenderer}, drm::{CreateDrmNodeError, DrmNode},
glow::GlowRenderer, renderer::{
multigpu::{ApiDevice, Error as MultiError, GraphicsApi}, RendererSuper,
gles::{GlesError, GlesRenderer, ffi},
glow::GlowRenderer,
multigpu::{ApiDevice, Error as MultiError, GraphicsApi},
},
}, },
reexports::drm::control::Device,
};
use std::{
borrow::{Borrow, BorrowMut},
cell::Cell,
ffi::{CStr, c_char},
}; };
use std::{borrow::Borrow, cell::Cell};
use std::{ use std::{
collections::HashMap, collections::HashMap,
fmt, fmt,
@ -98,7 +107,7 @@ impl<A: AsFd + Clone + Send + 'static> GbmGlowBackend<A> {
} }
} }
impl<A: AsFd + Clone + 'static> GraphicsApi for GbmGlowBackend<A> { impl<A: AsFd + Device + Clone + 'static> GraphicsApi for GbmGlowBackend<A> {
type Device = GbmGlowDevice; type Device = GbmGlowDevice;
type Error = Error; type Error = Error;
@ -123,11 +132,26 @@ impl<A: AsFd + Clone + 'static> GraphicsApi for GbmGlowBackend<A> {
.any(|renderer| renderer.node.dev_id() == node.dev_id()) .any(|renderer| renderer.node.dev_id() == node.dev_id())
}) })
.flat_map(|(node, (allocator, renderer))| { .flat_map(|(node, (allocator, renderer))| {
let renderer = renderer.replace(None)?; let mut renderer = renderer.replace(None)?;
let is_intel = allocator
.as_ref()
.get_driver()
.is_ok_and(|drv| drv.name().contains("i915"));
let intel_export_quirk = is_intel
&& BorrowMut::<GlesRenderer>::borrow_mut(&mut renderer)
.with_context(|gl| unsafe {
CStr::from_ptr(gl.GetString(ffi::RENDERER) as *const c_char)
})
.is_ok_and(|name| {
name.as_str().is_ok_and(|name| {
name.contains("MTL") || name.contains("ARL") || name.contains("LNL")
})
});
Some(GbmGlowDevice { Some(GbmGlowDevice {
node: *node, node: *node,
renderer, renderer,
intel_export_quirk,
allocator: Box::new(DmabufAllocator(allocator.clone())), allocator: Box::new(DmabufAllocator(allocator.clone())),
}) })
}) })
@ -150,6 +174,7 @@ impl<A: AsFd + Clone + 'static> GraphicsApi for GbmGlowBackend<A> {
pub struct GbmGlowDevice { pub struct GbmGlowDevice {
node: DrmNode, node: DrmNode,
renderer: GlowRenderer, renderer: GlowRenderer,
intel_export_quirk: bool,
allocator: Box<dyn Allocator<Buffer = Dmabuf, Error = AnyError>>, allocator: Box<dyn Allocator<Buffer = Dmabuf, Error = AnyError>>,
} }
@ -180,9 +205,14 @@ impl ApiDevice for GbmGlowDevice {
fn can_do_cross_device_imports(&self) -> bool { fn can_do_cross_device_imports(&self) -> bool {
!Borrow::<GlesRenderer>::borrow(&self.renderer).is_software() !Borrow::<GlesRenderer>::borrow(&self.renderer).is_software()
} }
fn should_do_cross_device_exports(&self) -> bool {
!self.intel_export_quirk
}
} }
impl<T: GraphicsApi, A: AsFd + Clone + 'static> FromGlesError for MultiError<GbmGlowBackend<A>, T> impl<T: GraphicsApi, A: AsFd + Device + Clone + 'static> FromGlesError
for MultiError<GbmGlowBackend<A>, T>
where where
T::Error: 'static, T::Error: 'static,
<<T::Device as ApiDevice>::Renderer as RendererSuper>::Error: 'static, <<T::Device as ApiDevice>::Renderer as RendererSuper>::Error: 'static,