Skip to content

Commit

Permalink
fix(mmserver): fix explicit sync on nvidia proprietary
Browse files Browse the repository at this point in the history
The implementation, besides being buggy, relied on something which I
didn't realize was Mesa-specific. Importing syncobj timelines as
timeline semaphores using the OPAQUE_FD handle type only works on vulkan
implementations which use syncobj internally to implement timeline
semaphores - so only Mesa.

This also tightens up the sync code so that semaphores are allocated and
destroyed correctly, and always waited on even if multiple content
updates precede a frame.

See KhronosGroup/Vulkan-Docs#2473

This reverts commit 32c0d17. The first
attempt at this fix (in 8d57864) was
incorrect, and the second attempt (in 8f806b2)
was missing some files.
  • Loading branch information
colinmarc committed Jan 30, 2025
1 parent 32c0d17 commit 3c70a79
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 225 deletions.
57 changes: 56 additions & 1 deletion mm-server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mm-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ cstr = "0.2"
ctrlc = "3"
cursor-icon = "1"
dasp = "0.11"
drm = "0.14"
drm-fourcc = "2"
either = "1"
git-version = "0.3"
Expand Down
50 changes: 22 additions & 28 deletions mm-server/src/session/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ use std::{collections::BTreeMap, sync::Arc};

use protocols::*;
use slotmap::SlotMap;
use tracing::trace;
use tracing::{instrument, trace};
use wayland_protocols::{
wp::{
fractional_scale::v1::server::wp_fractional_scale_manager_v1,
linux_dmabuf::zv1::server::zwp_linux_dmabuf_v1,
linux_drm_syncobj::v1::server::wp_linux_drm_syncobj_manager_v1,
pointer_constraints::zv1::server::zwp_pointer_constraints_v1,
presentation_time::server::{wp_presentation, wp_presentation_feedback},
presentation_time::server::wp_presentation,
relative_pointer::zv1::server::zwp_relative_pointer_manager_v1,
text_input::zv3::server::zwp_text_input_manager_v3,
},
Expand All @@ -26,8 +26,12 @@ use wayland_server::{
};

use crate::{
session::{control::*, video, SessionHandle},
vulkan::{VkContext, VkTimelinePoint},
session::{
control::*,
video::{self, TextureSync},
SessionHandle,
},
vulkan::VkContext,
};

pub mod buffers;
Expand All @@ -54,11 +58,9 @@ pub struct Compositor {
buffers: SlotMap<buffers::BufferKey, buffers::Buffer>,
shm_pools: SlotMap<shm::ShmPoolKey, shm::ShmPool>,
cached_dmabuf_feedback: buffers::CachedDmabufFeedback,
imported_buffer_timelines: SlotMap<buffers::BufferTimelineKey, buffers::BufferTimeline>,
pending_presentation_feedback: Vec<(
wp_presentation_feedback::WpPresentationFeedback,
VkTimelinePoint,
)>,
imported_syncobj_timelines: SlotMap<buffers::SyncobjTimelineKey, buffers::SyncobjTimeline>,
in_flight_buffers: Vec<surface::ContentUpdate>,
pending_presentation_feedback: Vec<surface::PendingPresentationFeedback>,

surface_stack: Vec<surface::SurfaceKey>,
active_surface: Option<surface::SurfaceKey>,
Expand Down Expand Up @@ -93,7 +95,8 @@ impl Compositor {
buffers: SlotMap::default(),
shm_pools: SlotMap::default(),
cached_dmabuf_feedback,
imported_buffer_timelines: SlotMap::default(),
imported_syncobj_timelines: SlotMap::default(),
in_flight_buffers: Vec::new(),
pending_presentation_feedback: Vec::new(),

surface_stack: Vec::new(),
Expand Down Expand Up @@ -164,6 +167,7 @@ impl Compositor {
Ok(())
}

#[instrument(skip_all)]
pub fn composite_frame(
&mut self,
video_pipeline: &mut video::EncodePipeline,
Expand Down Expand Up @@ -199,27 +203,17 @@ impl Compositor {
let buffer = &mut self.buffers[content.buffer];

let sync = match &mut buffer.backing {
buffers::BufferBacking::Dmabuf { .. } if content.explicit_sync.is_some() => {
let (acquire, _) = content.explicit_sync.as_ref().unwrap();
Some(video::TextureSync::TimelineAcquire(acquire.clone()))
}
buffers::BufferBacking::Dmabuf {
fd,
interop_sema,
interop_sema_tripped,
..
} if !*interop_sema_tripped => {
// Grab a semaphore for explicit sync interop.
buffers::import_dmabuf_fence_as_semaphore(self.vk.clone(), *interop_sema, fd)?;

// Make sure we only wait for the semaphore once per commit.
*interop_sema_tripped = true;
Some(video::TextureSync::BinaryAcquire(*interop_sema))
buffers::BufferBacking::Dmabuf { .. } => {
if let Some((acquire, _)) = content.explicit_sync.as_ref() {
Some(TextureSync::Explicit(acquire.clone()))
} else {
Some(TextureSync::ImplicitInterop)
}
}
_ => None,
};

unsafe { buffer.release_wait = video_pipeline.composite_surface(buffer, sync, conf)? };
unsafe { content.tp_done = video_pipeline.composite_surface(buffer, sync, conf)? };
if let Some(callback) = surface.frame_callback.current.take().as_mut() {
callback.done(now);
}
Expand All @@ -234,7 +228,7 @@ impl Compositor {
let tp_render = unsafe { video_pipeline.end_and_submit()? };
for fb in presentation_feedback.drain(..) {
self.pending_presentation_feedback
.push((fb, tp_render.clone()));
.push(surface::PendingPresentationFeedback(fb, tp_render.clone()));
}

Ok(())
Expand Down
Loading

0 comments on commit 3c70a79

Please sign in to comment.