From 53da1b0dc4995c08f84c5516f542729a394a61d6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 15:29:24 +0200 Subject: [PATCH 1/9] drivers/graphics/driver-graphics: Fix ioctl order --- drivers/graphics/driver-graphics/src/lib.rs | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 5652986b22..43c6b8d70a 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -929,6 +929,23 @@ impl SchemeSync for GraphicsSchemeInner { data.set_plane_id_ptr(&ids); Ok(0) }), + ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { + let i = id_index(data.plane_id()); + let crtc_id = self.objects.crtc_ids()[i as usize]; + let crtc = self.objects.get_crtc(crtc_id).unwrap(); + data.set_crtc_id(crtc_id.0); + data.set_fb_id( + crtc.lock() + .unwrap() + .state + .fb_id + .unwrap_or(KmsObjectId::INVALID) + .0, + ); + data.set_possible_crtcs(1 << i); + data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); + Ok(0) + }), ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { // FIXME handle multi-plane framebuffers @@ -950,23 +967,6 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), - ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { - let i = id_index(data.plane_id()); - let crtc_id = self.objects.crtc_ids()[i as usize]; - let crtc = self.objects.get_crtc(crtc_id).unwrap(); - data.set_crtc_id(crtc_id.0); - data.set_fb_id( - crtc.lock() - .unwrap() - .state - .fb_id - .unwrap_or(KmsObjectId::INVALID) - .0, - ); - data.set_possible_crtcs(1 << i); - data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); - Ok(0) - }), ipc::MODE_OBJ_GET_PROPERTIES => { ipc::DrmModeObjGetProperties::with(payload, |mut data| { // FIXME remove once all drm objects are materialized in self.objects From 835be6f654d35b18732e0e9263bf97f93484234e Mon Sep 17 00:00:00 2001 From: Meijlen Date: Thu, 14 May 2026 15:19:29 +0200 Subject: [PATCH 2/9] drivers/graphics: Implement support for planes --- .../driver-graphics/src/kms/objects.rs | 103 ++++++++++++++- .../driver-graphics/src/kms/properties.rs | 1 + drivers/graphics/driver-graphics/src/lib.rs | 118 ++++++++++++++++-- drivers/graphics/ihdgd/src/device/mod.rs | 13 +- drivers/graphics/ihdgd/src/device/scheme.rs | 42 +++++-- drivers/graphics/vesad/src/scheme.rs | 28 ++++- drivers/graphics/virtio-gpud/src/scheme.rs | 30 ++++- 7 files changed, 304 insertions(+), 31 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 805cea1386..f9a3682553 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex}; use drm_fourcc::DrmFourcc; use drm_sys::{ drm_mode_modeinfo, DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_CRTC, - DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PROPERTY, + DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PLANE, DRM_MODE_OBJECT_PROPERTY, }; use syscall::{Error, Result, ENOENT}; @@ -23,6 +23,7 @@ pub struct KmsObjects { pub(super) encoders: Vec, crtcs: Vec, framebuffers: Vec, + planes: Vec, pub(super) objects: HashMap>, _marker: PhantomData, } @@ -35,6 +36,7 @@ impl KmsObjects { encoders: vec![], crtcs: vec![], framebuffers: vec![], + planes: vec![], objects: HashMap::new(), _marker: PhantomData, }; @@ -129,6 +131,52 @@ impl KmsObjects { pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer> { self.get(id) } + + pub fn add_plane( + &mut self, + crtcs: &[KmsObjectId], + plane_type: KmsPlaneType, + driver_data: T::Plane, + driver_data_state: ::State, + ) -> KmsObjectId { + let mut possible_crtcs = 0u32; + for &crtc in crtcs { + possible_crtcs |= 1 << self.get_crtc(crtc).unwrap().lock().unwrap().crtc_index + } + let id = self.add(Mutex::new(KmsPlane { + possible_crtcs, + plane_type, + state: KmsPlaneState { + fb_id: None, + crtc_id: None, + src_rect: KmsRect { + x: 0u32, + y: 0, + width: 0, + height: 0, + }, + crtc_rect: KmsRect { + x: 0i32, + y: 0, + width: 0, + height: 0, + }, + driver_data: driver_data_state, + }, + driver_data, + })); + self.planes.push(id); + + id + } + + pub fn plane_ids(&self) -> &[KmsObjectId] { + &self.planes + } + + pub fn get_plane(&self, id: KmsObjectId) -> Result<&Mutex>> { + self.get(id) + } } #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -188,6 +236,7 @@ define_object_kinds! { Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER, Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY, + Plane(Mutex>) = DRM_MODE_OBJECT_PLANE, Framebuffer(KmsFramebuffer) = DRM_MODE_OBJECT_FB, Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB, } @@ -241,3 +290,55 @@ pub struct KmsFramebuffer { pub buffer: Arc, pub driver_data: T::Framebuffer, } + +pub trait KmsPlaneDriver: Debug { + type State: Clone + Debug; +} + +impl KmsPlaneDriver for () { + type State = (); +} + +#[derive(Debug)] +pub struct KmsPlane { + pub possible_crtcs: u32, + pub plane_type: KmsPlaneType, + pub state: KmsPlaneState, + pub driver_data: T::Plane, +} + +#[derive(Debug)] +pub struct KmsPlaneState { + pub fb_id: Option, + pub crtc_id: Option, + pub src_rect: KmsRect, + pub crtc_rect: KmsRect, + pub driver_data: ::State, +} + +impl Clone for KmsPlaneState { + fn clone(&self) -> Self { + Self { + fb_id: self.fb_id.clone(), + crtc_id: self.crtc_id.clone(), + src_rect: self.src_rect.clone(), + crtc_rect: self.crtc_rect.clone(), + driver_data: self.driver_data.clone(), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum KmsPlaneType { + Primary, + Overlay, + Cursor, +} + +#[derive(Debug, Clone)] +pub struct KmsRect { + pub x: T, + pub y: T, + pub width: u32, + pub height: u32, +} diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index 3a0e8bc5fc..bcd16005c7 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -70,6 +70,7 @@ impl KmsObjects { .unzip()) } KmsObject::Encoder(_) + | KmsObject::Plane(_) | KmsObject::Property(_) | KmsObject::Framebuffer(_) | KmsObject::Blob(_) => Ok((vec![], vec![])), diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 43c6b8d70a..9e72d66925 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -24,7 +24,10 @@ use syscall::schemev2::NewFdFlags; use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, ENXIO, EOPNOTSUPP}; use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState}; -use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects}; +use crate::kms::objects::{ + self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver, + KmsPlaneState, KmsPlaneType, KmsRect, +}; use crate::kms::properties::KmsPropertyKind; pub mod kms; @@ -83,6 +86,8 @@ pub trait GraphicsAdapter: Sized + Debug { type Connector: KmsConnectorDriver; type Crtc: KmsCrtcDriver; + type Plane: KmsPlaneDriver; + type Buffer: Buffer; type Framebuffer: Framebuffer; @@ -110,6 +115,15 @@ pub trait GraphicsAdapter: Sized + Debug { damage: Damage, ) -> syscall::Result<()>; + fn set_plane( + &mut self, + objects: &KmsObjects, + crtc: &Mutex>, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + damage: Damage, + ) -> syscall::Result<()>; + // FIXME replace this with an actual plane marked as cursor plane once we // support planes internally. fn has_cursor_plane(&self) -> bool; @@ -590,7 +604,8 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| { - let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?; + let crtc_id = KmsObjectId(data.crtc_id()); + let crtc = self.objects.get_crtc(crtc_id)?; let connector_ids: Vec = data .set_connectors_ptr() .iter() @@ -607,14 +622,44 @@ impl SchemeSync for GraphicsSchemeInner { } else { None }; - let mut new_state = crtc.lock().unwrap().state.clone(); - new_state.fb_id = fb_id; - new_state.mode = mode; + + let primary_plane_id = self + .objects + .plane_ids() + .iter() + .copied() + .find(|&pid| { + let plane = self.objects.get_plane(pid).unwrap().lock().unwrap(); + plane.plane_type == KmsPlaneType::Primary + && (plane.state.crtc_id == Some(crtc_id) + || plane.possible_crtcs + & (1 << crtc.lock().unwrap().crtc_index) + != 0) + }) + .ok_or(Error::new(EINVAL))?; + let plane = self.objects.get_plane(primary_plane_id)?; + let mut new_crtc_state = crtc.lock().unwrap().state.clone(); + new_crtc_state.mode = mode; + let mut new_plane_state = plane.lock().unwrap().state.clone(); + new_plane_state.fb_id = fb_id; + new_plane_state.crtc_id = Some(crtc_id); if *vt == self.active_vt { self.adapter.set_crtc( &self.objects, crtc, - new_state.clone(), + new_crtc_state.clone(), + Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }, + )?; + self.adapter.set_plane( + &self.objects, + crtc, + plane, + new_plane_state.clone(), Damage { x: data.x(), y: data.y(), @@ -622,18 +667,19 @@ impl SchemeSync for GraphicsSchemeInner { height: mode.map_or(0, |m| m.vdisplay as u32), }, )?; - for connector in connector_ids { self.objects .get_connector(connector)? .lock() .unwrap() .state - .crtc_id = KmsObjectId(data.crtc_id()); + .crtc_id = crtc_id } } + crtc.lock().unwrap().state = new_crtc_state.clone(); + plane.lock().unwrap().state = new_plane_state.clone(); self.vts.get_mut(vt).unwrap().crtc_state - [crtc.lock().unwrap().crtc_index as usize] = new_state; + [crtc.lock().unwrap().crtc_index as usize] = new_crtc_state; Ok(0) }), ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| { @@ -929,6 +975,60 @@ impl SchemeSync for GraphicsSchemeInner { data.set_plane_id_ptr(&ids); Ok(0) }), + ipc::MODE_SET_PLANE => ipc::DrmModeSetPlane::with(payload, |data| { + let plane_id = KmsObjectId(data.plane_id()); + let plane_mutex = self.objects.get_plane(plane_id)?; + + let crtc_id = KmsObjectId(data.crtc_id()); + let crtc = self.objects.get_crtc(crtc_id)?; + let crtc_index = crtc.lock().unwrap().crtc_index; + + let new_state; + { + let mut plane = plane_mutex.lock().unwrap(); + if plane.possible_crtcs & (1 << crtc_index) == 0 { + return Err(Error::new(EINVAL)); + } + let fb_id = if data.fb_id() != 0 { + KmsObjectId(data.fb_id()) + } else { + KmsObjectId::INVALID + }; + let mut state = plane.state.clone(); + state.fb_id = Some(fb_id); + state.crtc_id = Some(crtc_id); + state.src_rect = KmsRect { + x: data.src_x(), + y: data.src_y(), + width: data.src_w(), + height: data.src_h(), + }; + state.crtc_rect = KmsRect { + x: data.crtc_x() as i32, + y: data.crtc_y() as i32, + width: data.crtc_w(), + height: data.crtc_h(), + }; + plane.state = state.clone(); + new_state = state; + } + + if *vt == self.active_vt { + self.adapter.set_plane( + &self.objects, + crtc, + plane_mutex, + new_state, + Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }, + )?; + } + Ok(0) + }), ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { let i = id_index(data.plane_id()); let crtc_id = self.objects.crtc_ids()[i as usize]; diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index 607dcea0ab..4ed77eae55 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -451,13 +451,16 @@ impl Device { fn add_kms_pipe(objects: &mut KmsObjects, pipe_idx: usize, fb: KmsFramebuffer) { let crtc_id = objects.add_crtc(Crtc { pipe_idx }, ()); - let connector_id = objects.add_connector((), (), &[crtc_id]); - let mut connector = objects.get_connector(connector_id).unwrap().lock().unwrap(); - connector.connection = KmsConnectorStatus::Connected; - connector.update_from_size(fb.width, fb.height); - drop(connector); + let (width, height) = (fb.width, fb.height); let fb_id = objects.add_framebuffer(fb); + + let connector_id = objects.add_connector(Connector { fb_id: Some(fb_id) }, (), &[crtc_id]); + let mut connector = objects.get_connector(connector_id).unwrap().lock().unwrap(); + connector.connection = KmsConnectorStatus::Connected; + connector.update_from_size(width, height); + drop(connector); + objects .get_crtc(crtc_id) .unwrap() diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index eaa17f2764..d746e725aa 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -1,8 +1,8 @@ use std::sync::Mutex; -use driver_graphics::kms::connector::KmsConnectorStatus; +use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; use driver_graphics::kms::objects::{ - KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, + KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, }; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{ @@ -19,10 +19,19 @@ pub struct Crtc { pub pipe_idx: usize, } +#[derive(Debug)] +pub struct Connector { + pub fb_id: Option, +} + impl KmsCrtcDriver for Crtc { type State = (); } +impl KmsConnectorDriver for Connector { + type State = (); +} + impl Buffer for GpuBuffer { fn size(&self) -> usize { self.size as usize @@ -30,12 +39,14 @@ impl Buffer for GpuBuffer { } impl GraphicsAdapter for Device { - type Connector = (); + type Connector = Connector; type Crtc = Crtc; type Buffer = GpuBuffer; type Framebuffer = (); + type Plane = (); + fn name(&self) -> &'static [u8] { b"ihdgd" } @@ -95,14 +106,31 @@ impl GraphicsAdapter for Device { _damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); - let fb = state + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + crtc: &Mutex>, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + damage: Damage, + ) -> syscall::Result<()> { + let crtc = crtc.lock().unwrap(); + let mut plane = plane.lock().unwrap(); + + let buffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; - if let Some(primary_plane) = self.pipes[crtc.driver_data.pipe_idx].planes.first_mut() { - primary_plane.set_framebuffer(fb); + plane.state = new_plane_state; + + let pipe_idx = crtc.driver_data.pipe_idx; + if let Some(plane_hw) = self.pipes[pipe_idx].planes.first_mut() { + plane_hw.set_framebuffer(buffer); } Ok(()) diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index daa9908855..0d9c864044 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -4,7 +4,9 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{ + KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, +}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{ DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH, DRM_CAP_DUMB_PREFER_SHADOW, @@ -35,6 +37,8 @@ impl GraphicsAdapter for FbAdapter { type Buffer = GraphicScreen; type Framebuffer = (); + type Plane = (); + fn name(&self) -> &'static [u8] { b"vesad" } @@ -109,11 +113,27 @@ impl GraphicsAdapter for FbAdapter { damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); - let buffer = state + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + crtc: &Mutex>, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + damage: Damage, + ) -> syscall::Result<()> { + let mut crtc = crtc.lock().unwrap(); + let mut plane = plane.lock().unwrap(); + + let buffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; + + plane.state = new_plane_state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); @@ -128,7 +148,7 @@ impl GraphicsAdapter for FbAdapter { if let Some(buffer) = buffer { buffer.buffer.sync(framebuffer, damage) } else { - let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable + let onscreen_ptr = framebuffer.onscreen as *mut u32; for row in 0..framebuffer.height { unsafe { ptr::write_bytes( diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index e855eb704e..f7f6360777 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -3,7 +3,9 @@ use std::sync::{Arc, Mutex}; use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{ + KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, +}; use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme}; use drm_sys::{ DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH, @@ -345,6 +347,8 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { type Buffer = VirtGpuFramebuffer<'a>; type Framebuffer = (); + type Plane = (); + fn name(&self) -> &'static [u8] { b"virtio-gpud" } @@ -428,14 +432,31 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { crtc: &Mutex>, state: KmsCrtcState, damage: Damage, + ) -> syscall::Result<()> { + let mut crtc = crtc.lock().unwrap(); + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + crtc: &Mutex>, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + damage: Damage, ) -> syscall::Result<()> { futures::executor::block_on(async { - let mut crtc = crtc.lock().unwrap(); - let framebuffer = state + let crtc = crtc.lock().unwrap(); + let mut plane = plane.lock().unwrap(); + + // fb_id now in plane state + let framebuffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; + + plane.state = new_plane_state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); @@ -473,7 +494,6 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { let header = self.send_request(req).await.unwrap(); assert_eq!(header.ty, CommandTy::RespOkNodata); - // FIXME once we support resizing we also need to check that the current and target size match if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) { let scanout_request = Dma::new(SetScanout::new( From 76d63984731be0d0195fa12d81349ecddeff8a1f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 15:28:49 +0200 Subject: [PATCH 3/9] drivers/graphics/driver-graphics: Add primary plane for every CRTC --- .../graphics/driver-graphics/src/kms/objects.rs | 13 +++++++++++++ drivers/graphics/driver-graphics/src/lib.rs | 17 ++--------------- drivers/graphics/ihdgd/src/device/mod.rs | 2 +- drivers/graphics/vesad/src/scheme.rs | 2 +- drivers/graphics/virtio-gpud/src/scheme.rs | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index f9a3682553..329ca16710 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -82,12 +82,22 @@ impl KmsObjects { &mut self, driver_data: T::Crtc, driver_data_state: ::State, + plane_data: T::Plane, + plane_data_state: ::State, ) -> KmsObjectId { + let primary_plane = self.add_plane( + &[], + KmsPlaneType::Primary, + plane_data, + plane_data_state, + ); + let crtc_index = self.crtcs.len() as u32; let id = self.add(Mutex::new(KmsCrtc { crtc_index, gamma_size: 0, properties: KmsCrtc::base_properties(), + primary_plane, state: KmsCrtcState { fb_id: None, mode: None, @@ -97,6 +107,8 @@ impl KmsObjects { })); self.crtcs.push(id); + self.get_plane(primary_plane).unwrap().lock().unwrap().possible_crtcs = 1 << crtc_index; + id } @@ -254,6 +266,7 @@ pub struct KmsCrtc { pub crtc_index: u32, pub gamma_size: u32, pub properties: Vec>, + pub primary_plane: KmsObjectId, pub state: KmsCrtcState, pub driver_data: T::Crtc, } diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 9e72d66925..6a3357594c 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -26,7 +26,7 @@ use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, ENXIO, EO use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState}; use crate::kms::objects::{ self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver, - KmsPlaneState, KmsPlaneType, KmsRect, + KmsPlaneState, KmsRect, }; use crate::kms::properties::KmsPropertyKind; @@ -623,20 +623,7 @@ impl SchemeSync for GraphicsSchemeInner { None }; - let primary_plane_id = self - .objects - .plane_ids() - .iter() - .copied() - .find(|&pid| { - let plane = self.objects.get_plane(pid).unwrap().lock().unwrap(); - plane.plane_type == KmsPlaneType::Primary - && (plane.state.crtc_id == Some(crtc_id) - || plane.possible_crtcs - & (1 << crtc.lock().unwrap().crtc_index) - != 0) - }) - .ok_or(Error::new(EINVAL))?; + let primary_plane_id = crtc.lock().unwrap().primary_plane; let plane = self.objects.get_plane(primary_plane_id)?; let mut new_crtc_state = crtc.lock().unwrap().state.clone(); new_crtc_state.mode = mode; diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index 4ed77eae55..eb3ff9723f 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -449,7 +449,7 @@ impl Device { } fn add_kms_pipe(objects: &mut KmsObjects, pipe_idx: usize, fb: KmsFramebuffer) { - let crtc_id = objects.add_crtc(Crtc { pipe_idx }, ()); + let crtc_id = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); let (width, height) = (fb.width, fb.height); diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 0d9c864044..c8bab6d81f 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -49,7 +49,7 @@ impl GraphicsAdapter for FbAdapter { fn init(&mut self, objects: &mut KmsObjects) { for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() { - let crtc = objects.add_crtc((), ()); + let crtc = objects.add_crtc((), (), (), ()); objects.add_connector( Connector { diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index f7f6360777..de1f86d766 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -363,7 +363,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }); for display_id in 0..self.config.num_scanouts.get() { - let crtc = objects.add_crtc((), ()); + let crtc = objects.add_crtc((), (), (), ()); objects.add_connector(VirtGpuConnector { display_id }, (), &[crtc]); } From ab8bfb9d5d3a8853b6ad87fc18a3d64a9bba3d90 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 15:33:17 +0200 Subject: [PATCH 4/9] drivers/graphics/driver-graphics: Report actual planes from MODE_GET_PLANE --- drivers/graphics/driver-graphics/src/lib.rs | 41 ++++++++------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 6a3357594c..137d6d10ca 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -474,14 +474,6 @@ impl SchemeSync for GraphicsSchemeInner { ) -> Result { use redox_ioctl::drm as ipc; - fn id_index(id: u32) -> u32 { - id & 0xFF - } - - fn plane_id(i: u32) -> u32 { - id_index(i) | (1 << 13) - } - match self.handles.get_mut(id)? { Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)), Handle::V2 { @@ -954,11 +946,12 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| { - let count = self.objects.crtc_ids().len(); - let mut ids = Vec::with_capacity(count); - for i in 0..(count as u32) { - ids.push(plane_id(i)); - } + let ids = self + .objects + .plane_ids() + .iter() + .map(|id| id.0) + .collect::>(); data.set_plane_id_ptr(&ids); Ok(0) }), @@ -1017,19 +1010,15 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { - let i = id_index(data.plane_id()); - let crtc_id = self.objects.crtc_ids()[i as usize]; - let crtc = self.objects.get_crtc(crtc_id).unwrap(); - data.set_crtc_id(crtc_id.0); - data.set_fb_id( - crtc.lock() - .unwrap() - .state - .fb_id - .unwrap_or(KmsObjectId::INVALID) - .0, - ); - data.set_possible_crtcs(1 << i); + let plane = self + .objects + .get_plane(KmsObjectId(data.plane_id())) + .unwrap() + .lock() + .unwrap(); + data.set_crtc_id(plane.state.crtc_id.map_or(0, |id| id.0)); + data.set_fb_id(plane.state.fb_id.unwrap_or(KmsObjectId::INVALID).0); + data.set_possible_crtcs(plane.possible_crtcs); data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); Ok(0) }), From 0ee128ad8d10f9f83acebd5f1f5e59f55a83cec8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 15:49:57 +0200 Subject: [PATCH 5/9] drivers/graphics: Make everything work --- .../driver-graphics/src/kms/objects.rs | 30 +++-- drivers/graphics/driver-graphics/src/lib.rs | 103 ++++++++++-------- drivers/graphics/ihdgd/src/device/mod.rs | 4 +- drivers/graphics/ihdgd/src/device/scheme.rs | 11 +- drivers/graphics/vesad/src/scheme.rs | 11 +- drivers/graphics/virtio-gpud/src/scheme.rs | 11 +- 6 files changed, 96 insertions(+), 74 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 329ca16710..91ecc8c362 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -84,13 +84,9 @@ impl KmsObjects { driver_data_state: ::State, plane_data: T::Plane, plane_data_state: ::State, - ) -> KmsObjectId { - let primary_plane = self.add_plane( - &[], - KmsPlaneType::Primary, - plane_data, - plane_data_state, - ); + ) -> (KmsObjectId, KmsObjectId) { + let primary_plane = + self.add_plane(&[], KmsPlaneType::Primary, plane_data, plane_data_state); let crtc_index = self.crtcs.len() as u32; let id = self.add(Mutex::new(KmsCrtc { @@ -99,7 +95,6 @@ impl KmsObjects { properties: KmsCrtc::base_properties(), primary_plane, state: KmsCrtcState { - fb_id: None, mode: None, driver_data: driver_data_state, }, @@ -107,9 +102,13 @@ impl KmsObjects { })); self.crtcs.push(id); - self.get_plane(primary_plane).unwrap().lock().unwrap().possible_crtcs = 1 << crtc_index; + self.get_plane(primary_plane) + .unwrap() + .lock() + .unwrap() + .possible_crtcs = 1 << crtc_index; - id + (id, primary_plane) } pub fn crtc_ids(&self) -> &[KmsObjectId] { @@ -155,7 +154,9 @@ impl KmsObjects { for &crtc in crtcs { possible_crtcs |= 1 << self.get_crtc(crtc).unwrap().lock().unwrap().crtc_index } + let plane_index = self.planes.len() as u32; let id = self.add(Mutex::new(KmsPlane { + plane_index, possible_crtcs, plane_type, state: KmsPlaneState { @@ -186,6 +187,12 @@ impl KmsObjects { &self.planes } + pub fn planes(&self) -> impl Iterator>> + use<'_, T> { + self.planes + .iter() + .map(|&id| self.get::>>(id).unwrap()) + } + pub fn get_plane(&self, id: KmsObjectId) -> Result<&Mutex>> { self.get(id) } @@ -273,7 +280,6 @@ pub struct KmsCrtc { #[derive(Debug)] pub struct KmsCrtcState { - pub fb_id: Option, pub mode: Option, pub driver_data: ::State, } @@ -281,7 +287,6 @@ pub struct KmsCrtcState { impl Clone for KmsCrtcState { fn clone(&self) -> Self { Self { - fb_id: self.fb_id.clone(), mode: self.mode.clone(), driver_data: self.driver_data.clone(), } @@ -314,6 +319,7 @@ impl KmsPlaneDriver for () { #[derive(Debug)] pub struct KmsPlane { + pub plane_index: u32, pub possible_crtcs: u32, pub plane_type: KmsPlaneType, pub state: KmsPlaneState, diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 137d6d10ca..5a191f28f8 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -112,13 +112,11 @@ pub trait GraphicsAdapter: Sized + Debug { objects: &KmsObjects, crtc: &Mutex>, new_state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()>; fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, @@ -291,6 +289,7 @@ struct GraphicsSchemeInner { struct VtState { connector_state: Vec>, crtc_state: Vec>, + plane_state: Vec>, cursor_plane: Option>, } @@ -320,6 +319,10 @@ impl GraphicsSchemeInner { .crtcs() .map(|crtc| crtc.lock().unwrap().state.clone()) .collect(), + plane_state: objects + .planes() + .map(|plane| plane.lock().unwrap().state.clone()) + .collect(), cursor_plane: adapter.has_cursor_plane().then(|| CursorPlane { x: 0, y: 0, @@ -362,24 +365,8 @@ impl GraphicsSchemeInner { let crtc = self.objects.get_crtc(crtc_id).unwrap(); let connector_id = self.objects.connector_ids()[crtc_idx]; - let fb = crtc_state.fb_id.map(|fb_id| { - self.objects - .get_framebuffer(fb_id) - .expect("removed framebuffers should be unset") - }); - self.adapter - .set_crtc( - &self.objects, - crtc, - crtc_state.clone(), - Damage { - x: 0, - y: 0, - width: fb.map_or(0, |fb| fb.width), - height: fb.map_or(0, |fb| fb.height), - }, - ) + .set_crtc(&self.objects, crtc, crtc_state.clone()) .unwrap(); self.objects @@ -391,6 +378,31 @@ impl GraphicsSchemeInner { .crtc_id = crtc_id; } + for (plane_idx, plane_state) in vt_state.plane_state.iter().enumerate() { + let plane_id = self.objects.plane_ids()[plane_idx]; + let plane = self.objects.get_plane(plane_id).unwrap(); + + let fb = plane_state.fb_id.map(|fb_id| { + self.objects + .get_framebuffer(fb_id) + .expect("removed framebuffers should be unset") + }); + + self.adapter + .set_plane( + &self.objects, + plane, + plane_state.clone(), + Damage { + x: 0, + y: 0, + width: fb.map_or(0, |fb| fb.width), + height: fb.map_or(0, |fb| fb.height), + }, + ) + .unwrap(); + } + if let Some(cursor_plane) = &vt_state.cursor_plane { self.adapter.handle_cursor(cursor_plane, true); } @@ -581,7 +593,17 @@ impl SchemeSync for GraphicsSchemeInner { .lock() .unwrap(); // Don't touch set_connectors, that is only used by MODE_SET_CRTC - data.set_fb_id(crtc.state.fb_id.unwrap_or(KmsObjectId::INVALID).0); + data.set_fb_id( + self.objects + .get_plane(crtc.primary_plane) + .unwrap() + .lock() + .unwrap() + .state + .fb_id + .unwrap_or(KmsObjectId::INVALID) + .0, + ); // FIXME fill x and y with the data from the primary plane data.set_x(0); data.set_y(0); @@ -623,20 +645,10 @@ impl SchemeSync for GraphicsSchemeInner { new_plane_state.fb_id = fb_id; new_plane_state.crtc_id = Some(crtc_id); if *vt == self.active_vt { - self.adapter.set_crtc( - &self.objects, - crtc, - new_crtc_state.clone(), - Damage { - x: 0, - y: 0, - width: 0, - height: 0, - }, - )?; + self.adapter + .set_crtc(&self.objects, crtc, new_crtc_state.clone())?; self.adapter.set_plane( &self.objects, - crtc, plane, new_plane_state.clone(), Damage { @@ -659,6 +671,8 @@ impl SchemeSync for GraphicsSchemeInner { plane.lock().unwrap().state = new_plane_state.clone(); self.vts.get_mut(vt).unwrap().crtc_state [crtc.lock().unwrap().crtc_index as usize] = new_crtc_state; + self.vts.get_mut(vt).unwrap().plane_state + [plane.lock().unwrap().plane_index as usize] = new_plane_state; Ok(0) }), ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| { @@ -846,21 +860,21 @@ impl SchemeSync for GraphicsSchemeInner { // Disable planes that use this framebuffer. for (vt, vt_data) in &mut self.vts { - for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() { - if crtc_state.fb_id != Some(fb_id) { + for (plane_idx, plane_state) in vt_data.plane_state.iter_mut().enumerate() { + if plane_state.fb_id != Some(fb_id) { continue; } - crtc_state.fb_id = None; + plane_state.fb_id = None; if *vt != self.active_vt { continue; } - let crtc = self.objects.crtcs().nth(crtc_idx).unwrap(); + let plane = self.objects.planes().nth(plane_idx).unwrap(); self.adapter - .set_crtc( + .set_plane( &self.objects, - crtc, - crtc_state.clone(), + plane, + plane_state.clone(), Damage { x: 0, y: 0, @@ -895,10 +909,11 @@ impl SchemeSync for GraphicsSchemeInner { }); if *vt == self.active_vt { - for crtc in self.objects.crtcs() { - let state = crtc.lock().unwrap().state.clone(); + for plane in self.objects.planes() { + let state = plane.lock().unwrap().state.clone(); if state.fb_id == Some(KmsObjectId(data.fb_id())) { - self.adapter.set_crtc(&self.objects, crtc, state, damage)?; + self.adapter + .set_plane(&self.objects, plane, state, damage)?; } } } @@ -960,8 +975,7 @@ impl SchemeSync for GraphicsSchemeInner { let plane_mutex = self.objects.get_plane(plane_id)?; let crtc_id = KmsObjectId(data.crtc_id()); - let crtc = self.objects.get_crtc(crtc_id)?; - let crtc_index = crtc.lock().unwrap().crtc_index; + let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index; let new_state; { @@ -996,7 +1010,6 @@ impl SchemeSync for GraphicsSchemeInner { if *vt == self.active_vt { self.adapter.set_plane( &self.objects, - crtc, plane_mutex, new_state, Damage { diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index eb3ff9723f..f1845c40b5 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -449,7 +449,7 @@ impl Device { } fn add_kms_pipe(objects: &mut KmsObjects, pipe_idx: usize, fb: KmsFramebuffer) { - let crtc_id = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); + let (crtc_id, primary_plane_id) = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); let (width, height) = (fb.width, fb.height); @@ -462,7 +462,7 @@ impl Device { drop(connector); objects - .get_crtc(crtc_id) + .get_plane(primary_plane_id) .unwrap() .lock() .unwrap() diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index d746e725aa..a02e2b71b3 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -100,10 +100,9 @@ impl GraphicsAdapter for Device { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - _damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -113,12 +112,14 @@ impl GraphicsAdapter for Device { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, - damage: Damage, + _damage: Damage, ) -> syscall::Result<()> { - let crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); let buffer = new_plane_state diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index c8bab6d81f..50eb113d05 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -49,7 +49,7 @@ impl GraphicsAdapter for FbAdapter { fn init(&mut self, objects: &mut KmsObjects) { for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() { - let crtc = objects.add_crtc((), (), (), ()); + let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ()); objects.add_connector( Connector { @@ -107,10 +107,9 @@ impl GraphicsAdapter for FbAdapter { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -120,12 +119,14 @@ impl GraphicsAdapter for FbAdapter { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()> { - let mut crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); let buffer = new_plane_state diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index de1f86d766..a1f45429e7 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -363,7 +363,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }); for display_id in 0..self.config.num_scanouts.get() { - let crtc = objects.add_crtc((), (), (), ()); + let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ()); objects.add_connector(VirtGpuConnector { display_id }, (), &[crtc]); } @@ -428,10 +428,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -441,13 +440,15 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()> { futures::executor::block_on(async { - let crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); // fb_id now in plane state From 5d6faacfb37a91d280280c16d6695df1ecfbdd26 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 16:00:30 +0200 Subject: [PATCH 6/9] drivers/graphics/driver-graphics: Couple of fixups --- .../driver-graphics/src/kms/objects.rs | 60 +++++++++---------- drivers/graphics/driver-graphics/src/lib.rs | 58 +++++++++--------- drivers/graphics/ihdgd/src/device/scheme.rs | 3 +- drivers/graphics/vesad/src/scheme.rs | 2 +- drivers/graphics/virtio-gpud/src/scheme.rs | 3 +- 5 files changed, 61 insertions(+), 65 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 91ecc8c362..a56c587f8d 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -22,8 +22,8 @@ pub struct KmsObjects { pub(super) connectors: Vec, pub(super) encoders: Vec, crtcs: Vec, - framebuffers: Vec, planes: Vec, + framebuffers: Vec, pub(super) objects: HashMap>, _marker: PhantomData, } @@ -35,8 +35,8 @@ impl KmsObjects { connectors: vec![], encoders: vec![], crtcs: vec![], - framebuffers: vec![], planes: vec![], + framebuffers: vec![], objects: HashMap::new(), _marker: PhantomData, }; @@ -125,24 +125,6 @@ impl KmsObjects { self.get(id) } - pub fn add_framebuffer(&mut self, fb: KmsFramebuffer) -> KmsObjectId { - let id = self.add(fb); - self.framebuffers.push(id); - id - } - - pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> { - self.remove::>(id) - } - - pub fn fb_ids(&self) -> &[KmsObjectId] { - &self.framebuffers - } - - pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer> { - self.get(id) - } - pub fn add_plane( &mut self, crtcs: &[KmsObjectId], @@ -196,6 +178,24 @@ impl KmsObjects { pub fn get_plane(&self, id: KmsObjectId) -> Result<&Mutex>> { self.get(id) } + + pub fn add_framebuffer(&mut self, fb: KmsFramebuffer) -> KmsObjectId { + let id = self.add(fb); + self.framebuffers.push(id); + id + } + + pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> { + self.remove::>(id) + } + + pub fn fb_ids(&self) -> &[KmsObjectId] { + &self.framebuffers + } + + pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer> { + self.get(id) + } } #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -299,16 +299,6 @@ define_object_props!(object, KmsCrtc { } }); -#[derive(Debug)] -pub struct KmsFramebuffer { - pub width: u32, - pub height: u32, - pub pixel_format: DrmFourcc, - pub pitch: u32, - pub buffer: Arc, - pub driver_data: T::Framebuffer, -} - pub trait KmsPlaneDriver: Debug { type State: Clone + Debug; } @@ -361,3 +351,13 @@ pub struct KmsRect { pub width: u32, pub height: u32, } + +#[derive(Debug)] +pub struct KmsFramebuffer { + pub width: u32, + pub height: u32, + pub pixel_format: DrmFourcc, + pub pitch: u32, + pub buffer: Arc, + pub driver_data: T::Framebuffer, +} diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 5a191f28f8..faa60879cc 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -85,7 +85,6 @@ impl Damage { pub trait GraphicsAdapter: Sized + Debug { type Connector: KmsConnectorDriver; type Crtc: KmsCrtcDriver; - type Plane: KmsPlaneDriver; type Buffer: Buffer; @@ -972,46 +971,43 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_SET_PLANE => ipc::DrmModeSetPlane::with(payload, |data| { let plane_id = KmsObjectId(data.plane_id()); - let plane_mutex = self.objects.get_plane(plane_id)?; + let plane = self.objects.get_plane(plane_id)?; let crtc_id = KmsObjectId(data.crtc_id()); let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index; - let new_state; - { - let mut plane = plane_mutex.lock().unwrap(); + let mut new_state = { + let plane = plane.lock().unwrap(); if plane.possible_crtcs & (1 << crtc_index) == 0 { return Err(Error::new(EINVAL)); } - let fb_id = if data.fb_id() != 0 { - KmsObjectId(data.fb_id()) - } else { - KmsObjectId::INVALID - }; - let mut state = plane.state.clone(); - state.fb_id = Some(fb_id); - state.crtc_id = Some(crtc_id); - state.src_rect = KmsRect { - x: data.src_x(), - y: data.src_y(), - width: data.src_w(), - height: data.src_h(), - }; - state.crtc_rect = KmsRect { - x: data.crtc_x() as i32, - y: data.crtc_y() as i32, - width: data.crtc_w(), - height: data.crtc_h(), - }; - plane.state = state.clone(); - new_state = state; - } + plane.state.clone() + }; + let fb_id = if data.fb_id() != 0 { + KmsObjectId(data.fb_id()) + } else { + KmsObjectId::INVALID + }; + new_state.fb_id = Some(fb_id); + new_state.crtc_id = Some(crtc_id); + new_state.src_rect = KmsRect { + x: data.src_x(), + y: data.src_y(), + width: data.src_w(), + height: data.src_h(), + }; + new_state.crtc_rect = KmsRect { + x: data.crtc_x() as i32, + y: data.crtc_y() as i32, + width: data.crtc_w(), + height: data.crtc_h(), + }; if *vt == self.active_vt { self.adapter.set_plane( &self.objects, - plane_mutex, - new_state, + plane, + new_state.clone(), Damage { x: 0, y: 0, @@ -1020,6 +1016,8 @@ impl SchemeSync for GraphicsSchemeInner { }, )?; } + self.vts.get_mut(vt).unwrap().plane_state + [plane.lock().unwrap().plane_index as usize] = new_state; Ok(0) }), ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index a02e2b71b3..17eec84f6c 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -41,12 +41,11 @@ impl Buffer for GpuBuffer { impl GraphicsAdapter for Device { type Connector = Connector; type Crtc = Crtc; + type Plane = (); type Buffer = GpuBuffer; type Framebuffer = (); - type Plane = (); - fn name(&self) -> &'static [u8] { b"ihdgd" } diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 50eb113d05..55b4b9994c 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -33,11 +33,11 @@ impl KmsConnectorDriver for Connector { impl GraphicsAdapter for FbAdapter { type Connector = Connector; type Crtc = (); + type Plane = (); type Buffer = GraphicScreen; type Framebuffer = (); - type Plane = (); fn name(&self) -> &'static [u8] { b"vesad" diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index a1f45429e7..f970c970ca 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -343,12 +343,11 @@ impl<'a> VirtGpuAdapter<'a> { impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { type Connector = VirtGpuConnector; type Crtc = (); + type Plane = (); type Buffer = VirtGpuFramebuffer<'a>; type Framebuffer = (); - type Plane = (); - fn name(&self) -> &'static [u8] { b"virtio-gpud" } From 6a039c29fe39a7a1fa0c3d90edf5201bb4343f81 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 16:05:57 +0200 Subject: [PATCH 7/9] drivers/graphics/ihdgd: Don't access CRTC in set_plane --- drivers/graphics/ihdgd/src/device/mod.rs | 12 ++++++++-- drivers/graphics/ihdgd/src/device/scheme.rs | 26 ++++++++++----------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index f1845c40b5..142d1bc266 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -449,13 +449,21 @@ impl Device { } fn add_kms_pipe(objects: &mut KmsObjects, pipe_idx: usize, fb: KmsFramebuffer) { - let (crtc_id, primary_plane_id) = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); + let (crtc_id, primary_plane_id) = objects.add_crtc( + Crtc { pipe_idx }, + (), + scheme::Plane { + pipe_idx, + plane_idx: 0, + }, + (), + ); let (width, height) = (fb.width, fb.height); let fb_id = objects.add_framebuffer(fb); - let connector_id = objects.add_connector(Connector { fb_id: Some(fb_id) }, (), &[crtc_id]); + let connector_id = objects.add_connector((), (), &[crtc_id]); let mut connector = objects.get_connector(connector_id).unwrap().lock().unwrap(); connector.connection = KmsConnectorStatus::Connected; connector.update_from_size(width, height); diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 17eec84f6c..4cc81b050a 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -1,8 +1,9 @@ use std::sync::Mutex; -use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; +use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{ - KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, + KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver, + KmsPlaneState, }; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{ @@ -20,15 +21,16 @@ pub struct Crtc { } #[derive(Debug)] -pub struct Connector { - pub fb_id: Option, +pub struct Plane { + pub pipe_idx: usize, + pub plane_idx: usize, } impl KmsCrtcDriver for Crtc { type State = (); } -impl KmsConnectorDriver for Connector { +impl KmsPlaneDriver for Plane { type State = (); } @@ -39,9 +41,9 @@ impl Buffer for GpuBuffer { } impl GraphicsAdapter for Device { - type Connector = Connector; + type Connector = (); type Crtc = Crtc; - type Plane = (); + type Plane = Plane; type Buffer = GpuBuffer; type Framebuffer = (); @@ -115,10 +117,6 @@ impl GraphicsAdapter for Device { new_plane_state: KmsPlaneState, _damage: Damage, ) -> syscall::Result<()> { - let Some(crtc_id) = new_plane_state.crtc_id else { - return Ok(()); - }; - let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); let buffer = new_plane_state @@ -128,8 +126,10 @@ impl GraphicsAdapter for Device { plane.state = new_plane_state; - let pipe_idx = crtc.driver_data.pipe_idx; - if let Some(plane_hw) = self.pipes[pipe_idx].planes.first_mut() { + if let Some(plane_hw) = self.pipes[plane.driver_data.pipe_idx] + .planes + .get_mut(plane.driver_data.plane_idx) + { plane_hw.set_framebuffer(buffer); } From b0d7b6135e2b77998f742a23e66d704e650e81c4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 16:08:21 +0200 Subject: [PATCH 8/9] Restore some FIXMEs --- drivers/graphics/vesad/src/scheme.rs | 2 +- drivers/graphics/virtio-gpud/src/scheme.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 55b4b9994c..7276ef4ad6 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -149,7 +149,7 @@ impl GraphicsAdapter for FbAdapter { if let Some(buffer) = buffer { buffer.buffer.sync(framebuffer, damage) } else { - let onscreen_ptr = framebuffer.onscreen as *mut u32; + let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable for row in 0..framebuffer.height { unsafe { ptr::write_bytes( diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index f970c970ca..f3d0aed693 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -450,7 +450,6 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); - // fb_id now in plane state let framebuffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) @@ -494,6 +493,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { let header = self.send_request(req).await.unwrap(); assert_eq!(header.ty, CommandTy::RespOkNodata); + // FIXME once we support resizing we also need to check that the current and target size match if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) { let scanout_request = Dma::new(SetScanout::new( From 607906de284fa257fa9a18ccfa39b3de1b821b97 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 14 May 2026 16:19:10 +0200 Subject: [PATCH 9/9] Rustfmt --- drivers/graphics/vesad/src/scheme.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 7276ef4ad6..002b112390 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -38,7 +38,6 @@ impl GraphicsAdapter for FbAdapter { type Buffer = GraphicScreen; type Framebuffer = (); - fn name(&self) -> &'static [u8] { b"vesad" }