[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