drm: do not reject a non-BGRA scanout on the export side

grab_desc exports the raw scanout dma-buf; the unprivileged converter handles
every format libdrmtap supports (10-bit XR30/AR30 with tone mapping, HDR, CCS)
down to RGBA. The fourcc gate copied from the CPU-mapped grab() wrongly closed
the _drm stream for a 10-bit XR30 primary (0x30335258) that convert_dmabuf
converts fine -- observed live on an i915 seat scanning out XRGB2101010. Keep
the gate only on grab(), whose frame.format is already the converted BGRA.
This commit is contained in:
Mariano Abad
2026-07-21 02:01:03 -03:00
parent 2952ff0527
commit 3ac9b2e4cf

View File

@@ -301,25 +301,13 @@ impl DrmReader {
format!("DRM scanout geometry {w}x{h} out of range"),
));
}
// fourcc gate (see grab()): reject a scanout the converter could not
// present as BGRA. 0/unknown is allowed here — an older .so may not set
// it, and the converter reads `frame.format` authoritatively per frame.
const DRM_FORMAT_XRGB8888: u32 = 0x3432_5258; // 'XR24'
const DRM_FORMAT_ARGB8888: u32 = 0x3432_5241; // 'AR24'
if desc.format != 0
&& desc.format != DRM_FORMAT_XRGB8888
&& desc.format != DRM_FORMAT_ARGB8888
{
log::warn!(
"DRM scanout fourcc {:#010x} is not BGRA-compatible; falling back",
desc.format
);
(self.lib.frame_release)(self.ctx, &mut frame);
return Err(io::Error::new(
io::ErrorKind::Other,
"unsupported DRM scanout format",
));
}
// NO fourcc restriction on the export side. Unlike the CPU-mapped grab() (which returns a
// ready-to-encode BGRA buffer and so must reject a format it cannot present), grab_desc
// exports the RAW scanout dma-buf and the unprivileged converter (drmtap_convert_dmabuf)
// handles every format libdrmtap supports -- XRGB8888/ARGB8888, 10-bit XR30/AR30 (tone
// mapped), HDR and CCS-compressed -- down to linear RGBA, exactly as the old grab_mapped
// did internally. Gating on the raw fourcc here wrongly dropped a convertible scanout
// (e.g. XR30 = 0x30335258, a 10-bit primary that is common on modern Intel/AMD).
// num_planes must index offsets/pitches (0 is treated as 1 per the ABI).
let planes = if desc.num_planes == 0 { 1 } else { desc.num_planes };
if planes > 4 {