From e598e96468c77be63590da16c69d9af0794254c0 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Fri, 8 Nov 2024 20:42:05 +0100 Subject: [PATCH] backend-drm: Implement DRM_FORMAT_MOD_BROADCOM_SAND128 support The BROADCOM_SAND128 modifier is usually used with an extra parameter to pass in the stride via a side channel. Quoting from drm_fourcc.h: > The pitch between the start of each column is set to optimally > switch between SDRAM banks. This is passed as the number of lines > of column width in the modifier (we can't use the stride value due > to various core checks that look at it , so you should set the > stride to width*cpp). Fortunately this limitation only applies to the KMS layer - Mesa, Wayland, Gstreamer etc. can use the modifier and stride as usual. Implement the special modifier handling to enable KMS offloading. Signed-off-by: Robert Mader --- libweston/backend-drm/fb.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c index 05fba0cef..1faf24664 100644 --- a/libweston/backend-drm/fb.c +++ b/libweston/backend-drm/fb.c @@ -220,13 +220,32 @@ drm_fb_addfb(struct drm_device *device, struct drm_fb *fb) /* If we have a modifier set, we must only use the WithModifiers * entrypoint; we cannot import it through legacy ioctls. */ if (device->fb_modifiers && fb->modifier != DRM_FORMAT_MOD_INVALID) { + uint32_t strides[4] = { }; + uint64_t modifier; + + modifier = fb->modifier; + for (i = 0; i < ARRAY_LENGTH(strides) && fb->handles[i]; i++) + strides[i] = fb->strides[i]; + + if (fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128) { + uint32_t stride_multiplicator; + + modifier = + DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT (strides[0]); + + stride_multiplicator = + fb->format->format == DRM_FORMAT_NV12 ? 1 : 2; + for (i = 0; i < ARRAY_LENGTH(strides) && strides[i]; i++) + strides[i] = fb->width * stride_multiplicator; + } + /* KMS demands that if a modifier is set, it must be the same * for all planes. */ for (i = 0; i < ARRAY_LENGTH(mods) && fb->handles[i]; i++) - mods[i] = fb->modifier; + mods[i] = modifier; ret = drmModeAddFB2WithModifiers(fb->fd, fb->width, fb->height, fb->format->format, - fb->handles, fb->strides, + fb->handles, strides, fb->offsets, mods, &fb->fb_id, DRM_MODE_FB_MODIFIERS); return ret;