From 8ae815aca743dd5223a33c7068d420e3d775af64 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:46:32 +0100 Subject: [PATCH 1/2] drivers/graphics: Replace width and height methods on Buffer with size A buffer is not necessarily a framebuffer. It may also be a blob of bytes. --- drivers/graphics/driver-graphics/src/lib.rs | 8 ++------ drivers/graphics/ihdgd/src/device/scheme.rs | 8 ++------ drivers/graphics/vesad/src/scheme.rs | 8 ++------ drivers/graphics/virtio-gpud/src/scheme.rs | 8 ++------ 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index e979981f90..c09f903e81 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -112,8 +112,7 @@ pub trait GraphicsAdapter: Sized + Debug { } pub trait Buffer: Debug { - fn width(&self) -> u32; - fn height(&self) -> u32; + fn size(&self) -> usize; } pub trait Framebuffer: Debug {} @@ -868,10 +867,7 @@ impl SchemeSync for GraphicsSchemeInner { } // FIXME use a better scheme for creating map offsets - assert!( - ((buffers[&buffer_id].width() * buffers[&buffer_id].height() * 4) as usize) - < MAP_FAKE_OFFSET_MULTIPLIER - ); + assert!(buffers[&buffer_id].size() < MAP_FAKE_OFFSET_MULTIPLIER); data.set_offset((buffer_id as usize * MAP_FAKE_OFFSET_MULTIPLIER) as u64); diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 9fb0d0ba48..b5a2e1bf69 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -175,12 +175,8 @@ impl Drop for DumbFb { } impl Buffer for DumbFb { - fn width(&self) -> u32 { - self.width as u32 - } - - fn height(&self) -> u32 { - self.height as u32 + fn size(&self) -> usize { + self.width * self.height * 4 } } diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 5c13617136..99679d5cc6 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -239,12 +239,8 @@ impl Drop for GraphicScreen { } impl Buffer for GraphicScreen { - fn width(&self) -> u32 { - self.width as u32 - } - - fn height(&self) -> u32 { - self.height as u32 + fn size(&self) -> usize { + self.width * self.height * 4 } } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index fc3a6d2539..2851700ffd 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -57,12 +57,8 @@ impl<'a> fmt::Debug for VirtGpuFramebuffer<'a> { } impl DrmBuffer for VirtGpuFramebuffer<'_> { - fn width(&self) -> u32 { - self.width - } - - fn height(&self) -> u32 { - self.height + fn size(&self) -> usize { + (self.width * self.height * 4) as usize } } From d274ac28177d27ff07949355702032565e11517b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 22 Mar 2026 19:53:38 +0100 Subject: [PATCH 2/2] drivers/graphics: Return proper pitch to the drm client for dumb buffers --- drivers/graphics/driver-graphics/src/lib.rs | 12 ++++++----- drivers/graphics/ihdgd/src/device/scheme.rs | 4 ++-- drivers/graphics/vesad/src/scheme.rs | 7 +++++-- drivers/graphics/virtio-gpud/src/scheme.rs | 23 ++++++++++++--------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index c09f903e81..1daf1eab2e 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -94,7 +94,7 @@ pub trait GraphicsAdapter: Sized + Debug { fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId); - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer; + fn create_dumb_buffer(&mut self, width: u32, height: u32) -> (Self::Buffer, u32); fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8; fn create_framebuffer(&mut self, buffer: &Self::Buffer) -> Self::Framebuffer; @@ -842,17 +842,19 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_CREATE_DUMB => ipc::DrmModeCreateDumb::with(payload, |mut data| { - if data.bpp() != 32 { + if data.bpp() != 32 || data.flags() != 0 { return Err(Error::new(EINVAL)); } - let buffer = self.adapter.create_dumb_buffer(data.width(), data.height()); + let (buffer, pitch) = + self.adapter.create_dumb_buffer(data.width(), data.height()); + + data.set_pitch(pitch); + data.set_size(buffer.size() as u64); *next_id += 1; buffers.insert(*next_id, Arc::new(buffer)); data.set_handle(*next_id as u32); - data.set_pitch(data.width() * 4); - data.set_size(u64::from(data.width()) * u64::from(data.height()) * 4); Ok(0) }), ipc::MODE_MAP_DUMB => ipc::DrmModeMapDumb::with(payload, |mut data| { diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index b5a2e1bf69..84a8eabcd0 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -75,8 +75,8 @@ impl GraphicsAdapter for Device { // FIXME fetch EDID } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { - DumbFb::new(width as usize, height as usize) + fn create_dumb_buffer(&mut self, width: u32, height: u32) -> (Self::Buffer, u32) { + (DumbFb::new(width as usize, height as usize), width * 4) } fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8 { diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 99679d5cc6..5bf2be9125 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -80,8 +80,11 @@ impl GraphicsAdapter for FbAdapter { connector.update_from_size(connector.driver_data.width, connector.driver_data.height); } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { - GraphicScreen::new(width as usize, height as usize) + fn create_dumb_buffer(&mut self, width: u32, height: u32) -> (Self::Buffer, u32) { + ( + GraphicScreen::new(width as usize, height as usize), + width * 4, + ) } fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8 { diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 2851700ffd..22a985ee4e 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -247,12 +247,12 @@ impl VirtGpuAdapter<'_> { fn disable_cursor(&mut self) { if self.hidden_cursor.is_none() { let (width, height) = self.hw_cursor_size().unwrap(); - let cursor = self.create_dumb_buffer(width, height); + let (cursor, stride) = self.create_dumb_buffer(width, height); unsafe { core::ptr::write_bytes( cursor.sgl.as_ptr() as *mut u8, 0, - (width * height * 4) as usize, + (stride * height) as usize, ); } self.hidden_cursor = Some(Arc::new(cursor)); @@ -332,7 +332,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }); } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { + fn create_dumb_buffer(&mut self, width: u32, height: u32) -> (Self::Buffer, u32) { futures::executor::block_on(async { let bpp = 32; let fb_size = width as usize * height as usize * bpp / 8; @@ -381,13 +381,16 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { self.control_queue.send(command).await; assert_eq!(header.ty, CommandTy::RespOkNodata); - VirtGpuFramebuffer { - queue: self.control_queue.clone(), - id: res_id, - sgl, - width, - height, - } + ( + VirtGpuFramebuffer { + queue: self.control_queue.clone(), + id: res_id, + sgl, + width, + height, + }, + width * 4, + ) }) }