diff --git a/meson.build b/meson.build
index ab55c7f..a0ea1f3 100644
--- a/meson.build
+++ b/meson.build
@@ -44,6 +44,7 @@
 	'ext-session-lock': ['v1'],
 	'fractional-scale': ['v1'],
 	'security-context': ['v1'],
+	'linux-drm-syncobj': ['v1'],
 	'single-pixel-buffer': ['v1'],
 	'tearing-control': ['v1'],
 	'xdg-activation': ['v1'],
diff --git a/staging/linux-drm-syncobj/README b/staging/linux-drm-syncobj/README
new file mode 100644
index 0000000..a380b31
--- /dev/null
+++ b/staging/linux-drm-syncobj/README
@@ -0,0 +1,4 @@
+Linux DRM syncobj protocol
+
+Maintainers:
+Simon Ser <contact@emersion.fr>
diff --git a/staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml b/staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml
new file mode 100644
index 0000000..7326421
--- /dev/null
+++ b/staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="linux_drm_syncobj_v1">
+  <copyright>
+    Copyright 2016 The Chromium Authors.
+    Copyright 2017 Intel Corporation
+    Copyright 2018 Collabora, Ltd
+    Copyright 2021 Simon Ser
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice (including the next
+    paragraph) shall be included in all copies or substantial portions of the
+    Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+  </copyright>
+
+  <description summary="protocol for providing explicit synchronization">
+    This protocol allows clients to request explicit synchronization for
+    buffers. It is tied to the Linux DRM synchronization object framework.
+
+    Synchronization refers to co-ordination of pipelined operations performed
+    on buffers. Most GPU clients will schedule an asynchronous operation to
+    render to the buffer, then immediately send the buffer to the compositor
+    to be attached to a surface.
+
+    With implicit synchronization, ensuring that the rendering operation is
+    complete before the compositor displays the buffer is an implementation
+    detail handled by either the kernel or userspace graphics driver.
+
+    By contrast, with explicit synchronization, DRM synchronization object
+    timeline points mark when the asynchronous operations are complete. When
+    submitting a buffer, the client provides a timeline point which will be
+    waited on before the compositor accesses the buffer. The client can also
+    provide a timeline point that the compositor will signal when it no longer
+    needs to access the buffer contents for the purposes of the surface commit.
+
+    Linux DRM synchronization objects are documented at:
+    https://dri.freedesktop.org/docs/drm/gpu/drm-mm.html#drm-sync-objects
+
+    Warning! The protocol described in this file is currently in the testing
+    phase. Backward compatible changes may be added together with the
+    corresponding interface version bump. Backward incompatible changes can
+    only be done by creating a new major version of the extension.
+  </description>
+
+  <interface name="wp_linux_drm_syncobj_v1" version="1">
+    <description summary="global for providing explicit synchronization">
+      This global is a factory interface, allowing clients to request
+      explicit synchronization for buffers on a per-surface basis.
+
+      See wp_linux_drm_syncobj_surface_v1 for more information.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy explicit synchronization factory object">
+        Destroy this explicit synchronization factory object. Other objects
+        shall not be affected by this request.
+      </description>
+    </request>
+
+    <enum name="error">
+      <entry name="surface_exists" value="0"
+        summary="the surface already has a synchronization object associated"/>
+      <entry name="invalid_timeline" value="1"
+        summary="the timeline object could not be imported"/>
+    </enum>
+
+    <request name="get_surface">
+      <description summary="extend surface interface for explicit synchronization">
+        Instantiate an interface extension for the given wl_surface to provide
+        explicit synchronization.
+
+        If the given wl_surface already has an explicit synchronization object
+        associated, the surface_exists protocol error is raised.
+
+        Graphics APIs, like EGL or Vulkan, that manage the buffer queue and
+        commits of a wl_surface themselves, are likely to be using this
+        extension internally. If a client is using such an API for a
+        wl_surface, it should not directly use this extension on that surface,
+        to avoid raising a surface_exists protocol error.
+      </description>
+      <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_surface_v1"
+        summary="the new synchronization surface object id"/>
+      <arg name="surface" type="object" interface="wl_surface"
+        summary="the surface"/>
+    </request>
+
+    <request name="import_timeline">
+      <description summary="import a DRM syncobj timeline">
+        Import a DRM synchronization object timeline.
+
+        If the FD cannot be imported, the invalid_timeline error is raised.
+      </description>
+      <arg name="id" type="new_id" interface="wp_linux_drm_syncobj_timeline_v1"/>
+      <arg name="fd" type="fd" summary="drm_syncobj file descriptor"/>
+    </request>
+  </interface>
+
+  <interface name="wp_linux_drm_syncobj_timeline_v1" version="1">
+    <description summary="synchronization object timeline">
+      This object represents an explicit synchronization object timeline
+      imported by the client to the compositor.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the timeline">
+        Destroy the synchronization object timeline. Other objects are not
+        affected by this request, in particular timeline points set by
+        set_acquire_point and set_release_point are not unset.
+      </description>
+    </request>
+  </interface>
+
+  <interface name="wp_linux_drm_syncobj_surface_v1" version="1">
+    <description summary="per-surface explicit synchronization">
+      This object is an add-on interface for wl_surface to enable explicit
+      synchronization.
+
+      Each surface can be associated with only one object of this interface at
+      any time.
+
+      Explicit synchronization is guaranteed to be supported for buffers
+      created with any version of the linux-dmabuf protocol and for opaque EGL
+      buffers described in EGL_WL_bind_wayland_display. Compositors are free to
+      support explicit synchronization for additional buffer types.
+
+      As long as the wp_linux_drm_syncobj_surface_v1 object is alive, the
+      compositor may ignore implicit synchronization for buffers attached and
+      committed to the wl_surface.
+    </description>
+
+    <request name="destroy" type="destructor">
+      <description summary="destroy the surface synchronization object">
+        Destroy this surface synchronization object.
+
+        Any timeline point set by this object with set_acquire_point or
+        set_release_point since the last commit will be discarded by the
+        compositor. Any timeline point set by this object before the last
+        commit will not be affected.
+      </description>
+    </request>
+
+    <enum name="error">
+      <entry name="no_surface" value="1"
+        summary="the associated wl_surface was destroyed"/>
+      <entry name="unsupported_buffer" value="2"
+        summary="the buffer does not support explicit synchronization"/>
+      <entry name="no_buffer" value="3" summary="no buffer was attached"/>
+    </enum>
+
+    <request name="set_acquire_point">
+      <description summary="set the acquire timeline point">
+        Set the timeline point that must be signalled before the compositor may
+        sample from the buffer attached with wl_surface.attach.
+
+        The 64-bit unsigned value combined from point_hi and point_lo is the
+        point value.
+
+        The acquire point is double-buffered state, and will be applied on the
+        next wl_surface.commit request for the associated surface. Thus, it
+        applies only to the buffer that is attached to the surface at commit
+        time.
+
+        If an acquire point has already been attached during the same commit
+        cycle, the new point replaces the old one.
+
+        If the associated wl_surface was destroyed, a no_surface error is
+        raised.
+
+        If at surface commit time the attached buffer does not support explicit
+        synchronization, an unsupported_buffer error is raised.
+
+        If at surface commit time there is no buffer attached, a no_buffer
+        error is raised.
+      </description>
+      <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/>
+      <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/>
+      <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/>
+    </request>
+
+    <request name="set_release_point">
+      <description summary="set the release timeline point">
+        Set the timeline point that must be signalled by the compositor when it
+        has finished its usage of the buffer attached with wl_surface.attach
+        for the relevant commit.
+
+        Once the timeline point is signaled, and assuming the associated buffer
+        is not pending release from other wl_surface.commit requests on other
+        surfaces, no additional explicit or implicit synchronization is
+        required to safely re-use the buffer.
+
+        The 64-bit unsigned value combined from point_hi and point_lo is the
+        point value.
+
+        The release point is double-buffered state, and will be applied on the
+        next wl_surface.commit request for the associated surface. Thus, it
+        applies only to the buffer that is attached to the surface at commit
+        time.
+
+        If a release point has already been attached during the same commit
+        cycle, the new point replaces the old one.
+
+        If the associated wl_surface was destroyed, a no_surface error is
+        raised.
+
+        If at surface commit time the attached buffer does not support explicit
+        synchronization, an unsupported_buffer error is raised.
+
+        If at surface commit time there is no buffer attached, a no_buffer
+        error is raised.
+      </description>
+      <arg name="timeline" type="object" interface="wp_linux_drm_syncobj_timeline_v1"/>
+      <arg name="point_hi" type="uint" summary="high 32 bits of the point value"/>
+      <arg name="point_lo" type="uint" summary="low 32 bits of the point value"/>
+    </request>
+  </interface>
+</protocol>
