Index | Thread | Search

From:
Landry Breuil <landry@openbsd.org>
Subject:
poc: link mesa against wayland from ports
To:
tech@openbsd.org
Date:
Thu, 13 Nov 2025 16:34:32 +0100

Download raw body.

Thread
  • Landry Breuil:

    poc: link mesa against wayland from ports

Hi,

just a fun experiment, ofc not planned for inclusion/review, but with some
tinkering in the mesa makefiles i'm able to rebuild libEGL with wayland
support fully enabled, eg my wip wayland/wdisplays port shows the
current screen using EGL in the graphical monitor configuration widget,
and most importantly, i have full WebGL support in firefox when running
on top of wayland.

it doesnt need 'much':
- 5 new files, generated from the wayland protocol files using wayland-scanner
- enabling wayland support in libloader
- linking libdri_gbm with wayland client
- enable HAVE_WAYLAND_PLATFORM in config.mk
- build 4 new .c files (2 of them are generated from the xml files) &
  link libEGL with wayland-client/wayland-server

i've done a full rebuild of xenocara/lib with this diff, attached below
(including generated files), also at
https://github.com/openbsd/xenocara/compare/master...landryb:xenocara:link_mesa_against_wayland

Landry
diff --git a/lib/mesa/mk/config.mk b/lib/mesa/mk/config.mk
index 078be4eaf..f7b393fb0 100644
--- a/lib/mesa/mk/config.mk
+++ b/lib/mesa/mk/config.mk
@@ -105,6 +105,7 @@ CPPFLAGS+= \
 	-DHAVE_SYS_SHM_H \
 	-DHAVE_SYS_SYSCTL_H \
 	-DHAVE_X11_PLATFORM \
+	-DHAVE_WAYLAND_PLATFORM \
 	-DHAVE_XCB_PLATFORM \
 	-DHAVE_ZLIB \
 	-DHAVE___BUILTIN_BSWAP32 \
diff --git a/lib/mesa/mk/libEGL/Makefile b/lib/mesa/mk/libEGL/Makefile
index f51d9a746..bea415144 100644
--- a/lib/mesa/mk/libEGL/Makefile
+++ b/lib/mesa/mk/libEGL/Makefile
@@ -20,9 +20,13 @@ SRCS=	eglapi.c \
 
 .if ${XENOCARA_BUILD_DRI:L} == "yes"
 SRCS+=	egl_dri2.c \
+	wayland-drm.c \
+	linux-dmabuf-unstable-v1-protocol.c \
+	wayland-drm-protocol.c \
 	platform_device.c \
 	platform_drm.c \
 	platform_surfaceless.c \
+	platform_wayland.c \
 	platform_x11.c
 .endif
 
@@ -34,6 +38,7 @@ SRCS+=	platform_x11_dri3.c
 
 CFLAGS+=	${C_VIS_ARGS}
 CPPFLAGS+=	-I${MESA_SRC}/src/egl/main \
+		-I${MESA_SRC}/src/egl/wayland/wayland-drm \
 		-I${MESA_SRC}/src/loader \
 		-I${MESA_SRC}/src/gbm/main \
 		-I${MESA_SRC}/src/gbm/backends/dri \
@@ -42,6 +47,7 @@ CPPFLAGS+=	-I${MESA_SRC}/src/egl/main \
 		-I${MESA_SRC}/src/gallium/auxiliary \
 		-I${MESA_SRC}/src/gallium/frontends/dri \
 		-I${MESA_SRC}/src/x11 \
+		-I/usr/local/include \
 		-I${MESA_SRC}/generated/src \
 		-D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_X11 \
 		-DGALLIUM_SOFTPIPE
@@ -62,6 +68,7 @@ LDADD+= -L${.CURDIR}/../libgbm/${__objdir} -lgbm \
 	${.CURDIR}/../libmesa_util_c11/${__objdir}/libmesa_util_c11.a \
 	-Wl,-Bsymbolic -Wl,--gc-sections \
 	-lz -lm -lpthread \
+	-L/usr/local/lib -lwayland-client -lwayland-server \
 	-L${X11BASE}/lib -lX11-xcb -lX11 -lxcb -lxcb-randr \
 	-lxcb-xfixes -lxcb-shm
 
@@ -84,4 +91,5 @@ obj: _xenocara_obj
 .include <bsd.xorg.mk>
 
 .PATH:	${MESA_SRC}/src/egl/main
+.PATH:	${MESA_SRC}/src/egl/wayland/wayland-drm
 .PATH:	${MESA_SRC}/src/egl/drivers/dri2
diff --git a/lib/mesa/mk/libdri_gbm/Makefile b/lib/mesa/mk/libdri_gbm/Makefile
index 33b3b09cf..0109ef917 100644
--- a/lib/mesa/mk/libdri_gbm/Makefile
+++ b/lib/mesa/mk/libdri_gbm/Makefile
@@ -11,12 +11,14 @@ SRCS=	gbm_dri.c
 CFLAGS+=	${C_VIS_ARGS}
 CPPFLAGS+=	-I${MESA_SRC}/src/gbm/main \
 		-I${MESA_SRC}/src/gbm/backends/dri \
+		-I${MESA_SRC}/src/egl/wayland/wayland-drm \
 		-I${MESA_SRC}/src/loader \
 		-I${MESA_SRC}/src/mesa \
 		-I${MESA_SRC}/src/gallium/include \
 		-I${MESA_SRC}/src/gallium/auxiliary \
 		-I${MESA_SRC}/src/gallium/frontends/dri \
 		-I${MESA_SRC}/generated/src \
+		-I/usr/local/include \
 		-DDEFAULT_BACKENDS_PATH=\"${X11BASE}/lib/gbm\"
 
 LDADD+=	-Wl,--as-needed -Wl,--start-group \
@@ -26,6 +28,7 @@ LDADD+=	-Wl,--as-needed -Wl,--start-group \
 	${.CURDIR}/../libmesa_util_c11/${__objdir}/libmesa_util_c11.a \
 	${.CURDIR}/../libxmlconfig/${__objdir}/libxmlconfig.a \
 	-Wl,--gc-sections \
+	-L/usr/local/lib -lwayland-client \
 	-lz -lm -lexpat -lpthread -lxcb -lxcb-randr
 
 .if ${XENOCARA_BUILD_DRI:L} == "yes"
diff --git a/lib/mesa/mk/libloader/Makefile b/lib/mesa/mk/libloader/Makefile
index e0d6285e7..53467257e 100644
--- a/lib/mesa/mk/libloader/Makefile
+++ b/lib/mesa/mk/libloader/Makefile
@@ -5,6 +5,7 @@ LIB=	loader
 NOPROFILE=
 
 SRCS=	loader_dri_helper.c \
+	loader_wayland_helper.c \
 	loader.c
 
 .include "../Makefile.inc"
