Re: [RFC PATCH 06/20] lib: Add video format information library

2019-03-21 Thread Boris Brezillon
On Thu, 21 Mar 2019 09:20:41 +0100
Maxime Ripard  wrote:

> Hi Boris,
> 
> On Wed, Mar 20, 2019 at 02:39:44PM +0100, Boris Brezillon wrote:
> > On Tue, 19 Mar 2019 22:57:11 +0100
> > Maxime Ripard  wrote:
> >  
> > > Move the DRM formats API to turn this into a more generic image formats 
> > > API
> > > to be able to leverage it into some other places of the kernel, such as
> > > v4l2 drivers.
> > >
> > > Signed-off-by: Maxime Ripard 
> > > ---
> > >  include/linux/image-formats.h | 240 +++-
> > >  lib/Kconfig   |   7 +-
> > >  lib/Makefile  |   3 +-
> > >  lib/image-formats-selftests.c | 326 +++-
> > >  lib/image-formats.c   | 760 +++-
> > >  5 files changed, 1336 insertions(+)
> > >  create mode 100644 include/linux/image-formats.h
> > >  create mode 100644 lib/image-formats-selftests.c
> > >  create mode 100644 lib/image-formats.c
> > >  
> >
> > [...]
> >  
> > > --- /dev/null
> > > +++ b/lib/image-formats.c
> > > @@ -0,0 +1,760 @@
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +#include 
> > > +
> > > +static const struct image_format_info formats[] = {
> > > + {  
> >
> > ...
> >  
> > > + },
> > > +};
> > > +
> > > +#define __image_format_lookup(_field, _fmt)  \
> > > + ({  \
> > > + const struct image_format_info *format = NULL;  \
> > > + unsigned i; \
> > > + \
> > > + for (i = 0; i < ARRAY_SIZE(formats); i++)   \
> > > + if (formats[i]._field == _fmt)  \
> > > + format = [i];   \
> > > + \
> > > + format; \
> > > + })
> > > +
> > > +/**
> > > + * __image_format_drm_lookup - query information for a given format
> > > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel 
> > > format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> > > +{
> > > + return __image_format_lookup(drm_fmt, drm);
> > > +}
> > > +EXPORT_SYMBOL(__image_format_drm_lookup);
> > > +
> > > +/**
> > > + * image_format_drm_lookup - query information for a given format
> > > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel 
> > > format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > +{
> > > + const struct image_format_info *format;
> > > +
> > > + format = __image_format_drm_lookup(drm);
> > > +
> > > + WARN_ON(!format);
> > > + return format;
> > > +}
> > > +EXPORT_SYMBOL(image_format_drm_lookup);  
> >
> > I think this function and the DRM formats table should be moved in
> > drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
> > remaining functions can IMHO be placed in include/linux/image-formats.h
> > as static inline funcs. This way you can get rid of lib/image-formats.c
> > and the associated Kconfig entry.  
> 
> I'm not quite sure what you mean. The whole point of the series is to
> split out that table out of DRM so that we can use it in other places,
> so surely putting it back into DRM defeats the purpose?

Sorry, I hadn't read the patch series entirely when replying to this
email. I thought you were planning to create one table for DRM formats
and one for V4L ones and then just use the common infra to have a
generic image_format representation, hence my suggestion.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC PATCH 06/20] lib: Add video format information library

2019-03-21 Thread Maxime Ripard
Hi Boris,

On Wed, Mar 20, 2019 at 02:39:44PM +0100, Boris Brezillon wrote:
> On Tue, 19 Mar 2019 22:57:11 +0100
> Maxime Ripard  wrote:
>
> > Move the DRM formats API to turn this into a more generic image formats API
> > to be able to leverage it into some other places of the kernel, such as
> > v4l2 drivers.
> >
> > Signed-off-by: Maxime Ripard 
> > ---
> >  include/linux/image-formats.h | 240 +++-
> >  lib/Kconfig   |   7 +-
> >  lib/Makefile  |   3 +-
> >  lib/image-formats-selftests.c | 326 +++-
> >  lib/image-formats.c   | 760 +++-
> >  5 files changed, 1336 insertions(+)
> >  create mode 100644 include/linux/image-formats.h
> >  create mode 100644 lib/image-formats-selftests.c
> >  create mode 100644 lib/image-formats.c
> >
>
> [...]
>
> > --- /dev/null
> > +++ b/lib/image-formats.c
> > @@ -0,0 +1,760 @@
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +static const struct image_format_info formats[] = {
> > +   {
>
> ...
>
> > +   },
> > +};
> > +
> > +#define __image_format_lookup(_field, _fmt)\
> > +   ({  \
> > +   const struct image_format_info *format = NULL;  \
> > +   unsigned i; \
> > +   \
> > +   for (i = 0; i < ARRAY_SIZE(formats); i++)   \
> > +   if (formats[i]._field == _fmt)  \
> > +   format = [i];   \
> > +   \
> > +   format; \
> > +   })
> > +
> > +/**
> > + * __image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel 
> > format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> > +{
> > +   return __image_format_lookup(drm_fmt, drm);
> > +}
> > +EXPORT_SYMBOL(__image_format_drm_lookup);
> > +
> > +/**
> > + * image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + * Unsupported pixel formats will generate a warning in the kernel log.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel 
> > format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *image_format_drm_lookup(u32 drm)
> > +{
> > +   const struct image_format_info *format;
> > +
> > +   format = __image_format_drm_lookup(drm);
> > +
> > +   WARN_ON(!format);
> > +   return format;
> > +}
> > +EXPORT_SYMBOL(image_format_drm_lookup);
>
> I think this function and the DRM formats table should be moved in
> drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
> remaining functions can IMHO be placed in include/linux/image-formats.h
> as static inline funcs. This way you can get rid of lib/image-formats.c
> and the associated Kconfig entry.

I'm not quite sure what you mean. The whole point of the series is to
split out that table out of DRM so that we can use it in other places,
so surely putting it back into DRM defeats the purpose?

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


signature.asc
Description: PGP signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [RFC PATCH 06/20] lib: Add video format information library

2019-03-20 Thread Boris Brezillon
On Tue, 19 Mar 2019 22:57:11 +0100
Maxime Ripard  wrote:

> Move the DRM formats API to turn this into a more generic image formats API
> to be able to leverage it into some other places of the kernel, such as
> v4l2 drivers.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  include/linux/image-formats.h | 240 +++-
>  lib/Kconfig   |   7 +-
>  lib/Makefile  |   3 +-
>  lib/image-formats-selftests.c | 326 +++-
>  lib/image-formats.c   | 760 +++-
>  5 files changed, 1336 insertions(+)
>  create mode 100644 include/linux/image-formats.h
>  create mode 100644 lib/image-formats-selftests.c
>  create mode 100644 lib/image-formats.c
> 

[...]

> --- /dev/null
> +++ b/lib/image-formats.c
> @@ -0,0 +1,760 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +static const struct image_format_info formats[] = {
> + {

...

> + },
> +};
> +
> +#define __image_format_lookup(_field, _fmt)  \
> + ({  \
> + const struct image_format_info *format = NULL;  \
> + unsigned i; \
> + \
> + for (i = 0; i < ARRAY_SIZE(formats); i++)   \
> + if (formats[i]._field == _fmt)  \
> + format = [i];   \
> + \
> + format; \
> + })
> +
> +/**
> + * __image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, 
> or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> +{
> + return __image_format_lookup(drm_fmt, drm);
> +}
> +EXPORT_SYMBOL(__image_format_drm_lookup);
> +
> +/**
> + * image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, 
> or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_drm_lookup(u32 drm)
> +{
> + const struct image_format_info *format;
> +
> + format = __image_format_drm_lookup(drm);
> +
> + WARN_ON(!format);
> + return format;
> +}
> +EXPORT_SYMBOL(image_format_drm_lookup);

I think this function and the DRM formats table should be moved in
drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
remaining functions can IMHO be placed in include/linux/image-formats.h
as static inline funcs. This way you can get rid of lib/image-formats.c
and the associated Kconfig entry.

> +
> +/**
> + * image_format_plane_cpp - determine the bytes per pixel value
> + * @format: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The bytes per pixel value for the specified plane.
> + */
> +unsigned int image_format_plane_cpp(const struct image_format_info *format,
> + int plane)
> +{
> + if (!format || plane >= format->num_planes)
> + return 0;
> +
> + return format->cpp[plane];
> +}
> +EXPORT_SYMBOL(image_format_plane_cpp);
> +
> +/**
> + * image_format_plane_width - width of the plane given the first plane
> + * @format: pointer to the image_format
> + * @width: width of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The width of @plane, given that the width of the first plane is @width.
> + */
> +unsigned int image_format_plane_width(int width,
> +   const struct image_format_info *format,
> +   int plane)
> +{
> + if (!format || plane >= format->num_planes)
> + return 0;
> +
> + if (plane == 0)
> + return width;
> +
> + return width / format->hsub;
> +}
> +EXPORT_SYMBOL(image_format_plane_width);
> +
> +/**
> + * image_format_plane_height - height of the plane given the first plane
> + * @format: pointer to the image_format
> + * @height: height of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The height of @plane, given that the height of the first plane is @height.
> + */
> +unsigned int image_format_plane_height(int height,
> +const struct image_format_info *format,
> +int plane)
> +{
> + if (!format || plane >= format->num_planes)
> + 

[RFC PATCH 06/20] lib: Add video format information library

2019-03-19 Thread Maxime Ripard
Move the DRM formats API to turn this into a more generic image formats API
to be able to leverage it into some other places of the kernel, such as
v4l2 drivers.

Signed-off-by: Maxime Ripard 
---
 include/linux/image-formats.h | 240 +++-
 lib/Kconfig   |   7 +-
 lib/Makefile  |   3 +-
 lib/image-formats-selftests.c | 326 +++-
 lib/image-formats.c   | 760 +++-
 5 files changed, 1336 insertions(+)
 create mode 100644 include/linux/image-formats.h
 create mode 100644 lib/image-formats-selftests.c
 create mode 100644 lib/image-formats.c

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
new file mode 100644
index ..53fd73a71b3d
--- /dev/null
+++ b/include/linux/image-formats.h
@@ -0,0 +1,240 @@
+#ifndef _IMAGE_FORMATS_H_
+#define _IMAGE_FORMATS_H_
+
+#include 
+
+/**
+ * struct image_format_info - information about a image format
+ */
+struct image_format_info {
+   union {
+   /**
+* @drm_fmt:
+*
+* DRM 4CC format identifier (DRM_FORMAT_*)
+*/
+   u32 drm_fmt;
+
+   /**
+* @format:
+*
+* DRM 4CC format identifier (DRM_FORMAT_*). Kept
+* around for compatibility reasons with the current
+* DRM drivers.
+*/
+   u32 format;
+   };
+
+   /**
+* @depth:
+*
+* Color depth (number of bits per pixel excluding padding bits),
+* valid for a subset of RGB formats only. This is a legacy field, do
+* not use in new code and set to 0 for new formats.
+*/
+   u8 depth;
+
+   /** @num_planes: Number of color planes (1 to 3) */
+   u8 num_planes;
+
+   union {
+   /**
+* @cpp:
+*
+* Number of bytes per pixel (per plane), this is aliased with
+* @char_per_block. It is deprecated in favour of using the
+* triplet @char_per_block, @block_w, @block_h for better
+* describing the pixel format.
+*/
+   u8 cpp[3];
+
+   /**
+* @char_per_block:
+*
+* Number of bytes per block (per plane), where blocks are
+* defined as a rectangle of pixels which are stored next to
+* each other in a byte aligned memory region. Together with
+* @block_w and @block_h this is used to properly describe tiles
+* in tiled formats or to describe groups of pixels in packed
+* formats for which the memory needed for a single pixel is not
+* byte aligned.
+*
+* @cpp has been kept for historical reasons because there are
+* a lot of places in drivers where it's used. In drm core for
+* generic code paths the preferred way is to use
+* @char_per_block, image_format_block_width() and
+* image_format_block_height() which allows handling both
+* block and non-block formats in the same way.
+*
+* For formats that are intended to be used only with non-linear
+* modifiers both @cpp and @char_per_block must be 0 in the
+* generic format table. Drivers could supply accurate
+* information from their drm_mode_config.get_format_info hook
+* if they want the core to be validating the pitch.
+*/
+   u8 char_per_block[3];
+   };
+
+   /**
+* @block_w:
+*
+* Block width in pixels, this is intended to be accessed through
+* image_format_block_width()
+*/
+   u8 block_w[3];
+
+   /**
+* @block_h:
+*
+* Block height in pixels, this is intended to be accessed through
+* image_format_block_height()
+*/
+   u8 block_h[3];
+
+   /** @hsub: Horizontal chroma subsampling factor */
+   u8 hsub;
+   /** @vsub: Vertical chroma subsampling factor */
+   u8 vsub;
+
+   /** @has_alpha: Does the format embeds an alpha component? */
+   bool has_alpha;
+
+   /** @is_yuv: Is it a YUV format? */
+   bool is_yuv;
+};
+
+/**
+ * image_format_info_is_yuv_packed - check that the format info matches a YUV
+ * format with data laid in a single plane
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a packed YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_packed(const struct image_format_info *info)
+{
+   return info->is_yuv && info->num_planes == 1;
+}
+
+/**
+ * image_format_info_is_yuv_semiplanar - check that the format info matches a 
YUV
+ * format with data laid in two