From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 Dec 2017 21:22:30 +0200 Subject: drm: Check that the plane supports the request format+modifier combo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Git-commit: 23163a7d4b032489d375099d56571371c0456980 Patch-mainline: v4.17-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 Currently we only check that the plane supports the pixel format of the fb we're about to feed to it. Extend it to check also the modifier, and more specifically that the combination of the format and modifier is supported. Cc: dri-devel@lists.freedesktop.org Cc: Ben Widawsky Cc: Jason Ekstrand Cc: Daniel Stone Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20171222192231.17981-8-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter Acked-by: Petr Tesarik --- drivers/gpu/drm/drm_atomic.c | 10 ++++++---- drivers/gpu/drm/drm_crtc.c | 10 ++++++---- drivers/gpu/drm/drm_crtc_internal.h | 4 ++-- drivers/gpu/drm/drm_plane.c | 33 ++++++++++++++++++++++++++------- 4 files changed, 40 insertions(+), 17 deletions(-) --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -882,12 +882,14 @@ static int drm_atomic_plane_check(struct } /* Check whether this plane supports the fb pixel format. */ - ret = drm_plane_check_pixel_format(plane, state->fb->format->format); + ret = drm_plane_check_pixel_format(plane, state->fb->format->format, + state->fb->modifier); if (ret) { struct drm_format_name_buf format_name; - DRM_DEBUG_ATOMIC("Invalid pixel format %s\n", - drm_get_format_name(state->fb->format->format, - &format_name)); + DRM_DEBUG_ATOMIC("Invalid pixel format %s, modifier 0x%llx\n", + drm_get_format_name(state->fb->format->format, + &format_name), + state->fb->modifier); return ret; } --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -629,12 +629,14 @@ retry: */ if (!crtc->primary->format_default) { ret = drm_plane_check_pixel_format(crtc->primary, - fb->format->format); + fb->format->format, + fb->modifier); if (ret) { struct drm_format_name_buf format_name; - DRM_DEBUG_KMS("Invalid pixel format %s\n", - drm_get_format_name(fb->format->format, - &format_name)); + DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", + drm_get_format_name(fb->format->format, + &format_name), + fb->modifier); goto out; } } --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -196,8 +196,8 @@ int drm_mode_atomic_ioctl(struct drm_dev /* drm_plane.c */ int drm_plane_register_all(struct drm_device *dev); void drm_plane_unregister_all(struct drm_device *dev); -int drm_plane_check_pixel_format(const struct drm_plane *plane, - u32 format); +int drm_plane_check_pixel_format(struct drm_plane *plane, + u32 format, u64 modifier); /* drm_bridge.c */ void drm_bridge_detach(struct drm_bridge *bridge); --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -549,16 +549,33 @@ int drm_mode_getplane(struct drm_device return 0; } -int drm_plane_check_pixel_format(const struct drm_plane *plane, u32 format) +int drm_plane_check_pixel_format(struct drm_plane *plane, + u32 format, u64 modifier) { unsigned int i; for (i = 0; i < plane->format_count; i++) { if (format == plane->format_types[i]) - return 0; + break; } + if (i == plane->format_count) + return -EINVAL; - return -EINVAL; + if (!plane->modifier_count) + return 0; + + for (i = 0; i < plane->modifier_count; i++) { + if (modifier == plane->modifiers[i]) + break; + } + if (i == plane->modifier_count) + return -EINVAL; + + if (plane->funcs->format_mod_supported && + !plane->funcs->format_mod_supported(plane, format, modifier)) + return -EINVAL; + + return 0; } /* @@ -602,12 +619,14 @@ static int __setplane_internal(struct dr } /* Check whether this plane supports the fb pixel format. */ - ret = drm_plane_check_pixel_format(plane, fb->format->format); + ret = drm_plane_check_pixel_format(plane, fb->format->format, + fb->modifier); if (ret) { struct drm_format_name_buf format_name; - DRM_DEBUG_KMS("Invalid pixel format %s\n", - drm_get_format_name(fb->format->format, - &format_name)); + DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", + drm_get_format_name(fb->format->format, + &format_name), + fb->modifier); goto out; }