[PATCH v3 2/5] drm/plane: Expose function to create format/modifier blob

Murthy, Arun R arun.r.murthy at intel.com
Thu Jan 16 09:54:31 UTC 2025


> > > > 68b31c0563a4c0 100644
> > > > --- a/drivers/gpu/drm/drm_plane.c
> > > > +++ b/drivers/gpu/drm/drm_plane.c
> > > > @@ -191,7 +191,10 @@ modifiers_ptr(struct drm_format_modifier_blob
> > > > *blob)
> > > >  	return (struct drm_format_modifier *)(((char *)blob) + blob-
> > > > >modifiers_offset);  }
> > > >
> > > > -static int create_in_format_blob(struct drm_device *dev, struct
> > > > drm_plane
> > > > *plane)
> > > > +int drm_plane_create_format_blob(struct drm_device *dev,
> > > > +				 struct drm_plane *plane, u64 *modifiers,
> > > > +				 unsigned int modifier_count, u32 *formats,
> > > > +				 unsigned int format_count, bool is_async)
> > >
> > > We can retain the original arguments (dev, plane) here. As I
> > > understand, plane-
> > > >formats[] and plane->modifiers[] are populated with all the formats
> > > >and
> > > modifiers supported by the platform, respectively.
> > >
> > > The goal is to establish a mapping between the two using the
> > > callbacks
> > > format_mod_supported() or format_mod_supported_async().
> > > Since these arrays represent a superset of all the formats and
> > > modifiers the platform supports, we have sufficient information
> > > within drm_plane to decide how to pair them here.
> > >
> > Plane->format_types and plane->modifiers is the list of formats and
> > Plane->modifiers
> > supported by the plane.  (This is true for sync flips only.) For each
> > modifier all the formats listed in plane->format_types may not be
> > supported but all of the formats mentioned in plane->format_types is
> > supported by sync flips. In order to get the list of formats supported
> > for each modifier a bit mask is created by the func pointer
> format_mod_supported.
> > The element format_offset in struct drm_format_modifier_blob is plane-
> > >format_types. So this is list of formats supported by this plane and
> > >holds
> > good for only sync flips and may not support async flips. We need to
> > get the subset of formats for async from the superset of formats from
> > sync flips. For this we need a separate list of formats supported by async flip.
> >
> > Please let me know if my understanding is wrong!
> >
> > So with this understand we need pass 2 separate list of
> > formats/modifiers for sync and async hence making it a parameter to this
> function.
> 
> Your understanding is correct however from pure coding perspective it will still
> work even if we don't pass different parameters for async and sync.
> I am making an assumption here (please correct me if I am wrong) that all the
> formats and modifiers supported for async are a subset of all the formats and
> modifiers supported for sync flips.
> 
Yes this assumption is correct.

> In cases where none of the formats are supported for a modifier (or a format is
> not supported at all) the bit field will end up with all "Zero"s
> 
Yes, that’s right.

> 				if (!plane->funcs-
> >format_mod_supported_async ||
> 				    plane->funcs-
> >format_mod_supported_async(plane,
> 
> formats[j],
> 
> modifiers[i])) {
> 					mod->formats |= 1ULL << j;
> 				}
> 
> And if you look in the proposed mutter code[1] for example, it will lead to a
> NULL entry in the hash table for that particular format indicating that it is not
> supported.
> 
In the structure that is exposed to the user, struct drm_format_modifier_blob the 
element formats_offset holds the list of formats that hardware supports.
In order to get this list we will have to maintain the supported list between sync
and async separately.

> However, I do see merits in your implementation because it will avoid creation
> of unnecessary entries both in the blob and the hash table in user space.
> 
> On the flip side, it creates more static arrays that we need to maintain for
> different platforms. (Though we can perhaps avoid it by some smart re-use of
> intel_modifiers[] which IRC you had implemented in a previous patch).
> 
Yes somewhere in the driver we will have to have this statically either in a list
or in the format_mod_supported_async().

