diff --git a/include/vulkan/vk_platform.h b/include/vulkan/vk_platform.h
index 71858453fa2b384630faabd839e1d3f743192376..2e2133c57123f5c4af8a2751f662fe4716caebaf 100644
--- a/include/vulkan/vk_platform.h
+++ b/include/vulkan/vk_platform.h
@@ -77,6 +77,12 @@ extern "C"
#endif
#endif // !defined(VK_NO_STDINT_H)
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ // Forward declared for VK_EXT_acquire_wl_display
+ struct zwp_drm_lease_device_v1;
+ struct zwp_drm_lease_connector_v1;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
diff --git a/include/vulkan/vulkan_wayland.h b/include/vulkan/vulkan_wayland.h
index f7b307e519be8f97ccd76e7fd79cbb10d498229b..f2120c733540fc2385a741818aeccd709fef7c5d 100644
--- a/include/vulkan/vulkan_wayland.h
+++ b/include/vulkan/vulkan_wayland.h
@@ -47,6 +47,26 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR(
struct wl_display* display);
#endif
+
+#define VK_EXT_acquire_wl_display 1
+#define VK_EXT_ACQUIRE_WL_DISPLAY_SPEC_VERSION 1
+#define VK_EXT_ACQUIRE_WL_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_wl_display"
+typedef struct VkWaylandLeaseConnectorEXT {
+ struct zwp_drm_lease_connector_v1* pConnector;
+ VkDisplayKHR pDisplay;
+} VkWaylandLeaseConnectorEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireWaylandDisplayEXT)(VkPhysicalDevice physicalDevice, struct wl_display* display, struct zwp_drm_lease_device_v1* leaseDevice, uint32_t pConnectorCount, VkWaylandLeaseConnectorEXT* pConnectors);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWaylandDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ struct wl_display* display,
+ struct zwp_drm_lease_device_v1* leaseDevice,
+ uint32_t pConnectorCount,
+ VkWaylandLeaseConnectorEXT* pConnectors);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/meson.build b/meson.build
index 827651f088f6d4ffd0a3f07f2d847cc84aa7e4cb..5f01fdf6dfa9cb841c790f32639c654037fd7df3 100644
--- a/meson.build
+++ b/meson.build
@@ -419,6 +419,13 @@ else
with_xlib_lease = _xlib_lease == 'enabled'
endif
+_wl_lease = get_option('wl-lease')
+if _wl_lease == 'auto'
+ with_wl_lease = with_platform_wayland and system_has_kms_drm
+else
+ with_wl_lease = _wl_lease == 'enabled'
+endif
+
_egl = get_option('egl')
if _egl == 'true'
_egl = 'enabled'
diff --git a/meson_options.txt b/meson_options.txt
index 599a2b3fd898e3b6e8bbb4aa52e8be140e172bcc..3715dc937dc9e8fe558ceb9a4078b5177720654e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -420,6 +420,13 @@ option(
choices : ['auto', 'true', 'false', 'enabled', 'disabled'],
description : 'Enable VK_EXT_acquire_xlib_display.'
)
+option(
+ 'wl-lease',
+ type : 'combo',
+ value : 'auto',
+ choices : ['auto', 'enabled', 'disabled'],
+ description : 'Enable VK_EXT_acquire_wl_display.'
+)
option(
'glx-direct',
type : 'boolean',
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 3f6373469095b36ff36b281a19113a074be6fca9..7a2fbdc6d4a1d98c9cd6c65b821f83b8ff106c3e 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -121,6 +121,7 @@ EXTENSIONS = [
Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'),
Extension('VK_KHR_zero_initialize_workgroup_memory', 1, True),
Extension('VK_EXT_4444_formats', 1, True),
+ Extension('VK_EXT_acquire_wl_display', 1, 'VK_USE_PLATFORM_WAYLAND_KHR'),
Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
Extension('VK_EXT_buffer_device_address', 2, True),
Extension('VK_EXT_calibrated_timestamps', 1, 'RADV_SUPPORT_CALIBRATED_TIMESTAMPS'),
diff --git a/src/amd/vulkan/radv_wsi_display.c b/src/amd/vulkan/radv_wsi_display.c
index 64c7acd373441dffc21815979160f233cea22d1c..e3256834fb25381d68f812ab70b230beffdd324a 100644
--- a/src/amd/vulkan/radv_wsi_display.c
+++ b/src/amd/vulkan/radv_wsi_display.c
@@ -367,3 +367,25 @@ radv_GetSwapchainCounterEXT(VkDevice _device,
value);
}
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+/* VK_EXT_acquire_wl_display */
+
+VkResult
+radv_AcquireWaylandDisplayEXT(VkPhysicalDevice physical_device,
+ struct wl_display* display,
+ struct zwp_drm_lease_device_v1* lease_device,
+ uint32_t nConnectors,
+ VkWaylandLeaseConnectorEXT* pConnectors)
+{
+ RADV_FROM_HANDLE(radv_physical_device, pdevice, physical_device);
+
+ return wsi_acquire_wl_display(physical_device,
+ &pdevice->wsi_device,
+ display,
+ lease_device,
+ nConnectors,
+ pConnectors);
+}
+
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
diff --git a/src/vulkan/meson.build b/src/vulkan/meson.build
index 22610a5493f519fc18dc954edbf18e290b2a27bb..5fe9909b0a119efa5cbb51ee58fb091a77727475 100644
--- a/src/vulkan/meson.build
+++ b/src/vulkan/meson.build
@@ -42,7 +42,7 @@ if with_platform_x11
vulkan_wsi_list += ['xcb', 'x11']
endif
if with_platform_wayland
- vulkan_wsi_args += ['-DVK_USE_PLATFORM_WAYLAND_KHR']
+ vulkan_wsi_args += ['-DVK_USE_PLATFORM_WAYLAND_KHR', '-DVK_USE_PLATFORM_WAYLAND']
vulkan_wsi_deps += dep_wayland_client
vulkan_wsi_list += ['wayland']
endif
@@ -57,7 +57,6 @@ if with_xlib_lease
vulkan_wsi_list += ['xlib_xrandr']
endif
-
subdir('util')
subdir('wsi')
if with_vulkan_overlay_layer
diff --git a/src/vulkan/registry/vk.xml b/src/vulkan/registry/vk.xml
index fa31b42f0dc90dd64ea7b0162cbc68c76949427f..6a248fbbccf804460d57c5b610210f84dc1287f2 100644
--- a/src/vulkan/registry/vk.xml
+++ b/src/vulkan/registry/vk.xml
@@ -108,6 +108,8 @@ branch of the member gitlab server.
+
+
@@ -5148,6 +5150,10 @@ typedef void CAMetalLayer;
uint32_t mutableDescriptorTypeListCount
const VkMutableDescriptorTypeListVALVE* pMutableDescriptorTypeLists
+
+ struct zwp_drm_lease_connector_v1* pConnector
+ VkDisplayKHR pDisplay
+
Vulkan enumerant (token) definitions
@@ -9306,6 +9312,14 @@ typedef void CAMetalLayer;
const uint32_t* pMaxPrimitiveCounts
VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo
+
+ VkResult vkAcquireWaylandDisplayEXT
+ VkPhysicalDevice physicalDevice
+ struct wl_display* display
+ struct zwp_drm_lease_device_v1* leaseDevice
+ uint32_t pConnectorCount
+ VkWaylandLeaseConnectorEXT* pConnectors
+
@@ -13904,10 +13918,11 @@ typedef void CAMetalLayer;
-
+
-
-
+
+
+
diff --git a/src/vulkan/wsi/drm-lease-unstable-v1.xml b/src/vulkan/wsi/drm-lease-unstable-v1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..62641c2194295ed54a27d65827ea2534dcc3dda5
--- /dev/null
+++ b/src/vulkan/wsi/drm-lease-unstable-v1.xml
@@ -0,0 +1,260 @@
+
+
+
+ Copyright © 2018 NXP
+ Copyright © 2019 Status Research & Development GmbH.
+
+ 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.
+
+
+
+
+ This protocol is used by Wayland compositors which act as Direct
+ Renderering Manager (DRM) masters to lease DRM resources to Wayland
+ clients. Once leased, the compositor will not use the leased resources
+ until the lease is revoked or the client closes the file descriptor. The
+ compositor will advertise one zwp_drm_lease_device_v1 for each DRM node
+ which has resources available for leasing.
+
+ The lease device is used to advertise connectors which are available for
+ leasing, and by the client to negotiate a lease request.
+
+ Warning! The protocol described in this file is experimental and
+ backward incompatible changes may be made. Backward compatible changes
+ may be added together with the corresponding interface version bump.
+ Backward incompatible changes are done by bumping the version number in
+ the protocol and interface names and resetting the interface version.
+ Once the protocol is to be declared stable, the 'z' prefix and the
+ version number in the protocol and interface names are removed and the
+ interface version number is reset.
+
+
+
+
+ Creates a lease request object.
+
+ See the documentation for zwp_drm_lease_request_v1 for details.
+
+
+
+
+
+
+ Indicates the client no longer wishes to receive connector events. The
+ compositor may still send connector events until it sends the finish
+ event, however.
+ The client must not send any requests after this one, doing so will
+ raise a wl_display error.
+
+
+
+
+
+ The compositor will send this event when the zwp_drm_lease_device_v1
+ global is bound, although there are no guarantees as to how long this
+ takes - the compositor might need to wait until regaining DRM master.
+ The included fd is a non-master DRM file descriptor opened for this
+ device and the compositor must not authenticate it.
+ The purpose of this event is to give the client the ability to
+ query DRM and discover information which may help them pick the
+ appropriate DRM device or select the appropriate connectors therein.
+
+
+
+
+
+
+ The compositor will use this event to advertise connectors available for
+ lease by clients. Clients are guaranteed that no disconnected
+ connectors will be advertised. This object may be passed into a lease
+ request to indicate the client would like to lease that connector, see
+ zwp_drm_lease_request_v1.request_connector for details.
+
+ When this global is bound, the compositor will send all connectors
+ available for lease, but may send additional connectors at any time.
+
+
+
+
+
+
+ This event indicates that the compositor is done sending connector
+ events. The compositor will destroy this object immediately after
+ sending this event, and it will become invalid. The client should
+ release any resources associated with this device after receiving this
+ event.
+
+
+
+
+
+
+ Represents a DRM connector which is available for lease. These objects are
+ created via zwp_drm_lease_device_v1.connector, and should be passed into
+ lease requests via zwp_drm_lease_request_v1.request_connector.
+
+
+
+
+ The compositor sends this event once the connector is created to
+ indicate the name of this connector. This will not change for the
+ duration of the Wayland session, but is not guaranteed to be consistent
+ between sessions.
+
+ If the compositor also supports zxdg_output_manager_v1 and this
+ connector corresponds to a zxdg_output_v1, this name will match the
+ name of this zxdg_output_v1 object.
+
+
+
+
+
+
+ The compositor sends this event once the connector is created to provide
+ a human-readable description for this connector, which may be presented
+ to the user.
+
+
+
+
+
+
+ The compositor will send this event to indicate the DRM ID which
+ represents the underlying connector that is being offered. Note that
+ the final lease may include additional object IDs, such as CRTCs and
+ planes.
+
+
+
+
+
+
+ Sent to indicate that the compositor will no longer honor requests for
+ DRM leases which include this connector. The client may still issue a
+ lease request including this connector, but the compositor will send
+ zwp_drm_lease_v1.finished without issuing a lease fd.
+ Compositors are encouraged to send this event when it loses access to
+ connector because of hot-unplug or because of losing DRM master as well
+ as when the connector gets leased to a client.
+
+
+
+
+
+ The client may send this request to indicate that it will not issue a
+ lease request for this connector. Clients are encouraged to send this
+ after receiving the "withdrawn" request so that the server can release
+ the resources associated with this connector offer.
+ Destroyed connectors will be removed from lease requests. Existing
+ leases will however not be affected.
+
+
+
+
+
+
+ A client that wishes to lease DRM resources will attach the list of
+ connectors advertised with zwp_drm_lease_device_v1.connector that they
+ wish to lease, then use zwp_drm_lease_request_v1.submit to submit the
+ request.
+
+
+
+
+
+
+
+
+ Indicates that the client will no longer use this lease request.
+
+
+
+
+
+ Indicates that the client would like to lease the given connector.
+ This is only used as a suggestion, the compositor may choose to
+ include any resources in the lease it issues, or change the set of
+ leased resources at any time. Compositors are however encouraged to
+ include the requested connector and other resources necessary
+ to drive the connected output in the lease.
+
+ Requested connectors that were created from a different lease device
+ than this lease request as well as requests for adding connectors that
+ already are requested will be ignored by the compositor.
+
+
+
+
+
+
+ Submits the lease request and creates a new zwp_drm_lease_v1 object.
+ After calling submit, issuing any other request than destroy will cause
+ the submitted_lease error to be raised.
+ The compositor doesn't make any guarantees about the events of the
+ lease object, clients cannot expect an immediate response.
+
+
+
+
+
+
+
+ A DRM lease object is used to transfer the DRM file descriptor to the
+ client and manage the lifetime of the lease.
+
+
+
+
+ This event returns a file descriptor suitable for use with DRM-related
+ ioctls. The client should use drmModeGetLease to enumerate the DRM
+ objects which have been leased to them. If the compositor cannot or
+ will not grant a lease for the requested connectors, it will not send
+ this event, instead sending the finished event.
+
+ The compositor will only send this event at most once during this
+ objects lifetime.
+
+
+
+
+
+
+ When the compositor revokes the lease, it will issue this event to
+ notify clients of the change. If the client requires a new lease, they
+ should destroy this object and submit a new lease request. The
+ compositor will send no further events for this object after sending
+ the finish event.
+ Compositors should revoke the lease when any of the leased resources
+ become unavailable, namely when a hot-unplug occurs or when the
+ compositor loses DRM master.
+
+
+
+
+
+ The client should send this to indicate that it no longer wishes to use
+ this lease. The compositor should use drmModeRevokeLease on the
+ appropriate file descriptor, if necessary.
+
+
+
+
diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build
index ca948cefb26ab01b99b0696b68ad6bb2e18115b8..ea06c62fb734fd5cf520f82a4e220c50896c5a0a 100644
--- a/src/vulkan/wsi/meson.build
+++ b/src/vulkan/wsi/meson.build
@@ -42,6 +42,27 @@ if system_has_kms_drm and not with_platform_android
files_vulkan_wsi += files('wsi_common_display.c')
endif
+if with_wl_lease
+ drm_lease_unstable_v1_protocol_c = custom_target(
+ 'drm-lease-unstable-v1-protocol.c',
+ input : 'drm-lease-unstable-v1.xml',
+ output : 'drm-lease-unstable-v1-protocol.c',
+ command : [prog_wl_scanner, wl_scanner_arg, '@INPUT@', '@OUTPUT@'],
+ )
+
+ drm_lease_unstable_v1_client_protocol_h = custom_target(
+ 'linux-dmabuf-unstable-v1-client-protocol.h',
+ input : 'drm-lease-unstable-v1.xml',
+ output : 'drm-lease-unstable-v1-client-protocol.h',
+ command : [prog_wl_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
+ )
+
+ files_vulkan_wsi += [
+ drm_lease_unstable_v1_protocol_c,
+ drm_lease_unstable_v1_client_protocol_h,
+ ]
+endif
+
libvulkan_wsi = static_library(
'vulkan_wsi',
files_vulkan_wsi,
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index f6eea5906f8c8d3a10f08d84eaffecb33fcbd5e8..cf1af2795375bdad1d2fdff3b4401f1fc7bec2ca 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -37,6 +37,9 @@
#include
#include
#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include "drm-lease-unstable-v1-client-protocol.h"
+#endif
#include "util/hash_table.h"
#include "util/list.h"
@@ -83,6 +86,9 @@ typedef struct wsi_display_connector {
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
xcb_randr_output_t output;
#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+ struct wlr_drm_lease_v1 *drm_lease;
+#endif
} wsi_display_connector;
struct wsi_display {
@@ -2598,3 +2604,91 @@ wsi_get_swapchain_counter(VkDevice device,
return VK_SUCCESS;
}
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+static void drm_lease_handle_lease_fd(
+ void *data,
+ struct zwp_drm_lease_v1 *zwp_drm_lease_v1,
+ int32_t leased_fd)
+{
+ struct wsi_display *wsi = data;
+ wsi->fd = leased_fd;
+}
+
+static void drm_lease_handle_finished(
+ void *data,
+ struct zwp_drm_lease_v1 *zwp_drm_lease_v1)
+{
+ struct wsi_display *wsi = data;
+ if (wsi->fd > 0) {
+ close(wsi->fd);
+ wsi->fd = -1;
+ }
+}
+
+static const struct zwp_drm_lease_v1_listener drm_lease_listener = {
+ drm_lease_handle_lease_fd,
+ drm_lease_handle_finished,
+};
+
+/* VK_EXT_acquire_wl_display */
+VkResult
+wsi_acquire_wl_display(VkPhysicalDevice physical_device,
+ struct wsi_device *wsi_device,
+ struct wl_display *display,
+ struct zwp_drm_lease_device_v1 *lease_device,
+ uint32_t connectorsCount,
+ VkWaylandLeaseConnectorEXT *connectors)
+{
+ struct wsi_display *wsi =
+ (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
+
+ /* XXX no support for mulitple leases yet */
+ if (wsi->fd >= 0)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ /* XXX no support for mulitple connectors yet */
+ /* The solution will eventually involve adding a listener to each
+ * connector, round tripping, and matching EDIDs once the lease is
+ * granted. */
+ if (connectorsCount > 1)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ struct zwp_drm_lease_request_v1 *lease_request =
+ zwp_drm_lease_device_v1_create_lease_request(lease_device);
+ for (int i = 0; i < connectorsCount; ++i) {
+ zwp_drm_lease_request_v1_request_connector(lease_request,
+ connectors[i].pConnector);
+ }
+
+ struct zwp_drm_lease_v1 *drm_lease =
+ zwp_drm_lease_request_v1_submit(lease_request);
+ zwp_drm_lease_request_v1_destroy(lease_request);
+ zwp_drm_lease_v1_add_listener(drm_lease, &drm_lease_listener, wsi);
+ wl_display_roundtrip(display);
+
+ if (wsi->fd < 0)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ int nconn = 0;
+ drmModeResPtr res = drmModeGetResources(wsi->fd);
+ drmModeObjectListPtr lease = drmModeGetLease(wsi->fd);
+ for (uint32_t i = 0; i < res->count_connectors; ++i) {
+ for (uint32_t j = 0; j < lease->count; ++j) {
+ if (res->connectors[i] != lease->objects[j]) {
+ continue;
+ }
+ struct wsi_display_connector *connector =
+ wsi_display_get_connector(wsi_device, res->connectors[i]);
+ /* TODO: Match EDID with requested connector */
+ connectors[nconn].pDisplay =
+ wsi_display_connector_to_handle(connector);
+ ++nconn;
+ }
+ }
+ drmModeFreeResources(res);
+
+ return VK_SUCCESS;
+}
+
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
diff --git a/src/vulkan/wsi/wsi_common_display.h b/src/vulkan/wsi/wsi_common_display.h
index d65517ab941d2642430762433f89938ec7d204d6..de856994c200c4c2d8ae581cf17055b943a08fe6 100644
--- a/src/vulkan/wsi/wsi_common_display.h
+++ b/src/vulkan/wsi/wsi_common_display.h
@@ -157,4 +157,17 @@ wsi_get_swapchain_counter(VkDevice device,
VkSurfaceCounterFlagBitsEXT flag_bits,
uint64_t *value);
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+
+/* VK_EXT_acquire_wl_display */
+VkResult
+wsi_acquire_wl_display(VkPhysicalDevice physical_device,
+ struct wsi_device *wsi_device,
+ struct wl_display *display,
+ struct zwp_drm_lease_device_v1 *lease_device,
+ uint32_t connectorsCount,
+ VkWaylandLeaseConnectorEXT *connectors);
+
+#endif /* VK_USE_PLATFORM_WAYLAND_KHR */
+
#endif