[PATCH v3 02/15] drm: Centralize format information

Daniel Vetter daniel at ffwll.ch
Thu Jun 9 12:40:28 UTC 2016


On Thu, Jun 09, 2016 at 03:23:17PM +0300, Ville Syrjälä wrote:
> On Thu, Jun 09, 2016 at 10:52:23AM +0200, Daniel Vetter wrote:
> > On Thu, Jun 09, 2016 at 02:32:06AM +0300, Laurent Pinchart wrote:
> > > Various pieces of information about DRM formats (number of planes, color
> > > depth, chroma subsampling, ...) are scattered across different helper
> > > functions in the DRM core. Callers of those functions often need to
> > > access more than a single parameter of the format, leading to
> > > inefficiencies due to multiple lookups.
> > > 
> > > Centralize all format information in a data structure and create a
> > > function to look up information based on the format 4CC.
> > > 
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > ---
> > >  drivers/gpu/drm/drm_fourcc.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
> > >  include/drm/drm_fourcc.h     | 19 ++++++++++
> > >  2 files changed, 103 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > > index 0645c85d5f95..47b9abd743be 100644
> > > --- a/drivers/gpu/drm/drm_fourcc.c
> > > +++ b/drivers/gpu/drm/drm_fourcc.c
> > > @@ -62,6 +62,90 @@ const char *drm_get_format_name(uint32_t format)
> > >  EXPORT_SYMBOL(drm_get_format_name);
> > >  
> > >  /**
> > > + * drm_format_info - query information for a given format
> > > + * @format: pixel format (DRM_FORMAT_*)
> > > + *
> > > + * Returns:
> > > + * The instance of struct drm_format_info that describes the pixel format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct drm_format_info *drm_format_info(u32 format)
> > 
> > Bikeshed on your pixel format description table. I think the approach I've
> > seen in gallium/mesa to describe pixel formats is a lot more generic, and
> > we might as well adopt it when we change. Idea is to have a block size
> > measure in pixels (both h and v), and then cpp is bytes_per_block. This is
> > essentially what you have with hsub and vsub already, except confusing
> > names, more ill-defined (since it only makes sense for yuv) and less
> > generic. A few examples:
> 
> I think you have your confusion backwards. Calling something a block in
> planar formats would be more confusing. The only thing that really
> matters is the relative position of the samples between the planes.
> So there really is no "block" in there.

Atm U/V planes have a cpp of 1, which is definitely not true. There's much
less than 1 byte per visible pixel in those planes. And that's the part
that annoys me.

block here is an entirely free-standing concept that just means "group of
pixels over which the bytes-per-group is counted in each group". It's a
concept stolen from gallium and makes a lot more sense when talking about
compressed formats. But I think it also makes sense when talking about yuv
formats.

Maybe if you object "block" we can call it "group_of_pixels" instead. It's
_not_ meant to be a continuous block of bytes in memory at all.

E.g. for YUYV formats the gropu size would be (2, 1), with 4
bytes-per-group for an interleaved format of Y8U8Y8V8. In a way the
hsub/vsub stuff describes more the color data, the group-of-pixels stuff
is more useful imo to describe how much space you need on each plane.
-Daniel

> 
> > 	h_blocksize	v_blocksize	bytes_per_block (per-plane)
> > YUV410	4		4		{4, 1, 1}
> > YUV411	4		1		{4, 1, 1}
> > 
> > hsub = h_blocksize / bytes_per_block[U/V plane]
> > vsub = v_blocksize / bytes_per_block[U/V plane]
> > 
> > *_blocksize is in pixels
> > 
> > [not entirely sure on the precise data, but that's kinda the point.]
> > 
> > Ofc should maybe check that those helpers are only called on yuv planar
> > formats, too. This way we could also remove some of the comments in
> > drm_fourcc.h, or at least make the more clear. Another benefit is that
> > with this it's possible to write entirely generic size/stride checking
> > functions
> > 
> > Oh and if we go with this, some asciiart for what's meant (in sphinx/rst,
> > that will happen in 4.8) would be awesome.
> > -Daniel
> > 
> > > +{
> > > +	static const struct drm_format_info formats[] = { 
> > > +		{ .format = DRM_FORMAT_C8,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGB332,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGR233,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XRGB4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XBGR4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBX4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRX4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ARGB4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ABGR4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBA4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRA4444,	.depth = 12, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XRGB1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XBGR1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBX5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRX5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ARGB1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ABGR1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBA5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRA5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGB565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGR565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGB888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGR888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XRGB8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XBGR8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBX8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRX8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XRGB2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_XBGR2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBX1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRX1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ARGB2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ABGR2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBA1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRA1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ARGB8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_ABGR8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_RGBA8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_BGRA8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YUV410,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
> > > +		{ .format = DRM_FORMAT_YVU410,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4 },
> > > +		{ .format = DRM_FORMAT_YUV411,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YVU411,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YUV420,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
> > > +		{ .format = DRM_FORMAT_YVU420,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2 },
> > > +		{ .format = DRM_FORMAT_YUV422,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YVU422,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YUV444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YVU444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_NV12,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
> > > +		{ .format = DRM_FORMAT_NV21,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2 },
> > > +		{ .format = DRM_FORMAT_NV16,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_NV61,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_NV24,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_NV42,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YUYV,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_YVYU,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_UYVY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_VYUY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 },
> > > +		{ .format = DRM_FORMAT_AYUV,		.depth = 0,  .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
> > > +	};
> > > +
> > > +	unsigned int i;
> > > +
> > > +	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
> > > +		if (formats[i].format == format)
> > > +			return &formats[i];
> > > +	}
> > > +
> > > +	return NULL;
> > > +}
> > > +EXPORT_SYMBOL(drm_format_info);
> > > +
> > > +/**
> > >   * drm_fb_get_bpp_depth - get the bpp/depth values for format
> > >   * @format: pixel format (DRM_FORMAT_*)
> > >   * @depth: storage for the depth value
> > > diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> > > index 7f90a396cf2b..b077df507b51 100644
> > > --- a/include/drm/drm_fourcc.h
> > > +++ b/include/drm/drm_fourcc.h
> > > @@ -25,6 +25,25 @@
> > >  #include <linux/types.h>
> > >  #include <uapi/drm/drm_fourcc.h>
> > >  
> > > +/**
> > > + * struct drm_format_info - information about a DRM format
> > > + * @format: 4CC format identifier (DRM_FORMAT_*)
> > > + * @depth: color depth (number of bits per pixel excluding padding bits)
> > > + * @num_planes: number of color planes (1 to 3)
> > > + * @cpp: number of bytes per pixel (per plane)
> > > + * @hsub: horizontal chroma subsampling factor
> > > + * @vsub: vertical chroma subsampling factor
> > > + */
> > > +struct drm_format_info {
> > > +	u32 format;
> > > +	u8 depth;
> > > +	u8 num_planes;
> > > +	u8 cpp[3];
> > > +	u8 hsub;
> > > +	u8 vsub;
> > > +};
> > > +
> > > +const struct drm_format_info *drm_format_info(u32 format);
> > >  void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp);
> > >  int drm_format_num_planes(uint32_t format);
> > >  int drm_format_plane_cpp(uint32_t format, int plane);
> > > -- 
> > > Regards,
> > > 
> > > Laurent Pinchart
> > > 
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel at lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> > -- 
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the dri-devel mailing list