Merge branch 'gpu_drm31' into 'main'

Some more preparations for atomic modesetting

See merge request redox-os/base!187
This commit is contained in:
Jeremy Soller
2026-03-20 16:35:53 -06:00
8 changed files with 229 additions and 187 deletions
@@ -58,15 +58,13 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&self.connectors
}
pub fn connectors(
&self,
) -> impl Iterator<Item = &Mutex<KmsConnector<T::Connector>>> + use<'_, T> {
pub fn connectors(&self) -> impl Iterator<Item = &Mutex<KmsConnector<T>>> + use<'_, T> {
self.connectors
.iter()
.map(|&id| self.get_connector(id).unwrap())
}
pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex<KmsConnector<T::Connector>>> {
pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex<KmsConnector<T>>> {
self.get(id)
}
@@ -88,7 +86,7 @@ impl KmsConnectorDriver for () {
}
#[derive(Debug)]
pub struct KmsConnector<T: KmsConnectorDriver> {
pub struct KmsConnector<T: GraphicsAdapter> {
pub encoder_id: KmsObjectId,
pub modes: Vec<drm_mode_modeinfo>,
pub connector_type: u32,
@@ -99,18 +97,28 @@ pub struct KmsConnector<T: KmsConnectorDriver> {
pub subpixel: DrmSubpixelOrder,
pub properties: Vec<KmsPropertyData<Self>>,
pub edid: KmsObjectId,
pub state: KmsConnectorState<T::State>,
pub driver_data: T,
pub state: KmsConnectorState<T>,
pub driver_data: T::Connector,
}
#[derive(Debug, Clone)]
pub struct KmsConnectorState<T> {
#[derive(Debug)]
pub struct KmsConnectorState<T: GraphicsAdapter> {
pub dpms: KmsDpms,
pub crtc_id: KmsObjectId,
pub driver_data: T,
pub driver_data: <T::Connector as KmsConnectorDriver>::State,
}
define_object_props!(object, KmsConnector<T: KmsConnectorDriver> {
impl<T: GraphicsAdapter> Clone for KmsConnectorState<T> {
fn clone(&self) -> Self {
Self {
dpms: self.dpms.clone(),
crtc_id: self.crtc_id.clone(),
driver_data: self.driver_data.clone(),
}
}
}
define_object_props!(object, KmsConnector<T: GraphicsAdapter> {
EDID {
get => u64::from(object.edid.0),
}
@@ -122,9 +130,9 @@ define_object_props!(object, KmsConnector<T: KmsConnectorDriver> {
}
});
impl<T: KmsConnectorDriver> KmsConnector<T> {
impl<T: GraphicsAdapter> KmsConnector<T> {
pub fn update_from_size(&mut self, width: u32, height: u32) {
self.modes = vec![Self::modeinfo_for_size(width, height)];
self.modes = vec![modeinfo_for_size(width, height)];
}
pub fn update_from_edid(&mut self, edid: &[u8]) {
@@ -151,7 +159,7 @@ impl<T: KmsConnectorDriver> KmsConnector<T> {
match descriptor {
edid::Descriptor::DetailedTiming(detailed_timing) => {
// FIXME extract full information
Some(Self::modeinfo_for_size(
Some(modeinfo_for_size(
u32::from(detailed_timing.horizontal_active_pixels),
u32::from(detailed_timing.vertical_active_lines),
))
@@ -168,40 +176,40 @@ impl<T: KmsConnectorDriver> KmsConnector<T> {
// FIXME update the EDID property
}
}
pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
let mut modeinfo = drm_mode_modeinfo {
// The actual visible display size
hdisplay: width as u16,
vdisplay: height as u16,
pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
let mut modeinfo = drm_mode_modeinfo {
// The actual visible display size
hdisplay: width as u16,
vdisplay: height as u16,
// These are used to calculate the refresh rate
clock: 60 * width * height / 1000,
htotal: width as u16,
vtotal: height as u16,
vscan: 0,
vrefresh: 60,
// These are used to calculate the refresh rate
clock: 60 * width * height / 1000,
htotal: width as u16,
vtotal: height as u16,
vscan: 0,
vrefresh: 60,
type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER,
name: [0; 32],
type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER,
name: [0; 32],
// These only matter when modesetting physical display adapters. For
// those we should be able to parse the EDID blob.
hsync_start: width as u16,
hsync_end: width as u16,
hskew: 0,
vsync_start: height as u16,
vsync_end: height as u16,
flags: 0,
};
// These only matter when modesetting physical display adapters. For
// those we should be able to parse the EDID blob.
hsync_start: width as u16,
hsync_end: width as u16,
hskew: 0,
vsync_start: height as u16,
vsync_end: height as u16,
flags: 0,
};
let name = format!("{width}x{height}").into_bytes();
for (to, from) in modeinfo.name.iter_mut().zip(name) {
*to = from as c_char;
}
modeinfo
let name = format!("{width}x{height}").into_bytes();
for (to, from) in modeinfo.name.iter_mut().zip(name) {
*to = from as c_char;
}
modeinfo
}
#[derive(Debug, Copy, Clone)]
@@ -22,7 +22,7 @@ pub struct KmsObjects<T: GraphicsAdapter> {
pub(crate) encoders: Vec<KmsObjectId>,
crtcs: Vec<KmsObjectId>,
framebuffers: Vec<KmsObjectId>,
pub(crate) objects: HashMap<KmsObjectId, Arc<KmsObject<T>>>,
pub(crate) objects: HashMap<KmsObjectId, KmsObject<T>>,
_marker: PhantomData<T>,
}
@@ -43,7 +43,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
pub(crate) fn add<U: Into<KmsObject<T>>>(&mut self, data: U) -> KmsObjectId {
let id = self.next_id;
self.objects.insert(id, Arc::new(data.into()));
self.objects.insert(id, data.into());
self.next_id.0 += 1;
id
@@ -54,7 +54,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&'a U: TryFrom<&'a KmsObject<T>>,
{
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
if let Ok(object) = (&**object).try_into() {
if let Ok(object) = object.try_into() {
Ok(object)
} else {
Err(Error::new(EINVAL))
@@ -77,7 +77,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
gamma_size: 0,
properties: KmsCrtc::base_properties(),
state: KmsCrtcState {
fb_id: KmsObjectId::INVALID,
fb_id: None,
mode: None,
driver_data: driver_data_state,
},
@@ -92,27 +92,24 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&self.crtcs
}
pub fn crtcs(&self) -> impl Iterator<Item = &Mutex<KmsCrtc<T::Crtc>>> + use<'_, T> {
pub fn crtcs(&self) -> impl Iterator<Item = &Mutex<KmsCrtc<T>>> + use<'_, T> {
self.crtcs
.iter()
.map(|&id| self.get::<Mutex<KmsCrtc<T::Crtc>>>(id).unwrap())
.map(|&id| self.get::<Mutex<KmsCrtc<T>>>(id).unwrap())
}
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T::Crtc>>> {
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T>>> {
self.get(id)
}
pub fn add_framebuffer(
&mut self,
fb: KmsFramebuffer<T::Framebuffer, T::Buffer>,
) -> KmsObjectId {
pub fn add_framebuffer(&mut self, fb: KmsFramebuffer<T>) -> KmsObjectId {
let id = self.add(fb);
self.framebuffers.push(id);
id
}
pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> {
let Some(object) = self.objects.get(&id).map(|object| &**object) else {
let Some(object) = self.objects.get(&id) else {
return Err(Error::new(EINVAL));
};
let KmsObject::Framebuffer(_) = object else {
@@ -127,10 +124,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&self.framebuffers
}
pub fn get_framebuffer(
&self,
id: KmsObjectId,
) -> Result<&KmsFramebuffer<T::Framebuffer, T::Buffer>> {
pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer<T>> {
self.get(id)
}
}
@@ -187,11 +181,11 @@ macro_rules! define_object_kinds {
}
define_object_kinds! { <T>
Crtc(Mutex<KmsCrtc<T::Crtc>>) = DRM_MODE_OBJECT_CRTC,
Connector(Mutex<KmsConnector<T::Connector>>) = DRM_MODE_OBJECT_CONNECTOR,
Crtc(Mutex<KmsCrtc<T>>) = DRM_MODE_OBJECT_CRTC,
Connector(Mutex<KmsConnector<T>>) = DRM_MODE_OBJECT_CONNECTOR,
Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER,
Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY,
Framebuffer(KmsFramebuffer<T::Framebuffer, T::Buffer>) = DRM_MODE_OBJECT_FB,
Framebuffer(KmsFramebuffer<T>) = DRM_MODE_OBJECT_FB,
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
}
@@ -204,30 +198,40 @@ impl KmsCrtcDriver for () {
}
#[derive(Debug)]
pub struct KmsCrtc<T: KmsCrtcDriver> {
pub struct KmsCrtc<T: GraphicsAdapter> {
pub crtc_index: u32,
pub gamma_size: u32,
pub properties: Vec<KmsPropertyData<Self>>,
pub state: KmsCrtcState<T::State>,
pub driver_data: T,
pub state: KmsCrtcState<T>,
pub driver_data: T::Crtc,
}
#[derive(Debug, Clone)]
pub struct KmsCrtcState<T> {
pub fb_id: KmsObjectId,
pub mode: Option<drm_mode_modeinfo>,
pub driver_data: T,
}
define_object_props!(object, KmsCrtc<T: KmsCrtcDriver> {});
#[derive(Debug)]
pub struct KmsFramebuffer<T, Buf> {
pub struct KmsCrtcState<T: GraphicsAdapter> {
pub fb_id: Option<KmsObjectId>,
pub mode: Option<drm_mode_modeinfo>,
pub driver_data: <T::Crtc as KmsCrtcDriver>::State,
}
impl<T: GraphicsAdapter> Clone for KmsCrtcState<T> {
fn clone(&self) -> Self {
Self {
fb_id: self.fb_id.clone(),
mode: self.mode.clone(),
driver_data: self.driver_data.clone(),
}
}
}
define_object_props!(object, KmsCrtc<T: GraphicsAdapter> {});
#[derive(Debug)]
pub struct KmsFramebuffer<T: GraphicsAdapter> {
pub width: u32,
pub height: u32,
pub pitch: u32,
pub bpp: u32,
pub depth: u32,
pub buffer: Arc<Buf>,
pub driver_data: T,
pub buffer: Arc<T::Buffer>,
pub driver_data: T::Framebuffer,
}
@@ -52,7 +52,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
pub fn get_object_properties_data(&self, id: KmsObjectId) -> Result<(Vec<u32>, Vec<u64>)> {
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
match &**object {
match object {
KmsObject::Crtc(crtc) => {
let crtc = crtc.lock().unwrap();
let props = &crtc.properties;
+89 -68
View File
@@ -10,9 +10,9 @@ use std::{cmp, mem};
use drm_fourcc::DrmFourcc;
use drm_sys::{
drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE,
DRM_MODE_PROP_ATOMIC, DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM,
DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE,
drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, DRM_MODE_PROP_ATOMIC,
DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM, DRM_MODE_PROP_IMMUTABLE,
DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE,
};
use inputd::{DisplayHandle, VtEventKind};
use libredox::Fd;
@@ -21,8 +21,8 @@ use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket};
use syscall::schemev2::NewFdFlags;
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP};
use crate::kms::connector::{KmsConnector, KmsConnectorDriver};
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsObjectId, KmsObjects};
use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState};
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects};
use crate::kms::properties::KmsPropertyKind;
pub mod kms;
@@ -102,11 +102,10 @@ pub trait GraphicsAdapter: Sized + Debug {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
mode: Option<drm_mode_modeinfo>,
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
crtc: &Mutex<KmsCrtc<Self>>,
new_state: KmsCrtcState<Self>,
damage: Damage,
);
) -> syscall::Result<()>;
fn hw_cursor_size(&self) -> Option<(u32, u32)>;
fn handle_cursor(&mut self, cursor: &CursorPlane<Self::Buffer>, dirty_fb: bool);
@@ -236,35 +235,46 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
vt_event.vt,
);
for (display_id, fb) in vt_state.display_fbs.iter().enumerate() {
let crtc_id = self.inner.objects.crtc_ids()[display_id];
for (connector_idx, connector_state) in
vt_state.connector_state.iter().enumerate()
{
let connector_id = self.inner.objects.connector_ids()[connector_idx];
let mut connector = self
.inner
.objects
.get_connector(connector_id)
.unwrap()
.lock()
.unwrap();
connector.state = connector_state.clone();
}
for (crtc_idx, crtc_state) in vt_state.crtc_state.iter().enumerate() {
let crtc_id = self.inner.objects.crtc_ids()[crtc_idx];
let crtc = self.inner.objects.get_crtc(crtc_id).unwrap();
let connector_id = self.inner.objects.connector_ids()[display_id];
let connector_id = self.inner.objects.connector_ids()[crtc_idx];
crtc.lock().unwrap().state.fb_id = fb.unwrap_or(KmsObjectId::INVALID);
let fb = fb.map(|fb| {
let fb = crtc_state.fb_id.map(|fb_id| {
self.inner
.objects
.get_framebuffer(fb)
.get_framebuffer(fb_id)
.expect("removed framebuffers should be unset")
});
let mode =
fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height));
self.inner.adapter.set_crtc(
&self.inner.objects,
crtc,
mode,
fb,
Damage {
x: 0,
y: 0,
width: fb.map_or(0, |fb| fb.width),
height: fb.map_or(0, |fb| fb.height),
},
);
self.inner
.adapter
.set_crtc(
&self.inner.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),
},
)
.unwrap();
self.inner
.objects
@@ -344,7 +354,8 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
}
struct VtState<T: GraphicsAdapter> {
display_fbs: Vec<Option<KmsObjectId>>,
connector_state: Vec<KmsConnectorState<T>>,
crtc_state: Vec<KmsCrtcState<T>>,
cursor_plane: CursorPlane<T::Buffer>,
}
@@ -364,7 +375,14 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
vt: usize,
) -> &'a mut VtState<T> {
vts.entry(vt).or_insert_with(|| VtState {
display_fbs: vec![None; objects.crtc_ids().len()],
connector_state: objects
.connectors()
.map(|connector| connector.lock().unwrap().state.clone())
.collect(),
crtc_state: objects
.crtcs()
.map(|crtc| crtc.lock().unwrap().state.clone())
.collect(),
cursor_plane: CursorPlane {
x: 0,
y: 0,
@@ -539,7 +557,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
.lock()
.unwrap();
// Don't touch set_connectors, that is only used by MODE_SET_CRTC
data.set_fb_id(crtc.state.fb_id.0);
data.set_fb_id(crtc.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);
@@ -555,15 +573,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
}),
ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| {
let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?;
let display_id = crtc.lock().unwrap().crtc_index as usize;
let connector_ids: Vec<KmsObjectId> = data
.set_connectors_ptr()
.iter()
.take(data.count_connectors() as usize)
.map(|&id| KmsObjectId(id))
.collect();
let fb = if data.fb_id() != 0 {
Some(self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?)
let fb_id = if data.fb_id() != 0 {
Some(KmsObjectId(data.fb_id()))
} else {
None
};
@@ -572,20 +589,21 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
} else {
None
};
let mut new_state = crtc.lock().unwrap().state.clone();
new_state.fb_id = fb_id;
new_state.mode = mode;
if *vt == self.active_vt {
self.adapter.set_crtc(
&self.objects,
crtc,
mode,
fb.as_deref(),
new_state.clone(),
Damage {
x: data.x(),
y: data.y(),
width: mode.map_or(0, |m| m.hdisplay as u32),
height: mode.map_or(0, |m| m.vdisplay as u32),
},
);
crtc.lock().unwrap().state.fb_id = KmsObjectId(data.fb_id());
)?;
for connector in connector_ids {
self.objects
@@ -596,11 +614,8 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
.crtc_id = KmsObjectId(data.crtc_id());
}
}
self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if data.fb_id() != 0 {
Some(KmsObjectId(data.fb_id()))
} else {
None
};
self.vts.get_mut(vt).unwrap().crtc_state
[crtc.lock().unwrap().crtc_index as usize] = new_state;
Ok(0)
}),
ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| {
@@ -772,29 +787,29 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
// Disable planes that use this framebuffer.
for (vt, vt_data) in &mut self.vts {
for (display_id, fb) in vt_data.display_fbs.iter_mut().enumerate() {
if *fb != Some(fb_id) {
for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() {
if crtc_state.fb_id != Some(fb_id) {
continue;
}
*fb = None;
crtc_state.fb_id = None;
if *vt != self.active_vt {
continue;
}
let crtc = self.objects.crtcs().nth(display_id).unwrap();
crtc.lock().unwrap().state.fb_id = KmsObjectId::INVALID;
self.adapter.set_crtc(
&self.objects,
crtc,
None,
None,
Damage {
x: 0,
y: 0,
width: 0,
height: 0,
},
);
let crtc = self.objects.crtcs().nth(crtc_idx).unwrap();
self.adapter
.set_crtc(
&self.objects,
crtc,
crtc_state.clone(),
Damage {
x: 0,
y: 0,
width: 0,
height: 0,
},
)
.unwrap();
}
}
@@ -822,10 +837,9 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
if *vt == self.active_vt {
for crtc in self.objects.crtcs() {
if crtc.lock().unwrap().state.fb_id == KmsObjectId(data.fb_id()) {
let mode = crtc.lock().unwrap().state.mode;
self.adapter
.set_crtc(&self.objects, crtc, mode, Some(fb), damage);
let state = crtc.lock().unwrap().state.clone();
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
self.adapter.set_crtc(&self.objects, crtc, state, damage)?;
}
}
}
@@ -887,7 +901,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
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.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)
+11 -19
View File
@@ -404,7 +404,7 @@ impl Device {
let buffers = 1024;
//TODO: how to use 64-bit surface addresses?
let surface_memory = gm.size.min(u32::max_value() as usize) as u32;
let mut this = Self {
Ok(Self {
kind,
alloc_buffers: RangeAllocator::new(0..buffers),
alloc_surfaces: RangeAllocator::new(0..surface_memory),
@@ -422,12 +422,10 @@ impl Device {
power_wells,
ref_freq,
transcoders,
};
this.init()?;
Ok(this)
})
}
pub fn init(&mut self) -> Result<()> {
pub fn init_inner(&mut self) {
// Discover current framebuffers
self.alloc_buffers.reset();
self.alloc_surfaces.reset();
@@ -440,15 +438,12 @@ impl Device {
let buffer_end = (buf_cfg >> 16) & 0x7FF;
self.alloc_buffers
.allocate_exact_range(buffer_start..(buffer_end + 1))
.map_err(|err| {
log::warn!(
.unwrap_or_else(|err| {
panic!(
"failed to allocate pre-existing buffer blocks {} to {}: {:?}",
buffer_start,
buffer_end,
err
buffer_start, buffer_end, err
);
Error::new(EIO)
})?;
});
let size = plane.size.read();
let width = (size & 0xFFFF) + 1;
@@ -459,10 +454,9 @@ impl Device {
let surf = plane.surf.read() & 0xFFFFF000;
//TODO: read bits per pixel
let surf_size = (stride * height * 4).next_multiple_of(4096);
self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).map_err(|err| {
log::warn!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err);
Error::new(EIO)
})?;
self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).unwrap_or_else(|err| {
panic!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err);
});
self.framebuffers.push(unsafe {
DeviceFb::new(
@@ -480,7 +474,7 @@ impl Device {
// Probe all DDIs
let ddi_names: Vec<&str> = self.ddis.iter().map(|ddi| ddi.name).collect();
for ddi_name in ddi_names {
self.probe_ddi(ddi_name)?;
self.probe_ddi(ddi_name).expect("failed to probe DDI");
}
self.dump();
@@ -517,8 +511,6 @@ impl Device {
for change_detect in self.int.change_detects.iter_mut() {
change_detect.log();
}
Ok(())
}
pub fn dump(&self) {
+14 -7
View File
@@ -6,9 +6,9 @@ use std::ptr::{self, NonNull};
use std::sync::Mutex;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use syscall::{error::EINVAL, PAGE_SIZE};
use super::Device;
@@ -38,6 +38,8 @@ impl GraphicsAdapter for Device {
}
fn init(&mut self, objects: &mut KmsObjects<Self>) {
self.init_inner();
// FIXME enumerate actual connectors
for (framebuffer_id, _) in self.framebuffers.iter().enumerate() {
let crtc = objects.add_crtc((), ());
@@ -84,13 +86,16 @@ impl GraphicsAdapter for Device {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
mode: Option<drm_mode_modeinfo>,
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
damage: Damage,
) {
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
crtc.state.mode = mode;
let buffer = state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
@@ -117,6 +122,8 @@ impl GraphicsAdapter for Device {
}
}
}
Ok(())
}
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
+12 -7
View File
@@ -4,9 +4,9 @@ use std::ptr::{self, NonNull};
use std::sync::Mutex;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use syscall::{EINVAL, PAGE_SIZE};
#[derive(Debug)]
@@ -92,13 +92,16 @@ impl GraphicsAdapter for FbAdapter {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
mode: Option<drm_mode_modeinfo>,
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
damage: Damage,
) {
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
crtc.state.mode = mode;
let buffer = state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
@@ -125,6 +128,8 @@ impl GraphicsAdapter for FbAdapter {
}
}
}
Ok(())
}
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
+14 -9
View File
@@ -3,10 +3,10 @@ use std::sync::{Arc, Mutex};
use common::{dma::Dma, sgl};
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme};
use drm_sys::{
drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER,
DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER,
DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT,
};
@@ -405,14 +405,17 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
mode: Option<drm_mode_modeinfo>,
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
damage: Damage,
) {
) -> syscall::Result<()> {
futures::executor::block_on(async {
let mut crtc = crtc.lock().unwrap();
crtc.state.mode = mode;
let framebuffer = state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
@@ -433,7 +436,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
let header = self.send_request(scanout_request).await.unwrap();
assert_eq!(header.ty, CommandTy::RespOkNodata);
self.displays[display_id as usize].active_resource = None;
return;
return Ok(());
};
let req = Dma::new(XferToHost2d::new(
@@ -472,7 +475,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap();
assert_eq!(header.ty, CommandTy::RespOkNodata);
}
});
Ok(())
})
}
fn hw_cursor_size(&self) -> Option<(u32, u32)> {