Merge branch 'gpu_drm42' into 'main'
drivers/graphics/driver-graphics: Expose a bunch of properties on planes See merge request redox-os/base!267
This commit is contained in:
@@ -7,12 +7,14 @@ 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_PLANE, DRM_MODE_OBJECT_PROPERTY,
|
||||
DRM_PLANE_TYPE_CURSOR, DRM_PLANE_TYPE_OVERLAY, DRM_PLANE_TYPE_PRIMARY,
|
||||
};
|
||||
use syscall::{Error, Result, ENOENT};
|
||||
|
||||
use crate::kms::connector::{KmsConnector, KmsEncoder};
|
||||
use crate::kms::properties::{
|
||||
define_object_props, init_standard_props, KmsBlob, KmsProperty, KmsPropertyData, ACTIVE,
|
||||
define_object_props, init_standard_props, type_, KmsBlob, KmsProperty, KmsPropertyData, ACTIVE,
|
||||
CRTC_H, CRTC_ID, CRTC_W, CRTC_X, CRTC_Y, FB_ID, SRC_H, SRC_W, SRC_X, SRC_Y,
|
||||
};
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
@@ -141,6 +143,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
plane_index,
|
||||
possible_crtcs,
|
||||
plane_type,
|
||||
properties: KmsPlane::base_properties(),
|
||||
state: KmsPlaneState {
|
||||
fb_id: None,
|
||||
crtc_id: None,
|
||||
@@ -312,6 +315,7 @@ pub struct KmsPlane<T: GraphicsAdapter> {
|
||||
pub plane_index: u32,
|
||||
pub possible_crtcs: u32,
|
||||
pub plane_type: KmsPlaneType,
|
||||
pub properties: Vec<KmsPropertyData<Self>>,
|
||||
pub state: KmsPlaneState<T>,
|
||||
pub driver_data: T::Plane,
|
||||
}
|
||||
@@ -337,11 +341,48 @@ impl<T: GraphicsAdapter> Clone for KmsPlaneState<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
define_object_props!(object, KmsPlane<T: GraphicsAdapter> {
|
||||
type_ {
|
||||
get => object.plane_type as u64,
|
||||
}
|
||||
FB_ID {
|
||||
get => u64::from(object.state.fb_id.map_or(0, |id| id.0)),
|
||||
}
|
||||
CRTC_ID {
|
||||
get => u64::from(object.state.crtc_id.map_or(0, |id| id.0)),
|
||||
}
|
||||
CRTC_X {
|
||||
get => u64::from(object.state.crtc_rect.x.cast_unsigned()),
|
||||
}
|
||||
CRTC_Y {
|
||||
get => u64::from(object.state.crtc_rect.y.cast_unsigned()),
|
||||
}
|
||||
CRTC_W {
|
||||
get => u64::from(object.state.crtc_rect.width),
|
||||
}
|
||||
CRTC_H {
|
||||
get => u64::from(object.state.crtc_rect.height),
|
||||
}
|
||||
SRC_X {
|
||||
get => u64::from(object.state.src_rect.x),
|
||||
}
|
||||
SRC_Y {
|
||||
get => u64::from(object.state.src_rect.y),
|
||||
}
|
||||
SRC_W {
|
||||
get => u64::from(object.state.src_rect.width),
|
||||
}
|
||||
SRC_H {
|
||||
get => u64::from(object.state.src_rect.height),
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[repr(u32)]
|
||||
pub enum KmsPlaneType {
|
||||
Primary,
|
||||
Overlay,
|
||||
Cursor,
|
||||
Primary = DRM_PLANE_TYPE_PRIMARY,
|
||||
Overlay = DRM_PLANE_TYPE_OVERLAY,
|
||||
Cursor = DRM_PLANE_TYPE_CURSOR,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@@ -69,8 +69,15 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
.map(|prop| (prop.id.0, (prop.getter)(&connector)))
|
||||
.unzip())
|
||||
}
|
||||
KmsObject::Plane(plane) => {
|
||||
let plane = plane.lock().unwrap();
|
||||
Ok(plane
|
||||
.properties
|
||||
.iter()
|
||||
.map(|prop| (prop.id.0, (prop.getter)(&plane)))
|
||||
.unzip())
|
||||
}
|
||||
KmsObject::Encoder(_)
|
||||
| KmsObject::Plane(_)
|
||||
| KmsObject::Property(_)
|
||||
| KmsObject::Framebuffer(_)
|
||||
| KmsObject::Blob(_) => Ok((vec![], vec![])),
|
||||
|
||||
@@ -293,15 +293,17 @@ struct VtState<T: GraphicsAdapter> {
|
||||
}
|
||||
|
||||
enum Handle<T: GraphicsAdapter> {
|
||||
V2 {
|
||||
vt: usize,
|
||||
unique: Option<String>,
|
||||
next_id: u32,
|
||||
buffers: HashMap<u32, Arc<T::Buffer>>,
|
||||
},
|
||||
V2(DrmHandle<T>),
|
||||
SchemeRoot,
|
||||
}
|
||||
|
||||
struct DrmHandle<T: GraphicsAdapter> {
|
||||
vt: usize,
|
||||
unique: Option<String>,
|
||||
next_id: u32,
|
||||
buffers: HashMap<u32, Arc<T::Buffer>>,
|
||||
}
|
||||
|
||||
impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
fn get_or_create_vt<'a>(
|
||||
adapter: &T,
|
||||
@@ -440,12 +442,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
// Ensure the VT exists such that the rest of the methods can freely access it.
|
||||
Self::get_or_create_vt(&self.adapter, &self.objects, &mut self.vts, vt);
|
||||
|
||||
Handle::V2 {
|
||||
Handle::V2(DrmHandle {
|
||||
vt,
|
||||
unique: None,
|
||||
next_id: 0,
|
||||
buffers: HashMap::new(),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
@@ -464,12 +466,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> syscall::Result<usize> {
|
||||
FpathWriter::with(buf, &self.scheme_name, |w| {
|
||||
match self.handles.get(id)? {
|
||||
Handle::V2 {
|
||||
Handle::V2(DrmHandle {
|
||||
vt,
|
||||
unique: _,
|
||||
next_id: _,
|
||||
buffers: _,
|
||||
} => write!(w, "v2/{vt}").unwrap(),
|
||||
}) => write!(w, "v2/{vt}").unwrap(),
|
||||
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
|
||||
};
|
||||
Ok(())
|
||||
@@ -487,12 +489,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
match self.handles.get_mut(id)? {
|
||||
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
|
||||
Handle::V2 {
|
||||
vt,
|
||||
unique,
|
||||
next_id,
|
||||
buffers,
|
||||
} => match metadata[0] {
|
||||
Handle::V2(handle) => match metadata[0] {
|
||||
ipc::VERSION => ipc::DrmVersion::with(payload, |mut data| {
|
||||
data.set_version_major(1);
|
||||
data.set_version_minor(4);
|
||||
@@ -505,7 +502,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::GET_UNIQUE => ipc::DrmUnique::with(payload, |mut data| {
|
||||
if let Some(unique) = unique {
|
||||
if let Some(unique) = &handle.unique {
|
||||
data.set_unique(unsafe {
|
||||
mem::transmute::<&[u8], &[c_char]>(unique.as_bytes())
|
||||
});
|
||||
@@ -527,7 +524,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
data.set_drm_dd_major(1);
|
||||
data.set_drm_dd_minor(4);
|
||||
|
||||
*unique = Some(self.adapter.get_unique());
|
||||
handle.unique = Some(self.adapter.get_unique());
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
@@ -643,7 +640,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
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 {
|
||||
if handle.vt == self.active_vt {
|
||||
self.adapter
|
||||
.set_crtc(&self.objects, crtc, new_crtc_state.clone())?;
|
||||
self.adapter.set_plane(
|
||||
@@ -668,14 +665,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
}
|
||||
crtc.lock().unwrap().state = new_crtc_state.clone();
|
||||
plane.lock().unwrap().state = new_plane_state.clone();
|
||||
self.vts.get_mut(vt).unwrap().crtc_state
|
||||
self.vts.get_mut(&handle.vt).unwrap().crtc_state
|
||||
[crtc.lock().unwrap().crtc_index as usize] = new_crtc_state;
|
||||
self.vts.get_mut(vt).unwrap().plane_state
|
||||
self.vts.get_mut(&handle.vt).unwrap().plane_state
|
||||
[plane.lock().unwrap().plane_index as usize] = new_plane_state;
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| {
|
||||
let vt_state = self.vts.get_mut(vt).unwrap();
|
||||
let vt_state = self.vts.get_mut(&handle.vt).unwrap();
|
||||
|
||||
let Some(cursor_plane) = &mut vt_state.cursor_plane else {
|
||||
return Err(Error::new(ENXIO));
|
||||
@@ -685,7 +682,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
if update_buffer {
|
||||
cursor_plane.buffer = if data.handle() == 0 {
|
||||
None
|
||||
} else if let Some(buffer) = buffers.get(&data.handle()) {
|
||||
} else if let Some(buffer) = handle.buffers.get(&data.handle()) {
|
||||
Some(buffer.clone())
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
@@ -815,19 +812,22 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, fb.buffer.clone());
|
||||
handle.next_id += 1;
|
||||
handle.buffers.insert(handle.next_id, fb.buffer.clone());
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pitch(fb.pitch);
|
||||
data.set_bpp(bpp);
|
||||
data.set_depth(depth);
|
||||
data.set_handle(*next_id);
|
||||
data.set_handle(handle.next_id);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
let buffer = buffers.get(&data.handle()).ok_or(Error::new(EINVAL))?;
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handle())
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
if data.bpp() != 32 {
|
||||
return Err(Error::new(EINVAL));
|
||||
@@ -907,7 +907,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
height: fb.height,
|
||||
});
|
||||
|
||||
if *vt == self.active_vt {
|
||||
if handle.vt == self.active_vt {
|
||||
for plane in self.objects.planes() {
|
||||
let state = plane.lock().unwrap().state.clone();
|
||||
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
|
||||
@@ -930,9 +930,9 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
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);
|
||||
handle.next_id += 1;
|
||||
handle.buffers.insert(handle.next_id, Arc::new(buffer));
|
||||
data.set_handle(handle.next_id as u32);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_MAP_DUMB => ipc::DrmModeMapDumb::with(payload, |mut data| {
|
||||
@@ -942,19 +942,19 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
let buffer_id = data.handle();
|
||||
|
||||
if !buffers.contains_key(&buffer_id) {
|
||||
if !handle.buffers.contains_key(&buffer_id) {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
|
||||
// FIXME use a better scheme for creating map offsets
|
||||
assert!(buffers[&buffer_id].size() < MAP_FAKE_OFFSET_MULTIPLIER);
|
||||
assert!(handle.buffers[&buffer_id].size() < MAP_FAKE_OFFSET_MULTIPLIER);
|
||||
|
||||
data.set_offset((buffer_id as usize * MAP_FAKE_OFFSET_MULTIPLIER) as u64);
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_DESTROY_DUMB => ipc::DrmModeDestroyDumb::with(payload, |data| {
|
||||
if buffers.remove(&data.handle()).is_none() {
|
||||
if handle.buffers.remove(&data.handle()).is_none() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
Ok(0)
|
||||
@@ -1003,7 +1003,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
height: data.crtc_h(),
|
||||
};
|
||||
|
||||
if *vt == self.active_vt {
|
||||
if handle.vt == self.active_vt {
|
||||
self.adapter.set_plane(
|
||||
&self.objects,
|
||||
plane,
|
||||
@@ -1016,7 +1016,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
},
|
||||
)?;
|
||||
}
|
||||
self.vts.get_mut(vt).unwrap().plane_state
|
||||
self.vts.get_mut(&handle.vt).unwrap().plane_state
|
||||
[plane.lock().unwrap().plane_index as usize] = new_state;
|
||||
Ok(0)
|
||||
}),
|
||||
@@ -1036,7 +1036,10 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
|
||||
// FIXME handle multi-plane framebuffers
|
||||
|
||||
let buffer = buffers.get(&data.handles()[0]).ok_or(Error::new(EINVAL))?;
|
||||
let buffer = handle
|
||||
.buffers
|
||||
.get(&data.handles()[0])
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let fb = self.adapter.create_framebuffer(buffer);
|
||||
|
||||
@@ -1056,13 +1059,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
}),
|
||||
ipc::MODE_OBJ_GET_PROPERTIES => {
|
||||
ipc::DrmModeObjGetProperties::with(payload, |mut data| {
|
||||
// FIXME remove once all drm objects are materialized in self.objects
|
||||
if data.obj_id() >= 1 << 11 {
|
||||
data.set_props_ptr(&[]);
|
||||
data.set_prop_values_ptr(&[]);
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let (props, prop_vals) = self
|
||||
.objects
|
||||
.get_object_properties_data(KmsObjectId(data.obj_id()))?;
|
||||
@@ -1073,7 +1069,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
})
|
||||
}
|
||||
ipc::MODE_CURSOR2 => ipc::DrmModeCursor2::with(payload, |data| {
|
||||
let vt_state = self.vts.get_mut(vt).unwrap();
|
||||
let vt_state = self.vts.get_mut(&handle.vt).unwrap();
|
||||
|
||||
let Some(cursor_plane) = &mut vt_state.cursor_plane else {
|
||||
return Err(Error::new(ENXIO));
|
||||
@@ -1083,7 +1079,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
if update_buffer {
|
||||
cursor_plane.buffer = if data.handle() == 0 {
|
||||
None
|
||||
} else if let Some(buffer) = buffers.get(&data.handle()) {
|
||||
} else if let Some(buffer) = handle.buffers.get(&data.handle()) {
|
||||
Some(buffer.clone())
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
@@ -1104,13 +1100,13 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
|
||||
let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, fb.buffer.clone());
|
||||
handle.next_id += 1;
|
||||
handle.buffers.insert(handle.next_id, fb.buffer.clone());
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pixel_format(fb.pixel_format as u32);
|
||||
data.set_handles([*next_id, 0, 0, 0]);
|
||||
data.set_handles([handle.next_id, 0, 0, 0]);
|
||||
data.set_pitches([fb.pitch, 0, 0, 0]);
|
||||
data.set_offsets([0; 4]);
|
||||
data.set_modifier([0; 4]);
|
||||
@@ -1131,12 +1127,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
) -> syscall::Result<usize> {
|
||||
// log::trace!("KSMSG MMAP {} {:?} {} {}", id, _flags, _offset, _size);
|
||||
let (framebuffer, offset) = match self.handles.get(id)? {
|
||||
Handle::V2 {
|
||||
Handle::V2(DrmHandle {
|
||||
vt: _,
|
||||
unique: _,
|
||||
next_id: _,
|
||||
buffers,
|
||||
} => (
|
||||
}) => (
|
||||
buffers
|
||||
.get(&((offset as usize / MAP_FAKE_OFFSET_MULTIPLIER) as u32))
|
||||
.ok_or(Error::new(EINVAL))
|
||||
|
||||
Reference in New Issue
Block a user