From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Ben Widawsky <ben@bwidawsk.net>
Cc: Intel GFX <intel-gfx@lists.freedesktop.org>,
DRI Development <dri-devel@lists.freedesktop.org>
Subject: Re: [Intel-gfx] [PATCH 1/3] drm: Add new DRM_IOCTL_MODE_GETPLANE2
Date: Thu, 12 Jan 2017 12:23:16 +0200 [thread overview]
Message-ID: <20170112102316.GT31595@intel.com> (raw)
In-Reply-To: <20170112005118.19146-2-ben@bwidawsk.net>
On Wed, Jan 11, 2017 at 04:51:16PM -0800, Ben Widawsky wrote:
> Originally based off of a patch by Kristian.
>
> This new ioctl extends DRM_IOCTL_MODE_GETPLANE, by returning information
> about the modifiers that will work with each format.
>
> It's modified from Kristian's patch in that the modifiers and formats
> are setup by the driver, and then a callback is used to create the
> format list. The LOC was enough difference that I don't think it made
> sense to leave his authorship, but the new UABI was primarily his idea.
>
> Additionally, I hit a couple of drivers which Kristian missed updating.
>
> It also contains a change requested by Daniel to make the modifiers
> array a sentinel based structure instead of a sized one. Upon discussion
> on IRC, it was determined that having an invalid modifier might make
> sense in general as well.
>
> References: https://patchwork.kernel.org/patch/9482393/
> Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
> ---
<snip>
> diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
> index 2b33825f2f93..9cb1eede0b4d 100644
> --- a/drivers/gpu/drm/drm_modeset_helper.c
> +++ b/drivers/gpu/drm/drm_modeset_helper.c
> @@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
> &drm_primary_helper_funcs,
> safe_modeset_formats,
> ARRAY_SIZE(safe_modeset_formats),
> + NULL,
> DRM_PLANE_TYPE_PRIMARY, NULL);
> if (ret) {
> kfree(primary);
> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> index 7b7275f0c2df..2d4fad5db8ed 100644
> --- a/drivers/gpu/drm/drm_plane.c
> +++ b/drivers/gpu/drm/drm_plane.c
> @@ -70,6 +70,7 @@ static unsigned int drm_num_planes(struct drm_device *dev)
> * @funcs: callbacks for the new plane
> * @formats: array of supported formats (DRM_FORMAT\_\*)
> * @format_count: number of elements in @formats
> + * @format_modifiers: array of struct drm_format modifiers terminated by INVALID
> * @type: type of plane (overlay, primary, cursor)
> * @name: printf style format string for the plane name, or NULL for default name
> *
> @@ -82,10 +83,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
> uint32_t possible_crtcs,
> const struct drm_plane_funcs *funcs,
> const uint32_t *formats, unsigned int format_count,
> + const uint64_t *format_modifiers,
> enum drm_plane_type type,
> const char *name, ...)
> {
> struct drm_mode_config *config = &dev->mode_config;
> + unsigned int format_modifier_count = 0;
> int ret;
>
> ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
> @@ -105,6 +108,28 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
> return -ENOMEM;
> }
>
> + if (format_modifiers) {
> + const uint64_t *temp_modifiers = format_modifiers;
> + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
> + format_modifier_count++;
> + }
> +
> + if (format_modifier_count)
> + DRM_DEBUG_KMS("%d format modifiers added to list\n",
> + format_modifier_count);
nit: Not sure this is printk worthy.
> +
> + plane->modifier_count = format_modifier_count;
> + plane->modifiers = kmalloc_array(format_modifier_count,
> + sizeof(format_modifiers[0]),
> + GFP_KERNEL);
> +
> + if (format_modifier_count && !plane->modifiers) {
> + DRM_DEBUG_KMS("out of memory when allocating plane\n");
> + kfree(plane->format_types);
> + drm_mode_object_unregister(dev, &plane->base);
> + return -ENOMEM;
> + }
> +
> if (name) {
> va_list ap;
>
> @@ -117,12 +142,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
> }
> if (!plane->name) {
> kfree(plane->format_types);
> + kfree(plane->modifiers);
> drm_mode_object_unregister(dev, &plane->base);
> return -ENOMEM;
> }
>
> memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
> plane->format_count = format_count;
> + memcpy(plane->modifiers, format_modifiers,
> + format_modifier_count * sizeof(format_modifiers[0]));
Looks all right since we do the same for formats anyway. But it did
occur to me (twice at least) that a kmemdup_array() might a nice thing
to have for things like this. But that's a separate topic.
> plane->possible_crtcs = possible_crtcs;
> plane->type = type;
>
> @@ -205,7 +233,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
>
> type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
> return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
> - formats, format_count, type, NULL);
> + formats, format_count,
> + NULL, type, NULL);
> }
> EXPORT_SYMBOL(drm_plane_init);
>
> @@ -224,6 +253,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
> drm_modeset_lock_fini(&plane->mutex);
>
> kfree(plane->format_types);
> + kfree(plane->modifiers);
> drm_mode_object_unregister(dev, &plane->base);
>
> BUG_ON(list_empty(&plane->head));
> @@ -380,12 +410,15 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
> int drm_mode_getplane(struct drm_device *dev, void *data,
> struct drm_file *file_priv)
> {
> - struct drm_mode_get_plane *plane_resp = data;
> + struct drm_mode_get_plane2 *plane_resp = data;
> struct drm_plane *plane;
> uint32_t __user *format_ptr;
> + struct drm_format_modifier __user *modifier_ptr;
>
> if (!drm_core_check_feature(dev, DRIVER_MODESET))
> return -EINVAL;
> + if (plane_resp->flags)
> + return -EINVAL;
>
> plane = drm_plane_find(dev, plane_resp->plane_id);
> if (!plane)
> @@ -426,6 +459,36 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
> }
> plane_resp->count_format_types = plane->format_count;
>
> + if (plane->modifier_count &&
> + plane_resp->count_format_modifiers >= plane->modifier_count) {
> + struct drm_format_modifier mod;
> + int i;
> +
> + modifier_ptr = (struct drm_format_modifier __user *)
> + (unsigned long)plane_resp->format_modifier_ptr;
Didn't we have some something_user_ptr() thing? Hmm, I guess it's in i915 only.
> +
> + /* Build the mask for each modifier */
> + for (i = 0; i < plane->modifier_count; i++) {
> + int j;
> + mod.modifier = plane->modifiers[i];
> + for (j = 0; j < plane->format_count; j++) {
If we don't want to try and deal with more than 64 formats, I think we
need to make drm_universal_plane_init() WARN+bail if the driver
passes in more than that.
> + if (plane->funcs->format_mod_supported &&
> + plane->funcs->format_mod_supported(plane,
> + plane->format_types[j],
> + plane->modifiers[i])) {
> + mod.formats |= 1 << j;
> + }
> + }
> +
> + if (copy_to_user(modifier_ptr, &mod, sizeof(mod)))
> + return -EFAULT;
> +
> + modifier_ptr++;
> + }
> + }
> +
> + plane_resp->count_format_modifiers = plane->modifier_count;
> +
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
> index 35c5d99296b9..0406e71b38e8 100644
> --- a/drivers/gpu/drm/drm_simple_kms_helper.c
> +++ b/drivers/gpu/drm/drm_simple_kms_helper.c
> @@ -193,6 +193,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
> * @funcs: callbacks for the display pipe (optional)
> * @formats: array of supported formats (DRM_FORMAT\_\*)
> * @format_count: number of elements in @formats
> + * @modifiers: array of formats modifiers
@format_modifiers
> * @connector: connector to attach and register (optional)
> *
> * Sets up a display pipeline which consist of a really simple
> @@ -213,6 +214,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
> struct drm_simple_display_pipe *pipe,
> const struct drm_simple_display_pipe_funcs *funcs,
> const uint32_t *formats, unsigned int format_count,
> + const uint64_t *format_modifiers,
> struct drm_connector *connector)
> {
> struct drm_encoder *encoder = &pipe->encoder;
> @@ -227,6 +229,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
> ret = drm_universal_plane_init(dev, plane, 0,
> &drm_simple_kms_plane_funcs,
> formats, format_count,
> + format_modifiers,
> DRM_PLANE_TYPE_PRIMARY, NULL);
> if (ret)
> return ret;
<snip>
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index ce7efe2e8a5e..cea3de3aa301 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -209,6 +209,33 @@ struct drm_mode_get_plane {
> __u64 format_type_ptr;
> };
>
> +struct drm_format_modifier {
> + /* Bitmask of formats in get_plane format list this info
> + * applies to. */
> + uint64_t formats;
> +
> + /* This modifier can be used with the format for this plane. */
> + uint64_t modifier;
> +};
> +
> +struct drm_mode_get_plane2 {
> + __u32 plane_id;
> +
> + __u32 crtc_id;
> + __u32 fb_id;
> +
> + __u32 possible_crtcs;
> + __u32 gamma_size;
> +
> + __u32 count_format_types;
> + __u64 format_type_ptr;
> +
> + /* New in v2 */
> + __u32 count_format_modifiers;
> + __u32 flags;
ocd induced idea: Maybe put flags before the count?
> + __u64 format_modifier_ptr;
> +};
> +
> struct drm_mode_get_plane_res {
> __u64 plane_id_ptr;
> __u32 count_planes;
--
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2017-01-12 10:23 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-12 0:51 [PATCH 0/3] GET_PLANE2 w/ i915 implementation Ben Widawsky
2017-01-12 0:51 ` [PATCH 1/3] drm: Add new DRM_IOCTL_MODE_GETPLANE2 Ben Widawsky
2017-01-12 1:43 ` [Intel-gfx] " Rob Clark
2017-01-12 9:38 ` Ville Syrjälä
2017-01-12 14:56 ` Rob Clark
2017-01-12 17:04 ` Daniel Stone
2017-01-12 17:45 ` Ville Syrjälä
2017-01-12 17:50 ` Daniel Stone
2017-01-12 18:11 ` Ville Syrjälä
2017-01-12 19:27 ` Daniel Stone
2017-01-13 9:37 ` [Intel-gfx] " Ville Syrjälä
2017-01-13 9:45 ` Daniel Stone
2017-01-12 10:23 ` Ville Syrjälä [this message]
2023-11-24 15:08 ` [Intel-gfx] " Andy Shevchenko
2017-01-25 5:20 ` [PATCH 1/3] [v2] " Ben Widawsky
2017-01-25 15:28 ` Ville Syrjälä
2017-01-26 23:34 ` [PATCH 1/3] [v3] " Ben Widawsky
2017-01-12 0:51 ` [PATCH 2/3] drm/i915: Add format modifiers for Intel Ben Widawsky
2017-01-12 10:51 ` Ville Syrjälä
2017-01-12 18:00 ` Ben Widawsky
2017-01-12 18:32 ` Ville Syrjälä
2017-01-12 18:56 ` Ben Widawsky
2017-01-13 9:35 ` Ville Syrjälä
2017-01-12 0:51 ` [PATCH 3/3] drm/i915: Add support for GET_PLANE2 CCS modifiers Ben Widawsky
2017-01-12 1:01 ` ✗ Fi.CI.BAT: failure for GET_PLANE2 w/ i915 implementation Patchwork
2017-01-12 1:23 ` Ben Widawsky
2017-01-25 6:32 ` ✗ Fi.CI.BAT: failure for GET_PLANE2 w/ i915 implementation (rev2) Patchwork
2017-01-27 1:02 ` ✗ Fi.CI.BAT: failure for GET_PLANE2 w/ i915 implementation (rev3) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170112102316.GT31595@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=ben@bwidawsk.net \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).