> So as far exposing the arguments I leave it to you. You can weigh in both the
> options.
> 
> [1] https://gitlab.gnome.org/GNOME/mutter/-
> /merge_requests/4063/diffs?commit_id=c21a47175d7ec0f48414335cd2de010
> ae9670626#0806c68597f9e25c110c6597ae0c9e69d9c0c5a8_378_448
> 
> >
> > > >  {
> > > >  	const struct drm_mode_config *config = &dev->mode_config;
> > > >  	struct drm_property_blob *blob;
> > > > @@ -200,14 +203,14 @@ static int create_in_format_blob(struct
> > > > drm_device *dev, struct drm_plane *plane
> > > >  	struct drm_format_modifier_blob *blob_data;
> > > >  	unsigned int i, j;
> > > >
> > > > -	formats_size = sizeof(__u32) * plane->format_count;
> > > > +	formats_size = sizeof(__u32) * format_count;
> > > >  	if (WARN_ON(!formats_size)) {
> > > >  		/* 0 formats are never expected */
> > > >  		return 0;
> > > >  	}
> > > >
> > > >  	modifiers_size =
> > > > -		sizeof(struct drm_format_modifier) * plane->modifier_count;
> > > > +		sizeof(struct drm_format_modifier) * modifier_count;
> > > >
> > > >  	blob_size = sizeof(struct drm_format_modifier_blob);
> > > >  	/* Modifiers offset is a pointer to a struct with a 64 bit field
> > > > so it @@ -
> > > > 223,37 +226,45 @@ static int create_in_format_blob(struct
> > > > drm_device *dev, struct drm_plane *plane
> > > >
> > > >  	blob_data = blob->data;
> > > >  	blob_data->version = FORMAT_BLOB_CURRENT;
> > > > -	blob_data->count_formats = plane->format_count;
> > > > +	blob_data->count_formats = format_count;
> > > >  	blob_data->formats_offset = sizeof(struct
> > drm_format_modifier_blob);
> > > > -	blob_data->count_modifiers = plane->modifier_count;
> > > > +	blob_data->count_modifiers = modifier_count;
> > > >
> > > >  	blob_data->modifiers_offset =
> > > >  		ALIGN(blob_data->formats_offset + formats_size, 8);
> > > >
> > > > -	memcpy(formats_ptr(blob_data), plane->format_types,
> > > > formats_size);
> > > > +	memcpy(formats_ptr(blob_data), formats, formats_size);
> > > >
> > > >  	mod = modifiers_ptr(blob_data);
> > > > -	for (i = 0; i < plane->modifier_count; i++) {
> > > > -		for (j = 0; j < plane->format_count; j++) {
> > > > -			if (!plane->funcs->format_mod_supported ||
> > > > +	for (i = 0; i < modifier_count; i++) {
> > > > +		for (j = 0; j < format_count; j++) {
> > > > +			if (is_async ||
> > >
> > > This patch looks incomplete because the implementation for async is
> > > split between this and [1]. It might be a good idea to have both the
> > > patch
> > squashed.
> > >
> > >
> > > [1]
> > > https://patchwork.freedesktop.org/patch/631261/?series=140935&rev=2
> > >
> > In the 1st patch property is created and this 2nd patch trying to
> > fetch the data to be exposed by the property created in 1st patch. I
> > can squash both the patch in my next version if it makes sense to have
> > both of these in a single patch.
> >
> 
> If at all it should be made other way around. First fill up the data and then
> expose the property.
> Also the patch has some remnants of the previous version which do not fit well
> with the current version.
> For example the part,
> 
> +			if (is_async ||
> +			    !plane->funcs->format_mod_supported ||
> 
> Making it one patch should be good enough.
Ok, Done!

Thanks and Regards,
Arun R Murthy
-------------------


More information about the dri-devel mailing list