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:
        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

Reply via email to