From e537382991ea44a6b8dae41875c94d0455620e9a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sun, 17 Jan 2021 10:19:51 +0100 Subject: [PATCH] backend/x11: add support for DRI3 1.0 Add fallbacks when DRI3 1.2 isn't supported. Closes: https://github.com/swaywm/wlroots/issues/2586 --- backend/x11/backend.c | 11 ++++++++--- backend/x11/output.c | 22 +++++++++++++++++----- include/backend/x11.h | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/backend/x11/backend.c b/backend/x11/backend.c index eb2649c0..5d8179f3 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -297,6 +297,10 @@ static int query_dri3_drm_fd(struct wlr_x11_backend *x11) { static bool query_dri3_modifiers(struct wlr_x11_backend *x11, const struct wlr_x11_format *format) { + if (x11->dri3_major_version == 1 && x11->dri3_minor_version < 2) { + return true; // GetSupportedModifiers requires DRI3 1.2 + } + // Query the root window's supported modifiers, because we only care about // screen_modifiers for now xcb_dri3_get_supported_modifiers_cookie_t modifiers_cookie = @@ -415,13 +419,14 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, xcb_dri3_query_version(x11->xcb, 1, 2); xcb_dri3_query_version_reply_t *dri3_reply = xcb_dri3_query_version_reply(x11->xcb, dri3_cookie, NULL); - if (!dri3_reply || dri3_reply->major_version < 1 || - dri3_reply->minor_version < 2) { + if (!dri3_reply || dri3_reply->major_version < 1) { wlr_log(WLR_ERROR, "X11 does not support required DRI3 version " - "(has %"PRIu32".%"PRIu32", want 1.2)", + "(has %"PRIu32".%"PRIu32", want 1.0)", dri3_reply->major_version, dri3_reply->minor_version); goto error_display; } + x11->dri3_major_version = dri3_reply->major_version; + x11->dri3_minor_version = dri3_reply->minor_version; free(dri3_reply); // Present extension diff --git a/backend/x11/output.c b/backend/x11/output.c index 4f91a55f..63dfb110 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -164,11 +164,23 @@ static struct wlr_x11_buffer *create_x11_buffer(struct wlr_x11_output *output, const struct wlr_x11_format *x11_fmt = x11->x11_format; xcb_pixmap_t pixmap = xcb_generate_id(x11->xcb); - xcb_dri3_pixmap_from_buffers(x11->xcb, pixmap, output->win, - attrs.n_planes, attrs.width, attrs.height, attrs.stride[0], - attrs.offset[0], attrs.stride[1], attrs.offset[1], attrs.stride[2], - attrs.offset[2], attrs.stride[3], attrs.offset[3], x11_fmt->depth, - x11_fmt->bpp, attrs.modifier, dup_attrs.fd); + + if (x11->dri3_major_version > 1 || x11->dri3_minor_version >= 2) { + xcb_dri3_pixmap_from_buffers(x11->xcb, pixmap, output->win, + attrs.n_planes, attrs.width, attrs.height, attrs.stride[0], + attrs.offset[0], attrs.stride[1], attrs.offset[1], attrs.stride[2], + attrs.offset[2], attrs.stride[3], attrs.offset[3], x11_fmt->depth, + x11_fmt->bpp, attrs.modifier, dup_attrs.fd); + } else { + // PixmapFromBuffers requires DRI3 1.2 + if (attrs.n_planes != 1 || attrs.modifier != DRM_FORMAT_MOD_INVALID) { + wlr_dmabuf_attributes_finish(&dup_attrs); + return NULL; + } + xcb_dri3_pixmap_from_buffer(x11->xcb, pixmap, output->win, + attrs.height * attrs.stride[0], attrs.width, attrs.height, + attrs.stride[0], x11_fmt->depth, x11_fmt->bpp, dup_attrs.fd[0]); + } struct wlr_x11_buffer *buffer = calloc(1, sizeof(struct wlr_x11_buffer)); if (!buffer) { diff --git a/include/backend/x11.h b/include/backend/x11.h index 85836ad4..b21d818e 100644 --- a/include/backend/x11.h +++ b/include/backend/x11.h @@ -68,6 +68,7 @@ struct wlr_x11_backend { xcb_depth_t *depth; xcb_visualid_t visualid; xcb_colormap_t colormap; + uint32_t dri3_major_version, dri3_minor_version; size_t requested_outputs; size_t last_output_num;