Merge branch 'gpu_drm27' into 'main'
Remove last custom DRM ioctl See merge request redox-os/base!176
This commit is contained in:
Generated
+1
-10
@@ -593,10 +593,10 @@ dependencies = [
|
||||
"common",
|
||||
"drm-sys",
|
||||
"edid",
|
||||
"graphics-ipc",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"log",
|
||||
"redox-ioctl",
|
||||
"redox-scheme",
|
||||
"redox_syscall 0.7.3",
|
||||
]
|
||||
@@ -932,13 +932,7 @@ dependencies = [
|
||||
name = "graphics-ipc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"drm",
|
||||
"libredox",
|
||||
"log",
|
||||
"plain",
|
||||
"redox-ioctl",
|
||||
"redox_syscall 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1088,7 +1082,6 @@ dependencies = [
|
||||
"drm-sys",
|
||||
"edid",
|
||||
"embedded-hal",
|
||||
"graphics-ipc",
|
||||
"libredox",
|
||||
"log",
|
||||
"nb 1.1.0",
|
||||
@@ -2514,7 +2507,6 @@ dependencies = [
|
||||
"daemon",
|
||||
"driver-graphics",
|
||||
"drm-sys",
|
||||
"graphics-ipc",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
"ransid",
|
||||
@@ -2569,7 +2561,6 @@ dependencies = [
|
||||
"driver-graphics",
|
||||
"drm-sys",
|
||||
"futures",
|
||||
"graphics-ipc",
|
||||
"libredox",
|
||||
"log",
|
||||
"orbclient",
|
||||
|
||||
@@ -7,9 +7,49 @@ use std::{cmp, io, mem, ptr};
|
||||
use drm::buffer::{Buffer, DrmFourcc};
|
||||
use drm::control::dumbbuffer::{DumbBuffer, DumbMapping};
|
||||
use drm::control::{framebuffer, ClipRect, Device};
|
||||
use graphics_ipc::v2::{Damage, V2GraphicsHandle};
|
||||
use graphics_ipc::V2GraphicsHandle;
|
||||
use orbclient::FONT;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
pub struct Damage {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
pub const NONE: Self = Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
pub fn merge(self, other: Self) -> Self {
|
||||
if self.width == 0 || self.height == 0 {
|
||||
return other;
|
||||
}
|
||||
|
||||
if other.width == 0 || other.height == 0 {
|
||||
return self;
|
||||
}
|
||||
|
||||
let x = cmp::min(self.x, other.x);
|
||||
let y = cmp::min(self.y, other.y);
|
||||
let x2 = cmp::max(self.x + self.width, other.x + other.width);
|
||||
let y2 = cmp::max(self.y + self.height, other.y + other.height);
|
||||
|
||||
Damage {
|
||||
x,
|
||||
y,
|
||||
width: x2 - x,
|
||||
height: y2 - y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct V2DisplayMap {
|
||||
pub display_handle: V2GraphicsHandle,
|
||||
fb: framebuffer::Handle,
|
||||
|
||||
@@ -9,12 +9,12 @@ drm-sys.workspace = true
|
||||
#TODO: edid is abandoned, fork it an maintain?
|
||||
edid = "0.3.0"
|
||||
log.workspace = true
|
||||
redox-ioctl.workspace = true
|
||||
redox-scheme.workspace = true
|
||||
redox_syscall.workspace = true
|
||||
libredox.workspace = true
|
||||
|
||||
common = { path = "../../common" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
inputd = { path = "../../inputd" }
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#![feature(macro_metavar_expr)]
|
||||
#![feature(slice_as_array)]
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::ffi::c_char;
|
||||
use std::fmt::Debug;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::mem;
|
||||
use std::mem::transmute;
|
||||
use std::os::fd::BorrowedFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{cmp, mem};
|
||||
|
||||
use drm_sys::{
|
||||
drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE,
|
||||
@@ -17,7 +15,6 @@ use drm_sys::{
|
||||
DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE,
|
||||
DRM_PROP_NAME_LEN,
|
||||
};
|
||||
use graphics_ipc::v2::Damage;
|
||||
use inputd::{DisplayHandle, VtEventKind};
|
||||
use libredox::Fd;
|
||||
use redox_scheme::scheme::{register_scheme_inner, SchemeState, SchemeSync};
|
||||
@@ -31,6 +28,56 @@ use crate::kms::properties::KmsPropertyKind;
|
||||
|
||||
pub mod kms;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
pub struct Damage {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
fn merge(self, other: Self) -> Self {
|
||||
if self.width == 0 || self.height == 0 {
|
||||
return other;
|
||||
}
|
||||
|
||||
if other.width == 0 || other.height == 0 {
|
||||
return self;
|
||||
}
|
||||
|
||||
let x = cmp::min(self.x, other.x);
|
||||
let y = cmp::min(self.y, other.y);
|
||||
let x2 = cmp::max(self.x + self.width, other.x + other.width);
|
||||
let y2 = cmp::max(self.y + self.height, other.y + other.height);
|
||||
|
||||
Damage {
|
||||
x,
|
||||
y,
|
||||
width: x2 - x,
|
||||
height: y2 - y,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn clip(mut self, width: u32, height: u32) -> Self {
|
||||
// Clip damage
|
||||
let x2 = self.x + self.width;
|
||||
self.x = cmp::min(self.x, width);
|
||||
if x2 > width {
|
||||
self.width = width - self.x;
|
||||
}
|
||||
|
||||
let y2 = self.y + self.height;
|
||||
self.y = cmp::min(self.y, height);
|
||||
if y2 > height {
|
||||
self.height = height - self.y;
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GraphicsAdapter: Sized + Debug {
|
||||
type Connector: Debug;
|
||||
type Crtc: Debug;
|
||||
@@ -425,7 +472,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
metadata: &[u64],
|
||||
_ctx: &CallerCtx,
|
||||
) -> Result<usize> {
|
||||
use graphics_ipc::v2::ipc;
|
||||
use redox_ioctl::drm as ipc;
|
||||
|
||||
const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888
|
||||
|
||||
@@ -953,55 +1000,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
data.set_modifier([0; 4]);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::UPDATE_PLANE => {
|
||||
if payload.len() < size_of::<ipc::UpdatePlane>() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let payload = unsafe {
|
||||
transmute::<&mut [u8; size_of::<ipc::UpdatePlane>()], &mut ipc::UpdatePlane>(
|
||||
payload.as_mut_array().unwrap(),
|
||||
)
|
||||
};
|
||||
|
||||
let display_id = payload.display_id;
|
||||
let Some(crtc) = self.objects.crtcs().nth(display_id) else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let fb = if payload.fb_id == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self.objects.get_framebuffer(KmsObjectId(payload.fb_id))?)
|
||||
};
|
||||
|
||||
self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if payload.fb_id == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(KmsObjectId(payload.fb_id))
|
||||
};
|
||||
|
||||
if *vt == self.active_vt {
|
||||
crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id);
|
||||
|
||||
let mode =
|
||||
fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height));
|
||||
|
||||
self.adapter.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
&[self.objects.connector_ids()[display_id]],
|
||||
mode,
|
||||
fb,
|
||||
payload.damage,
|
||||
);
|
||||
|
||||
crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id);
|
||||
crtc.lock().unwrap().target_connectors =
|
||||
vec![self.objects.connector_ids()[display_id]];
|
||||
}
|
||||
|
||||
Ok(size_of::<ipc::UpdatePlane>())
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::cmp;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use console_draw::{TextScreen, V2DisplayMap};
|
||||
use console_draw::{Damage, TextScreen, V2DisplayMap};
|
||||
use drm::buffer::Buffer;
|
||||
use drm::control::Device;
|
||||
use graphics_ipc::v2::{Damage, V2GraphicsHandle};
|
||||
use graphics_ipc::V2GraphicsHandle;
|
||||
use inputd::ConsumerHandle;
|
||||
use orbclient::{Event, EventOption};
|
||||
use redox_scheme::scheme::SchemeSync;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use console_draw::{TextScreen, V2DisplayMap};
|
||||
use console_draw::{Damage, TextScreen, V2DisplayMap};
|
||||
use drm::buffer::Buffer;
|
||||
use drm::control::Device;
|
||||
use graphics_ipc::v2::{Damage, V2GraphicsHandle};
|
||||
use graphics_ipc::V2GraphicsHandle;
|
||||
use inputd::ConsumerHandle;
|
||||
use std::io;
|
||||
|
||||
|
||||
@@ -6,13 +6,6 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
drm.workspace = true
|
||||
log.workspace = true
|
||||
libredox.workspace = true
|
||||
plain = "0.2"
|
||||
redox-ioctl.workspace = true
|
||||
redox_syscall.workspace = true
|
||||
|
||||
common = { path = "../../common" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use std::cmp;
|
||||
|
||||
// Keep synced with orbital's SyncRect
|
||||
// Technically orbital uses i32 rather than u32, but values larger than i32::MAX
|
||||
// would be a bug anyway.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, packed)]
|
||||
pub struct Damage {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Damage {
|
||||
pub const NONE: Self = Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
pub fn merge(self, other: Self) -> Self {
|
||||
if self.width == 0 || self.height == 0 {
|
||||
return other;
|
||||
}
|
||||
|
||||
if other.width == 0 || other.height == 0 {
|
||||
return self;
|
||||
}
|
||||
|
||||
let x = cmp::min(self.x, other.x);
|
||||
let y = cmp::min(self.y, other.y);
|
||||
let x2 = cmp::max(self.x + self.width, other.x + other.width);
|
||||
let y2 = cmp::max(self.y + self.height, other.y + other.height);
|
||||
|
||||
Damage {
|
||||
x,
|
||||
y,
|
||||
width: x2 - x,
|
||||
height: y2 - y,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn clip(mut self, width: u32, height: u32) -> Self {
|
||||
// Clip damage
|
||||
let x2 = self.x + self.width;
|
||||
self.x = cmp::min(self.x, width);
|
||||
if x2 > width {
|
||||
self.width = width - self.x;
|
||||
}
|
||||
|
||||
let y2 = self.y + self.height;
|
||||
self.y = cmp::min(self.y, height);
|
||||
if y2 > height {
|
||||
self.height = height - self.y;
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,42 @@
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::os::fd::{AsFd, BorrowedFd};
|
||||
|
||||
mod common;
|
||||
pub mod v2;
|
||||
use drm::control::connector::{self, State};
|
||||
use drm::control::Device as _;
|
||||
use drm::{Device as _, DriverCapability};
|
||||
|
||||
/// A graphics handle using the v2 graphics API.
|
||||
///
|
||||
/// The v2 graphics API allows creating framebuffers on the fly, using them for page flipping and
|
||||
/// handles all displays using a single fd. This is basically a subset of the Linux DRM interface
|
||||
/// with a couple of custom ioctls in the place of the KMS ioctls that are missing.
|
||||
pub struct V2GraphicsHandle {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl AsFd for V2GraphicsHandle {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
self.file.as_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl drm::Device for V2GraphicsHandle {}
|
||||
impl drm::control::Device for V2GraphicsHandle {}
|
||||
|
||||
impl V2GraphicsHandle {
|
||||
pub fn from_file(file: File) -> io::Result<Self> {
|
||||
let handle = V2GraphicsHandle { file };
|
||||
assert!(handle.get_driver_capability(DriverCapability::DumbBuffer)? == 1);
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub fn first_display(&self) -> io::Result<connector::Handle> {
|
||||
for &connector in self.resource_handles().unwrap().connectors() {
|
||||
if self.get_connector(connector, true)?.state() == State::Connected {
|
||||
return Ok(connector);
|
||||
}
|
||||
}
|
||||
Err(io::Error::other("no connected display"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::os::fd::{AsFd, BorrowedFd};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
use drm::control::connector::{self, State};
|
||||
use drm::control::Device as _;
|
||||
use drm::{Device as _, DriverCapability};
|
||||
use syscall::CallFlags;
|
||||
|
||||
pub use crate::common::Damage;
|
||||
|
||||
/// A graphics handle using the v2 graphics API.
|
||||
///
|
||||
/// The v2 graphics API allows creating framebuffers on the fly, using them for page flipping and
|
||||
/// handles all displays using a single fd. This is basically a subset of the Linux DRM interface
|
||||
/// with a couple of custom ioctls in the place of the KMS ioctls that are missing.
|
||||
pub struct V2GraphicsHandle {
|
||||
file: File,
|
||||
}
|
||||
|
||||
impl AsFd for V2GraphicsHandle {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
self.file.as_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl drm::Device for V2GraphicsHandle {}
|
||||
impl drm::control::Device for V2GraphicsHandle {}
|
||||
|
||||
impl V2GraphicsHandle {
|
||||
pub fn from_file(file: File) -> io::Result<Self> {
|
||||
let handle = V2GraphicsHandle { file };
|
||||
assert!(handle.get_driver_capability(DriverCapability::DumbBuffer)? == 1);
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub fn first_display(&self) -> io::Result<connector::Handle> {
|
||||
for &connector in self.resource_handles().unwrap().connectors() {
|
||||
if self.get_connector(connector, true)?.state() == State::Connected {
|
||||
return Ok(connector);
|
||||
}
|
||||
}
|
||||
Err(io::Error::other("no connected display"))
|
||||
}
|
||||
|
||||
pub fn update_plane(&self, display_id: usize, fb_id: u32, damage: Damage) -> io::Result<()> {
|
||||
let cmd = ipc::UpdatePlane {
|
||||
display_id,
|
||||
fb_id,
|
||||
damage,
|
||||
};
|
||||
libredox::call::call_wo(
|
||||
self.file.as_raw_fd() as usize,
|
||||
unsafe { plain::as_bytes(&cmd) },
|
||||
CallFlags::empty(),
|
||||
&[ipc::UPDATE_PLANE, 0, 0],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub mod ipc {
|
||||
use crate::common::Damage;
|
||||
|
||||
pub use redox_ioctl::drm::*;
|
||||
|
||||
// FIXME replace these with proper drm interfaces and update orbital
|
||||
pub const UPDATE_PLANE: u64 = 0x12345670;
|
||||
#[repr(C, packed)]
|
||||
pub struct UpdatePlane {
|
||||
pub display_id: usize,
|
||||
pub fb_id: u32,
|
||||
pub damage: Damage,
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ void = "1.0"
|
||||
common = { path = "../../common" }
|
||||
daemon = { path = "../../../daemon" }
|
||||
driver-graphics = { path = "../driver-graphics" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
pcid = { path = "../../pcid" }
|
||||
|
||||
libredox.workspace = true
|
||||
|
||||
@@ -8,10 +8,10 @@ use std::sync::Mutex;
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::properties::DPMS;
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter};
|
||||
use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON};
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
use graphics_ipc::v2::Damage;
|
||||
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
|
||||
use drm_sys::{
|
||||
drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON,
|
||||
};
|
||||
use syscall::{error::EINVAL, PAGE_SIZE};
|
||||
|
||||
use super::Device;
|
||||
|
||||
@@ -14,7 +14,6 @@ redox_event.workspace = true
|
||||
common = { path = "../../common" }
|
||||
daemon = { path = "../../../daemon" }
|
||||
driver-graphics = { path = "../driver-graphics" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
libredox.workspace = true
|
||||
|
||||
[features]
|
||||
|
||||
@@ -6,10 +6,10 @@ use std::sync::Mutex;
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::properties::DPMS;
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter};
|
||||
use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON};
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
use graphics_ipc::v2::Damage;
|
||||
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
|
||||
use drm_sys::{
|
||||
drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON,
|
||||
};
|
||||
use syscall::{EINVAL, PAGE_SIZE};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -15,7 +15,6 @@ anyhow.workspace = true
|
||||
common = { path = "../../common" }
|
||||
daemon = { path = "../../../daemon" }
|
||||
driver-graphics = { path = "../driver-graphics" }
|
||||
graphics-ipc = { path = "../graphics-ipc" }
|
||||
virtio-core = { path = "../../virtio-core" }
|
||||
pcid = { path = "../../pcid" }
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ use common::{dma::Dma, sgl};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::properties::{DPMS, EDID};
|
||||
use driver_graphics::{Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme};
|
||||
use drm_sys::{drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_MODE_DPMS_ON};
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
use graphics_ipc::v2::Damage;
|
||||
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_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, DRM_MODE_DPMS_ON,
|
||||
};
|
||||
|
||||
use syscall::{EINVAL, PAGE_SIZE};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user