Merge branch 'gpu_drm' into 'main'

drivers/graphics/graphics-ipc: Add counterparts for the VERSION, GET_CAP and...

See merge request redox-os/base!62
This commit is contained in:
Jeremy Soller
2025-12-14 09:54:39 -07:00
4 changed files with 119 additions and 2 deletions
@@ -18,6 +18,12 @@ pub trait GraphicsAdapter {
type Framebuffer: Framebuffer;
type Cursor: CursorFramebuffer;
fn name(&self) -> [u8;16];
fn desc(&self) -> [u8;16];
fn get_cap(&self, cap: u64) -> Result<u64>;
fn set_client_cap(&self, cap: u64, value: u64) -> Result<()>;
/// The maximum amount of displays that could be attached.
///
/// This must be constant for the lifetime of the graphics adapter.
@@ -430,6 +436,36 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
return Err(Error::new(EOPNOTSUPP));
}
Handle::V2 { vt, next_id, fbs } => match metadata[0] {
ipc::VERSION => {
if payload.len() < size_of::<ipc::Version>() {
return Err(Error::new(EINVAL));
}
let payload = unsafe {
transmute::<&mut [u8; size_of::<ipc::Version>()], &mut ipc::Version>(
payload.as_mut_array().unwrap(),
)
};
payload.version_major = 1;
payload.version_minor = 4;
payload.version_patchlevel = 0;
payload.name = self.adapter.name();
payload.desc = self.adapter.desc();
Ok(size_of::<ipc::DisplayCount>())
}
ipc::GET_CAP => {
if payload.len() < size_of::<ipc::GetCap>() {
return Err(Error::new(EINVAL));
}
let payload = unsafe {
transmute::<&mut [u8; size_of::<ipc::GetCap>()], &mut ipc::GetCap>(
payload.as_mut_array().unwrap(),
)
};
payload.value = self.adapter.get_cap(payload.capability)?;
Ok(size_of::<ipc::DisplayCount>())
}
ipc::DISPLAY_COUNT => {
if payload.len() < size_of::<ipc::DisplayCount>() {
return Err(Error::new(EINVAL));
+28
View File
@@ -153,6 +153,34 @@ impl V2GraphicsHandle {
pub mod ipc {
use crate::common::Damage;
pub const VERSION: u64 = 0;
#[repr(C, packed)]
pub struct Version {
pub version_major: u32,
pub version_minor: u32,
pub version_patchlevel: u32,
// FIXME allow variable sized fields
pub name: [u8; 16],
pub desc: [u8; 16],
}
pub const GET_CAP: u64 = 0x0C;
pub const CAP_DUMB_BUFFER: u64 = 0x1;
#[repr(C, packed)]
pub struct GetCap {
pub capability: u64,
pub value: u64,
}
pub const SET_CLIENT_CAP: u64 = 0x0D;
pub const CLIENT_CAP_CURSOR_PLANE_HOTSPOT: u64 = 6;
#[repr(C, packed)]
pub struct SetClientCap {
pub capability: u64,
pub value: u64,
}
// FIXME replace these with proper drm interfaces
pub const DISPLAY_COUNT: u64 = 1;
#[repr(C, packed)]
pub struct DisplayCount {
+26 -1
View File
@@ -4,7 +4,8 @@ use std::ptr::{self, NonNull};
use driver_graphics::{CursorFramebuffer, CursorPlane, Framebuffer, GraphicsAdapter};
use graphics_ipc::v1::Damage;
use syscall::PAGE_SIZE;
use graphics_ipc::v2::ipc::{CAP_DUMB_BUFFER, CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use syscall::{EINVAL, PAGE_SIZE};
pub struct FbAdapter {
pub framebuffers: Vec<FrameBuffer>,
@@ -18,6 +19,30 @@ impl GraphicsAdapter for FbAdapter {
type Framebuffer = GraphicScreen;
type Cursor = VesadCursor;
fn name(&self) -> [u8; 16] {
[
b'v', b'e', b's', b'a', b'd', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]
}
fn desc(&self) -> [u8; 16] {
[b'V', b'E', b'S', b'A', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
fn get_cap(&self, cap: u64) -> syscall::Result<u64> {
match cap {
CAP_DUMB_BUFFER => Ok(1),
_ => Err(syscall::Error::new(EINVAL))
}
}
fn set_client_cap(&self, cap: u64, _value: u64) -> syscall::Result<()> {
match cap {
CLIENT_CAP_CURSOR_PLANE_HOTSPOT => Ok(()),
_ => Err(syscall::Error::new(EINVAL))
}
}
fn display_count(&self) -> usize {
self.framebuffers.len()
}
+29 -1
View File
@@ -5,9 +5,10 @@ use driver_graphics::{
CursorFramebuffer, CursorPlane, Framebuffer, GraphicsAdapter, GraphicsScheme,
};
use graphics_ipc::v1::Damage;
use graphics_ipc::v2::ipc::{CAP_DUMB_BUFFER, CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
use inputd::DisplayHandle;
use syscall::PAGE_SIZE;
use syscall::{EINVAL, PAGE_SIZE};
use virtio_core::spec::{Buffer, ChainBuilder, DescriptorFlags};
use virtio_core::transport::{Error, Queue, Transport};
@@ -200,6 +201,33 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
type Framebuffer = VirtGpuFramebuffer<'a>;
type Cursor = VirtGpuCursor;
fn name(&self) -> [u8; 16] {
[
b'v', b'i', b'r', b't', b'i', b'o', b'-', b'g', b'p', b'u', b'd', 0, 0, 0, 0, 0,
]
}
fn desc(&self) -> [u8; 16] {
[
b'V', b'i', b'r', b't', b'I', b'O', b' ', b'G', b'P', b'U', 0, 0, 0, 0, 0, 0,
]
}
fn get_cap(&self, cap: u64) -> syscall::Result<u64> {
match cap {
CAP_DUMB_BUFFER => Ok(1),
_ => Err(syscall::Error::new(EINVAL))
}
}
fn set_client_cap(&self, cap: u64, _value: u64) -> syscall::Result<()> {
match cap {
// FIXME hide cursor plane unless this client cap is set
CLIENT_CAP_CURSOR_PLANE_HOTSPOT => Ok(()),
_ => Err(syscall::Error::new(EINVAL))
}
}
fn display_count(&self) -> usize {
self.displays.len()
}