diff options
author | Ella-0 <23418164+Ella-0@users.noreply.github.com> | 2020-11-20 08:57:07 +0000 |
---|---|---|
committer | Iago Toral Quiroga <itoral@igalia.com> | 2020-11-25 07:49:53 +0100 |
commit | 472e81ed805a1f8f9e6d1b2ca39c089c674c33df (patch) | |
tree | 2adcb0b25ac7c1bc3d51a3fa7e00621b0d5ef66f | |
parent | 9fa1cdfe7ffd9e7ebd83055e2008f3e4b8ada549 (diff) |
v3dv: Wayland WSI support
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7303>
-rw-r--r-- | src/broadcom/vulkan/meson.build | 7 | ||||
-rw-r--r-- | src/broadcom/vulkan/v3dv_device.c | 137 | ||||
-rw-r--r-- | src/broadcom/vulkan/v3dv_wsi_wayland.c | 55 |
3 files changed, 198 insertions, 1 deletions
diff --git a/src/broadcom/vulkan/meson.build b/src/broadcom/vulkan/meson.build index 58f4bcee989..938595afa1d 100644 --- a/src/broadcom/vulkan/meson.build +++ b/src/broadcom/vulkan/meson.build @@ -105,6 +105,13 @@ if with_platform_x11 libv3dv_files += files('v3dv_wsi_x11.c') endif +if with_platform_wayland + v3dv_deps += [dep_wayland_client, dep_wl_protocols] + v3dv_flags += '-DVK_USE_PLATFORM_WAYLAND_KHR' + libv3dv_files += files('v3dv_wsi_wayland.c') + libv3dv_files += [wayland_drm_client_protocol_h, wayland_drm_protocol_c] +endif + if system_has_kms_drm and not with_platform_android v3dv_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR' libv3dv_files += files('v3dv_wsi_display.c') diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index 95672c5ab06..8b299fa7491 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -52,6 +52,11 @@ #include <X11/Xlib-xcb.h> #endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +#include <wayland-client.h> +#include "wayland-drm-client-protocol.h" +#endif + #ifdef USE_V3D_SIMULATOR #include "drm-uapi/i915_drm.h" #endif @@ -383,6 +388,126 @@ finish: } #endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR +struct v3dv_wayland_info { + struct wl_drm *wl_drm; + int fd; + bool is_set; + bool authenticated; +}; + +static void +v3dv_drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + struct v3dv_wayland_info *info = data; + info->fd = open(device, O_RDWR | O_CLOEXEC); + info->is_set = info->fd != -1; + + drm_magic_t magic; + drmGetMagic(info->fd, &magic); + wl_drm_authenticate(info->wl_drm, magic); +} + +static void +v3dv_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) +{ +} + +static void +v3dv_drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + struct v3dv_wayland_info *info = data; + info->authenticated = true; +} + +static void +v3dv_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value) +{ +} + +struct wl_drm_listener v3dv_drm_listener = { + .device = v3dv_drm_handle_device, + .format = v3dv_drm_handle_format, + .authenticated = v3dv_drm_handle_authenticated, + .capabilities = v3dv_drm_handle_capabilities +}; + +static void +v3dv_registry_global(void *data, + struct wl_registry *registry, + uint32_t name, + const char *interface, + uint32_t version) +{ + struct v3dv_wayland_info *info = data; + if (strcmp(interface, "wl_drm") == 0) { + info->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, + MIN2(version, 2)); + wl_drm_add_listener(info->wl_drm, &v3dv_drm_listener, data); + }; +} + +static void +v3dv_registry_global_remove_cb(void *data, + struct wl_registry *registry, + uint32_t name) +{ +} + +static int +create_display_fd_wayland(VkIcdSurfaceBase *surface) +{ + struct wl_display *display; + struct wl_registry *registry = NULL; + + struct v3dv_wayland_info info = { + .wl_drm = NULL, + .fd = -1, + .is_set = false, + .authenticated = false + }; + + if (surface) + display = ((VkIcdSurfaceWayland *) surface)->display; + else + display = wl_display_connect(NULL); + + if (!display) + return -1; + + registry = wl_display_get_registry(display); + if (!registry) { + if (!surface) + wl_display_disconnect(display); + return -1; + } + + static const struct wl_registry_listener registry_listener = { + v3dv_registry_global, + v3dv_registry_global_remove_cb + }; + wl_registry_add_listener(registry, ®istry_listener, &info); + + wl_display_roundtrip(display); /* For the registry advertisement */ + wl_display_roundtrip(display); /* For the DRM device event */ + wl_display_roundtrip(display); /* For the authentication event */ + + wl_drm_destroy(info.wl_drm); + wl_registry_destroy(registry); + + if (!surface) + wl_display_disconnect(display); + + if (!info.is_set) + return -1; + + if (!info.authenticated) + return -1; + + return info.fd; +} +#endif + /* Acquire an authenticated display fd without a surface reference. This is the * case where the application is making WSI allocations outside the Vulkan * swapchain context (only Zink, for now). Since we lack information about the @@ -393,8 +518,13 @@ static void acquire_display_device_no_surface(struct v3dv_instance *instance, struct v3dv_physical_device *pdevice) { +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + pdevice->display_fd = create_display_fd_wayland(NULL); +#endif + #ifdef VK_USE_PLATFORM_XCB_KHR - pdevice->display_fd = create_display_fd_xcb(NULL); + if (pdevice->display_fd == -1) + pdevice->display_fd = create_display_fd_xcb(NULL); #endif #ifdef VK_USE_PLATFORM_DISPLAY_KHR @@ -424,6 +554,11 @@ acquire_display_device_surface(struct v3dv_instance *instance, } #endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND) + pdevice->display_fd = create_display_fd_wayland(surface); +#endif + #ifdef VK_USE_PLATFORM_DISPLAY_KHR if (surface->platform == VK_ICD_WSI_PLATFORM_DISPLAY && pdevice->master_fd >= 0) { diff --git a/src/broadcom/vulkan/v3dv_wsi_wayland.c b/src/broadcom/vulkan/v3dv_wsi_wayland.c new file mode 100644 index 00000000000..f769449eaf8 --- /dev/null +++ b/src/broadcom/vulkan/v3dv_wsi_wayland.c @@ -0,0 +1,55 @@ +/* + * Copyright © 2020 Ella Stanforth + * based on intel anv code: + * Copyright © 2015 Intel Corporation + * + * 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 "wsi_common_wayland.h" +#include "v3dv_private.h" + +VkBool32 v3dv_GetPhysicalDeviceWaylandPresentationSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct wl_display* display) +{ + V3DV_FROM_HANDLE(v3dv_physical_device, physical_device, physicalDevice); + + return wsi_wl_get_presentation_support(&physical_device->wsi_device, display); +} + +VkResult v3dv_CreateWaylandSurfaceKHR( + VkInstance _instance, + const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface) +{ + V3DV_FROM_HANDLE(v3dv_instance, instance, _instance); + const VkAllocationCallbacks *alloc; + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR); + + if (pAllocator) + alloc = pAllocator; + else + alloc = &instance->alloc; + + return wsi_create_wl_surface(alloc, pCreateInfo, pSurface); +} |