@@ -12,6 +13,7 @@ SRCS=	loader_dri_helper.c \
 CFLAGS+=	${C_VIS_ARGS}
 CPPFLAGS+=	-DUSE_DRICONF \
 		-DDEFAULT_DRIVER_DIR=\"${X11BASE}/lib/modules/dri\" \
+		-I/usr/local/include \
 		-I${MESA_SRC}/src/loader \
 		-I${MESA_SRC}/src/gallium/include \
 		-I${MESA_SRC}/generated/src \
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-client-protocol.h b/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-client-protocol.h
new file mode 100644
index 000000000..88bcc1110
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-client-protocol.h
@@ -0,0 +1,1084 @@
+/* Generated by wayland-scanner 1.24.0 */
+
+#ifndef LINUX_DMABUF_UNSTABLE_V1_CLIENT_PROTOCOL_H
+#define LINUX_DMABUF_UNSTABLE_V1_CLIENT_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @page page_linux_dmabuf_unstable_v1 The linux_dmabuf_unstable_v1 protocol
+ * @section page_ifaces_linux_dmabuf_unstable_v1 Interfaces
+ * - @subpage page_iface_zwp_linux_dmabuf_v1 - factory for creating dmabuf-based wl_buffers
+ * - @subpage page_iface_zwp_linux_buffer_params_v1 - parameters for creating a dmabuf-based wl_buffer
+ * - @subpage page_iface_zwp_linux_dmabuf_feedback_v1 - dmabuf feedback
+ * @section page_copyright_linux_dmabuf_unstable_v1 Copyright
+ * <pre>
+ *
+ * Copyright © 2014, 2015 Collabora, Ltd.
+ *
+ * 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.
+ * </pre>
+ */
+struct wl_buffer;
+struct wl_surface;
+struct zwp_linux_buffer_params_v1;
+struct zwp_linux_dmabuf_feedback_v1;
+struct zwp_linux_dmabuf_v1;
+
+#ifndef ZWP_LINUX_DMABUF_V1_INTERFACE
+#define ZWP_LINUX_DMABUF_V1_INTERFACE
+/**
+ * @page page_iface_zwp_linux_dmabuf_v1 zwp_linux_dmabuf_v1
+ * @section page_iface_zwp_linux_dmabuf_v1_desc Description
+ *
+ * Following the interfaces from:
+ * https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
+ * and the Linux DRM sub-system's AddFb2 ioctl.
+ *
+ * This interface offers ways to create generic dmabuf-based wl_buffers.
+ *
+ * Clients can use the get_surface_feedback request to get dmabuf feedback
+ * for a particular surface. If the client wants to retrieve feedback not
+ * tied to a surface, they can use the get_default_feedback request.
+ *
+ * The following are required from clients:
+ *
+ * - Clients must ensure that either all data in the dma-buf is
+ * coherent for all subsequent read access or that coherency is
+ * correctly handled by the underlying kernel-side dma-buf
+ * implementation.
+ *
+ * - Don't make any more attachments after sending the buffer to the
+ * compositor. Making more attachments later increases the risk of
+ * the compositor not being able to use (re-import) an existing
+ * dmabuf-based wl_buffer.
+ *
+ * The underlying graphics stack must ensure the following:
+ *
+ * - The dmabuf file descriptors relayed to the server will stay valid
+ * for the whole lifetime of the wl_buffer. This means the server may
+ * at any time use those fds to import the dmabuf into any kernel
+ * sub-system that might accept it.
+ *
+ * However, when the underlying graphics stack fails to deliver the
+ * promise, because of e.g. a device hot-unplug which raises internal
+ * errors, after the wl_buffer has been successfully created the
+ * compositor must not raise protocol errors to the client when dmabuf
+ * import later fails.
+ *
+ * To create a wl_buffer from one or more dmabufs, a client creates a
+ * zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params
+ * request. All planes required by the intended format are added with
+ * the 'add' request. Finally, a 'create' or 'create_immed' request is
+ * issued, which has the following outcome depending on the import success.
+ *
+ * The 'create' request,
+ * - on success, triggers a 'created' event which provides the final
+ * wl_buffer to the client.
+ * - on failure, triggers a 'failed' event to convey that the server
+ * cannot use the dmabufs received from the client.
+ *
+ * For the 'create_immed' request,
+ * - on success, the server immediately imports the added dmabufs to
+ * create a wl_buffer. No event is sent from the server in this case.
+ * - on failure, the server can choose to either:
+ * - terminate the client by raising a fatal error.
+ * - mark the wl_buffer as failed, and send a 'failed' event to the
+ * client. If the client uses a failed wl_buffer as an argument to any
+ * request, the behaviour is compositor implementation-defined.
+ *
+ * For all DRM formats and unless specified in another protocol extension,
+ * pre-multiplied alpha is used for pixel values.
+ *
+ * Unless specified otherwise in another protocol extension, implicit
+ * synchronization is used. In other words, compositors and clients must
+ * wait and signal fences implicitly passed via the DMA-BUF's reservation
+ * mechanism.
+ *
+ * Disclaimer: This protocol extension has been marked stable. This copy is
+ * no longer used and only retained for backwards compatibility. The
+ * canonical version can be found in the stable/ directory.
+ * @section page_iface_zwp_linux_dmabuf_v1_api API
+ * See @ref iface_zwp_linux_dmabuf_v1.
+ */
+/**
+ * @defgroup iface_zwp_linux_dmabuf_v1 The zwp_linux_dmabuf_v1 interface
+ *
+ * Following the interfaces from:
+ * https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
+ * and the Linux DRM sub-system's AddFb2 ioctl.
+ *
+ * This interface offers ways to create generic dmabuf-based wl_buffers.
+ *
+ * Clients can use the get_surface_feedback request to get dmabuf feedback
+ * for a particular surface. If the client wants to retrieve feedback not
+ * tied to a surface, they can use the get_default_feedback request.
+ *
+ * The following are required from clients:
+ *
+ * - Clients must ensure that either all data in the dma-buf is
+ * coherent for all subsequent read access or that coherency is
+ * correctly handled by the underlying kernel-side dma-buf
+ * implementation.
+ *
+ * - Don't make any more attachments after sending the buffer to the
+ * compositor. Making more attachments later increases the risk of
+ * the compositor not being able to use (re-import) an existing
+ * dmabuf-based wl_buffer.
+ *
+ * The underlying graphics stack must ensure the following:
+ *
+ * - The dmabuf file descriptors relayed to the server will stay valid
+ * for the whole lifetime of the wl_buffer. This means the server may
+ * at any time use those fds to import the dmabuf into any kernel
+ * sub-system that might accept it.
+ *
+ * However, when the underlying graphics stack fails to deliver the
+ * promise, because of e.g. a device hot-unplug which raises internal
+ * errors, after the wl_buffer has been successfully created the
+ * compositor must not raise protocol errors to the client when dmabuf
+ * import later fails.
+ *
+ * To create a wl_buffer from one or more dmabufs, a client creates a
+ * zwp_linux_dmabuf_params_v1 object with a zwp_linux_dmabuf_v1.create_params
+ * request. All planes required by the intended format are added with
+ * the 'add' request. Finally, a 'create' or 'create_immed' request is
+ * issued, which has the following outcome depending on the import success.
+ *
+ * The 'create' request,
+ * - on success, triggers a 'created' event which provides the final
+ * wl_buffer to the client.
+ * - on failure, triggers a 'failed' event to convey that the server
+ * cannot use the dmabufs received from the client.
+ *
+ * For the 'create_immed' request,
+ * - on success, the server immediately imports the added dmabufs to
+ * create a wl_buffer. No event is sent from the server in this case.
+ * - on failure, the server can choose to either:
+ * - terminate the client by raising a fatal error.
+ * - mark the wl_buffer as failed, and send a 'failed' event to the
+ * client. If the client uses a failed wl_buffer as an argument to any
+ * request, the behaviour is compositor implementation-defined.
+ *
+ * For all DRM formats and unless specified in another protocol extension,
+ * pre-multiplied alpha is used for pixel values.
+ *
+ * Unless specified otherwise in another protocol extension, implicit
+ * synchronization is used. In other words, compositors and clients must
+ * wait and signal fences implicitly passed via the DMA-BUF's reservation
+ * mechanism.
+ *
+ * Disclaimer: This protocol extension has been marked stable. This copy is
+ * no longer used and only retained for backwards compatibility. The
+ * canonical version can be found in the stable/ directory.
+ */
+extern const struct wl_interface zwp_linux_dmabuf_v1_interface;
+#endif
+#ifndef ZWP_LINUX_BUFFER_PARAMS_V1_INTERFACE
+#define ZWP_LINUX_BUFFER_PARAMS_V1_INTERFACE
+/**
+ * @page page_iface_zwp_linux_buffer_params_v1 zwp_linux_buffer_params_v1
+ * @section page_iface_zwp_linux_buffer_params_v1_desc Description
+ *
+ * This temporary object is a collection of dmabufs and other
+ * parameters that together form a single logical buffer. The temporary
+ * object may eventually create one wl_buffer unless cancelled by
+ * destroying it before requesting 'create'.
+ *
+ * Single-planar formats only require one dmabuf, however
+ * multi-planar formats may require more than one dmabuf. For all
+ * formats, an 'add' request must be called once per plane (even if the
+ * underlying dmabuf fd is identical).
+ *
+ * You must use consecutive plane indices ('plane_idx' argument for 'add')
+ * from zero to the number of planes used by the drm_fourcc format code.
+ * All planes required by the format must be given exactly once, but can
+ * be given in any order. Each plane index can be set only once.
+ * @section page_iface_zwp_linux_buffer_params_v1_api API
+ * See @ref iface_zwp_linux_buffer_params_v1.
+ */
+/**
+ * @defgroup iface_zwp_linux_buffer_params_v1 The zwp_linux_buffer_params_v1 interface
+ *
+ * This temporary object is a collection of dmabufs and other
+ * parameters that together form a single logical buffer. The temporary
+ * object may eventually create one wl_buffer unless cancelled by
+ * destroying it before requesting 'create'.
+ *
+ * Single-planar formats only require one dmabuf, however
+ * multi-planar formats may require more than one dmabuf. For all
+ * formats, an 'add' request must be called once per plane (even if the
+ * underlying dmabuf fd is identical).
+ *
+ * You must use consecutive plane indices ('plane_idx' argument for 'add')
+ * from zero to the number of planes used by the drm_fourcc format code.
+ * All planes required by the format must be given exactly once, but can
+ * be given in any order. Each plane index can be set only once.
+ */
+extern const struct wl_interface zwp_linux_buffer_params_v1_interface;
+#endif
+#ifndef ZWP_LINUX_DMABUF_FEEDBACK_V1_INTERFACE
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_INTERFACE
+/**
+ * @page page_iface_zwp_linux_dmabuf_feedback_v1 zwp_linux_dmabuf_feedback_v1
+ * @section page_iface_zwp_linux_dmabuf_feedback_v1_desc Description
+ *
+ * This object advertises dmabuf parameters feedback. This includes the
+ * preferred devices and the supported formats/modifiers.
+ *
+ * The parameters are sent once when this object is created and whenever they
+ * change. The done event is always sent once after all parameters have been
+ * sent. When a single parameter changes, all parameters are re-sent by the
+ * compositor.
+ *
+ * Compositors can re-send the parameters when the current client buffer
+ * allocations are sub-optimal. Compositors should not re-send the
+ * parameters if re-allocating the buffers would not result in a more optimal
+ * configuration. In particular, compositors should avoid sending the exact
+ * same parameters multiple times in a row.
+ *
+ * The tranche_target_device and tranche_formats events are grouped by
+ * tranches of preference. For each tranche, a tranche_target_device, one
+ * tranche_flags and one or more tranche_formats events are sent, followed
+ * by a tranche_done event finishing the list. The tranches are sent in
+ * descending order of preference. All formats and modifiers in the same
+ * tranche have the same preference.
+ *
+ * To send parameters, the compositor sends one main_device event, tranches
+ * (each consisting of one tranche_target_device event, one tranche_flags
+ * event, tranche_formats events and then a tranche_done event), then one
+ * done event.
+ * @section page_iface_zwp_linux_dmabuf_feedback_v1_api API
+ * See @ref iface_zwp_linux_dmabuf_feedback_v1.
+ */
+/**
+ * @defgroup iface_zwp_linux_dmabuf_feedback_v1 The zwp_linux_dmabuf_feedback_v1 interface
+ *
+ * This object advertises dmabuf parameters feedback. This includes the
+ * preferred devices and the supported formats/modifiers.
+ *
+ * The parameters are sent once when this object is created and whenever they
+ * change. The done event is always sent once after all parameters have been
+ * sent. When a single parameter changes, all parameters are re-sent by the
+ * compositor.
+ *
+ * Compositors can re-send the parameters when the current client buffer
+ * allocations are sub-optimal. Compositors should not re-send the
+ * parameters if re-allocating the buffers would not result in a more optimal
+ * configuration. In particular, compositors should avoid sending the exact
+ * same parameters multiple times in a row.
+ *
+ * The tranche_target_device and tranche_formats events are grouped by
+ * tranches of preference. For each tranche, a tranche_target_device, one
+ * tranche_flags and one or more tranche_formats events are sent, followed
+ * by a tranche_done event finishing the list. The tranches are sent in
+ * descending order of preference. All formats and modifiers in the same
+ * tranche have the same preference.
+ *
+ * To send parameters, the compositor sends one main_device event, tranches
+ * (each consisting of one tranche_target_device event, one tranche_flags
+ * event, tranche_formats events and then a tranche_done event), then one
+ * done event.
+ */
+extern const struct wl_interface zwp_linux_dmabuf_feedback_v1_interface;
+#endif
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ * @struct zwp_linux_dmabuf_v1_listener
+ */
+struct zwp_linux_dmabuf_v1_listener {
+	/**
+	 * supported buffer format
+	 *
+	 * This event advertises one buffer format that the server
+	 * supports. All the supported formats are advertised once when the
+	 * client binds to this interface. A roundtrip after binding
+	 * guarantees that the client has received all supported formats.
+	 *
+	 * For the definition of the format codes, see the
+	 * zwp_linux_buffer_params_v1::create request.
+	 *
+	 * Starting version 4, the format event is deprecated and must not
+	 * be sent by compositors. Instead, use get_default_feedback or
+	 * get_surface_feedback.
+	 * @param format DRM_FORMAT code
+	 */
+	void (*format)(void *data,
+		       struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1,
+		       uint32_t format);
+	/**
+	 * supported buffer format modifier
+	 *
+	 * This event advertises the formats that the server supports,
+	 * along with the modifiers supported for each format. All the
+	 * supported modifiers for all the supported formats are advertised
+	 * once when the client binds to this interface. A roundtrip after
+	 * binding guarantees that the client has received all supported
+	 * format-modifier pairs.
+	 *
+	 * For legacy support, DRM_FORMAT_MOD_INVALID (that is, modifier_hi
+	 * == 0x00ffffff and modifier_lo == 0xffffffff) is allowed in this
+	 * event. It indicates that the server can support the format with
+	 * an implicit modifier. When a plane has DRM_FORMAT_MOD_INVALID as
+	 * its modifier, it is as if no explicit modifier is specified. The
+	 * effective modifier will be derived from the dmabuf.
+	 *
+	 * A compositor that sends valid modifiers and
+	 * DRM_FORMAT_MOD_INVALID for a given format supports both explicit
+	 * modifiers and implicit modifiers.
+	 *
+	 * For the definition of the format and modifier codes, see the
+	 * zwp_linux_buffer_params_v1::create and
+	 * zwp_linux_buffer_params_v1::add requests.
+	 *
+	 * Starting version 4, the modifier event is deprecated and must
+	 * not be sent by compositors. Instead, use get_default_feedback or
+	 * get_surface_feedback.
+	 * @param format DRM_FORMAT code
+	 * @param modifier_hi high 32 bits of layout modifier
+	 * @param modifier_lo low 32 bits of layout modifier
+	 * @since 3
+	 */
+	void (*modifier)(void *data,
+			 struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1,
+			 uint32_t format,
+			 uint32_t modifier_hi,
+			 uint32_t modifier_lo);
+};
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+static inline int
+zwp_linux_dmabuf_v1_add_listener(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1,
+				 const struct zwp_linux_dmabuf_v1_listener *listener, void *data)
+{
+	return wl_proxy_add_listener((struct wl_proxy *) zwp_linux_dmabuf_v1,
+				     (void (**)(void)) listener, data);
+}
+
+#define ZWP_LINUX_DMABUF_V1_DESTROY 0
+#define ZWP_LINUX_DMABUF_V1_CREATE_PARAMS 1
+#define ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK 2
+#define ZWP_LINUX_DMABUF_V1_GET_SURFACE_FEEDBACK 3
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_FORMAT_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION 3
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_DESTROY_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_CREATE_PARAMS_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION 4
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ */
+#define ZWP_LINUX_DMABUF_V1_GET_SURFACE_FEEDBACK_SINCE_VERSION 4
+
+/** @ingroup iface_zwp_linux_dmabuf_v1 */
+static inline void
+zwp_linux_dmabuf_v1_set_user_data(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) zwp_linux_dmabuf_v1, user_data);
+}
+
+/** @ingroup iface_zwp_linux_dmabuf_v1 */
+static inline void *
+zwp_linux_dmabuf_v1_get_user_data(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) zwp_linux_dmabuf_v1);
+}
+
+static inline uint32_t
+zwp_linux_dmabuf_v1_get_version(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1)
+{
+	return wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_v1);
+}
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ *
+ * Objects created through this interface, especially wl_buffers, will
+ * remain valid.
+ */
+static inline void
+zwp_linux_dmabuf_v1_destroy(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_dmabuf_v1,
+			 ZWP_LINUX_DMABUF_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ *
+ * This temporary object is used to collect multiple dmabuf handles into
+ * a single batch to create a wl_buffer. It can only be used once and
+ * should be destroyed after a 'created' or 'failed' event has been
+ * received.
+ */
+static inline struct zwp_linux_buffer_params_v1 *
+zwp_linux_dmabuf_v1_create_params(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1)
+{
+	struct wl_proxy *params_id;
+
+	params_id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_dmabuf_v1,
+			 ZWP_LINUX_DMABUF_V1_CREATE_PARAMS, &zwp_linux_buffer_params_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_v1), 0, NULL);
+
+	return (struct zwp_linux_buffer_params_v1 *) params_id;
+}
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ *
+ * This request creates a new wp_linux_dmabuf_feedback object not bound
+ * to a particular surface. This object will deliver feedback about dmabuf
+ * parameters to use if the client doesn't support per-surface feedback
+ * (see get_surface_feedback).
+ */
+static inline struct zwp_linux_dmabuf_feedback_v1 *
+zwp_linux_dmabuf_v1_get_default_feedback(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_dmabuf_v1,
+			 ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK, &zwp_linux_dmabuf_feedback_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_v1), 0, NULL);
+
+	return (struct zwp_linux_dmabuf_feedback_v1 *) id;
+}
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_v1
+ *
+ * This request creates a new wp_linux_dmabuf_feedback object for the
+ * specified wl_surface. This object will deliver feedback about dmabuf
+ * parameters to use for buffers attached to this surface.
+ *
+ * If the surface is destroyed before the wp_linux_dmabuf_feedback object,
+ * the feedback object becomes inert.
+ */
+static inline struct zwp_linux_dmabuf_feedback_v1 *
+zwp_linux_dmabuf_v1_get_surface_feedback(struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1, struct wl_surface *surface)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_dmabuf_v1,
+			 ZWP_LINUX_DMABUF_V1_GET_SURFACE_FEEDBACK, &zwp_linux_dmabuf_feedback_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_v1), 0, NULL, surface);
+
+	return (struct zwp_linux_dmabuf_feedback_v1 *) id;
+}
+
+#ifndef ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM
+#define ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM
+enum zwp_linux_buffer_params_v1_error {
+	/**
+	 * the dmabuf_batch object has already been used to create a wl_buffer
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED = 0,
+	/**
+	 * plane index out of bounds
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX = 1,
+	/**
+	 * the plane index was already set
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET = 2,
+	/**
+	 * missing or too many planes to create a buffer
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE = 3,
+	/**
+	 * format not supported
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT = 4,
+	/**
+	 * invalid width or height
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS = 5,
+	/**
+	 * offset + stride * height goes out of dmabuf bounds
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS = 6,
+	/**
+	 * invalid wl_buffer resulted from importing dmabufs via                the create_immed request on given buffer_params
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER = 7,
+};
+#endif /* ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ENUM */
+
+#ifndef ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM
+#define ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM
+enum zwp_linux_buffer_params_v1_flags {
+	/**
+	 * contents are y-inverted
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT = 1,
+	/**
+	 * content is interlaced
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED = 2,
+	/**
+	 * bottom field first
+	 */
+	ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST = 4,
+};
+#endif /* ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_ENUM */
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ * @struct zwp_linux_buffer_params_v1_listener
+ */
+struct zwp_linux_buffer_params_v1_listener {
+	/**
+	 * buffer creation succeeded
+	 *
+	 * This event indicates that the attempted buffer creation was
+	 * successful. It provides the new wl_buffer referencing the
+	 * dmabuf(s).
+	 *
+	 * Upon receiving this event, the client should destroy the
+	 * zwp_linux_buffer_params_v1 object.
+	 * @param buffer the newly created wl_buffer
+	 */
+	void (*created)(void *data,
+			struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1,
+			struct wl_buffer *buffer);
+	/**
+	 * buffer creation failed
+	 *
+	 * This event indicates that the attempted buffer creation has
+	 * failed. It usually means that one of the dmabuf constraints has
+	 * not been fulfilled.
+	 *
+	 * Upon receiving this event, the client should destroy the
+	 * zwp_linux_buffer_params_v1 object.
+	 */
+	void (*failed)(void *data,
+		       struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1);
+};
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+static inline int
+zwp_linux_buffer_params_v1_add_listener(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1,
+					const struct zwp_linux_buffer_params_v1_listener *listener, void *data)
+{
+	return wl_proxy_add_listener((struct wl_proxy *) zwp_linux_buffer_params_v1,
+				     (void (**)(void)) listener, data);
+}
+
+#define ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY 0
+#define ZWP_LINUX_BUFFER_PARAMS_V1_ADD 1
+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE 2
+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED 3
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATED_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_FAILED_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_ADD_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ */
+#define ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED_SINCE_VERSION 2
+
+/** @ingroup iface_zwp_linux_buffer_params_v1 */
+static inline void
+zwp_linux_buffer_params_v1_set_user_data(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) zwp_linux_buffer_params_v1, user_data);
+}
+
+/** @ingroup iface_zwp_linux_buffer_params_v1 */
+static inline void *
+zwp_linux_buffer_params_v1_get_user_data(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) zwp_linux_buffer_params_v1);
+}
+
+static inline uint32_t
+zwp_linux_buffer_params_v1_get_version(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1)
+{
+	return wl_proxy_get_version((struct wl_proxy *) zwp_linux_buffer_params_v1);
+}
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ *
+ * Cleans up the temporary data sent to the server for dmabuf-based
+ * wl_buffer creation.
+ */
+static inline void
+zwp_linux_buffer_params_v1_destroy(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_buffer_params_v1,
+			 ZWP_LINUX_BUFFER_PARAMS_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_linux_buffer_params_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ *
+ * This request adds one dmabuf to the set in this
+ * zwp_linux_buffer_params_v1.
+ *
+ * The 64-bit unsigned value combined from modifier_hi and modifier_lo
+ * is the dmabuf layout modifier. DRM AddFB2 ioctl calls this the
+ * fb modifier, which is defined in drm_mode.h of Linux UAPI.
+ * This is an opaque token. Drivers use this token to express tiling,
+ * compression, etc. driver-specific modifications to the base format
+ * defined by the DRM fourcc code.
+ *
+ * Starting from version 4, the invalid_format protocol error is sent if
+ * the format + modifier pair was not advertised as supported.
+ *
+ * Starting from version 5, the invalid_format protocol error is sent if
+ * all planes don't use the same modifier.
+ *
+ * This request raises the PLANE_IDX error if plane_idx is too large.
+ * The error PLANE_SET is raised if attempting to set a plane that
+ * was already set.
+ */
+static inline void
+zwp_linux_buffer_params_v1_add(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1, int32_t fd, uint32_t plane_idx, uint32_t offset, uint32_t stride, uint32_t modifier_hi, uint32_t modifier_lo)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_buffer_params_v1,
+			 ZWP_LINUX_BUFFER_PARAMS_V1_ADD, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_linux_buffer_params_v1), 0, fd, plane_idx, offset, stride, modifier_hi, modifier_lo);
+}
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ *
+ * This asks for creation of a wl_buffer from the added dmabuf
+ * buffers. The wl_buffer is not created immediately but returned via
+ * the 'created' event if the dmabuf sharing succeeds. The sharing
+ * may fail at runtime for reasons a client cannot predict, in
+ * which case the 'failed' event is triggered.
+ *
+ * The 'format' argument is a DRM_FORMAT code, as defined by the
+ * libdrm's drm_fourcc.h. The Linux kernel's DRM sub-system is the
+ * authoritative source on how the format codes should work.
+ *
+ * The 'flags' is a bitfield of the flags defined in enum "flags".
+ * 'y_invert' means the that the image needs to be y-flipped.
+ *
+ * Flag 'interlaced' means that the frame in the buffer is not
+ * progressive as usual, but interlaced. An interlaced buffer as
+ * supported here must always contain both top and bottom fields.
+ * The top field always begins on the first pixel row. The temporal
+ * ordering between the two fields is top field first, unless
+ * 'bottom_first' is specified. It is undefined whether 'bottom_first'
+ * is ignored if 'interlaced' is not set.
+ *
+ * This protocol does not convey any information about field rate,
+ * duration, or timing, other than the relative ordering between the
+ * two fields in one buffer. A compositor may have to estimate the
+ * intended field rate from the incoming buffer rate. It is undefined
+ * whether the time of receiving wl_surface.commit with a new buffer
+ * attached, applying the wl_surface state, wl_surface.frame callback
+ * trigger, presentation, or any other point in the compositor cycle
+ * is used to measure the frame or field times. There is no support
+ * for detecting missed or late frames/fields/buffers either, and
+ * there is no support whatsoever for cooperating with interlaced
+ * compositor output.
+ *
+ * The composited image quality resulting from the use of interlaced
+ * buffers is explicitly undefined. A compositor may use elaborate
+ * hardware features or software to deinterlace and create progressive
+ * output frames from a sequence of interlaced input buffers, or it
+ * may produce substandard image quality. However, compositors that
+ * cannot guarantee reasonable image quality in all cases are recommended
+ * to just reject all interlaced buffers.
+ *
+ * Any argument errors, including non-positive width or height,
+ * mismatch between the number of planes and the format, bad
+ * format, bad offset or stride, may be indicated by fatal protocol
+ * errors: INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS,
+ * OUT_OF_BOUNDS.
+ *
+ * Dmabuf import errors in the server that are not obvious client
+ * bugs are returned via the 'failed' event as non-fatal. This
+ * allows attempting dmabuf sharing and falling back in the client
+ * if it fails.
+ *
+ * This request can be sent only once in the object's lifetime, after
+ * which the only legal request is destroy. This object should be
+ * destroyed after issuing a 'create' request. Attempting to use this
+ * object after issuing 'create' raises ALREADY_USED protocol error.
+ *
+ * It is not mandatory to issue 'create'. If a client wants to
+ * cancel the buffer creation, it can just destroy this object.
+ */
+static inline void
+zwp_linux_buffer_params_v1_create(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1, int32_t width, int32_t height, uint32_t format, uint32_t flags)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_buffer_params_v1,
+			 ZWP_LINUX_BUFFER_PARAMS_V1_CREATE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_linux_buffer_params_v1), 0, width, height, format, flags);
+}
+
+/**
+ * @ingroup iface_zwp_linux_buffer_params_v1
+ *
+ * This asks for immediate creation of a wl_buffer by importing the
+ * added dmabufs.
+ *
+ * In case of import success, no event is sent from the server, and the
+ * wl_buffer is ready to be used by the client.
+ *
+ * Upon import failure, either of the following may happen, as seen fit
+ * by the implementation:
+ * - the client is terminated with one of the following fatal protocol
+ * errors:
+ * - INCOMPLETE, INVALID_FORMAT, INVALID_DIMENSIONS, OUT_OF_BOUNDS,
+ * in case of argument errors such as mismatch between the number
+ * of planes and the format, bad format, non-positive width or
+ * height, or bad offset or stride.
+ * - INVALID_WL_BUFFER, in case the cause for failure is unknown or
+ * platform specific.
+ * - the server creates an invalid wl_buffer, marks it as failed and
+ * sends a 'failed' event to the client. The result of using this
+ * invalid wl_buffer as an argument in any request by the client is
+ * defined by the compositor implementation.
+ *
+ * This takes the same arguments as a 'create' request, and obeys the
+ * same restrictions.
+ */
+static inline struct wl_buffer *
+zwp_linux_buffer_params_v1_create_immed(struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1, int32_t width, int32_t height, uint32_t format, uint32_t flags)
+{
+	struct wl_proxy *buffer_id;
+
+	buffer_id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_buffer_params_v1,
+			 ZWP_LINUX_BUFFER_PARAMS_V1_CREATE_IMMED, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) zwp_linux_buffer_params_v1), 0, NULL, width, height, format, flags);
+
+	return (struct wl_buffer *) buffer_id;
+}
+
+#ifndef ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_ENUM
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_ENUM
+enum zwp_linux_dmabuf_feedback_v1_tranche_flags {
+	/**
+	 * direct scan-out tranche
+	 */
+	ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT = 1,
+};
+#endif /* ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_ENUM */
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ * @struct zwp_linux_dmabuf_feedback_v1_listener
+ */
+struct zwp_linux_dmabuf_feedback_v1_listener {
+	/**
+	 * all feedback has been sent
+	 *
+	 * This event is sent after all parameters of a
+	 * wp_linux_dmabuf_feedback object have been sent.
+	 *
+	 * This allows changes to the wp_linux_dmabuf_feedback parameters
+	 * to be seen as atomic, even if they happen via multiple events.
+	 */
+	void (*done)(void *data,
+		     struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1);
+	/**
+	 * format and modifier table
+	 *
+	 * This event provides a file descriptor which can be
+	 * memory-mapped to access the format and modifier table.
+	 *
+	 * The table contains a tightly packed array of consecutive format
+	 * + modifier pairs. Each pair is 16 bytes wide. It contains a
+	 * format as a 32-bit unsigned integer, followed by 4 bytes of
+	 * unused padding, and a modifier as a 64-bit unsigned integer. The
+	 * native endianness is used.
+	 *
+	 * The client must map the file descriptor in read-only private
+	 * mode.
+	 *
+	 * Compositors are not allowed to mutate the table file contents
+	 * once this event has been sent. Instead, compositors must create
+	 * a new, separate table file and re-send feedback parameters.
+	 * Compositors are allowed to store duplicate format + modifier
+	 * pairs in the table.
+	 * @param fd table file descriptor
+	 * @param size table size, in bytes
+	 */
+	void (*format_table)(void *data,
+			     struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+			     int32_t fd,
+			     uint32_t size);
+	/**
+	 * preferred main device
+	 *
+	 * This event advertises the main device that the server prefers
+	 * to use when direct scan-out to the target device isn't possible.
+	 * The advertised main device may be different for each
+	 * wp_linux_dmabuf_feedback object, and may change over time.
+	 *
+	 * There is exactly one main device. The compositor must send at
+	 * least one preference tranche with tranche_target_device equal to
+	 * main_device.
+	 *
+	 * Clients need to create buffers that the main device can import
+	 * and read from, otherwise creating the dmabuf wl_buffer will fail
+	 * (see the wp_linux_buffer_params.create and create_immed requests
+	 * for details). The main device will also likely be kept active by
+	 * the compositor, so clients can use it instead of waking up
+	 * another device for power savings.
+	 *
+	 * In general the device is a DRM node. The DRM node type (primary
+	 * vs. render) is unspecified. Clients must not rely on the
+	 * compositor sending a particular node type. Clients cannot check
+	 * two devices for equality by comparing the dev_t value.
+	 *
+	 * If explicit modifiers are not supported and the client performs
+	 * buffer allocations on a different device than the main device,
+	 * then the client must force the buffer to have a linear layout.
+	 * @param device device dev_t value
+	 */
+	void (*main_device)(void *data,
+			    struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+			    struct wl_array *device);
+	/**
+	 * a preference tranche has been sent
+	 *
+	 * This event splits tranche_target_device and tranche_formats
+	 * events in preference tranches. It is sent after a set of
+	 * tranche_target_device and tranche_formats events; it represents
+	 * the end of a tranche. The next tranche will have a lower
+	 * preference.
+	 */
+	void (*tranche_done)(void *data,
+			     struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1);
+	/**
+	 * target device
+	 *
+	 * This event advertises the target device that the server
+	 * prefers to use for a buffer created given this tranche. The
+	 * advertised target device may be different for each preference
+	 * tranche, and may change over time.
+	 *
+	 * There is exactly one target device per tranche.
+	 *
+	 * The target device may be a scan-out device, for example if the
+	 * compositor prefers to directly scan-out a buffer created given
+	 * this tranche. The target device may be a rendering device, for
+	 * example if the compositor prefers to texture from said buffer.
+	 *
+	 * The client can use this hint to allocate the buffer in a way
+	 * that makes it accessible from the target device, ideally
+	 * directly. The buffer must still be accessible from the main
+	 * device, either through direct import or through a potentially
+	 * more expensive fallback path. If the buffer can't be directly
+	 * imported from the main device then clients must be prepared for
+	 * the compositor changing the tranche priority or making wl_buffer
+	 * creation fail (see the wp_linux_buffer_params.create and
+	 * create_immed requests for details).
+	 *
+	 * If the device is a DRM node, the DRM node type (primary vs.
+	 * render) is unspecified. Clients must not rely on the compositor
+	 * sending a particular node type. Clients cannot check two devices
+	 * for equality by comparing the dev_t value.
+	 *
+	 * This event is tied to a preference tranche, see the tranche_done
+	 * event.
+	 * @param device device dev_t value
+	 */
+	void (*tranche_target_device)(void *data,
+				      struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+				      struct wl_array *device);
+	/**
+	 * supported buffer format modifier
+	 *
+	 * This event advertises the format + modifier combinations that
+	 * the compositor supports.
+	 *
+	 * It carries an array of indices, each referring to a format +
+	 * modifier pair in the last received format table (see the
+	 * format_table event). Each index is a 16-bit unsigned integer in
+	 * native endianness.
+	 *
+	 * For legacy support, DRM_FORMAT_MOD_INVALID is an allowed
+	 * modifier. It indicates that the server can support the format
+	 * with an implicit modifier. When a buffer has
+	 * DRM_FORMAT_MOD_INVALID as its modifier, it is as if no explicit
+	 * modifier is specified. The effective modifier will be derived
+	 * from the dmabuf.
+	 *
+	 * A compositor that sends valid modifiers and
+	 * DRM_FORMAT_MOD_INVALID for a given format supports both explicit
+	 * modifiers and implicit modifiers.
+	 *
+	 * Compositors must not send duplicate format + modifier pairs
+	 * within the same tranche or across two different tranches with
+	 * the same target device and flags.
+	 *
+	 * This event is tied to a preference tranche, see the tranche_done
+	 * event.
+	 *
+	 * For the definition of the format and modifier codes, see the
+	 * wp_linux_buffer_params.create request.
+	 * @param indices array of 16-bit indexes
+	 */
+	void (*tranche_formats)(void *data,
+				struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+				struct wl_array *indices);
+	/**
+	 * tranche flags
+	 *
+	 * This event sets tranche-specific flags.
+	 *
+	 * The scanout flag is a hint that direct scan-out may be attempted
+	 * by the compositor on the target device if the client
+	 * appropriately allocates a buffer. How to allocate a buffer that
+	 * can be scanned out on the target device is
+	 * implementation-defined.
+	 *
+	 * This event is tied to a preference tranche, see the tranche_done
+	 * event.
+	 * @param flags tranche flags
+	 */
+	void (*tranche_flags)(void *data,
+			      struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+			      uint32_t flags);
+};
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+static inline int
+zwp_linux_dmabuf_feedback_v1_add_listener(struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
+					  const struct zwp_linux_dmabuf_feedback_v1_listener *listener, void *data)
+{
+	return wl_proxy_add_listener((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1,
+				     (void (**)(void)) listener, data);
+}
+
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_DESTROY 0
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_DONE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_FORMAT_TABLE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_MAIN_DEVICE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_DONE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_TARGET_DEVICE_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FORMATS_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ */
+#define ZWP_LINUX_DMABUF_FEEDBACK_V1_DESTROY_SINCE_VERSION 1
+
+/** @ingroup iface_zwp_linux_dmabuf_feedback_v1 */
+static inline void
+zwp_linux_dmabuf_feedback_v1_set_user_data(struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1, user_data);
+}
+
+/** @ingroup iface_zwp_linux_dmabuf_feedback_v1 */
+static inline void *
+zwp_linux_dmabuf_feedback_v1_get_user_data(struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1);
+}
+
+static inline uint32_t
+zwp_linux_dmabuf_feedback_v1_get_version(struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
+{
+	return wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1);
+}
+
+/**
+ * @ingroup iface_zwp_linux_dmabuf_feedback_v1
+ *
+ * Using this request a client can tell the server that it is not going to
+ * use the wp_linux_dmabuf_feedback object anymore.
+ */
+static inline void
+zwp_linux_dmabuf_feedback_v1_destroy(struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1,
+			 ZWP_LINUX_DMABUF_FEEDBACK_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_linux_dmabuf_feedback_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-protocol.c b/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-protocol.c
new file mode 100644
index 000000000..d03908384
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-drm/linux-dmabuf-unstable-v1-protocol.c
@@ -0,0 +1,120 @@
+/* Generated by wayland-scanner 1.24.0 */
+
+/*
+ * Copyright © 2014, 2015 Collabora, Ltd.
+ *
+ * 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.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+#ifndef __has_attribute
+# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
+#endif
+
+#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
+#define WL_PRIVATE __attribute__ ((visibility("hidden")))
+#else
+#define WL_PRIVATE
+#endif
+
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface zwp_linux_buffer_params_v1_interface;
+extern const struct wl_interface zwp_linux_dmabuf_feedback_v1_interface;
+
+static const struct wl_interface *linux_dmabuf_unstable_v1_types[] = {
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	&zwp_linux_buffer_params_v1_interface,
+	&zwp_linux_dmabuf_feedback_v1_interface,
+	&zwp_linux_dmabuf_feedback_v1_interface,
+	&wl_surface_interface,
+	&wl_buffer_interface,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	&wl_buffer_interface,
+};
+
+static const struct wl_message zwp_linux_dmabuf_v1_requests[] = {
+	{ "destroy", "", linux_dmabuf_unstable_v1_types + 0 },
+	{ "create_params", "n", linux_dmabuf_unstable_v1_types + 6 },
+	{ "get_default_feedback", "4n", linux_dmabuf_unstable_v1_types + 7 },
+	{ "get_surface_feedback", "4no", linux_dmabuf_unstable_v1_types + 8 },
+};
+
+static const struct wl_message zwp_linux_dmabuf_v1_events[] = {
+	{ "format", "u", linux_dmabuf_unstable_v1_types + 0 },
+	{ "modifier", "3uuu", linux_dmabuf_unstable_v1_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface zwp_linux_dmabuf_v1_interface = {
+	"zwp_linux_dmabuf_v1", 5,
+	4, zwp_linux_dmabuf_v1_requests,
+	2, zwp_linux_dmabuf_v1_events,
+};
+
+static const struct wl_message zwp_linux_buffer_params_v1_requests[] = {
+	{ "destroy", "", linux_dmabuf_unstable_v1_types + 0 },
+	{ "add", "huuuuu", linux_dmabuf_unstable_v1_types + 0 },
+	{ "create", "iiuu", linux_dmabuf_unstable_v1_types + 0 },
+	{ "create_immed", "2niiuu", linux_dmabuf_unstable_v1_types + 10 },
+};
+
+static const struct wl_message zwp_linux_buffer_params_v1_events[] = {
+	{ "created", "n", linux_dmabuf_unstable_v1_types + 15 },
+	{ "failed", "", linux_dmabuf_unstable_v1_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface zwp_linux_buffer_params_v1_interface = {
+	"zwp_linux_buffer_params_v1", 5,
+	4, zwp_linux_buffer_params_v1_requests,
+	2, zwp_linux_buffer_params_v1_events,
+};
+
+static const struct wl_message zwp_linux_dmabuf_feedback_v1_requests[] = {
+	{ "destroy", "", linux_dmabuf_unstable_v1_types + 0 },
+};
+
+static const struct wl_message zwp_linux_dmabuf_feedback_v1_events[] = {
+	{ "done", "", linux_dmabuf_unstable_v1_types + 0 },
+	{ "format_table", "hu", linux_dmabuf_unstable_v1_types + 0 },
+	{ "main_device", "a", linux_dmabuf_unstable_v1_types + 0 },
+	{ "tranche_done", "", linux_dmabuf_unstable_v1_types + 0 },
+	{ "tranche_target_device", "a", linux_dmabuf_unstable_v1_types + 0 },
+	{ "tranche_formats", "a", linux_dmabuf_unstable_v1_types + 0 },
+	{ "tranche_flags", "u", linux_dmabuf_unstable_v1_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface zwp_linux_dmabuf_feedback_v1_interface = {
+	"zwp_linux_dmabuf_feedback_v1", 5,
+	1, zwp_linux_dmabuf_feedback_v1_requests,
+	7, zwp_linux_dmabuf_feedback_v1_events,
+};
+
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-client-protocol.h b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-client-protocol.h
new file mode 100644
index 000000000..f6a7fce0d
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-client-protocol.h
@@ -0,0 +1,313 @@
+/* Generated by wayland-scanner 1.24.0 */
+
+#ifndef DRM_CLIENT_PROTOCOL_H
+#define DRM_CLIENT_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @page page_drm The drm protocol
+ * @section page_ifaces_drm Interfaces
+ * - @subpage page_iface_wl_drm - 
+ * @section page_copyright_drm Copyright
+ * <pre>
+ *
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ * </pre>
+ */
+struct wl_buffer;
+struct wl_drm;
+
+#ifndef WL_DRM_INTERFACE
+#define WL_DRM_INTERFACE
+/**
+ * @page page_iface_wl_drm wl_drm
+ * @section page_iface_wl_drm_api API
+ * See @ref iface_wl_drm.
+ */
+/**
+ * @defgroup iface_wl_drm The wl_drm interface
+ */
+extern const struct wl_interface wl_drm_interface;
+#endif
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+	WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+	WL_DRM_ERROR_INVALID_FORMAT = 1,
+	WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+#ifndef WL_DRM_FORMAT_ENUM
+#define WL_DRM_FORMAT_ENUM
+enum wl_drm_format {
+	WL_DRM_FORMAT_C8 = 0x20203843,
+	WL_DRM_FORMAT_RGB332 = 0x38424752,
+	WL_DRM_FORMAT_BGR233 = 0x38524742,
+	WL_DRM_FORMAT_XRGB4444 = 0x32315258,
+	WL_DRM_FORMAT_XBGR4444 = 0x32314258,
+	WL_DRM_FORMAT_RGBX4444 = 0x32315852,
+	WL_DRM_FORMAT_BGRX4444 = 0x32315842,
+	WL_DRM_FORMAT_ARGB4444 = 0x32315241,
+	WL_DRM_FORMAT_ABGR4444 = 0x32314241,
+	WL_DRM_FORMAT_RGBA4444 = 0x32314152,
+	WL_DRM_FORMAT_BGRA4444 = 0x32314142,
+	WL_DRM_FORMAT_XRGB1555 = 0x35315258,
+	WL_DRM_FORMAT_XBGR1555 = 0x35314258,
+	WL_DRM_FORMAT_RGBX5551 = 0x35315852,
+	WL_DRM_FORMAT_BGRX5551 = 0x35315842,
+	WL_DRM_FORMAT_ARGB1555 = 0x35315241,
+	WL_DRM_FORMAT_ABGR1555 = 0x35314241,
+	WL_DRM_FORMAT_RGBA5551 = 0x35314152,
+	WL_DRM_FORMAT_BGRA5551 = 0x35314142,
+	WL_DRM_FORMAT_RGB565 = 0x36314752,
+	WL_DRM_FORMAT_BGR565 = 0x36314742,
+	WL_DRM_FORMAT_RGB888 = 0x34324752,
+	WL_DRM_FORMAT_BGR888 = 0x34324742,
+	WL_DRM_FORMAT_XRGB8888 = 0x34325258,
+	WL_DRM_FORMAT_XBGR8888 = 0x34324258,
+	WL_DRM_FORMAT_RGBX8888 = 0x34325852,
+	WL_DRM_FORMAT_BGRX8888 = 0x34325842,
+	WL_DRM_FORMAT_ARGB8888 = 0x34325241,
+	WL_DRM_FORMAT_ABGR8888 = 0x34324241,
+	WL_DRM_FORMAT_RGBA8888 = 0x34324152,
+	WL_DRM_FORMAT_BGRA8888 = 0x34324142,
+	WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
+	WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
+	WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
+	WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
+	WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
+	WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
+	WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
+	WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
+	WL_DRM_FORMAT_YUYV = 0x56595559,
+	WL_DRM_FORMAT_YVYU = 0x55595659,
+	WL_DRM_FORMAT_UYVY = 0x59565955,
+	WL_DRM_FORMAT_VYUY = 0x59555956,
+	WL_DRM_FORMAT_AYUV = 0x56555941,
+	WL_DRM_FORMAT_XYUV8888 = 0x56555958,
+	WL_DRM_FORMAT_NV12 = 0x3231564e,
+	WL_DRM_FORMAT_NV21 = 0x3132564e,
+	WL_DRM_FORMAT_NV16 = 0x3631564e,
+	WL_DRM_FORMAT_NV61 = 0x3136564e,
+	WL_DRM_FORMAT_YUV410 = 0x39565559,
+	WL_DRM_FORMAT_YVU410 = 0x39555659,
+	WL_DRM_FORMAT_YUV411 = 0x31315559,
+	WL_DRM_FORMAT_YVU411 = 0x31315659,
+	WL_DRM_FORMAT_YUV420 = 0x32315559,
+	WL_DRM_FORMAT_YVU420 = 0x32315659,
+	WL_DRM_FORMAT_YUV422 = 0x36315559,
+	WL_DRM_FORMAT_YVU422 = 0x36315659,
+	WL_DRM_FORMAT_YUV444 = 0x34325559,
+	WL_DRM_FORMAT_YVU444 = 0x34325659,
+	WL_DRM_FORMAT_ABGR16F = 0x48344241,
+	WL_DRM_FORMAT_XBGR16F = 0x48344258,
+};
+#endif /* WL_DRM_FORMAT_ENUM */
+
+#ifndef WL_DRM_CAPABILITY_ENUM
+#define WL_DRM_CAPABILITY_ENUM
+/**
+ * @ingroup iface_wl_drm
+ * wl_drm capability bitmask
+ *
+ * Bitmask of capabilities.
+ */
+enum wl_drm_capability {
+	/**
+	 * wl_drm prime available
+	 */
+	WL_DRM_CAPABILITY_PRIME = 1,
+};
+#endif /* WL_DRM_CAPABILITY_ENUM */
+
+/**
+ * @ingroup iface_wl_drm
+ * @struct wl_drm_listener
+ */
+struct wl_drm_listener {
+	/**
+	 */
+	void (*device)(void *data,
+		       struct wl_drm *wl_drm,
+		       const char *name);
+	/**
+	 */
+	void (*format)(void *data,
+		       struct wl_drm *wl_drm,
+		       uint32_t format);
+	/**
+	 */
+	void (*authenticated)(void *data,
+			      struct wl_drm *wl_drm);
+	/**
+	 */
+	void (*capabilities)(void *data,
+			     struct wl_drm *wl_drm,
+			     uint32_t value);
+};
+
+/**
+ * @ingroup iface_wl_drm
+ */
+static inline int
+wl_drm_add_listener(struct wl_drm *wl_drm,
+		    const struct wl_drm_listener *listener, void *data)
+{
+	return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
+				     (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE 0
+#define WL_DRM_CREATE_BUFFER 1
+#define WL_DRM_CREATE_PLANAR_BUFFER 2
+#define WL_DRM_CREATE_PRIME_BUFFER 3
+
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_DEVICE_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_FORMAT_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_AUTHENTICATED_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CAPABILITIES_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_AUTHENTICATE_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_BUFFER_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_PLANAR_BUFFER_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_PRIME_BUFFER_SINCE_VERSION 2
+
+/** @ingroup iface_wl_drm */
+static inline void
+wl_drm_set_user_data(struct wl_drm *wl_drm, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) wl_drm, user_data);
+}
+
+/** @ingroup iface_wl_drm */
+static inline void *
+wl_drm_get_user_data(struct wl_drm *wl_drm)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) wl_drm);
+}
+
+static inline uint32_t
+wl_drm_get_version(struct wl_drm *wl_drm)
+{
+	return wl_proxy_get_version((struct wl_proxy *) wl_drm);
+}
+
+/** @ingroup iface_wl_drm */
+static inline void
+wl_drm_destroy(struct wl_drm *wl_drm)
+{
+	wl_proxy_destroy((struct wl_proxy *) wl_drm);
+}
+
+/**
+ * @ingroup iface_wl_drm
+ */
+static inline void
+wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) wl_drm,
+			 WL_DRM_AUTHENTICATE, NULL, wl_proxy_get_version((struct wl_proxy *) wl_drm), 0, id);
+}
+
+/**
+ * @ingroup iface_wl_drm
+ */
+static inline struct wl_buffer *
+wl_drm_create_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t stride, uint32_t format)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) wl_drm,
+			 WL_DRM_CREATE_BUFFER, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_drm), 0, NULL, name, width, height, stride, format);
+
+	return (struct wl_buffer *) id;
+}
+
+/**
+ * @ingroup iface_wl_drm
+ */
+static inline struct wl_buffer *
+wl_drm_create_planar_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) wl_drm,
+			 WL_DRM_CREATE_PLANAR_BUFFER, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_drm), 0, NULL, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+	return (struct wl_buffer *) id;
+}
+
+/**
+ * @ingroup iface_wl_drm
+ */
+static inline struct wl_buffer *
+wl_drm_create_prime_buffer(struct wl_drm *wl_drm, int32_t name, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) wl_drm,
+			 WL_DRM_CREATE_PRIME_BUFFER, &wl_buffer_interface, wl_proxy_get_version((struct wl_proxy *) wl_drm), 0, NULL, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+	return (struct wl_buffer *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c
new file mode 100644
index 000000000..7bd3cb82b
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-protocol.c
@@ -0,0 +1,97 @@
+/* Generated by wayland-scanner 1.24.0 */
+
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+#ifndef __has_attribute
+# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
+#endif
+
+#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
+#define WL_PRIVATE __attribute__ ((visibility("hidden")))
+#else
+#define WL_PRIVATE
+#endif
+
+extern const struct wl_interface wl_buffer_interface;
+
+static const struct wl_interface *drm_types[] = {
+	NULL,
+	&wl_buffer_interface,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	&wl_buffer_interface,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	&wl_buffer_interface,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+};
+
+static const struct wl_message wl_drm_requests[] = {
+	{ "authenticate", "u", drm_types + 0 },
+	{ "create_buffer", "nuiiuu", drm_types + 1 },
+	{ "create_planar_buffer", "nuiiuiiiiii", drm_types + 7 },
+	{ "create_prime_buffer", "2nhiiuiiiiii", drm_types + 18 },
+};
+
+static const struct wl_message wl_drm_events[] = {
+	{ "device", "s", drm_types + 0 },
+	{ "format", "u", drm_types + 0 },
+	{ "authenticated", "", drm_types + 0 },
+	{ "capabilities", "u", drm_types + 0 },
+};
+
+WL_PRIVATE const struct wl_interface wl_drm_interface = {
+	"wl_drm", 2,
+	4, wl_drm_requests,
+	4, wl_drm_events,
+};
+
diff --git a/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-server-protocol.h b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-server-protocol.h
new file mode 100644
index 000000000..ebadf65d4
--- /dev/null
+++ b/lib/mesa/src/egl/wayland/wayland-drm/wayland-drm-server-protocol.h
@@ -0,0 +1,481 @@
+/* Generated by wayland-scanner 1.24.0 */
+
+#ifndef DRM_SERVER_PROTOCOL_H
+#define DRM_SERVER_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-server.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct wl_client;
+struct wl_resource;
+
+/**
+ * @page page_drm The drm protocol
+ * @section page_ifaces_drm Interfaces
+ * - @subpage page_iface_wl_drm - 
+ * @section page_copyright_drm Copyright
+ * <pre>
+ *
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ * </pre>
+ */
+struct wl_buffer;
+struct wl_drm;
+
+#ifndef WL_DRM_INTERFACE
+#define WL_DRM_INTERFACE
+/**
+ * @page page_iface_wl_drm wl_drm
+ * @section page_iface_wl_drm_api API
+ * See @ref iface_wl_drm.
+ */
+/**
+ * @defgroup iface_wl_drm The wl_drm interface
+ */
+extern const struct wl_interface wl_drm_interface;
+#endif
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+	WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+	WL_DRM_ERROR_INVALID_FORMAT = 1,
+	WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+#ifndef WL_DRM_ERROR_ENUM_IS_VALID
+#define WL_DRM_ERROR_ENUM_IS_VALID
+/**
+ * @ingroup iface_wl_drm
+ * Validate a wl_drm error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_drm_error
+ */
+static inline bool
+wl_drm_error_is_valid(uint32_t value, uint32_t version) {
+	switch (value) {
+	case WL_DRM_ERROR_AUTHENTICATE_FAIL:
+		return version >= 1;
+	case WL_DRM_ERROR_INVALID_FORMAT:
+		return version >= 1;
+	case WL_DRM_ERROR_INVALID_NAME:
+		return version >= 1;
+	default:
+		return false;
+	}
+}
+#endif /* WL_DRM_ERROR_ENUM_IS_VALID */
+
+#ifndef WL_DRM_FORMAT_ENUM
+#define WL_DRM_FORMAT_ENUM
+enum wl_drm_format {
+	WL_DRM_FORMAT_C8 = 0x20203843,
+	WL_DRM_FORMAT_RGB332 = 0x38424752,
+	WL_DRM_FORMAT_BGR233 = 0x38524742,
+	WL_DRM_FORMAT_XRGB4444 = 0x32315258,
+	WL_DRM_FORMAT_XBGR4444 = 0x32314258,
+	WL_DRM_FORMAT_RGBX4444 = 0x32315852,
+	WL_DRM_FORMAT_BGRX4444 = 0x32315842,
+	WL_DRM_FORMAT_ARGB4444 = 0x32315241,
+	WL_DRM_FORMAT_ABGR4444 = 0x32314241,
+	WL_DRM_FORMAT_RGBA4444 = 0x32314152,
+	WL_DRM_FORMAT_BGRA4444 = 0x32314142,
+	WL_DRM_FORMAT_XRGB1555 = 0x35315258,
+	WL_DRM_FORMAT_XBGR1555 = 0x35314258,
+	WL_DRM_FORMAT_RGBX5551 = 0x35315852,
+	WL_DRM_FORMAT_BGRX5551 = 0x35315842,
+	WL_DRM_FORMAT_ARGB1555 = 0x35315241,
+	WL_DRM_FORMAT_ABGR1555 = 0x35314241,
+	WL_DRM_FORMAT_RGBA5551 = 0x35314152,
+	WL_DRM_FORMAT_BGRA5551 = 0x35314142,
+	WL_DRM_FORMAT_RGB565 = 0x36314752,
+	WL_DRM_FORMAT_BGR565 = 0x36314742,
+	WL_DRM_FORMAT_RGB888 = 0x34324752,
+	WL_DRM_FORMAT_BGR888 = 0x34324742,
+	WL_DRM_FORMAT_XRGB8888 = 0x34325258,
+	WL_DRM_FORMAT_XBGR8888 = 0x34324258,
+	WL_DRM_FORMAT_RGBX8888 = 0x34325852,
+	WL_DRM_FORMAT_BGRX8888 = 0x34325842,
+	WL_DRM_FORMAT_ARGB8888 = 0x34325241,
+	WL_DRM_FORMAT_ABGR8888 = 0x34324241,
+	WL_DRM_FORMAT_RGBA8888 = 0x34324152,
+	WL_DRM_FORMAT_BGRA8888 = 0x34324142,
+	WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
+	WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
+	WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
+	WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
+	WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
+	WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
+	WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
+	WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
+	WL_DRM_FORMAT_YUYV = 0x56595559,
+	WL_DRM_FORMAT_YVYU = 0x55595659,
+	WL_DRM_FORMAT_UYVY = 0x59565955,
+	WL_DRM_FORMAT_VYUY = 0x59555956,
+	WL_DRM_FORMAT_AYUV = 0x56555941,
+	WL_DRM_FORMAT_XYUV8888 = 0x56555958,
+	WL_DRM_FORMAT_NV12 = 0x3231564e,
+	WL_DRM_FORMAT_NV21 = 0x3132564e,
+	WL_DRM_FORMAT_NV16 = 0x3631564e,
+	WL_DRM_FORMAT_NV61 = 0x3136564e,
+	WL_DRM_FORMAT_YUV410 = 0x39565559,
+	WL_DRM_FORMAT_YVU410 = 0x39555659,
+	WL_DRM_FORMAT_YUV411 = 0x31315559,
+	WL_DRM_FORMAT_YVU411 = 0x31315659,
+	WL_DRM_FORMAT_YUV420 = 0x32315559,
+	WL_DRM_FORMAT_YVU420 = 0x32315659,
+	WL_DRM_FORMAT_YUV422 = 0x36315559,
+	WL_DRM_FORMAT_YVU422 = 0x36315659,
+	WL_DRM_FORMAT_YUV444 = 0x34325559,
+	WL_DRM_FORMAT_YVU444 = 0x34325659,
+	WL_DRM_FORMAT_ABGR16F = 0x48344241,
+	WL_DRM_FORMAT_XBGR16F = 0x48344258,
+};
+#endif /* WL_DRM_FORMAT_ENUM */
+
+#ifndef WL_DRM_FORMAT_ENUM_IS_VALID
+#define WL_DRM_FORMAT_ENUM_IS_VALID
+/**
+ * @ingroup iface_wl_drm
+ * Validate a wl_drm format value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_drm_format
+ */
+static inline bool
+wl_drm_format_is_valid(uint32_t value, uint32_t version) {
+	switch (value) {
+	case WL_DRM_FORMAT_C8:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGB332:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGR233:
+		return version >= 1;
+	case WL_DRM_FORMAT_XRGB4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_XBGR4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBX4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRX4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_ARGB4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_ABGR4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBA4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRA4444:
+		return version >= 1;
+	case WL_DRM_FORMAT_XRGB1555:
+		return version >= 1;
+	case WL_DRM_FORMAT_XBGR1555:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBX5551:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRX5551:
+		return version >= 1;
+	case WL_DRM_FORMAT_ARGB1555:
+		return version >= 1;
+	case WL_DRM_FORMAT_ABGR1555:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBA5551:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRA5551:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGB565:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGR565:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGB888:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGR888:
+		return version >= 1;
+	case WL_DRM_FORMAT_XRGB8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_XBGR8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBX8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRX8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_ARGB8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_ABGR8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBA8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRA8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_XRGB2101010:
+		return version >= 1;
+	case WL_DRM_FORMAT_XBGR2101010:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBX1010102:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRX1010102:
+		return version >= 1;
+	case WL_DRM_FORMAT_ARGB2101010:
+		return version >= 1;
+	case WL_DRM_FORMAT_ABGR2101010:
+		return version >= 1;
+	case WL_DRM_FORMAT_RGBA1010102:
+		return version >= 1;
+	case WL_DRM_FORMAT_BGRA1010102:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUYV:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVYU:
+		return version >= 1;
+	case WL_DRM_FORMAT_UYVY:
+		return version >= 1;
+	case WL_DRM_FORMAT_VYUY:
+		return version >= 1;
+	case WL_DRM_FORMAT_AYUV:
+		return version >= 1;
+	case WL_DRM_FORMAT_XYUV8888:
+		return version >= 1;
+	case WL_DRM_FORMAT_NV12:
+		return version >= 1;
+	case WL_DRM_FORMAT_NV21:
+		return version >= 1;
+	case WL_DRM_FORMAT_NV16:
+		return version >= 1;
+	case WL_DRM_FORMAT_NV61:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUV410:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVU410:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUV411:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVU411:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUV420:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVU420:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUV422:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVU422:
+		return version >= 1;
+	case WL_DRM_FORMAT_YUV444:
+		return version >= 1;
+	case WL_DRM_FORMAT_YVU444:
+		return version >= 1;
+	case WL_DRM_FORMAT_ABGR16F:
+		return version >= 1;
+	case WL_DRM_FORMAT_XBGR16F:
+		return version >= 1;
+	default:
+		return false;
+	}
+}
+#endif /* WL_DRM_FORMAT_ENUM_IS_VALID */
+
+#ifndef WL_DRM_CAPABILITY_ENUM
+#define WL_DRM_CAPABILITY_ENUM
+/**
+ * @ingroup iface_wl_drm
+ * wl_drm capability bitmask
+ *
+ * Bitmask of capabilities.
+ */
+enum wl_drm_capability {
+	/**
+	 * wl_drm prime available
+	 */
+	WL_DRM_CAPABILITY_PRIME = 1,
+};
+#endif /* WL_DRM_CAPABILITY_ENUM */
+
+#ifndef WL_DRM_CAPABILITY_ENUM_IS_VALID
+#define WL_DRM_CAPABILITY_ENUM_IS_VALID
+/**
+ * @ingroup iface_wl_drm
+ * Validate a wl_drm capability value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_drm_capability
+ */
+static inline bool
+wl_drm_capability_is_valid(uint32_t value, uint32_t version) {
+	switch (value) {
+	case WL_DRM_CAPABILITY_PRIME:
+		return version >= 1;
+	default:
+		return false;
+	}
+}
+#endif /* WL_DRM_CAPABILITY_ENUM_IS_VALID */
+
+/**
+ * @ingroup iface_wl_drm
+ * @struct wl_drm_interface
+ */
+struct wl_drm_interface {
+	/**
+	 */
+	void (*authenticate)(struct wl_client *client,
+			     struct wl_resource *resource,
+			     uint32_t id);
+	/**
+	 */
+	void (*create_buffer)(struct wl_client *client,
+			      struct wl_resource *resource,
+			      uint32_t id,
+			      uint32_t name,
+			      int32_t width,
+			      int32_t height,
+			      uint32_t stride,
+			      uint32_t format);
+	/**
+	 */
+	void (*create_planar_buffer)(struct wl_client *client,
+				     struct wl_resource *resource,
+				     uint32_t id,
+				     uint32_t name,
+				     int32_t width,
+				     int32_t height,
+				     uint32_t format,
+				     int32_t offset0,
+				     int32_t stride0,
+				     int32_t offset1,
+				     int32_t stride1,
+				     int32_t offset2,
+				     int32_t stride2);
+	/**
+	 * @since 2
+	 */
+	void (*create_prime_buffer)(struct wl_client *client,
+				    struct wl_resource *resource,
+				    uint32_t id,
+				    int32_t name,
+				    int32_t width,
+				    int32_t height,
+				    uint32_t format,
+				    int32_t offset0,
+				    int32_t stride0,
+				    int32_t offset1,
+				    int32_t stride1,
+				    int32_t offset2,
+				    int32_t stride2);
+};
+
+#define WL_DRM_DEVICE 0
+#define WL_DRM_FORMAT 1
+#define WL_DRM_AUTHENTICATED 2
+#define WL_DRM_CAPABILITIES 3
+
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_DEVICE_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_FORMAT_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_AUTHENTICATED_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CAPABILITIES_SINCE_VERSION 1
+
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_AUTHENTICATE_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_BUFFER_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_PLANAR_BUFFER_SINCE_VERSION 1
+/**
+ * @ingroup iface_wl_drm
+ */
+#define WL_DRM_CREATE_PRIME_BUFFER_SINCE_VERSION 2
+
+/**
+ * @ingroup iface_wl_drm
+ * Sends an device event to the client owning the resource.
+ * @param resource_ The client's resource
+ */
+static inline void
+wl_drm_send_device(struct wl_resource *resource_, const char *name)
+{
+	wl_resource_post_event(resource_, WL_DRM_DEVICE, name);
+}
+
+/**
+ * @ingroup iface_wl_drm
+ * Sends an format event to the client owning the resource.
+ * @param resource_ The client's resource
+ */
+static inline void
+wl_drm_send_format(struct wl_resource *resource_, uint32_t format)
+{
+	wl_resource_post_event(resource_, WL_DRM_FORMAT, format);
+}
+
+/**
+ * @ingroup iface_wl_drm
+ * Sends an authenticated event to the client owning the resource.
+ * @param resource_ The client's resource
+ */
+static inline void
+wl_drm_send_authenticated(struct wl_resource *resource_)
+{
+	wl_resource_post_event(resource_, WL_DRM_AUTHENTICATED);
+}
+
+/**
+ * @ingroup iface_wl_drm
+ * Sends an capabilities event to the client owning the resource.
+ * @param resource_ The client's resource
+ */
+static inline void
+wl_drm_send_capabilities(struct wl_resource *resource_, uint32_t value)
+{
+	wl_resource_post_event(resource_, WL_DRM_CAPABILITIES, value);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif