Port remaining drm ioctls to the new infrastructure

This commit is contained in:
bjorn3
2025-12-15 23:37:16 +01:00
parent c3f4711403
commit 0eb96178db
2 changed files with 241 additions and 2 deletions
+131
View File
@@ -432,6 +432,36 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
) -> Result<usize> {
use graphics_ipc::v2::ipc;
const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888
fn id_index(id: u32) -> u32 {
id & 0xFF
}
fn conn_id(i: u32) -> u32 {
id_index(i) | (1 << 8)
}
fn crtc_id(i: u32) -> u32 {
id_index(i) | (1 << 9)
}
fn enc_id(i: u32) -> u32 {
id_index(i) | (1 << 10)
}
fn fb_id(i: u32) -> u32 {
id_index(i) | (1 << 11)
}
fn fb_handle_id(i: u32) -> u32 {
id_index(i) | (1 << 12)
}
fn plane_id(i: u32) -> u32 {
id_index(i) | (1 << 13)
}
match self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
Handle::V1Screen { .. } => {
return Err(Error::new(EOPNOTSUPP));
@@ -467,6 +497,107 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
)?;
Ok(0)
}),
ipc::MODE_CARD_RES => ipc::DrmModeCardRes::with(payload, |mut data| {
let count = self.adapter.display_count();
let mut conn_ids = Vec::with_capacity(count);
let mut crtc_ids = Vec::with_capacity(count);
let mut enc_ids = Vec::with_capacity(count);
let mut fb_ids = Vec::with_capacity(count);
for i in 0..(count as u32) {
conn_ids.push(conn_id(i));
crtc_ids.push(crtc_id(i));
enc_ids.push(enc_id(i));
fb_ids.push(fb_id(i));
}
data.set_fb_id_ptr(&fb_ids);
data.set_crtc_id_ptr(&crtc_ids);
data.set_connector_id_ptr(&conn_ids);
data.set_encoder_id_ptr(&enc_ids);
data.set_min_width(0);
data.set_max_width(16384);
data.set_min_height(0);
data.set_max_height(16384);
Ok(0)
}),
ipc::MODE_GET_CRTC => ipc::DrmModeCrtc::with(payload, |mut data| {
let i = id_index(data.crtc_id());
let (width, height) = self.adapter.display_size(i as usize);
//TOOD: connectors
data.set_fb_id(fb_id(i));
data.set_x(0);
data.set_y(0);
data.set_gamma_size(0);
data.set_mode_valid(0);
//TODO: mode
data.set_mode(Default::default());
Ok(0)
}),
ipc::MODE_GET_ENCODER => ipc::DrmModeGetEncoder::with(payload, |mut data| {
let i = id_index(data.encoder_id());
let (width, height) = self.adapter.display_size(i as usize);
data.set_crtc_id(crtc_id(i));
data.set_possible_crtcs(1 << i);
data.set_possible_clones(1 << i);
Ok(0)
}),
ipc::MODE_GET_CONNECTOR => ipc::DrmModeGetConnector::with(payload, |mut data| {
let i = id_index(data.connector_id());
let (width, height) = self.adapter.display_size(i as usize);
data.set_modes_ptr(&[]);
data.set_props_ptr(&[]);
data.set_prop_values_ptr(&[]);
data.set_encoders_ptr(&[enc_id(i)]);
Ok(0)
}),
ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
let i = id_index(data.fb_id());
let (width, height) = self.adapter.display_size(i as usize);
data.set_width(width);
data.set_height(height);
data.set_pitch(width * 4); //TODO: stride
data.set_bpp(32);
data.set_depth(24);
data.set_handle(fb_handle_id(i));
Ok(0)
}),
ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| {
let count = self.adapter.display_count();
let mut ids = Vec::with_capacity(count);
for i in 0..(count as u32) {
ids.push(plane_id(i));
}
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 (width, height) = self.adapter.display_size(i as usize);
data.set_crtc_id(crtc_id(i));
data.set_fb_id(fb_id(i));
data.set_possible_crtcs(1 << i);
data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]);
Ok(0)
}),
ipc::MODE_OBJ_GET_PROPERTIES => {
ipc::DrmModeObjGetProperties::with(payload, |mut data| {
// TODO
data.set_props_ptr(&[]);
data.set_prop_values_ptr(&[]);
Ok(0)
})
}
ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
let i = id_index(data.fb_id());
let (width, height) = self.adapter.display_size(i as usize);
data.set_width(width);
data.set_height(height);
data.set_pixel_format(DRM_FORMAT_ARGB8888);
data.set_handles([fb_handle_id(i), 0, 0, 0]);
data.set_pitches([width * 4, 0, 0, 0]);
data.set_offsets([0; 4]);
data.set_modifier([0; 4]);
Ok(0)
}),
ipc::DISPLAY_COUNT => {
if payload.len() < size_of::<ipc::DisplayCount>() {
return Err(Error::new(EINVAL));
+110 -2
View File
@@ -188,7 +188,7 @@ pub mod ipc {
);
};
(struct $ioctl_ty:ident, $mem_ty:ident {
$field:ident: $ty:ty [array<$el:ident, $counted_by:ident>],
$field:ident: $ty:ty [array<$el:ty, $counted_by:ident>],
$($rest:tt)*
} =>
($($ioctl_fields:tt)*),
@@ -204,7 +204,7 @@ pub mod ipc {
};
(struct $ioctl_ty:ident, $mem_ty:ident {} =>
($($ioctl_field:ident: $ioctl_field_ty:ty,)*),
($($counted_field:ident: $counted_ty:ty [array<$el:ident, $counted_by:ident>],)*),
($($counted_field:ident: $counted_ty:ty [array<$el:ty, $counted_by:ident>],)*),
($($noncounted_field:ident: $noncounted_ty:ty,)*)
) => {
pub use drm_sys::$ioctl_ty;
@@ -380,6 +380,114 @@ pub mod ipc {
}
}
pub const MODE_GET_CRTC: u64 = 0xA1;
define_ioctl_data! {
struct drm_mode_crtc, DrmModeCrtc {
set_connectors_ptr: u64,
count_connectors: u32,
crtc_id: u32,
fb_id: u32,
x: u32,
y: u32,
gamma_size: u32,
mode_valid: u32,
mode: drm_sys::drm_mode_modeinfo,
}
}
pub const MODE_GET_ENCODER: u64 = 0xA6;
define_ioctl_data! {
struct drm_mode_get_encoder, DrmModeGetEncoder {
encoder_id: u32,
encoder_type: u32,
crtc_id: u32,
possible_crtcs: u32,
possible_clones: u32,
}
}
pub const MODE_GET_CONNECTOR: u64 = 0xA7;
define_ioctl_data! {
struct drm_mode_get_connector, DrmModeGetConnector {
encoders_ptr: u64 [array<u32, count_encoders>],
modes_ptr: u64 [array<drm_sys::drm_mode_modeinfo, count_modes>],
props_ptr: u64 [array<u32, count_props>],
prop_values_ptr: u64 [array<u64, count_props>],
count_modes: u32,
count_props: u32,
count_encoders: u32,
encoder_id: u32,
connector_id: u32,
connector_type: u32,
connector_type_id: u32,
connection: u32,
mm_width: u32,
mm_height: u32,
subpixel: u32,
pad: u32,
}
}
pub const MODE_GET_FB: u64 = 0xAD;
define_ioctl_data! {
struct drm_mode_fb_cmd, DrmModeFbCmd {
fb_id: u32,
width: u32,
height: u32,
pitch: u32,
bpp: u32,
depth: u32,
handle: u32,
}
}
pub const MODE_GET_PLANE_RES: u64 = 0xB5;
define_ioctl_data! {
struct drm_mode_get_plane_res, DrmModeGetPlaneRes {
plane_id_ptr: u64 [array<u32, count_planes>],
count_planes: u32,
}
}
pub const MODE_GET_PLANE: u64 = 0xB6;
define_ioctl_data! {
struct drm_mode_get_plane, DrmModeGetPlane {
plane_id: u32,
crtc_id: u32,
fb_id: u32,
possible_crtcs: u32,
gamma_size: u32,
count_format_types: u32,
format_type_ptr: u64 [array<u32, count_format_types>],
}
}
pub const MODE_OBJ_GET_PROPERTIES: u64 = 0xB9;
define_ioctl_data! {
struct drm_mode_obj_get_properties, DrmModeObjGetProperties {
props_ptr: u64 [array<u32, count_props>],
prop_values_ptr: u64 [array<u64, count_props>],
count_props: u32,
obj_id: u32,
obj_type: u32,
}
}
pub const MODE_GET_FB2: u64 = 0xCE;
define_ioctl_data! {
struct drm_mode_fb_cmd2, DrmModeFbCmd2 {
fb_id: u32,
width: u32,
height: u32,
pixel_format: u32,
flags: u32,
handles: [u32; 4],
pitches: [u32; 4],
offsets: [u32; 4],
modifier: [u64; 4],
}
}
// FIXME replace these with proper drm interfaces
pub const DISPLAY_COUNT: u64 = 1;
#[repr(C, packed)]