From e8057bb60c4666d73ec776fa8f37ef4858c18fbe Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sun, 26 May 2019 17:38:35 +0300 Subject: [PATCH] backend/drm: fallback to drmModeAddFB2 --- backend/drm/atomic.c | 3 ++- backend/drm/drm.c | 11 +++++++---- backend/drm/util.c | 18 +++++++++++++----- include/backend/drm/drm.h | 1 + include/backend/drm/util.h | 3 ++- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index c9fb1f45..8ce1e1e6 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -172,7 +172,8 @@ static bool atomic_crtc_set_cursor(struct wlr_drm_backend *drm, atomic_begin(crtc, &atom); if (bo) { - uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format); + uint32_t fb_id = + get_fb_for_bo(bo, plane->drm_format, drm->addfb2_modifiers); set_plane_props(&atom, plane, crtc->id, fb_id, false); } else { atomic_add(&atom, plane->id, plane->props.fb_id, 0); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 9d177810..f90890e7 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -66,6 +66,9 @@ bool check_drm_features(struct wlr_drm_backend *drm) { int ret = drmGetCap(drm->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap); drm->clock = (ret == 0 && cap == 1) ? CLOCK_MONOTONIC : CLOCK_REALTIME; + ret = drmGetCap(drm->fd, DRM_CAP_ADDFB2_MODIFIERS, &cap); + drm->addfb2_modifiers = ret == 0 && cap == 1; + return true; } @@ -319,7 +322,7 @@ static bool drm_connector_commit(struct wlr_output *output) { return false; } } - fb_id = get_fb_for_bo(bo, plane->drm_format); + fb_id = get_fb_for_bo(bo, plane->drm_format, drm->addfb2_modifiers); if (fb_id == 0) { wlr_log(WLR_ERROR, "get_fb_for_bo failed"); return false; @@ -332,7 +335,7 @@ static bool drm_connector_commit(struct wlr_output *output) { return false; } - fb_id = get_fb_for_bo(bo, gbm_bo_get_format(bo)); + fb_id = get_fb_for_bo(bo, gbm_bo_get_format(bo), drm->addfb2_modifiers); if (fb_id == 0) { wlr_log(WLR_ERROR, "get_fb_for_bo failed"); return false; @@ -462,7 +465,7 @@ static void drm_connector_start_renderer(struct wlr_drm_connector *conn) { struct gbm_bo *bo = get_drm_surface_front( drm->parent ? &plane->mgpu_surf : &plane->surf); - uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format); + uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format, drm->addfb2_modifiers); struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode; if (drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, &mode->drm_mode)) { @@ -887,7 +890,7 @@ static bool drm_connector_schedule_frame(struct wlr_output *output) { return true; } - uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format); + uint32_t fb_id = get_fb_for_bo(bo, plane->drm_format, drm->addfb2_modifiers); if (!drm->iface->crtc_pageflip(drm, conn, crtc, fb_id, NULL)) { return false; } diff --git a/backend/drm/util.c b/backend/drm/util.c index 2fa948f5..263f5a92 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -178,7 +178,8 @@ static void free_fb(struct gbm_bo *bo, void *data) { } } -uint32_t get_fb_for_bo(struct gbm_bo *bo, uint32_t drm_format) { +uint32_t get_fb_for_bo(struct gbm_bo *bo, uint32_t drm_format, + bool with_modifiers) { uint32_t id = (uintptr_t)gbm_bo_get_user_data(bo); if (id) { return id; @@ -192,11 +193,18 @@ uint32_t get_fb_for_bo(struct gbm_bo *bo, uint32_t drm_format) { uint32_t handles[4] = {gbm_bo_get_handle(bo).u32}; uint32_t strides[4] = {gbm_bo_get_stride(bo)}; uint32_t offsets[4] = {gbm_bo_get_offset(bo, 0)}; - uint64_t modifiers[4] = {gbm_bo_get_modifier(bo)}; - if (drmModeAddFB2WithModifiers(fd, width, height, drm_format, - handles, strides, offsets, modifiers, &id, DRM_MODE_FB_MODIFIERS)) { - wlr_log_errno(WLR_ERROR, "Unable to add DRM framebuffer"); + if (with_modifiers && gbm_bo_get_modifier(bo) != DRM_FORMAT_MOD_INVALID) { + uint64_t modifiers[4] = {gbm_bo_get_modifier(bo)}; + if (drmModeAddFB2WithModifiers(fd, width, height, drm_format, handles, + strides, offsets, modifiers, &id, DRM_MODE_FB_MODIFIERS)) { + wlr_log_errno(WLR_ERROR, "Unable to add DRM framebuffer"); + } + } else { + if (drmModeAddFB2(fd, width, height, drm_format, handles, strides, + offsets, &id, 0)) { + wlr_log_errno(WLR_ERROR, "Unable to add DRM framebuffer"); + } } gbm_bo_set_user_data(bo, (void *)(uintptr_t)id, free_fb); diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 3821c358..99120852 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -72,6 +72,7 @@ struct wlr_drm_backend { struct wlr_drm_backend *parent; const struct wlr_drm_interface *iface; clockid_t clock; + bool addfb2_modifiers; int fd; diff --git a/include/backend/drm/util.h b/include/backend/drm/util.h index 2491e703..2d9d11f4 100644 --- a/include/backend/drm/util.h +++ b/include/backend/drm/util.h @@ -14,7 +14,8 @@ void parse_edid(struct wlr_output *restrict output, size_t len, // Returns the string representation of a DRM output type const char *conn_get_name(uint32_t type_id); // Returns the DRM framebuffer id for a gbm_bo -uint32_t get_fb_for_bo(struct gbm_bo *bo, uint32_t drm_format); +uint32_t get_fb_for_bo(struct gbm_bo *bo, uint32_t drm_format, + bool with_modifiers); // Part of match_obj enum {