diff --git a/local/recipes/gpu/redox-drm/source/src/kms/connector.rs b/local/recipes/gpu/redox-drm/source/src/kms/connector.rs index 65843dbdda..20d2c57e45 100644 --- a/local/recipes/gpu/redox-drm/source/src/kms/connector.rs +++ b/local/recipes/gpu/redox-drm/source/src/kms/connector.rs @@ -59,9 +59,9 @@ pub fn synthetic_edid() -> Vec { // 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, diff --git a/local/recipes/gpu/redox-drm/source/src/scheme.rs b/local/recipes/gpu/redox-drm/source/src/scheme.rs index a177e39af9..b0599720a1 100644 --- a/local/recipes/gpu/redox-drm/source/src/scheme.rs +++ b/local/recipes/gpu/redox-drm/source/src/scheme.rs @@ -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, gem_export_refs: BTreeMap, prime_exports: BTreeMap, + blobs: BTreeMap>, + 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) -> 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::(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::() * 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 => {