video: always use correct modifiers
This commit is contained in:
parent
283774ae4c
commit
bf90204db6
17 changed files with 196 additions and 55 deletions
|
|
@ -108,6 +108,14 @@ pub enum MetalError {
|
|||
DevicePauseSignalHandler(#[source] DbusError),
|
||||
#[error("Could not create device-resumed signal handler")]
|
||||
DeviceResumeSignalHandler(#[source] DbusError),
|
||||
#[error("Device render context does not support required format {0}")]
|
||||
MissingDevFormat(&'static str),
|
||||
#[error("Render context does not support required format {0}")]
|
||||
MissingRenderFormat(&'static str),
|
||||
#[error("Device cannot scan out any buffers writable by its GFX API (format {0})")]
|
||||
MissingDevModifier(&'static str),
|
||||
#[error("Device GFX API cannot read any buffers writable by the render GFX API (format {0})")]
|
||||
MissingRenderModifier(&'static str),
|
||||
}
|
||||
|
||||
pub struct MetalBackend {
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@ use {
|
|||
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
|
||||
},
|
||||
gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT},
|
||||
Modifier,
|
||||
Modifier, INVALID_MODIFIER,
|
||||
},
|
||||
},
|
||||
ahash::{AHashMap, AHashSet},
|
||||
bstr::{BString, ByteSlice},
|
||||
indexmap::{indexset, IndexSet},
|
||||
std::{
|
||||
cell::{Cell, RefCell},
|
||||
ffi::CString,
|
||||
|
|
@ -508,7 +509,7 @@ pub enum PlaneType {
|
|||
#[derive(Debug)]
|
||||
pub struct PlaneFormat {
|
||||
_format: &'static Format,
|
||||
modifiers: Vec<Modifier>,
|
||||
modifiers: IndexSet<Modifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -785,7 +786,7 @@ fn create_plane(plane: DrmPlane, master: &Rc<DrmMaster>) -> Result<MetalPlane, D
|
|||
format,
|
||||
PlaneFormat {
|
||||
_format: f,
|
||||
modifiers: vec![],
|
||||
modifiers: indexset![INVALID_MODIFIER],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -1593,14 +1594,14 @@ impl MetalBackend {
|
|||
&self,
|
||||
dev: &Rc<MetalDrmDevice>,
|
||||
format: &Format,
|
||||
modifiers: &[Modifier],
|
||||
plane_modifiers: &IndexSet<Modifier>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
ctx: &MetalRenderContext,
|
||||
cursor: bool,
|
||||
) -> Result<[RenderBuffer; 2], MetalError> {
|
||||
let create =
|
||||
|| self.create_scanout_buffer(dev, format, modifiers, width, height, ctx, cursor);
|
||||
|| self.create_scanout_buffer(dev, format, plane_modifiers, width, height, ctx, cursor);
|
||||
Ok([create()?, create()?])
|
||||
}
|
||||
|
||||
|
|
@ -1608,17 +1609,35 @@ impl MetalBackend {
|
|||
&self,
|
||||
dev: &Rc<MetalDrmDevice>,
|
||||
format: &Format,
|
||||
modifiers: &[Modifier],
|
||||
plane_modifiers: &IndexSet<Modifier>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
render_ctx: &MetalRenderContext,
|
||||
cursor: bool,
|
||||
) -> Result<RenderBuffer, MetalError> {
|
||||
let dev_gfx_formats = dev.ctx.gfx.formats();
|
||||
let dev_gfx_format = match dev_gfx_formats.get(&format.drm) {
|
||||
None => return Err(MetalError::MissingDevFormat(format.name)),
|
||||
Some(f) => f,
|
||||
};
|
||||
let possible_modifiers: Vec<_> = dev_gfx_format
|
||||
.write_modifiers
|
||||
.iter()
|
||||
.filter(|m| plane_modifiers.contains(*m))
|
||||
.copied()
|
||||
.collect();
|
||||
if possible_modifiers.is_empty() {
|
||||
log::warn!("Scanout modifiers: {:?}", plane_modifiers);
|
||||
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.write_modifiers);
|
||||
return Err(MetalError::MissingDevModifier(format.name));
|
||||
}
|
||||
let mut usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
|
||||
if cursor && modifiers.is_empty() {
|
||||
if cursor {
|
||||
usage |= GBM_BO_USE_LINEAR;
|
||||
};
|
||||
let dev_bo = dev.gbm.create_bo(width, height, format, modifiers, usage);
|
||||
let dev_bo = dev
|
||||
.gbm
|
||||
.create_bo(width, height, format, &possible_modifiers, usage);
|
||||
let dev_bo = match dev_bo {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Err(MetalError::ScanoutBuffer(e)),
|
||||
|
|
@ -1644,11 +1663,31 @@ impl MetalBackend {
|
|||
(None, render_tex, None)
|
||||
} else {
|
||||
// Create a _bridge_ BO in the render device
|
||||
let render_gfx_formats = render_ctx.gfx.formats();
|
||||
let render_gfx_format = match render_gfx_formats.get(&format.drm) {
|
||||
None => return Err(MetalError::MissingRenderFormat(format.name)),
|
||||
Some(f) => f,
|
||||
};
|
||||
let possible_modifiers: Vec<_> = render_gfx_format
|
||||
.write_modifiers
|
||||
.iter()
|
||||
.filter(|m| dev_gfx_format.read_modifiers.contains(*m))
|
||||
.copied()
|
||||
.collect();
|
||||
if possible_modifiers.is_empty() {
|
||||
log::warn!(
|
||||
"Render GFX modifiers: {:?}",
|
||||
render_gfx_format.write_modifiers
|
||||
);
|
||||
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.read_modifiers);
|
||||
return Err(MetalError::MissingRenderModifier(format.name));
|
||||
}
|
||||
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
|
||||
let render_bo = render_ctx
|
||||
.gfx
|
||||
.gbm()
|
||||
.create_bo(width, height, format, &[], usage);
|
||||
let render_bo =
|
||||
render_ctx
|
||||
.gfx
|
||||
.gbm()
|
||||
.create_bo(width, height, format, &possible_modifiers, usage);
|
||||
let render_bo = match render_bo {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Err(MetalError::ScanoutBuffer(e)),
|
||||
|
|
@ -1765,7 +1804,7 @@ impl MetalBackend {
|
|||
false,
|
||||
)?);
|
||||
let mut cursor_plane = None;
|
||||
let mut cursor_modifiers = &[][..];
|
||||
let mut cursor_modifiers = &IndexSet::new();
|
||||
for plane in crtc.possible_planes.values() {
|
||||
if plane.ty == PlaneType::Cursor
|
||||
&& !plane.assigned.get()
|
||||
|
|
@ -1773,7 +1812,7 @@ impl MetalBackend {
|
|||
{
|
||||
if let Some(format) = plane.formats.get(&ARGB8888.drm) {
|
||||
cursor_plane = Some(plane.clone());
|
||||
cursor_modifiers = &format.modifiers[..];
|
||||
cursor_modifiers = &format.modifiers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ use {
|
|||
},
|
||||
video::{
|
||||
drm::{ConnectorType, Drm, DrmError, DrmVersion},
|
||||
gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING},
|
||||
gbm::{GbmDevice, GbmError, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING},
|
||||
INVALID_MODIFIER, LINEAR_MODIFIER,
|
||||
},
|
||||
wire_xcon::{
|
||||
ChangeProperty, ChangeWindowAttributes, ConfigureNotify, CreateCursor, CreatePixmap,
|
||||
|
|
@ -117,6 +118,8 @@ pub enum XBackendError {
|
|||
QueryDevice(#[source] XconError),
|
||||
#[error("Could not fstat the drm device")]
|
||||
DrmDeviceFstat(#[source] Errno),
|
||||
#[error("Render device does not support XRGB8888 format")]
|
||||
XRGB8888,
|
||||
}
|
||||
|
||||
pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
|
||||
|
|
@ -376,10 +379,24 @@ impl XBackend {
|
|||
height: i32,
|
||||
) -> Result<[XImage; 2], XBackendError> {
|
||||
let mut images = [None, None];
|
||||
let formats = self.ctx.formats();
|
||||
let format = match formats.get(&XRGB8888.drm) {
|
||||
Some(f) => f,
|
||||
None => return Err(XBackendError::XRGB8888),
|
||||
};
|
||||
let mut usage = GBM_BO_USE_RENDERING;
|
||||
let modifier = if format.write_modifiers.contains(&LINEAR_MODIFIER) {
|
||||
&[LINEAR_MODIFIER]
|
||||
} else if format.write_modifiers.contains(&INVALID_MODIFIER) {
|
||||
usage |= GBM_BO_USE_LINEAR;
|
||||
&[INVALID_MODIFIER]
|
||||
} else {
|
||||
panic!("Neither linear nor invalid modifier is supported");
|
||||
};
|
||||
for image in &mut images {
|
||||
let bo = self
|
||||
.gbm
|
||||
.create_bo(width, height, XRGB8888, &[], GBM_BO_USE_RENDERING)?;
|
||||
.create_bo(width, height, XRGB8888, modifier, usage)?;
|
||||
let dma = bo.dmabuf();
|
||||
assert!(dma.planes.len() == 1);
|
||||
let plane = dma.planes.first().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue