From: Simon Ser Date: Thu, 28 May 2020 17:59:35 +0000 (+0200) Subject: vulkan/wsi: prefer the Wayland linux-dmabuf protocol X-Git-Tag: upstream/21.2.3~1123 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fc667fdf3bf3956337ac474d308e09dede619518;p=platform%2Fupstream%2Fmesa.git vulkan/wsi: prefer the Wayland linux-dmabuf protocol When the linux-dmabuf protocol is available, prefer it over the old wl_drm protocol. Previously wl_drm was used when modifiers aren't supported, however linux-dmabuf supports formats without modifiers too. In this case, linux-dmabuf will send a DRM_FORMAT_MOD_INVALID modifier for each supported format [1]. All of this allows compositors to better handle these buffers, getting a DMA-BUF and implementing features like direct scan-out. A similar logic has been implemented for EGL [2]. In this patch, we bind to linux-dmabuf even if the driver doesn't support modifiers. In this case the formats advertised by the compositor will still be added to the display->dmabuf.formats list. In wsi_wl_image_init, drop the assertions that display->drm_wrapper and display->dmabuf.wl_dmabuf can't be both present. If the driver doesn't support modifiers, the modifier is already set to DRM_FORMAT_MOD_INVALID. If the parent compositor doesn't support modifiers, the modifiers list passed to wsi_create_native_image will be empty, and the common code will ensure that the image's modifier is set to DRM_FORMAT_MOD_INVALID. In wsi_wl_surface_create_swapchain, create the wl_proxy proxy if we've bound to it earlier. Don't decide to create the proxy depending on the number of supported modifiers. [1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/commit/fb9b2a87317c77e26283da5f6c9559d709f6fdcd [2]: https://gitlab.freedesktop.org/mesa/mesa/-/commit/c376865f5eeca535c4aa8e33bcf166052c1ce2f2 Signed-off-by: Simon Ser Part-of: --- diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index d0cabf9..4294863 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -310,10 +310,6 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, if (display->dmabuf.formats.element_size == 0) return; - if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) && - modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff)) - return; - switch (format) { case WL_DRM_FORMAT_ARGB8888: modifiers = &display->dmabuf.modifiers.argb8888; @@ -327,6 +323,10 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, wsi_wl_display_add_wl_format(display, &display->dmabuf.formats, format); + if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) && + modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff)) + return; + mod = u_vector_add(modifiers); if (!mod) return; @@ -353,8 +353,7 @@ registry_handle_global(void *data, struct wl_registry *registry, display->drm.wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, 2); wl_drm_add_listener(display->drm.wl_drm, &drm_listener, display); - } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3 && - display->wsi_wl->wsi->supports_modifiers) { + } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3) { display->dmabuf.wl_dmabuf = wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, 3); zwp_linux_dmabuf_v1_add_listener(display->dmabuf.wl_dmabuf, @@ -461,12 +460,13 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, } } - /* We need prime support for wl_drm */ - if (display->drm.wl_drm && + /* Prefer the linux-dmabuf protocol if available */ + if (display->dmabuf.wl_dmabuf) { + display->formats = &display->dmabuf.formats; + } else if (display->drm.wl_drm && (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) { + /* We need prime support for wl_drm */ display->formats = &display->drm.formats; - } else if (display->dmabuf.wl_dmabuf) { - display->formats = &display->dmabuf.formats; } if (!display->formats) { @@ -760,9 +760,6 @@ struct wsi_wl_swapchain { struct wl_surface * surface; - /* non-NULL when wl_drm should be used for wl_buffer creation; otherwise, - * zwp_linux_dmabuf_v1 should be used. - */ struct wl_drm * drm_wrapper; struct wl_callback * frame; @@ -956,11 +953,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, if (result != VK_SUCCESS) return result; - if (!chain->drm_wrapper) { - /* Only request modifiers if we have dmabuf, else it must be implicit. */ - assert(display->dmabuf.wl_dmabuf); - assert(image->base.drm_modifier != DRM_FORMAT_MOD_INVALID); - + if (display->dmabuf.wl_dmabuf) { struct zwp_linux_buffer_params_v1 *params = zwp_linux_dmabuf_v1_create_params(display->dmabuf.wl_dmabuf); wl_proxy_set_queue((struct wl_proxy *) params, chain->display->queue); @@ -1144,13 +1137,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, } } - /* When there are explicit DRM format modifiers, we must use - * zwp_linux_dmabuf_v1 for wl_buffer creation. Otherwise, we must use - * wl_drm. - */ - if (!chain->num_drm_modifiers) { - assert(chain->display->drm.wl_drm); - + if (chain->display->drm.wl_drm) { chain->drm_wrapper = wl_proxy_create_wrapper(chain->display->drm.wl_drm); if (!chain->drm_wrapper) {