drm: blob registry, GETPROPBLOB fix, MODE_ATOMIC stub, GAMMA properties
- Add blob registry (blobs: BTreeMap<u32, Vec<u8>>) to DrmScheme with create_blob()/blob_data() methods for property blob storage. - Fix GETPROPBLOB to return actual blob data instead of echoing back the request payload. Unknown blob IDs return zero-length blobs. - Add MODE_ATOMIC ioctl stub: test-only commits return success, nonblock/page-flip commits delegate to legacy path. - Add CRTC_PROP_GAMMA_LUT_SIZE (immutable range, min=0 max=256) and CRTC_PROP_GAMMA_LUT (atomic blob) properties. - Update crtc_count in GETRESOURCES from 1 to 4 (matches AmdDriver). - Rename synthetic EDID monitor name from 'Synthetic DP' to 'RedBearSynthDP' for honest origin identification.
This commit is contained in:
@@ -59,9 +59,9 @@ pub fn synthetic_edid() -> Vec<u8> {
|
||||
// Bytes 72–89: Descriptor 2 — Monitor range limits (tag 0xFD)
|
||||
0x00, 0x00, 0x00, 0xFD, 0x00, 0x32, 0x4C, 0x1E,
|
||||
0x53, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
// Bytes 90–107: Descriptor 3 — Monitor name (tag 0xFC): "Synthetic DP\n"
|
||||
0x00, 0x00, 0x00, 0xFC, 0x00, 0x53, 0x79, 0x6E,
|
||||
0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x20, 0x44, 0x50, 0x0A,
|
||||
// Bytes 90–107: Descriptor 3 — Monitor name (tag 0xFC): "RedBearSynthDP\n"
|
||||
0x00, 0x00, 0x00, 0xFC, 0x00, 0x52, 0x65, 0x64,
|
||||
0x42, 0x65, 0x61, 0x72, 0x53, 0x79, 0x6E, 0x74, 0x68, 0x0A,
|
||||
// Bytes 108–125: Descriptor 4 — unused (pixel_clock = 0, skipped)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
@@ -68,6 +68,10 @@ const DRM_IOCTL_MODE_GETPLANERESOURCES: usize = DRM_IOCTL_BASE + 0x56;
|
||||
const DRM_IOCTL_MODE_GETPLANE: usize = DRM_IOCTL_BASE + 0x57;
|
||||
const DRM_IOCTL_MODE_SETPLANE: usize = DRM_IOCTL_BASE + 0x58;
|
||||
const DRM_IOCTL_MODE_CURSOR: usize = DRM_IOCTL_BASE + 0x3B;
|
||||
const DRM_IOCTL_MODE_ATOMIC: usize = DRM_IOCTL_BASE + 0x3C;
|
||||
const DRM_MODE_ATOMIC_TEST_ONLY: u32 = 0x0100;
|
||||
const DRM_MODE_ATOMIC_NONBLOCK: u32 = 0x0200;
|
||||
const DRM_MODE_PAGE_FLIP_EVENT: u32 = 0x01;
|
||||
const DRM_IOCTL_MODE_ADDFB2: usize = DRM_IOCTL_BASE + 0x59;
|
||||
const DRM_IOCTL_GET_PCI_INFO: usize = DRM_IOCTL_BASE + 0x60;
|
||||
const DRM_IOCTL_VIRTGPU_MAP: usize = 0x0041;
|
||||
@@ -114,6 +118,8 @@ const PLANE_PROP_FB_ID: u32 = 19;
|
||||
// CRTC property IDs (20-29 range)
|
||||
const CRTC_PROP_ACTIVE: u32 = 20;
|
||||
const CRTC_PROP_MODE_ID: u32 = 21;
|
||||
const CRTC_PROP_GAMMA_LUT_SIZE: u32 = 22;
|
||||
const CRTC_PROP_GAMMA_LUT: u32 = 23;
|
||||
|
||||
// Connector property IDs (30-39 range)
|
||||
const CONN_PROP_CRTC_ID: u32 = 30;
|
||||
@@ -599,6 +605,8 @@ pub struct DrmScheme {
|
||||
active_gem_maps: BTreeMap<GemHandle, usize>,
|
||||
gem_export_refs: BTreeMap<GemHandle, usize>,
|
||||
prime_exports: BTreeMap<u32, GemHandle>,
|
||||
blobs: BTreeMap<u32, Vec<u8>>,
|
||||
next_blob_id: u32,
|
||||
}
|
||||
|
||||
impl DrmScheme {
|
||||
@@ -616,9 +624,22 @@ impl DrmScheme {
|
||||
active_gem_maps: BTreeMap::new(),
|
||||
gem_export_refs: BTreeMap::new(),
|
||||
prime_exports: BTreeMap::new(),
|
||||
blobs: BTreeMap::new(),
|
||||
next_blob_id: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_blob(&mut self, data: Vec<u8>) -> u32 {
|
||||
let id = self.next_blob_id;
|
||||
self.next_blob_id = self.next_blob_id.wrapping_add(1);
|
||||
self.blobs.insert(id, data);
|
||||
id
|
||||
}
|
||||
|
||||
fn blob_data(&self, blob_id: u32) -> Option<&[u8]> {
|
||||
self.blobs.get(&blob_id).map(|v| v.as_slice())
|
||||
}
|
||||
|
||||
fn is_fb_active(&self, fb_id: u32) -> bool {
|
||||
self.active_crtc_fb.values().any(|&id| id == fb_id)
|
||||
|| self.pending_flip_fb.values().any(|&(_, id)| id == fb_id)
|
||||
@@ -979,7 +1000,7 @@ impl DrmScheme {
|
||||
let connectors = self.driver.detect_connectors();
|
||||
let payload = DrmResourcesWire {
|
||||
connector_count: connectors.len() as u32,
|
||||
crtc_count: 1,
|
||||
crtc_count: 4,
|
||||
encoder_count: connectors.len() as u32,
|
||||
};
|
||||
let mut out = bytes_of(&payload);
|
||||
@@ -1252,6 +1273,21 @@ impl DrmScheme {
|
||||
|
||||
out = bytes_of(&response);
|
||||
}
|
||||
CRTC_PROP_GAMMA_LUT_SIZE => {
|
||||
response.flags = DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_RANGE;
|
||||
response.count_values = 2;
|
||||
copy_c_string(&mut response.name, b"GAMMA_LUT_SIZE");
|
||||
|
||||
out = bytes_of(&response);
|
||||
out.extend_from_slice(&0u64.to_le_bytes());
|
||||
out.extend_from_slice(&256u64.to_le_bytes());
|
||||
}
|
||||
CRTC_PROP_GAMMA_LUT => {
|
||||
response.flags = DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB;
|
||||
copy_c_string(&mut response.name, b"GAMMA_LUT");
|
||||
|
||||
out = bytes_of(&response);
|
||||
}
|
||||
CONN_PROP_CRTC_ID => {
|
||||
response.flags = DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_OBJECT;
|
||||
response.count_values = 0;
|
||||
@@ -1347,6 +1383,7 @@ impl DrmScheme {
|
||||
DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB => "VIRTGPU_RESOURCE_CREATE_BLOB",
|
||||
DRM_IOCTL_VIRTGPU_CONTEXT_INIT => "VIRTGPU_CONTEXT_INIT",
|
||||
DRM_IOCTL_MODE_CURSOR => "CURSOR",
|
||||
DRM_IOCTL_MODE_ATOMIC => "ATOMIC",
|
||||
_ => "UNKNOWN",
|
||||
};
|
||||
log::info!(
|
||||
@@ -1498,6 +1535,20 @@ impl DrmScheme {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
DRM_IOCTL_MODE_ATOMIC => {
|
||||
let flags = read_u32(payload, 0)?;
|
||||
if flags & DRM_MODE_ATOMIC_TEST_ONLY != 0 {
|
||||
return Ok(1);
|
||||
}
|
||||
if flags & DRM_MODE_ATOMIC_NONBLOCK != 0 {
|
||||
info!("redox-drm: ATOMIC nonblock commit (delegated to legacy path)");
|
||||
}
|
||||
if flags & DRM_MODE_PAGE_FLIP_EVENT != 0 {
|
||||
info!("redox-drm: ATOMIC page flip event requested");
|
||||
}
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
DRM_IOCTL_MODE_CREATE_DUMB => {
|
||||
let mut req = decode_wire::<DrmCreateDumbWire>(payload)?;
|
||||
info!(
|
||||
@@ -2451,11 +2502,24 @@ impl DrmScheme {
|
||||
}
|
||||
|
||||
DRM_IOCTL_MODE_GETPROPBLOB => {
|
||||
let mut resp = zeroed_response(payload.len());
|
||||
copy_bytes(&mut resp, payload, 0, 4);
|
||||
copy_bytes(&mut resp, payload, 8, 8);
|
||||
write_u32(&mut resp, 4, 0);
|
||||
resp
|
||||
let blob_id = read_u32(payload, 0)?;
|
||||
match self.blob_data(blob_id) {
|
||||
Some(data) => {
|
||||
let mut resp = Vec::with_capacity(size_of::<u32>() * 3 + data.len());
|
||||
resp.extend_from_slice(&blob_id.to_le_bytes());
|
||||
let len = data.len() as u32;
|
||||
resp.extend_from_slice(&len.to_le_bytes());
|
||||
resp.extend_from_slice(&0u64.to_le_bytes());
|
||||
resp.extend_from_slice(data);
|
||||
resp
|
||||
}
|
||||
None => {
|
||||
let mut resp = zeroed_response(payload.len());
|
||||
copy_bytes(&mut resp, payload, 0, 4);
|
||||
write_u32(&mut resp, 4, 0);
|
||||
resp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRM_IOCTL_MODE_CREATE_LEASE => {
|
||||
|
||||
Reference in New Issue
Block a user