Merge branch 'gpu_drm40' into 'main'
drivers/graphics/driver-graphics: Implement some things that libdrm needs See merge request redox-os/base!265
This commit is contained in:
Generated
+2
-1
@@ -1073,6 +1073,7 @@ dependencies = [
|
||||
"common",
|
||||
"daemon",
|
||||
"driver-graphics",
|
||||
"drm-fourcc",
|
||||
"drm-sys",
|
||||
"edid",
|
||||
"embedded-hal",
|
||||
@@ -1823,7 +1824,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "redox-ioctl"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#36d2efa33444d26a584d3e6cb17ba108079c24ea"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#546bc6fb21b990ca9195a1115717c9a842fe4909"
|
||||
dependencies = [
|
||||
"drm-sys",
|
||||
"redox_syscall 0.7.5",
|
||||
|
||||
@@ -79,6 +79,7 @@ anyhow = "1"
|
||||
bitflags = "2"
|
||||
clap = "4"
|
||||
drm = "0.15.0"
|
||||
drm-fourcc = "2.2.0"
|
||||
drm-sys = "0.8.1"
|
||||
edid = "0.3.0" #TODO: edid is abandoned, fork it and maintain?
|
||||
fdt = "0.1.5"
|
||||
|
||||
@@ -5,7 +5,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
drm-fourcc = "2.2.0"
|
||||
drm-fourcc.workspace = true
|
||||
drm-sys.workspace = true
|
||||
edid.workspace = true #TODO: edid is abandoned, fork it and maintain?
|
||||
log.workspace = true
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
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_PROPERTY,
|
||||
@@ -235,9 +236,8 @@ define_object_props!(object, KmsCrtc<T: GraphicsAdapter> {
|
||||
pub struct KmsFramebuffer<T: GraphicsAdapter> {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub pixel_format: DrmFourcc,
|
||||
pub pitch: u32,
|
||||
pub bpp: u32,
|
||||
pub depth: u32,
|
||||
pub buffer: Arc<T::Buffer>,
|
||||
pub driver_data: T::Framebuffer,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::c_char;
|
||||
use std::fmt::Debug;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
@@ -90,6 +91,7 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>);
|
||||
|
||||
fn get_unique(&self) -> String;
|
||||
fn get_cap(&self, cap: u32) -> Result<u64>;
|
||||
fn set_client_cap(&self, cap: u32, value: u64) -> Result<()>;
|
||||
|
||||
@@ -281,6 +283,7 @@ struct VtState<T: GraphicsAdapter> {
|
||||
enum Handle<T: GraphicsAdapter> {
|
||||
V2 {
|
||||
vt: usize,
|
||||
unique: Option<String>,
|
||||
next_id: u32,
|
||||
buffers: HashMap<u32, Arc<T::Buffer>>,
|
||||
},
|
||||
@@ -414,6 +417,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
Handle::V2 {
|
||||
vt,
|
||||
unique: None,
|
||||
next_id: 0,
|
||||
buffers: HashMap::new(),
|
||||
}
|
||||
@@ -427,11 +431,17 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
})
|
||||
}
|
||||
|
||||
fn fstat(&mut self, _id: usize, stat: &mut syscall::Stat, _ctx: &CallerCtx) -> Result<()> {
|
||||
stat.st_dev = 226 /*DRM_MAJOR*/ << 8;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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 {
|
||||
vt,
|
||||
unique: _,
|
||||
next_id: _,
|
||||
buffers: _,
|
||||
} => write!(w, "v2/{vt}").unwrap(),
|
||||
@@ -462,6 +472,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
|
||||
Handle::V2 {
|
||||
vt,
|
||||
unique,
|
||||
next_id,
|
||||
buffers,
|
||||
} => match metadata[0] {
|
||||
@@ -476,12 +487,39 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::GET_UNIQUE => ipc::DrmUnique::with(payload, |mut data| {
|
||||
if let Some(unique) = unique {
|
||||
data.set_unique(unsafe {
|
||||
mem::transmute::<&[u8], &[c_char]>(unique.as_bytes())
|
||||
});
|
||||
} else {
|
||||
data.set_unique_len(0);
|
||||
}
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::SET_VERSION => ipc::DrmSetVersion::with(payload, |mut data| {
|
||||
// We only support version 1.4 currently
|
||||
if data.drm_di_major() != 0 || data.drm_di_minor() != 4 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
if data.drm_dd_major() != 0 || data.drm_dd_minor() != 4 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
data.set_drm_di_major(1);
|
||||
data.set_drm_di_minor(4);
|
||||
data.set_drm_dd_major(1);
|
||||
data.set_drm_dd_minor(4);
|
||||
|
||||
*unique = Some(self.adapter.get_unique());
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::GET_CAP => ipc::DrmGetCap::with(payload, |mut data| {
|
||||
data.set_value(
|
||||
self.adapter.get_cap(
|
||||
data.capability()
|
||||
.try_into()
|
||||
.map_err(|_| syscall::Error::new(EINVAL))?,
|
||||
.map_err(|_| Error::new(EINVAL))?,
|
||||
)?,
|
||||
);
|
||||
Ok(0)
|
||||
@@ -490,7 +528,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
self.adapter.set_client_cap(
|
||||
data.capability()
|
||||
.try_into()
|
||||
.map_err(|_| syscall::Error::new(EINVAL))?,
|
||||
.map_err(|_| Error::new(EINVAL))?,
|
||||
data.value(),
|
||||
)?;
|
||||
Ok(0)
|
||||
@@ -733,28 +771,42 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
let (bpp, depth) = match fb.pixel_format {
|
||||
DrmFourcc::Xrgb8888 => (32, 24),
|
||||
DrmFourcc::Argb8888 => (32, 32),
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, fb.buffer.clone());
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pitch(fb.pitch);
|
||||
data.set_bpp(fb.bpp);
|
||||
data.set_depth(fb.depth);
|
||||
data.set_bpp(bpp);
|
||||
data.set_depth(depth);
|
||||
data.set_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))?;
|
||||
|
||||
if data.bpp() != 32 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let pixel_format = match data.depth() {
|
||||
24 => DrmFourcc::Xrgb8888,
|
||||
32 => DrmFourcc::Argb8888,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
|
||||
let fb = self.adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = self.objects.add_framebuffer(objects::KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format,
|
||||
pitch: data.pitch(),
|
||||
bpp: data.bpp(),
|
||||
depth: data.depth(),
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
@@ -877,6 +929,27 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
data.set_plane_id_ptr(&ids);
|
||||
Ok(0)
|
||||
}),
|
||||
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 fb = self.adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = self.objects.add_framebuffer(objects::KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pixel_format: DrmFourcc::try_from(data.pixel_format())
|
||||
.map_err(|_| Error::new(EINVAL))?,
|
||||
pitch: data.pitches()[0],
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| {
|
||||
let i = id_index(data.plane_id());
|
||||
let crtc_id = self.objects.crtc_ids()[i as usize];
|
||||
@@ -949,9 +1022,9 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pixel_format(DrmFourcc::Argb8888 as u32);
|
||||
data.set_pixel_format(fb.pixel_format as u32);
|
||||
data.set_handles([*next_id, 0, 0, 0]);
|
||||
data.set_pitches([fb.width * 4, 0, 0, 0]);
|
||||
data.set_pitches([fb.pitch, 0, 0, 0]);
|
||||
data.set_offsets([0; 4]);
|
||||
data.set_modifier([0; 4]);
|
||||
Ok(0)
|
||||
@@ -973,6 +1046,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
let (framebuffer, offset) = match self.handles.get(id)? {
|
||||
Handle::V2 {
|
||||
vt: _,
|
||||
unique: _,
|
||||
next_id: _,
|
||||
buffers,
|
||||
} => (
|
||||
|
||||
@@ -6,6 +6,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitbang-hal = "0.3"
|
||||
drm-fourcc.workspace = true
|
||||
drm-sys.workspace = true
|
||||
edid.workspace = true #TODO: edid is abandoned, fork it and maintain?
|
||||
#TODO: waiting for bitbang-hal to update to embedded-hal 1.0
|
||||
|
||||
@@ -4,6 +4,7 @@ use common::{
|
||||
};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsFramebuffer, KmsObjects};
|
||||
use drm_fourcc::DrmFourcc;
|
||||
use pcid_interface::{PciFunction, PciFunctionHandle};
|
||||
use range_alloc::RangeAllocator;
|
||||
use std::{collections::VecDeque, fmt, mem, sync::Arc};
|
||||
@@ -168,6 +169,7 @@ enum VideoInput {
|
||||
}
|
||||
|
||||
pub struct Device {
|
||||
unique: String,
|
||||
kind: DeviceKind,
|
||||
alloc_buffers: RangeAllocator<u32>,
|
||||
bios: Option<Bios>,
|
||||
@@ -426,6 +428,7 @@ impl Device {
|
||||
//TODO: get number of available buffers
|
||||
let buffers = 1024;
|
||||
Ok(Self {
|
||||
unique: format!("pci:{}", pcid_handle.config().func.addr),
|
||||
kind,
|
||||
alloc_buffers: RangeAllocator::new(0..buffers),
|
||||
bios,
|
||||
@@ -764,9 +767,8 @@ impl Device {
|
||||
let fb = KmsFramebuffer {
|
||||
width,
|
||||
height,
|
||||
pixel_format: DrmFourcc::Argb8888,
|
||||
pitch: stride,
|
||||
bpp: 32,
|
||||
depth: 32,
|
||||
buffer: Arc::new(buffer),
|
||||
driver_data: (),
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use common::io::{Io, MmioPtr};
|
||||
use driver_graphics::kms::objects::KmsFramebuffer;
|
||||
use drm_fourcc::DrmFourcc;
|
||||
use range_alloc::RangeAllocator;
|
||||
use syscall::error::Result;
|
||||
use syscall::{Error, EIO};
|
||||
@@ -94,9 +95,8 @@ impl Plane {
|
||||
KmsFramebuffer {
|
||||
width,
|
||||
height,
|
||||
pixel_format: DrmFourcc::Argb8888,
|
||||
pitch: stride,
|
||||
bpp: 32,
|
||||
depth: 32,
|
||||
buffer: Arc::new(buffer),
|
||||
driver_data: (),
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@ impl GraphicsAdapter for Device {
|
||||
self.init_inner(objects);
|
||||
}
|
||||
|
||||
fn get_unique(&self) -> String {
|
||||
self.unique.clone()
|
||||
}
|
||||
|
||||
fn get_cap(&self, cap: u32) -> syscall::Result<u64> {
|
||||
match cap {
|
||||
DRM_CAP_DUMB_BUFFER => Ok(1),
|
||||
|
||||
@@ -59,6 +59,10 @@ impl GraphicsAdapter for FbAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_unique(&self) -> String {
|
||||
format!("vesad:{:x}", self.framebuffers[0].phys)
|
||||
}
|
||||
|
||||
fn get_cap(&self, cap: u32) -> syscall::Result<u64> {
|
||||
match cap {
|
||||
DRM_CAP_DUMB_BUFFER => Ok(1),
|
||||
|
||||
@@ -534,6 +534,7 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
|
||||
EventQueue::new().expect("virtio-gpud: failed to create event queue");
|
||||
|
||||
let mut scheme = scheme::GpuScheme::new(
|
||||
format!("pci:{}", pcid_handle.config().func.addr),
|
||||
config,
|
||||
control_queue.clone(),
|
||||
cursor_queue.clone(),
|
||||
|
||||
@@ -88,6 +88,7 @@ pub struct Display {
|
||||
}
|
||||
|
||||
pub struct VirtGpuAdapter<'a> {
|
||||
unique: String,
|
||||
pub config: &'a mut GpuConfig,
|
||||
control_queue: Arc<Queue<'a>>,
|
||||
cursor_queue: Arc<Queue<'a>>,
|
||||
@@ -364,6 +365,10 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_unique(&self) -> String {
|
||||
self.unique.clone()
|
||||
}
|
||||
|
||||
fn get_cap(&self, cap: u32) -> syscall::Result<u64> {
|
||||
match cap {
|
||||
DRM_CAP_DUMB_BUFFER => Ok(1),
|
||||
@@ -521,6 +526,7 @@ pub struct GpuScheme {}
|
||||
|
||||
impl<'a> GpuScheme {
|
||||
pub fn new(
|
||||
unique: String,
|
||||
config: &'a mut GpuConfig,
|
||||
control_queue: Arc<Queue<'a>>,
|
||||
cursor_queue: Arc<Queue<'a>>,
|
||||
@@ -528,6 +534,7 @@ impl<'a> GpuScheme {
|
||||
has_edid: bool,
|
||||
) -> Result<GraphicsScheme<VirtGpuAdapter<'a>>, Error> {
|
||||
let adapter = VirtGpuAdapter {
|
||||
unique,
|
||||
config,
|
||||
control_queue,
|
||||
cursor_queue,
|
||||
|
||||
Reference in New Issue
Block a user