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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.