[igt-dev] [PATCH v3 03/11] fb: Add format conversion routine

Ville Syrjälä ville.syrjala at linux.intel.com
Thu May 24 14:58:13 UTC 2018


On Thu, May 24, 2018 at 04:24:42PM +0200, Maxime Ripard wrote:
> The chamelium format subtests will need to convert the reference pattern to
> the format to be tested on the DRM device.
> 
> However, Cairo is very limited when it comes to format, and while pixman
> has much more support for formats, it's still falling short compared to
> what DRM exposes, especially on the YUV side.

We already have the capability to do format conversions automagically.
I'm extending it to handle more YUV stuff here:
https://patchwork.freedesktop.org/series/43651/

Can you hook up the pixman stuff in the same way so that we don't
have to any explicit conversion stuff in the tests themselves?

> 
> In order to abstract this away, let's create a function that will convert a
> igt_fb structure to another DRM format and return the converted igt_fb.
> 
> For now, we will use pixman to do the conversion, but we will use other
> libraries or roll our own routines to convert to more exotic formats and
> abstract it away from the users.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard at bootlin.com>
> ---
>  lib/igt_fb.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-----
>  lib/igt_fb.h |  2 +-
>  2 files changed, 84 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 66ded11a73ca..e5e66f7df7f5 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -28,6 +28,7 @@
>  #include <stdio.h>
>  #include <math.h>
>  #include <inttypes.h>
> +#include <pixman.h>
>  
>  #include "drmtest.h"
>  #include "igt_fb.h"
> @@ -54,24 +55,27 @@
>   * functions to work with these pixel format codes.
>   */
>  
> +#define PIXMAN_invalid	0
> +
>  /* drm fourcc/cairo format maps */
> -#define DF(did, cid, ...)	\
> -	{ DRM_FORMAT_##did, CAIRO_FORMAT_##cid, # did, __VA_ARGS__ }
> +#define DF(did, cid, pid, ...)					\
> +	{ DRM_FORMAT_##did, CAIRO_FORMAT_##cid, PIXMAN_##pid, # did, __VA_ARGS__ }
>  static struct format_desc_struct {
>  	uint32_t drm_id;
>  	cairo_format_t cairo_id;
> +	pixman_format_code_t pixman_id;
>  	const char *name;
>  	int bpp;
>  	int depth;
>  	int planes;
>  	int plane_bpp[4];
>  } format_desc[] = {
> -	DF(RGB565,	RGB16_565,	16, 16),
> -	//DF(RGB888,	INVALID,	24, 24),
> -	DF(XRGB8888,	RGB24,		32, 24),
> -	DF(XRGB2101010,	RGB30,		32, 30),
> -	DF(ARGB8888,	ARGB32,		32, 32),
> -	DF(NV12,	RGB24,		32, -1, 2, {8, 16}),
> +	DF(RGB565,	RGB16_565,	r5g6b5,		16, 16),
> +	//DF(RGB888,	INVALID,	r8g8b8,		24, 24),
> +	DF(XRGB8888,	RGB24,		x8r8g8b8,	32, 24),
> +	DF(XRGB2101010,	RGB30,		x2r10g10b10,	32, 30),
> +	DF(ARGB8888,	ARGB32,		a8r8g8b8,	32, 32),
> +	DF(NV12,	RGB24,		invalid,	32, -1, 2, {8, 16}),
>  };
>  #undef DF
>  
> @@ -1123,6 +1127,18 @@ unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
>  	return fb_id;
>  }
>  
> +static pixman_format_code_t drm_format_to_pixman(uint32_t drm_format)
> +{
> +	struct format_desc_struct *f;
> +
> +	for_each_format(f)
> +		if (f->drm_id == drm_format)
> +			return f->pixman_id;
> +
> +	igt_assert_f(0, "can't find a pixman format for %08x (%s)\n",
> +		     drm_format, igt_format_str(drm_format));
> +}
> +
>  static cairo_format_t drm_format_to_cairo(uint32_t drm_format)
>  {
>  	struct format_desc_struct *f;
> @@ -1676,6 +1692,64 @@ void igt_remove_fb(int fd, struct igt_fb *fb)
>  }
>  
>  /**
> + * igt_fb_convert:
> + * @dst: pointer to the #igt_fb structure that will store the conversion result
> + * @src: pointer to the #igt_fb structure that stores the frame we convert
> + * @dst_fourcc: DRM format specifier to convert to
> + *
> + * This will convert a given @src content to the @dst_fourcc format,
> + * storing the result in the @dst fb, allocating the @dst fb
> + * underlying buffer.
> + *
> + * Once done with @dst, the caller will have to call igt_remove_fb()
> + * on it to free the associated resources.
> + *
> + * Returns:
> + * The kms id of the created framebuffer.
> + */
> +unsigned int igt_fb_convert(struct igt_fb *dst, struct igt_fb *src,
> +			    uint32_t dst_fourcc)
> +{
> +	pixman_format_code_t src_pixman = drm_format_to_pixman(src->drm_format);
> +	pixman_format_code_t dst_pixman = drm_format_to_pixman(dst_fourcc);
> +	pixman_image_t *dst_image, *src_image;
> +	void *dst_ptr, *src_ptr;
> +	int fb_id;
> +
> +	igt_assert(src_pixman != PIXMAN_invalid);
> +	igt_assert(dst_pixman != PIXMAN_invalid);
> +
> +	fb_id = igt_create_fb(src->fd, src->width, src->height,
> +			      dst_fourcc, LOCAL_DRM_FORMAT_MOD_NONE, dst);
> +	igt_assert(fb_id > 0);
> +
> +	src_ptr = igt_fb_map_buffer(src->fd, src);
> +	igt_assert(src_ptr);
> +
> +	dst_ptr = igt_fb_map_buffer(dst->fd, dst);
> +	igt_assert(dst_ptr);
> +
> +	src_image = pixman_image_create_bits(src_pixman,
> +					     src->width, src->height,
> +					     src_ptr, src->stride);
> +	igt_assert(src_image);
> +
> +	dst_image = pixman_image_create_bits(dst_pixman,
> +					     dst->width, dst->height,
> +					     dst_ptr, dst->stride);
> +	igt_assert(dst_image);
> +
> +	pixman_image_composite(PIXMAN_OP_SRC, src_image, NULL, dst_image,
> +			       0, 0, 0, 0, 0, 0, dst->width, dst->height);
> +	pixman_image_unref(dst_image);
> +	pixman_image_unref(src_image);
> +	igt_fb_unmap_buffer(dst, dst_ptr);
> +	igt_fb_unmap_buffer(src, src_ptr);
> +
> +	return fb_id;
> +}
> +
> +/**
>   * igt_bpp_depth_to_drm_format:
>   * @bpp: desired bits per pixel
>   * @depth: desired depth
> diff --git a/lib/igt_fb.h b/lib/igt_fb.h
> index f5f6d31445a0..c4ca39866b9a 100644
> --- a/lib/igt_fb.h
> +++ b/lib/igt_fb.h
> @@ -126,6 +126,8 @@ unsigned int igt_create_image_fb(int drm_fd,  int width, int height,
>  				 struct igt_fb *fb /* out */);
>  unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
>  				  uint32_t format, uint64_t tiling);
> +unsigned int igt_fb_convert(struct igt_fb *dst, struct igt_fb *src,
> +			    uint32_t dst_fourcc);
>  void igt_remove_fb(int fd, struct igt_fb *fb);
>  int igt_dirty_fb(int fd, struct igt_fb *fb);
>  void *igt_fb_map_buffer(int fd, struct igt_fb *fb);
> -- 
> git-series 0.9.1
> _______________________________________________
> igt-dev mailing list
> igt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Ville Syrjälä
Intel


More information about the igt-dev mailing list