metal: disable implicit sync in KMS
This commit is contained in:
parent
0dc5d9adb8
commit
a1985b2870
5 changed files with 42 additions and 8 deletions
|
|
@ -16,7 +16,7 @@ use {
|
||||||
},
|
},
|
||||||
dbus::{DbusError, SignalHandler},
|
dbus::{DbusError, SignalHandler},
|
||||||
drm_feedback::DrmFeedback,
|
drm_feedback::DrmFeedback,
|
||||||
gfx_api::GfxError,
|
gfx_api::{GfxError, SyncFile},
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_output::OutputId,
|
wl_output::OutputId,
|
||||||
wl_seat::tablet::{
|
wl_seat::tablet::{
|
||||||
|
|
@ -150,6 +150,7 @@ pub struct MetalBackend {
|
||||||
pause_handler: Cell<Option<SignalHandler>>,
|
pause_handler: Cell<Option<SignalHandler>>,
|
||||||
resume_handler: Cell<Option<SignalHandler>>,
|
resume_handler: Cell<Option<SignalHandler>>,
|
||||||
ctx: CloneCell<Option<Rc<MetalRenderContext>>>,
|
ctx: CloneCell<Option<Rc<MetalRenderContext>>>,
|
||||||
|
signaled_sync_file: CloneCell<Option<SyncFile>>,
|
||||||
default_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
default_feedback: CloneCell<Option<Rc<DrmFeedback>>>,
|
||||||
persistent_display_data: CopyHashMap<Rc<OutputId>, Rc<PersistentDisplayData>>,
|
persistent_display_data: CopyHashMap<Rc<OutputId>, Rc<PersistentDisplayData>>,
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +325,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<MetalBackend>, MetalError> {
|
||||||
pause_handler: Default::default(),
|
pause_handler: Default::default(),
|
||||||
resume_handler: Default::default(),
|
resume_handler: Default::default(),
|
||||||
ctx: Default::default(),
|
ctx: Default::default(),
|
||||||
|
signaled_sync_file: Default::default(),
|
||||||
default_feedback: Default::default(),
|
default_feedback: Default::default(),
|
||||||
persistent_display_data: Default::default(),
|
persistent_display_data: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@ impl MetalConnector {
|
||||||
change!(c, plane.crtc_w, crtc_w);
|
change!(c, plane.crtc_w, crtc_w);
|
||||||
change!(c, plane.crtc_h, crtc_h);
|
change!(c, plane.crtc_h, crtc_h);
|
||||||
if !try_async_flip && !self.dev.is_nvidia {
|
if !try_async_flip && !self.dev.is_nvidia {
|
||||||
c.change(plane.in_fence_fd, -1i32 as u64);
|
if let Some(sf) = self.backend.signaled_sync_file.get() {
|
||||||
|
c.change(plane.in_fence_fd, sf.0.raw() as u64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -329,7 +331,9 @@ impl MetalConnector {
|
||||||
c.change(plane.src_w.id, (*width as u64) << 16);
|
c.change(plane.src_w.id, (*width as u64) << 16);
|
||||||
c.change(plane.src_h.id, (*height as u64) << 16);
|
c.change(plane.src_h.id, (*height as u64) << 16);
|
||||||
if !self.dev.is_nvidia {
|
if !self.dev.is_nvidia {
|
||||||
c.change(plane.in_fence_fd, -1i32 as u64);
|
if let Some(sf) = self.backend.signaled_sync_file.get() {
|
||||||
|
c.change(plane.in_fence_fd, sf.0.raw() as u64);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -512,8 +516,8 @@ impl MetalConnector {
|
||||||
}
|
}
|
||||||
ct
|
ct
|
||||||
};
|
};
|
||||||
if let AcquireSync::None = ct.acquire_sync {
|
if let AcquireSync::None | AcquireSync::Implicit = ct.acquire_sync {
|
||||||
// Cannot perform scanout without sync.
|
// Cannot perform scanout without explicit sync.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if ct.source.buffer_transform != ct.target.output_transform {
|
if ct.source.buffer_transform != ct.target.output_transform {
|
||||||
|
|
|
||||||
|
|
@ -2029,6 +2029,18 @@ impl MetalBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ctx = dev.ctx.get();
|
let ctx = dev.ctx.get();
|
||||||
|
if self.signaled_sync_file.is_none() {
|
||||||
|
if let Some(sync) = ctx.gfx.sync_obj_ctx() {
|
||||||
|
match sync.create_signaled_sync_file() {
|
||||||
|
Ok(sf) => {
|
||||||
|
self.signaled_sync_file.set(Some(sf));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Could not create signaled sync file: {}", ErrorFmt(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
self.state.set_render_ctx(Some(ctx.gfx.clone()));
|
self.state.set_render_ctx(Some(ctx.gfx.clone()));
|
||||||
let fb = match DrmFeedback::new(&self.state.drm_feedback_ids, &*ctx.gfx) {
|
let fb = match DrmFeedback::new(&self.state.drm_feedback_ids, &*ctx.gfx) {
|
||||||
Ok(fb) => Some(Rc::new(fb)),
|
Ok(fb) => Some(Rc::new(fb)),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ use {
|
||||||
sys::{
|
sys::{
|
||||||
sync_ioc_merge, sync_obj_create, sync_obj_destroy, sync_obj_eventfd,
|
sync_ioc_merge, sync_obj_create, sync_obj_destroy, sync_obj_eventfd,
|
||||||
sync_obj_fd_to_handle, sync_obj_handle_to_fd, sync_obj_signal, sync_obj_transfer,
|
sync_obj_fd_to_handle, sync_obj_handle_to_fd, sync_obj_signal, sync_obj_transfer,
|
||||||
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
|
DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
|
||||||
|
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
||||||
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE,
|
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE,
|
||||||
},
|
},
|
||||||
DrmError,
|
DrmError,
|
||||||
|
|
@ -125,6 +126,21 @@ impl SyncObjCtx {
|
||||||
Ok(sync_obj)
|
Ok(sync_obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_signaled_sync_file(&self) -> Result<SyncFile, DrmError> {
|
||||||
|
let handle = sync_obj_create(self.inner.drm.raw(), DRM_SYNCOBJ_CREATE_SIGNALED)
|
||||||
|
.map_err(DrmError::CreateSyncObj)?;
|
||||||
|
let handle = SyncObjHandle(handle);
|
||||||
|
let fd = sync_obj_handle_to_fd(
|
||||||
|
self.inner.drm.raw(),
|
||||||
|
handle.0,
|
||||||
|
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
||||||
|
);
|
||||||
|
destroy(&self.inner.drm, handle);
|
||||||
|
fd.map_err(DrmError::ExportSyncObj)
|
||||||
|
.map(Rc::new)
|
||||||
|
.map(SyncFile)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wait_for_point(
|
pub fn wait_for_point(
|
||||||
&self,
|
&self,
|
||||||
eventfd: &OwnedFd,
|
eventfd: &OwnedFd,
|
||||||
|
|
|
||||||
|
|
@ -1177,7 +1177,7 @@ pub struct drm_format_modifier {
|
||||||
|
|
||||||
unsafe impl Pod for drm_format_modifier {}
|
unsafe impl Pod for drm_format_modifier {}
|
||||||
|
|
||||||
// pub const DRM_SYNCOBJ_CREATE_SIGNALED: u32 = 1 << 0;
|
pub const DRM_SYNCOBJ_CREATE_SIGNALED: u32 = 1 << 0;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct drm_syncobj_create {
|
struct drm_syncobj_create {
|
||||||
|
|
@ -1212,7 +1212,7 @@ pub fn sync_obj_destroy(drm: c::c_int, handle: u32) -> Result<(), OsError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE: u32 = 1 << 0;
|
pub const DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE: u32 = 1 << 0;
|
||||||
// pub const DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE: u32 = 1 << 0;
|
pub const DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE: u32 = 1 << 0;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct drm_syncobj_handle {
|
struct drm_syncobj_handle {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue