Skip to content

wayland_vulkan dma-buf present: follow-ups (pacing, explicit sync, platform views) #317

Description

@jwinarske

Tracks the follow-up increments for the experimental zero-copy dma-buf present path landed in #316 (behind IVI_VK_DMABUF, default off). #316 is the direct-present increment: it renders continuously and correctly on mutter and tinywl (AMD RADV), but has known gaps captured here.

1. Refresh-adaptive pacing (highest priority)

Symptom: on mutter the rasterizer runs free (~1140 fps) instead of pacing to the panel refresh. On tinywl (no wp_presentation) the engine's wall-clock scheduler paces correctly at 59 fps, which localizes the problem to the feedback-driven vsync path, not the present ring.

Root cause: the swapchain path gets backpressure from vkQueuePresentKHR blocking at vblank under FIFO, so the engine commits at ~refresh → ~60 wp_presentation_feedback answers/s → the vsync provider delivers one baton per answer → ~60 fps. The dma-buf path's commit is non-blocking, so the engine commits as fast as it renders; the compositor answers every feedback (presented and discarded), the provider delivers a baton per answer, and the engine runs away.

Fix options (need design):

  • Add Wayland-idiomatic backpressure: a wl_surface.frame callback the producer waits on before the next commit (bounds commits to refresh). Requires coordinating the raster thread with the Display event thread that dispatches the callback.
  • Or rate-limit baton delivery in WaylandVsyncProvider to the reported refresh (AdaptPacingToRefresh, as in the skia-skottie-canvas example) — but that path is shared with the swapchain backend, so it needs care.

Once paced, the wl_buffer.release gating added in #316 becomes a rare safety rather than the primary guard.

2. Explicit sync (wp_linux_drm_syncobj_v1)

#316 uses a per-slot CPU fence (block until the blit completes before commit). Replace with explicit GPU sync: export a sync_file from a signaled VkSemaphore (vkGetSemaphoreFdKHR, already done in drm_kms_vulkan) into a drm_syncobj acquire point the compositor waits on, and poll the release point before reusing a slot. Blocked on a wayland-cxx-scanner bumpwp_linux_drm_syncobj isn't vendored yet.

3. Platform-view compositing on the dma-buf path

PresentLayersDmabuf composites only the backing-store layers today; kFlutterLayerContentTypePlatformView layers are skipped (the swapchain path handles them via wl_subsurface/ICompositorSurface).

4. Validation

  • weston/AGL with a real DRM backend (advertising dma-buf) — the nested software instances tested in wayland_vulkan: experimental zero-copy dma-buf present path (IVI_VK_DMABUF) #316 don't advertise dma-buf, so they fall through to the pre-existing swapchain SURFACE_LOST.
  • Steam Deck (needs a nested weston — no compositor over SSH).
  • Once paced + explicit sync: flip on by default and benchmark vs the swapchain path (present-mode table in the backend README).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions