From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Cc: igt-dev@lists.freedesktop.org, ville.syrjala@intel.com,
juha-pekka.heikkila@intel.com, martin.peres@intel.com
Subject: Re: [igt-dev] [PATCH i-g-t] lib/igt_fb: Added XYUV format support for testing
Date: Tue, 28 Aug 2018 15:57:41 +0300 [thread overview]
Message-ID: <20180828125741.GZ5565@intel.com> (raw)
In-Reply-To: <20180828104522.18996-1-stanislav.lisovskiy@intel.com>
On Tue, Aug 28, 2018 at 01:45:22PM +0300, Stanislav Lisovskiy wrote:
> XYUV format support has been added to DRM, modified
> IGT to reflect those changes.
> ---
> include/drm-uapi/drm_fourcc.h | 1 +
> lib/igt_fb.c | 160 +++++++++++++++++++++++++++++++++-
> 2 files changed, 160 insertions(+), 1 deletion(-)
>
> diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
> index e04613d3..0bf66de2 100644
> --- a/include/drm-uapi/drm_fourcc.h
> +++ b/include/drm-uapi/drm_fourcc.h
> @@ -112,6 +112,7 @@ extern "C" {
> #define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
>
> #define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
> +#define DRM_FORMAT_XYUV fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
>
> /*
> * 2 plane RGB + A
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 7404ba7c..27f9d657 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -68,6 +68,8 @@ static struct format_desc_struct {
> } format_desc[] = {
> DF(RGB565, RGB16_565, 16, 16),
> //DF(RGB888, INVALID, 24, 24),
> + DF(XYUV, RGB24, 32, 24, 1, {32}),
> + DF(XRGB8888, RGB24, 32, 24),
> DF(XRGB8888, RGB24, 32, 24),
> DF(XRGB2101010, RGB30, 32, 30),
> DF(ARGB8888, ARGB32, 32, 32),
> @@ -1399,6 +1401,94 @@ static void convert_nv12_to_rgb24(struct igt_fb *fb, struct fb_convert_blit_uplo
> free(buf);
> }
>
> +#define MAKE_YUV_601_Y(r, g, b) \
> + ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) / 256) + 16)
> +#define MAKE_YUV_601_U(r, g, b) \
> + (((-38 * (r) - 74 * (g) + 112 * (b) + 128) / 256) + 128)
> +#define MAKE_YUV_601_V(r, g, b) \
> + (((112 * (r) - 94 * (g) - 18 * (b) + 128) / 256) + 128)
Reuse the yuv<->rgb stuff we already have.
> +
> +#define MAKE_RGB_24_R(y, u, v) \
> + (y + 0 * u + 1.13983 * v)
> +
> +#define MAKE_RGB_24_G(y, u, v) \
> + (y + -0.39465 * u + -0.58060 * v)
> +
> +#define MAKE_RGB_24_B(y, u, v) \
> + (y + -0.03211 * u + 0 * v)
> +
> +static void convert_yuv444_to_rgb24(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
> +{
> + int i, j;
> + uint8_t *yuv;
> + uint8_t *rgb24 = blit->rgb24.map;
> + unsigned rgb24_stride = blit->rgb24.stride, planar_stride = blit->linear.stride;
> + uint8_t *buf = malloc(blit->linear.size);
> +
> + /*
> + * Reading from the BO is awfully slow because of lack of read caching,
> + * it's faster to copy the whole BO to a temporary buffer and convert
> + * from there.
> + */
> + igt_memcpy_from_wc(buf, blit->linear.map, blit->linear.size);
> + yuv = &buf[blit->linear.offsets[0]];
> +
> + for (i = 0; i < fb->plane_height[0]; i++) {
> + for (j = 0; j < fb->plane_width[0]; j++) {
> + float r, g, b, y, u, v;
> + v = yuv[i * planar_stride + j*sizeof(uint32_t)];
> + u = yuv[i * planar_stride + j*sizeof(uint32_t) + 1];
> + y = yuv[i * planar_stride + j*sizeof(uint32_t) + 2];
> + r = MAKE_RGB_24_R(y,u,v);
> + g = MAKE_RGB_24_G(y,u,v);
> + b = MAKE_RGB_24_B(y,u,v);
> + rgb24[i * rgb24_stride + j*sizeof(uint32_t)] = b;
> + rgb24[i * rgb24_stride + j*sizeof(uint32_t) + 1] = g;
> + rgb24[i * rgb24_stride + j*sizeof(uint32_t) + 2] = r;
> + }
> + }
> +
> + free(buf);
> +}
> +
> +
> +static void convert_rgb24_to_yuv444(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
> +{
> + int i, j;
> + uint8_t *rgb;
> + uint8_t *yuv444 = blit->linear.map;
> + unsigned rgb24_stride = blit->rgb24.stride, planar_stride = blit->linear.stride;
> + uint8_t *buf = malloc(blit->linear.size);
> +
> + /*
> + * Reading from the BO is awfully slow because of lack of read caching,
> + * it's faster to copy the whole BO to a temporary buffer and convert
> + * from there.
> + */
> + igt_memcpy_from_wc(buf, blit->rgb24.map, blit->linear.size);
> + rgb = &buf[blit->linear.offsets[0]];
> +
> + for (i = 0; i < fb->plane_height[0]; i++) {
> + for (j = 0; j < fb->plane_width[0]; j++) {
> + float r, g, b, y, u, v;
> + b = rgb[i * rgb24_stride + j*sizeof(uint32_t)];
> + g = rgb[i * rgb24_stride + j*sizeof(uint32_t) + 1];
> + r = rgb[i * rgb24_stride + j*sizeof(uint32_t) + 2];
> + y = MAKE_YUV_601_Y(r,g,b);
> + u = MAKE_YUV_601_U(r,g,b);
> + v = MAKE_YUV_601_V(r,g,b);
> + yuv444[i * planar_stride + j*sizeof(uint32_t)] = v;
> + yuv444[i * planar_stride + j*sizeof(uint32_t) + 1] = u;
> + yuv444[i * planar_stride + j*sizeof(uint32_t) + 2] = y;
> + }
> + }
> +
> + free(buf);
> +}
> +
> +
> +
> +
> static void convert_rgb24_to_nv12(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
> {
> int i, j;
> @@ -1534,6 +1624,72 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
> blit, destroy_cairo_surface__convert);
> }
>
> +
> +static void destroy_cairo_surface__convert_yuv(void *arg)
> +{
> + struct fb_convert_blit_upload *blit = arg;
> + struct igt_fb *fb = blit->fb;
> +
> + /* Convert back to planar! */
> + igt_assert_f(fb->drm_format == DRM_FORMAT_XYUV,
> + "Conversion not implemented for !XYUV planar formats\n");
> +
> + convert_rgb24_to_yuv444(fb, blit);
> +
> + munmap(blit->rgb24.map, blit->rgb24.size);
> +
> + if (blit->linear.handle)
> + free_linear_mapping(blit->fd, blit->fb, &blit->linear);
> + else
> + gem_munmap(blit->linear.map, fb->size);
> +
> + free(blit);
> +
> + fb->cairo_surface = NULL;
> +}
> +
> +
> +static void create_cairo_surface__convert_yuv(int fd, struct igt_fb *fb)
No need to duplicate all this. Just add the xyuv case to the existing
function.
> +{
> + struct fb_convert_blit_upload *blit = malloc(sizeof(*blit));
> + igt_assert(blit);
> +
> + blit->fd = fd;
> + blit->fb = fb;
> + blit->rgb24.stride = ALIGN(fb->width * 4, 16);
> + blit->rgb24.size = ALIGN(blit->rgb24.stride * fb->height, sysconf(_SC_PAGESIZE));
> + blit->rgb24.map = mmap(NULL, blit->rgb24.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> + igt_assert(blit->rgb24.map != MAP_FAILED);
> +
> + if (fb->tiling == LOCAL_I915_FORMAT_MOD_Y_TILED ||
> + fb->tiling == LOCAL_I915_FORMAT_MOD_Yf_TILED) {
> + setup_linear_mapping(fd, fb, &blit->linear);
> + } else {
> + blit->linear.handle = 0;
> + blit->linear.map = gem_mmap__gtt(fd, fb->gem_handle, fb->size,
> + PROT_READ | PROT_WRITE);
> + igt_assert(blit->linear.map);
> + blit->linear.stride = fb->stride;
> + blit->linear.size = fb->size;
> + memcpy(blit->linear.offsets, fb->offsets, sizeof(fb->offsets));
> + }
> +
> + /* Convert to linear! */
> + igt_assert_f(fb->drm_format == DRM_FORMAT_XYUV,
> + "Conversion not implemented for !XYUV planar formats\n");
> + convert_yuv444_to_rgb24(fb, blit);
> +
> + fb->cairo_surface =
> + cairo_image_surface_create_for_data(blit->rgb24.map,
> + CAIRO_FORMAT_RGB24,
> + fb->width, fb->height,
> + blit->rgb24.stride);
> +
> + cairo_surface_set_user_data(fb->cairo_surface,
> + (cairo_user_data_key_t *)create_cairo_surface__convert_yuv,
> + blit, destroy_cairo_surface__convert_yuv);
> +}
> +
> /**
> * igt_get_cairo_surface:
> * @fd: open drm file descriptor
> @@ -1548,7 +1704,9 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
> cairo_surface_t *igt_get_cairo_surface(int fd, struct igt_fb *fb)
> {
> if (fb->cairo_surface == NULL) {
> - if (fb->num_planes > 1)
> + if (fb->drm_format == DRM_FORMAT_XYUV)
> + create_cairo_surface__convert_yuv(fd, fb);
> + else if (fb->num_planes > 1)
> create_cairo_surface__convert(fd, fb);
> else if (fb->tiling == LOCAL_I915_FORMAT_MOD_Y_TILED ||
> fb->tiling == LOCAL_I915_FORMAT_MOD_Yf_TILED)
> --
> 2.17.0
>
> _______________________________________________
> igt-dev mailing list
> igt-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev
--
Ville Syrjälä
Intel
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
prev parent reply other threads:[~2018-08-28 12:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-28 10:45 [igt-dev] [PATCH i-g-t] lib/igt_fb: Added XYUV format support for testing Stanislav Lisovskiy
2018-08-28 11:30 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
2018-08-28 12:57 ` Ville Syrjälä [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180828125741.GZ5565@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=juha-pekka.heikkila@intel.com \
--cc=martin.peres@intel.com \
--cc=stanislav.lisovskiy@intel.com \
--cc=ville.syrjala@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.