All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium
@ 2019-01-25 14:58 Maxime Ripard
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
                   ` (13 more replies)
  0 siblings, 14 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

Here is a first attempt at expanding the current Chamelium formats
test to YUV formats.

It builds on top of the current infrastructure for the YUV convertions, and
the format suppport of the Chamelium. It reworks igt_fb quite significantly
to add generic support for YUV formats, and adds a bunch of new formats
along the way.

Let me know what you think,
Maxime

Changes from v4:
  - Added Paul Reviewed-by's
  - Removed the patch that moves calc_fb_size for everybody, and added some
    asserts

Changes from v3:
  - Fixed build breakage

Changes from v2:
  - Added Paul Reviewed-by's
  - Fixed a stride issue on the buffer allocation
  - Take into account the plane bpp so that we don't overallocate
  - Rebased on master

Changes from v1:
  - Support more YUV formats than just NV12
  - Rework the YUV convertion functions to add generic routines
  - Took the comments into account.

Maxime Ripard (13):
  igt: fb: Add subsampling parameters to the formats
  igt: fb: Reduce tile size alignment for non intel platforms
  igt: fb: generic YUV convertion function
  igt: fb: Move i915 YUV buffer clearing code to a function
  igt: fb: Refactor dumb buffer allocation path
  igt: fb: Account for all planes bpp
  igt: fb: Don't pass the stride when allocating a dumb, multi-planar
    buffer
  igt: fb: Clear YUV dumb buffers
  igt: fb: Rework YUV i915 allocation path
  igt: fb: Add a bunch of new YUV formats
  igt: tests: chamelium: Start to unify tests
  igt: tests: chamelium: Convert VGA tests to do_test_display
  igt: tests: chamelium: Add YUV formats tests

 lib/igt_fb.c          | 830 ++++++++++++++++++++----------------------
 tests/kms_chamelium.c | 254 +++++++------
 2 files changed, 528 insertions(+), 556 deletions(-)

-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
  2019-02-05 12:52   ` Paul Kocialkowski
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms Maxime Ripard
                   ` (12 subsequent siblings)
  13 siblings, 2 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

In order to improve the YUV support, let's add the horizontal and vertical
subsampling parameters to the IGT formats.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 5cd1829a3ce4..e23908e28c07 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -71,85 +71,104 @@ static const struct format_desc_struct {
 	int depth;
 	int num_planes;
 	int plane_bpp[4];
+	uint8_t hsub;
+	uint8_t vsub;
 } format_desc[] = {
 	{ .name = "ARGB1555", .depth = -1, .drm_id = DRM_FORMAT_ARGB1555,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_a1r5g5b5,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "XRGB1555", .depth = -1, .drm_id = DRM_FORMAT_XRGB1555,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_x1r5g5b5,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "RGB565", .depth = 16, .drm_id = DRM_FORMAT_RGB565,
 	  .cairo_id = CAIRO_FORMAT_RGB16_565,
 	  .pixman_id = PIXMAN_r5g6b5,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "BGR565", .depth = -1, .drm_id = DRM_FORMAT_BGR565,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_b5g6r5,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "BGR888", .depth = -1, .drm_id = DRM_FORMAT_BGR888,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_b8g8r8,
 	  .num_planes = 1, .plane_bpp = { 24, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "RGB888", .depth = -1, .drm_id = DRM_FORMAT_RGB888,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_r8g8b8,
 	  .num_planes = 1, .plane_bpp = { 24, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "XYUV8888", .depth = -1, .drm_id = DRM_FORMAT_XYUV8888,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .pixman_id = PIXMAN_x8r8g8b8,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "XBGR8888", .depth = -1, .drm_id = DRM_FORMAT_XBGR8888,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_x8b8g8r8,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "XRGB2101010", .depth = 30, .drm_id = DRM_FORMAT_XRGB2101010,
 	  .cairo_id = CAIRO_FORMAT_RGB30,
 	  .pixman_id = PIXMAN_x2r10g10b10,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "ARGB8888", .depth = 32, .drm_id = DRM_FORMAT_ARGB8888,
 	  .cairo_id = CAIRO_FORMAT_ARGB32,
 	  .pixman_id = PIXMAN_a8r8g8b8,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "ABGR8888", .depth = -1, .drm_id = DRM_FORMAT_ABGR8888,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .pixman_id = PIXMAN_a8b8g8r8,
 	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
 	},
 	{ .name = "NV12", .depth = -1, .drm_id = DRM_FORMAT_NV12,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 2, .plane_bpp = { 8, 16, },
+	  .hsub = 2, .vsub = 2,
 	},
 	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 2, .vsub = 1,
 	},
 	{ .name = "YVYU", .depth = -1, .drm_id = DRM_FORMAT_YVYU,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 2, .vsub = 1,
 	},
 	{ .name = "UYVY", .depth = -1, .drm_id = DRM_FORMAT_UYVY,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 2, .vsub = 1,
 	},
 	{ .name = "VYUY", .depth = -1, .drm_id = DRM_FORMAT_VYUY,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 16, },
+	  .hsub = 2, .vsub = 1,
 	},
 };
 #define for_each_format(f)	\
@@ -239,10 +258,12 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int fb_bpp,
 
 static unsigned fb_plane_width(const struct igt_fb *fb, int plane)
 {
-	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
-		return DIV_ROUND_UP(fb->width, 2);
+	const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
 
-	return fb->width;
+	if (plane == 0)
+		return fb->width;
+
+	return DIV_ROUND_UP(fb->width, format->hsub);
 }
 
 static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
@@ -254,10 +275,12 @@ static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
 
 static unsigned fb_plane_height(const struct igt_fb *fb, int plane)
 {
-	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
-		return DIV_ROUND_UP(fb->height, 2);
+	const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
 
-	return fb->height;
+	if (plane == 0)
+		return fb->height;
+
+	return DIV_ROUND_UP(fb->height, format->vsub);
 }
 
 static int fb_num_planes(const struct igt_fb *fb)
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
  2019-02-05 12:52   ` Paul Kocialkowski
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
                   ` (11 subsequent siblings)
  13 siblings, 2 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Aligning the width on 64 pixels only make sense on intel platforms, make
sure to add a check against this.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index e23908e28c07..1a5c338ea532 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -204,7 +204,11 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int fb_bpp,
 {
 	switch (tiling) {
 	case LOCAL_DRM_FORMAT_MOD_NONE:
-		*width_ret = 64;
+		if (is_i915_device(fd))
+			*width_ret = 64;
+		else
+			*width_ret = 1;
+
 		*height_ret = 1;
 		break;
 	case LOCAL_I915_FORMAT_MOD_X_TILED:
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
                     ` (2 more replies)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function Maxime Ripard
                   ` (10 subsequent siblings)
  13 siblings, 3 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The current way we work when we want to support a new YUV format to IGT, we
also need to add new function to convert to and from XRGB8888.

This doesn't really scale however, and creates a lot of code to maintain.
In order to work around this, create a generic function to convert to RGB
and one to convert from RGB.

The only thing that is needed now is to add new parameters, and that's it.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 537 ++++++++++++++++-----------------------------------
 1 file changed, 171 insertions(+), 366 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 1a5c338ea532..45691fd441d9 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -1577,424 +1577,237 @@ static void convert_src_put(const struct fb_convert *cvt,
 		free(src_buf);
 }
 
-static void convert_nv12_to_rgb24(struct fb_convert *cvt)
+struct yuv_parameters {
+	unsigned	y_inc;
+	unsigned	uv_inc;
+	unsigned	y_stride;
+	unsigned	uv_stride;
+	unsigned	y_offset;
+	unsigned	u_offset;
+	unsigned	v_offset;
+};
+
+static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 {
-	int i, j;
-	const uint8_t *y, *uv;
-	uint8_t *rgb24 = cvt->dst.ptr;
-	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
-	unsigned int planar_stride = cvt->src.fb->strides[0];
-	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
-						    cvt->src.fb->color_range);
-	uint8_t *buf;
-
-	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_NV12 &&
-		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
-
-	buf = convert_src_get(cvt);
-	y = buf + cvt->src.fb->offsets[0];
-	uv = buf + cvt->src.fb->offsets[1];
-
-	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x2 pixel blocks */
-			struct igt_vec4 yuv[4];
-			struct igt_vec4 rgb[4];
-
-			yuv[0].d[0] = y[j * 2 + 0];
-			yuv[1].d[0] = y[j * 2 + 1];
-			yuv[2].d[0] = y[j * 2 + 0 + planar_stride];
-			yuv[3].d[0] = y[j * 2 + 1 + planar_stride];
-
-			yuv[0].d[1] = yuv[1].d[1] = yuv[2].d[1] = yuv[3].d[1] = uv[j * 2 + 0];
-			yuv[0].d[2] = yuv[1].d[2] = yuv[2].d[2] = yuv[3].d[2] = uv[j * 2 + 1];
-			yuv[0].d[3] = yuv[1].d[3] = yuv[2].d[3] = yuv[3].d[3] = 1.0f;
-
-			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
-			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
-			rgb[2] = igt_matrix_transform(&m, &yuv[2]);
-			rgb[3] = igt_matrix_transform(&m, &yuv[3]);
-
-			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
-			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
-			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[2]);
-			write_rgb(&rgb24[j * 8 + 4 + rgb24_stride], &rgb[3]);
-		}
-
-		if (cvt->dst.fb->width & 1) {
-			/* Convert 1x2 pixel block */
-			struct igt_vec4 yuv[2];
-			struct igt_vec4 rgb[2];
-
-			yuv[0].d[0] = y[j * 2 + 0];
-			yuv[1].d[0] = y[j * 2 + 0 + planar_stride];
+	igt_assert(igt_format_is_yuv(fb->drm_format));
 
-			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
-			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
-			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
+	switch (fb->drm_format) {
+	case DRM_FORMAT_NV12:
+		params->y_inc = 1;
+		params->uv_inc = 2;
+		break;
 
-			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
-			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
-
-			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
-			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[1]);
-		}
-
-		rgb24 += 2 * rgb24_stride;
-		y += 2 * planar_stride;
-		uv += planar_stride;
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+		params->y_inc = 2;
+		params->uv_inc = 4;
+		break;
+
+	case DRM_FORMAT_XYUV8888:
+		params->y_inc = 4;
+		params->uv_inc = 4;
+		break;
 	}
 
-	if (cvt->dst.fb->height & 1) {
-		/* Convert last row */
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x1 pixel blocks */
-			struct igt_vec4 yuv[2];
-			struct igt_vec4 rgb[2];
-
-			yuv[0].d[0] = y[j * 2 + 0];
-			yuv[1].d[0] = y[j * 2 + 1];
-			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
-			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
-			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
+	switch (fb->drm_format) {
+	case DRM_FORMAT_NV12:
+		params->y_stride = fb->strides[0];
+		params->uv_stride = fb->strides[1];
+		break;
 
-			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
-			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_XYUV8888:
+		params->y_stride = fb->strides[0];
+		params->uv_stride = fb->strides[0];
+		break;
+	}
 
-			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
-			write_rgb(&rgb24[j * 8 + 4], &rgb[0]);
-		}
+	switch (fb->drm_format) {
+	case DRM_FORMAT_NV12:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[1];
+		params->v_offset = fb->offsets[1] + 1;
+		break;
 
-		if (cvt->dst.fb->width & 1) {
-			/* Convert single pixel */
-			struct igt_vec4 yuv;
-			struct igt_vec4 rgb;
+	case DRM_FORMAT_YUYV:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[0] + 1;
+		params->v_offset = fb->offsets[0] + 3;
+		break;
 
-			yuv.d[0] = y[j * 2 + 0];
-			yuv.d[1] = uv[j * 2 + 0];
-			yuv.d[2] = uv[j * 2 + 1];
-			yuv.d[3] = 1.0f;
+	case DRM_FORMAT_YVYU:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[0] + 3;
+		params->v_offset = fb->offsets[0] + 1;
+		break;
 
-			rgb = igt_matrix_transform(&m, &yuv);
+	case DRM_FORMAT_UYVY:
+		params->y_offset = fb->offsets[0] + 1;
+		params->u_offset = fb->offsets[0];
+		params->v_offset = fb->offsets[0] + 2;
+		break;
 
-			write_rgb(&rgb24[j * 8 + 0], &rgb);
-		}
+	case DRM_FORMAT_VYUY:
+		params->y_offset = fb->offsets[0] + 1;
+		params->u_offset = fb->offsets[0] + 2;
+		params->v_offset = fb->offsets[0];
+		break;
+
+	case DRM_FORMAT_XYUV8888:
+		params->y_offset = fb->offsets[0] + 1;
+		params->u_offset = fb->offsets[0] + 2;
+		params->v_offset = fb->offsets[0] + 3;
+		break;
 	}
-
-	convert_src_put(cvt, buf);
 }
 
-static void convert_yuv444_to_rgb24(struct fb_convert *cvt)
+static void convert_yuv_to_rgb24(struct fb_convert *cvt)
 {
+	const struct format_desc_struct *src_fmt =
+		lookup_drm_format(cvt->src.fb->drm_format);
 	int i, j;
-	uint8_t *yuv24;
+	uint8_t bpp = 4;
+	uint8_t *y, *u, *v;
 	uint8_t *rgb24 = cvt->dst.ptr;
-	unsigned rgb24_stride = cvt->dst.fb->strides[0], xyuv_stride = cvt->src.fb->strides[0];
-	uint8_t *buf = malloc(cvt->src.fb->size);
+	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
 	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
 						    cvt->src.fb->color_range);
+	uint8_t *buf;
+	struct yuv_parameters params = { };
 
-	/*
-	 * 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, cvt->src.ptr + cvt->src.fb->offsets[0], cvt->src.fb->size);
-	yuv24 = buf;
+	igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
+		   igt_format_is_yuv(cvt->src.fb->drm_format));
+
+	buf = convert_src_get(cvt);
+	get_yuv_parameters(cvt->src.fb, &params);
+	y = buf + params.y_offset;
+	u = buf + params.u_offset;
+	v = buf + params.v_offset;
 
 	for (i = 0; i < cvt->dst.fb->height; i++) {
+		const uint8_t *y_tmp = y;
+		const uint8_t *u_tmp = u;
+		const uint8_t *v_tmp = v;
+		uint8_t *rgb_tmp = rgb24;
+
 		for (j = 0; j < cvt->dst.fb->width; j++) {
-			float y, u, v;
-			struct igt_vec4 yuv;
-			struct igt_vec4 rgb;
-
-			v = yuv24[i * xyuv_stride + j * 4];
-			u = yuv24[i * xyuv_stride + j * 4 + 1];
-			y = yuv24[i * xyuv_stride + j * 4 + 2];
-			yuv.d[0] = y;
-			yuv.d[1] = u;
-			yuv.d[2] = v;
+			struct igt_vec4 rgb, yuv;
+
+			yuv.d[0] = *y_tmp;
+			yuv.d[1] = *u_tmp;
+			yuv.d[2] = *v_tmp;
 			yuv.d[3] = 1.0f;
 
 			rgb = igt_matrix_transform(&m, &yuv);
+			write_rgb(rgb_tmp, &rgb);
 
-			write_rgb(&rgb24[i * rgb24_stride + j * 4], &rgb);
-		}
-	}
-
-	free(buf);
-}
-
-
-static void convert_rgb24_to_yuv444(struct fb_convert *cvt)
-{
-	int i, j;
-	uint8_t *rgb24;
-	uint8_t *yuv444 = cvt->dst.ptr + cvt->dst.fb->offsets[0];
-	unsigned int rgb24_stride = cvt->src.fb->strides[0], xyuv_stride = cvt->dst.fb->strides[0];
-	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
-						    cvt->dst.fb->color_range);
-
-	rgb24 = cvt->src.ptr;
+			rgb_tmp += bpp;
+			y_tmp += params.y_inc;
 
-	igt_assert_f(cvt->dst.fb->drm_format == DRM_FORMAT_XYUV8888,
-		     "Conversion not implemented for !XYUV packed formats\n");
-
-	for (i = 0; i < cvt->dst.fb->height; i++) {
-		for (j = 0; j < cvt->dst.fb->width; j++) {
-			struct igt_vec4 rgb;
-			struct igt_vec4 yuv;
-
-			read_rgb(&rgb, &rgb24[i * rgb24_stride + j * 4]);
+			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
+				u_tmp += params.uv_inc;
+				v_tmp += params.uv_inc;
+			}
+		}
 
-			yuv = igt_matrix_transform(&m, &rgb);
+		rgb24 += rgb24_stride;
+		y += params.y_stride;
 
-			yuv444[i * xyuv_stride + j * 4] = yuv.d[2];
-			yuv444[i * xyuv_stride + j * 4 + 1] = yuv.d[1];
-			yuv444[i * xyuv_stride + j * 4 + 2] = yuv.d[0];
+		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
+			u += params.uv_stride;
+			v += params.uv_stride;
 		}
 	}
+
+	convert_src_put(cvt, buf);
 }
 
-static void convert_rgb24_to_nv12(struct fb_convert *cvt)
+static void convert_rgb24_to_yuv(struct fb_convert *cvt)
 {
+	const struct format_desc_struct *dst_fmt =
+		lookup_drm_format(cvt->dst.fb->drm_format);
 	int i, j;
-	uint8_t *y = cvt->dst.ptr + cvt->dst.fb->offsets[0];
-	uint8_t *uv = cvt->dst.ptr + cvt->dst.fb->offsets[1];
+	uint8_t *y, *u, *v;
 	const uint8_t *rgb24 = cvt->src.ptr;
+	uint8_t bpp = 4;
 	unsigned rgb24_stride = cvt->src.fb->strides[0];
-	unsigned planar_stride = cvt->dst.fb->strides[0];
 	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
 						    cvt->dst.fb->color_range);
+	struct yuv_parameters params = { };
 
 	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
-		   cvt->dst.fb->drm_format == DRM_FORMAT_NV12);
+		   igt_format_is_yuv(cvt->dst.fb->drm_format));
 
-	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x2 pixel blocks */
-			struct igt_vec4 rgb[4];
-			struct igt_vec4 yuv[4];
+	get_yuv_parameters(cvt->dst.fb, &params);
+	y = cvt->dst.ptr + params.y_offset;
+	u = cvt->dst.ptr + params.u_offset;
+	v = cvt->dst.ptr + params.v_offset;
 
-			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
-			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
-			read_rgb(&rgb[2], &rgb24[j * 8 + 0 + rgb24_stride]);
-			read_rgb(&rgb[3], &rgb24[j * 8 + 4 + rgb24_stride]);
-
-			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
-			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
-			yuv[2] = igt_matrix_transform(&m, &rgb[2]);
-			yuv[3] = igt_matrix_transform(&m, &rgb[3]);
-
-			y[j * 2 + 0] = yuv[0].d[0];
-			y[j * 2 + 1] = yuv[1].d[0];
-			y[j * 2 + 0 + planar_stride] = yuv[2].d[0];
-			y[j * 2 + 1 + planar_stride] = yuv[3].d[0];
+	for (i = 0; i < cvt->dst.fb->height; i++) {
+		const uint8_t *rgb_tmp = rgb24;
+		uint8_t *y_tmp = y;
+		uint8_t *u_tmp = u;
+		uint8_t *v_tmp = v;
 
-			/*
-			 * We assume the MPEG2 chroma siting convention, where
-			 * pixel center for Cb'Cr' is between the left top and
-			 * bottom pixel in a 2x2 block, so take the average.
-			 */
-			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[2].d[1]) / 2.0f;
-			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[2].d[2]) / 2.0f;
-		}
+		for (j = 0; j < cvt->dst.fb->width; j++) {
+			const uint8_t *pair_rgb24 = rgb_tmp;
+			struct igt_vec4 pair_rgb, rgb;
+			struct igt_vec4 pair_yuv, yuv;
 
-		if (cvt->dst.fb->width & 1) {
-			/* Convert 1x2 pixel block */
-			struct igt_vec4 rgb[2];
-			struct igt_vec4 yuv[2];
+			read_rgb(&rgb, rgb_tmp);
+			yuv = igt_matrix_transform(&m, &rgb);
 
-			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
-			read_rgb(&rgb[1], &rgb24[j * 8 + 0 + rgb24_stride]);
+			rgb_tmp += bpp;
 
-			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
-			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
+			*y_tmp = yuv.d[0];
+			y_tmp += params.y_inc;
 
-			y[j * 2 + 0] = yuv[0].d[0];
-			y[j * 2 + 0 + planar_stride] = yuv[1].d[0];
+			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
+				continue;
 
 			/*
 			 * We assume the MPEG2 chroma siting convention, where
 			 * pixel center for Cb'Cr' is between the left top and
 			 * bottom pixel in a 2x2 block, so take the average.
+			 *
+			 * Therefore, if we use subsampling, we only really care
+			 * about two pixels all the time, either the two
+			 * subsequent pixels horizontally, vertically, or the
+			 * two corners in a 2x2 block.
+			 *
+			 * The only corner case is when we have an odd number of
+			 * pixels, but this can be handled pretty easily by not
+			 * incrementing the paired pixel pointer in the
+			 * direction it's odd in.
 			 */
-			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
-			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
-		}
-
-		rgb24 += 2 * rgb24_stride;
-		y += 2 * planar_stride;
-		uv += planar_stride;
-	}
-
-	/* Last row cannot be interpolated between 2 pixels, take the single value */
-	if (cvt->dst.fb->height & 1) {
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x1 pixel blocks */
-			struct igt_vec4 rgb[2];
-			struct igt_vec4 yuv[2];
-
-			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
-			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
-
-			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
-			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
+			if (j != (cvt->dst.fb->width - 1))
+				pair_rgb24 += (dst_fmt->hsub - 1) * bpp;
 
-			y[j * 2 + 0] = yuv[0].d[0];
-			y[j * 2 + 1] = yuv[1].d[0];
-			uv[j * 2 + 0] = yuv[0].d[1];
-			uv[j * 2 + 1] = yuv[0].d[2];
-		}
-
-		if (cvt->dst.fb->width & 1) {
-			/* Convert single pixel */
-			struct igt_vec4 rgb;
-			struct igt_vec4 yuv;
+			if (i != (cvt->dst.fb->height - 1))
+				pair_rgb24 += rgb24_stride * (dst_fmt->vsub - 1);
 
-			read_rgb(&rgb, &rgb24[j * 8 + 0]);
+			read_rgb(&pair_rgb, pair_rgb24);
+			pair_yuv = igt_matrix_transform(&m, &pair_rgb);
 
-			yuv = igt_matrix_transform(&m, &rgb);
+			*u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
+			*v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
 
-			y[j * 2 + 0] = yuv.d[0];
-			uv[j * 2 + 0] = yuv.d[1];
-			uv[j * 2 + 1] = yuv.d[2];
-		}
-	}
-}
-
-/* { Y0, U, Y1, V } */
-static const unsigned char swizzle_yuyv[] = { 0, 1, 2, 3 };
-static const unsigned char swizzle_yvyu[] = { 0, 3, 2, 1 };
-static const unsigned char swizzle_uyvy[] = { 1, 0, 3, 2 };
-static const unsigned char swizzle_vyuy[] = { 1, 2, 3, 0 };
-
-static const unsigned char *yuyv_swizzle(uint32_t format)
-{
-	switch (format) {
-	default:
-	case DRM_FORMAT_YUYV:
-		return swizzle_yuyv;
-	case DRM_FORMAT_YVYU:
-		return swizzle_yvyu;
-	case DRM_FORMAT_UYVY:
-		return swizzle_uyvy;
-	case DRM_FORMAT_VYUY:
-		return swizzle_vyuy;
-	}
-}
-
-static void convert_yuyv_to_rgb24(struct fb_convert *cvt)
-{
-	int i, j;
-	const uint8_t *yuyv;
-	uint8_t *rgb24 = cvt->dst.ptr;
-	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
-	unsigned int yuyv_stride = cvt->src.fb->strides[0];
-	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
-						    cvt->src.fb->color_range);
-	const unsigned char *swz = yuyv_swizzle(cvt->src.fb->drm_format);
-	uint8_t *buf;
-
-	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_YUYV ||
-		    cvt->src.fb->drm_format == DRM_FORMAT_UYVY ||
-		    cvt->src.fb->drm_format == DRM_FORMAT_YVYU ||
-		    cvt->src.fb->drm_format == DRM_FORMAT_VYUY) &&
-		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
-
-	buf = convert_src_get(cvt);
-	yuyv = buf;
-
-	for (i = 0; i < cvt->dst.fb->height; i++) {
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x1 pixel blocks */
-			struct igt_vec4 yuv[2];
-			struct igt_vec4 rgb[2];
-
-			yuv[0].d[0] = yuyv[j * 4 + swz[0]];
-			yuv[1].d[0] = yuyv[j * 4 + swz[2]];
-			yuv[0].d[1] = yuv[1].d[1] = yuyv[j * 4 + swz[1]];
-			yuv[0].d[2] = yuv[1].d[2] = yuyv[j * 4 + swz[3]];
-			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
-
-			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
-			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
-
-			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
-			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
-		}
-
-		if (cvt->dst.fb->width & 1) {
-			struct igt_vec4 yuv;
-			struct igt_vec4 rgb;
-
-			yuv.d[0] = yuyv[j * 4 + swz[0]];
-			yuv.d[1] = yuyv[j * 4 + swz[1]];
-			yuv.d[2] = yuyv[j * 4 + swz[3]];
-			yuv.d[3] = 1.0f;
-
-			rgb = igt_matrix_transform(&m, &yuv);
-
-			write_rgb(&rgb24[j * 8 + 0], &rgb);
+			u_tmp += params.uv_inc;
+			v_tmp += params.uv_inc;
 		}
 
 		rgb24 += rgb24_stride;
-		yuyv += yuyv_stride;
-	}
-
-	convert_src_put(cvt, buf);
-}
-
-static void convert_rgb24_to_yuyv(struct fb_convert *cvt)
-{
-	int i, j;
-	uint8_t *yuyv = cvt->dst.ptr;
-	const uint8_t *rgb24 = cvt->src.ptr;
-	unsigned rgb24_stride = cvt->src.fb->strides[0];
-	unsigned yuyv_stride = cvt->dst.fb->strides[0];
-	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
-						    cvt->dst.fb->color_range);
-	const unsigned char *swz = yuyv_swizzle(cvt->dst.fb->drm_format);
-
-	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
-		   (cvt->dst.fb->drm_format == DRM_FORMAT_YUYV ||
-		    cvt->dst.fb->drm_format == DRM_FORMAT_UYVY ||
-		    cvt->dst.fb->drm_format == DRM_FORMAT_YVYU ||
-		    cvt->dst.fb->drm_format == DRM_FORMAT_VYUY));
-
-	for (i = 0; i < cvt->dst.fb->height; i++) {
-		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
-			/* Convert 2x1 pixel blocks */
-			struct igt_vec4 rgb[2];
-			struct igt_vec4 yuv[2];
-
-			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
-			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
-
-			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
-			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
+		y += params.y_stride;
 
-			yuyv[j * 4 + swz[0]] = yuv[0].d[0];
-			yuyv[j * 4 + swz[2]] = yuv[1].d[0];
-			yuyv[j * 4 + swz[1]] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
-			yuyv[j * 4 + swz[3]] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
+		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
+			u += params.uv_stride;
+			v += params.uv_stride;
 		}
-
-		if (cvt->dst.fb->width & 1) {
-			struct igt_vec4 rgb;
-			struct igt_vec4 yuv;
-
-			read_rgb(&rgb, &rgb24[j * 8 + 0]);
-
-			yuv = igt_matrix_transform(&m, &rgb);
-
-			yuyv[j * 4 + swz[0]] = yuv.d[0];
-			yuyv[j * 4 + swz[1]] = yuv.d[1];
-			yuyv[j * 4 + swz[3]] = yuv.d[2];
-		}
-
-		rgb24 += rgb24_stride;
-		yuyv += yuyv_stride;
 	}
 }
 
@@ -2046,31 +1859,23 @@ static void fb_convert(struct fb_convert *cvt)
 	} else if (cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888) {
 		switch (cvt->src.fb->drm_format) {
 		case DRM_FORMAT_XYUV8888:
-			convert_yuv444_to_rgb24(cvt);
-			return;
 		case DRM_FORMAT_NV12:
-			convert_nv12_to_rgb24(cvt);
-			return;
-		case DRM_FORMAT_YUYV:
-		case DRM_FORMAT_YVYU:
 		case DRM_FORMAT_UYVY:
 		case DRM_FORMAT_VYUY:
-			convert_yuyv_to_rgb24(cvt);
+		case DRM_FORMAT_YUYV:
+		case DRM_FORMAT_YVYU:
+			convert_yuv_to_rgb24(cvt);
 			return;
 		}
 	} else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
 		switch (cvt->dst.fb->drm_format) {
 		case DRM_FORMAT_XYUV8888:
-			convert_rgb24_to_yuv444(cvt);
-			return;
 		case DRM_FORMAT_NV12:
-			convert_rgb24_to_nv12(cvt);
-			return;
 		case DRM_FORMAT_YUYV:
 		case DRM_FORMAT_YVYU:
 		case DRM_FORMAT_UYVY:
 		case DRM_FORMAT_VYUY:
-			convert_rgb24_to_yuyv(cvt);
+			convert_rgb24_to_yuv(cvt);
 			return;
 		}
 	}
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (2 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 19:43   ` Lyude Paul
  2019-02-05 12:53   ` Paul Kocialkowski
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path Maxime Ripard
                   ` (9 subsequent siblings)
  13 siblings, 2 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The YUV buffer allocation path for the i915 driver also has some code to
clear a YUV buffer.

As that is going to be useful for all the other drivers, let's move it to
a separate function.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 80 +++++++++++++++++++++++++++-------------------------
 1 file changed, 42 insertions(+), 38 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 45691fd441d9..d69c3fb2d38d 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -484,6 +484,47 @@ uint64_t igt_fb_tiling_to_mod(uint64_t tiling)
 	}
 }
 
+static void clear_yuv_buffer(struct igt_fb *fb)
+{
+	bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
+	void *ptr;
+
+	igt_assert(igt_format_is_yuv(fb->drm_format));
+
+	/* Ensure the framebuffer is preallocated */
+	ptr = igt_fb_map_buffer(fb->fd, fb);
+	igt_assert(*(uint32_t *)ptr == 0);
+
+	switch (fb->drm_format) {
+	case DRM_FORMAT_NV12:
+		memset(ptr + fb->offsets[0],
+		       full_range ? 0x00 : 0x10,
+		       fb->strides[0] * fb->plane_height[0]);
+		memset(ptr + fb->offsets[1],
+		       0x80,
+		       fb->strides[1] * fb->plane_height[1]);
+		break;
+	case DRM_FORMAT_XYUV8888:
+		wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 : 0x00108080,
+			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
+		break;
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_YVYU:
+		wmemset(ptr + fb->offsets[0],
+			full_range ? 0x80008000 : 0x80108010,
+			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
+		break;
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+		wmemset(ptr + fb->offsets[0],
+			full_range ? 0x00800080 : 0x10801080,
+			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
+		break;
+	}
+
+	igt_fb_unmap_buffer(fb, ptr);
+}
+
 /* helpers to create nice-looking framebuffers */
 static int create_bo_for_fb(struct igt_fb *fb)
 {
@@ -501,50 +542,13 @@ static int create_bo_for_fb(struct igt_fb *fb)
 		fb->is_dumb = false;
 
 		if (is_i915_device(fd)) {
-			void *ptr;
-			bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
 
 			fb->gem_handle = gem_create(fd, fb->size);
 
 			gem_set_tiling(fd, fb->gem_handle,
 				       igt_fb_mod_to_tiling(fb->tiling),
 				       fb->strides[0]);
-
-			gem_set_domain(fd, fb->gem_handle,
-				       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
-
-			/* Ensure the framebuffer is preallocated */
-			ptr = gem_mmap__gtt(fd, fb->gem_handle,
-					    fb->size, PROT_READ | PROT_WRITE);
-			igt_assert(*(uint32_t *)ptr == 0);
-
-			switch (fb->drm_format) {
-			case DRM_FORMAT_NV12:
-				memset(ptr + fb->offsets[0],
-				       full_range ? 0x00 : 0x10,
-				       fb->strides[0] * fb->plane_height[0]);
-				memset(ptr + fb->offsets[1],
-				       0x80,
-				       fb->strides[1] * fb->plane_height[1]);
-				break;
-			case DRM_FORMAT_XYUV8888:
-				wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 : 0x00108080,
-					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
-				break;
-			case DRM_FORMAT_YUYV:
-			case DRM_FORMAT_YVYU:
-				wmemset(ptr + fb->offsets[0],
-					full_range ? 0x80008000 : 0x80108010,
-					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
-				break;
-			case DRM_FORMAT_UYVY:
-			case DRM_FORMAT_VYUY:
-				wmemset(ptr + fb->offsets[0],
-					full_range ? 0x00800080 : 0x10801080,
-					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
-				break;
-			}
-			gem_munmap(ptr, fb->size);
+			clear_yuv_buffer(fd);
 
 			return fb->gem_handle;
 		} else {
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (3 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-25 16:16   ` Deepak Singh Rawat
  2019-01-29 19:46   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 06/13] igt: fb: Account for all planes bpp Maxime Ripard
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The else condition is not needed, since all the other conditions return
when they are done.

Move the KMS dumb buffer allocation outside of the outer else condition,
this will also allow to ease later changes.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index d69c3fb2d38d..270db8d6dc90 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -557,15 +557,24 @@ static int create_bo_for_fb(struct igt_fb *fb)
 			igt_require(driver_has_gem_api);
 			return -EINVAL;
 		}
-	} else {
-		fb->is_dumb = true;
-
-		fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
-						     fb->plane_bpp[0],
-						     &fb->strides[0], &fb->size);
-
-		return fb->gem_handle;
 	}
+
+	/*
+	 * The current dumb buffer allocation API doesn't really allow to
+	 * specify a custom size or stride. Yet the caller is free to specify
+	 * them, so we need to make sure to error out in this case.
+	 */
+	igt_assert(fb->size == 0);
+	igt_assert(fb->strides[0] == 0);
+
+	fb->size = calc_fb_size(fb);
+
+	fb->is_dumb = true;
+	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
+					     fb->plane_bpp[0],
+					     &fb->strides[0], &fb->size);
+
+	return fb->gem_handle;
 }
 
 /**
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 06/13] igt: fb: Account for all planes bpp
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (4 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer Maxime Ripard
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

When allocating a dumb buffer for a format with multiple plane, we need to
account for all plane's bpp in order to allocate the proper size.

Let's add all the planes bpp and use the result to allocate our buffer.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 270db8d6dc90..1c52aebb674e 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -528,6 +528,8 @@ static void clear_yuv_buffer(struct igt_fb *fb)
 /* helpers to create nice-looking framebuffers */
 static int create_bo_for_fb(struct igt_fb *fb)
 {
+	const struct format_desc_struct *fmt = lookup_drm_format(fb->drm_format);
+	unsigned int plane, bpp;
 	int fd = fb->fd;
 
 	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format)) {
@@ -568,11 +570,13 @@ static int create_bo_for_fb(struct igt_fb *fb)
 	igt_assert(fb->strides[0] == 0);
 
 	fb->size = calc_fb_size(fb);
+	for (plane = 0; plane < fb->num_planes; plane++)
+		bpp += DIV_ROUND_UP(fb->plane_bpp[plane],
+				    plane ? fmt->hsub * fmt->vsub : 1);
 
 	fb->is_dumb = true;
 	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
-					     fb->plane_bpp[0],
-					     &fb->strides[0], &fb->size);
+					     bpp, &fb->strides[0], &fb->size);
 
 	return fb->gem_handle;
 }
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (5 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 06/13] igt: fb: Account for all planes bpp Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:08   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers Maxime Ripard
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The dumb buffer allocation API only considers a single plane, and even
though allocating multi-planar buffers through it is allowed, the stride it
gives back is the the width times the bpp passed as an argument.

That doesn't work in our case, since the bpp is going to be the one we give
as an argument, but split over three planes so the stride doesn't match
anymore.

A proper fix for this would be to have a better dumb buffer allocation API,
but for the time being, let's do it that way.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 1c52aebb674e..048d274e5d36 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -530,6 +530,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
 {
 	const struct format_desc_struct *fmt = lookup_drm_format(fb->drm_format);
 	unsigned int plane, bpp;
+	unsigned *strides = &fb->strides[0];
 	int fd = fb->fd;
 
 	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format)) {
@@ -575,8 +576,22 @@ static int create_bo_for_fb(struct igt_fb *fb)
 				    plane ? fmt->hsub * fmt->vsub : 1);
 
 	fb->is_dumb = true;
+
+	/*
+	 * We can't really pass the stride array here since the dumb
+	 * buffer allocation is assuming that it operates on one
+	 * plane, and therefore will calculate the stride as if each
+	 * pixels were stored on a single plane.
+	 *
+	 * This might cause issues at some point on drivers that would
+	 * change the stride of YUV buffers, but we haven't
+	 * encountered any yet.
+	 */
+	if (fb->num_planes > 1)
+		strides = NULL;
+
 	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
-					     bpp, &fb->strides[0], &fb->size);
+					     bpp, strides, &fb->size);
 
 	return fb->gem_handle;
 }
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (6 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:08   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

YUV dumb buffers, just like i915 GEM buffers also need to be cleared once
allocated. Make sure it happens.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 048d274e5d36..65aa99ecf7ae 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -593,6 +593,9 @@ static int create_bo_for_fb(struct igt_fb *fb)
 	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
 					     bpp, strides, &fb->size);
 
+	if (igt_format_is_yuv(fb->drm_format))
+		clear_yuv_buffer(fb);
+
 	return fb->gem_handle;
 }
 
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (7 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-25 15:34   ` Paul Kocialkowski
                     ` (2 more replies)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats Maxime Ripard
                   ` (4 subsequent siblings)
  13 siblings, 3 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

We only need to allocate a buffer using the GEM API when we're in the
condition that we currently test, and that we're running on i915.

All the other cases can be handled by a fallback to a dumb buffer
allocation. Let's simplify the code a bit to reflect that.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 65aa99ecf7ae..43e527d1a3dd 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -533,7 +533,8 @@ static int create_bo_for_fb(struct igt_fb *fb)
 	unsigned *strides = &fb->strides[0];
 	int fd = fb->fd;
 
-	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format)) {
+	if (is_i915_device(fd) &&
+	   (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format))) {
 		uint64_t size;
 
 		size = calc_fb_size(fb);
@@ -543,23 +544,12 @@ static int create_bo_for_fb(struct igt_fb *fb)
 			fb->size = size;
 
 		fb->is_dumb = false;
+		fb->gem_handle = gem_create(fd, fb->size);
+		gem_set_tiling(fd, fb->gem_handle,
+			       igt_fb_mod_to_tiling(fb->tiling),
+			       fb->strides[0]);
 
-		if (is_i915_device(fd)) {
-
-			fb->gem_handle = gem_create(fd, fb->size);
-
-			gem_set_tiling(fd, fb->gem_handle,
-				       igt_fb_mod_to_tiling(fb->tiling),
-				       fb->strides[0]);
-			clear_yuv_buffer(fd);
-
-			return fb->gem_handle;
-		} else {
-			bool driver_has_gem_api = false;
-
-			igt_require(driver_has_gem_api);
-			return -EINVAL;
-		}
+		goto out;
 	}
 
 	/*
@@ -593,6 +583,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
 	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
 					     bpp, strides, &fb->size);
 
+out:
 	if (igt_format_is_yuv(fb->drm_format))
 		clear_yuv_buffer(fb);
 
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (8 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:11   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests Maxime Ripard
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Thanks to the previous reworks, we can now add new YUV formats pretty
easily. This patch adds support for the NV12, NV16, NV21, NV61, YUV420,
YVU420, YUV422 and YVU422 formats.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 lib/igt_fb.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 98 insertions(+), 2 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 43e527d1a3dd..7ed1397c08fa 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -150,6 +150,21 @@ static const struct format_desc_struct {
 	  .num_planes = 2, .plane_bpp = { 8, 16, },
 	  .hsub = 2, .vsub = 2,
 	},
+	{ .name = "NV16", .depth = -1, .drm_id = DRM_FORMAT_NV16,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 2, .plane_bpp = { 8, 16, },
+	  .hsub = 2, .vsub = 1,
+	},
+	{ .name = "NV21", .depth = -1, .drm_id = DRM_FORMAT_NV21,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 2, .plane_bpp = { 8, 16, },
+	  .hsub = 2, .vsub = 2,
+	},
+	{ .name = "NV61", .depth = -1, .drm_id = DRM_FORMAT_NV61,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 2, .plane_bpp = { 8, 16, },
+	  .hsub = 2, .vsub = 1,
+	},
 	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 16, },
@@ -170,6 +185,26 @@ static const struct format_desc_struct {
 	  .num_planes = 1, .plane_bpp = { 16, },
 	  .hsub = 2, .vsub = 1,
 	},
+	{ .name = "YU12", .depth = -1, .drm_id = DRM_FORMAT_YUV420,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
+	  .hsub = 2, .vsub = 2,
+	},
+	{ .name = "YU16", .depth = -1, .drm_id = DRM_FORMAT_YUV422,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
+	  .hsub = 2, .vsub = 1,
+	},
+	{ .name = "YV12", .depth = -1, .drm_id = DRM_FORMAT_YVU420,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
+	  .hsub = 2, .vsub = 2,
+	},
+	{ .name = "YV16", .depth = -1, .drm_id = DRM_FORMAT_YVU422,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
+	  .hsub = 2, .vsub = 1,
+	},
 };
 #define for_each_format(f)	\
 	for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
@@ -1619,10 +1654,21 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 
 	switch (fb->drm_format) {
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV61:
 		params->y_inc = 1;
 		params->uv_inc = 2;
 		break;
 
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YUV422:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YVU422:
+		params->y_inc = 1;
+		params->uv_inc = 1;
+		break;
+
 	case DRM_FORMAT_YUYV:
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
@@ -1639,6 +1685,13 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 
 	switch (fb->drm_format) {
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV61:
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YUV422:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YVU422:
 		params->y_stride = fb->strides[0];
 		params->uv_stride = fb->strides[1];
 		break;
@@ -1655,11 +1708,33 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 
 	switch (fb->drm_format) {
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
 		params->y_offset = fb->offsets[0];
 		params->u_offset = fb->offsets[1];
 		params->v_offset = fb->offsets[1] + 1;
 		break;
 
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV61:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[1] + 1;
+		params->v_offset = fb->offsets[1];
+		break;
+
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YUV422:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[1];
+		params->v_offset = fb->offsets[2];
+		break;
+
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YVU422:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[2];
+		params->v_offset = fb->offsets[1];
+		break;
+
 	case DRM_FORMAT_YUYV:
 		params->y_offset = fb->offsets[0];
 		params->u_offset = fb->offsets[0] + 1;
@@ -1886,9 +1961,16 @@ static void fb_convert(struct fb_convert *cvt)
 		switch (cvt->src.fb->drm_format) {
 		case DRM_FORMAT_XYUV8888:
 		case DRM_FORMAT_NV12:
+		case DRM_FORMAT_NV16:
+		case DRM_FORMAT_NV21:
+		case DRM_FORMAT_NV61:
 		case DRM_FORMAT_UYVY:
 		case DRM_FORMAT_VYUY:
+		case DRM_FORMAT_YUV420:
+		case DRM_FORMAT_YUV422:
 		case DRM_FORMAT_YUYV:
+		case DRM_FORMAT_YVU420:
+		case DRM_FORMAT_YVU422:
 		case DRM_FORMAT_YVYU:
 			convert_yuv_to_rgb24(cvt);
 			return;
@@ -1897,10 +1979,17 @@ static void fb_convert(struct fb_convert *cvt)
 		switch (cvt->dst.fb->drm_format) {
 		case DRM_FORMAT_XYUV8888:
 		case DRM_FORMAT_NV12:
-		case DRM_FORMAT_YUYV:
-		case DRM_FORMAT_YVYU:
+		case DRM_FORMAT_NV16:
+		case DRM_FORMAT_NV21:
+		case DRM_FORMAT_NV61:
 		case DRM_FORMAT_UYVY:
 		case DRM_FORMAT_VYUY:
+		case DRM_FORMAT_YUV420:
+		case DRM_FORMAT_YUV422:
+		case DRM_FORMAT_YUYV:
+		case DRM_FORMAT_YVU420:
+		case DRM_FORMAT_YVU422:
+		case DRM_FORMAT_YVYU:
 			convert_rgb24_to_yuv(cvt);
 			return;
 		}
@@ -2247,6 +2336,13 @@ bool igt_format_is_yuv(uint32_t drm_format)
 {
 	switch (drm_format) {
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV61:
+	case DRM_FORMAT_YUV420:
+	case DRM_FORMAT_YUV422:
+	case DRM_FORMAT_YVU420:
+	case DRM_FORMAT_YVU422:
 	case DRM_FORMAT_YUYV:
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (9 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:13   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display Maxime Ripard
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The various tests in kms_chamelium are really variants of one another
but share little code.

In addition to the duplication, this gets in the way of the
introduction of more tests, or to be able to run all the tests on all
the output, which isn't the case at the moment, with the HDMI and DP
tests and the VGA tests being different.

Start by introducing a check parameter to the do_test_display
function, that will tell which test method we want to use to compare
the frames.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 tests/kms_chamelium.c | 134 +++++++++++++++++++++++-------------------
 1 file changed, 73 insertions(+), 61 deletions(-)

diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 2d848c2f0620..8230cb852cfb 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -527,12 +527,15 @@ static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
 	return fb_id;
 }
 
-static void do_test_display_crc(data_t *data, struct chamelium_port *port,
-				igt_output_t *output, drmModeModeInfo *mode,
-				uint32_t fourcc, int count)
+enum chamelium_check {
+	CHAMELIUM_CHECK_CRC,
+};
+
+static void do_test_display(data_t *data, struct chamelium_port *port,
+			    igt_output_t *output, drmModeModeInfo *mode,
+			    uint32_t fourcc, enum chamelium_check check,
+			    int count)
 {
-	igt_crc_t *crc;
-	igt_crc_t *expected_crc;
 	struct chamelium_fb_crc_async_data *fb_crc;
 	struct igt_fb frame_fb, fb;
 	int i, fb_id, captured_frame_count;
@@ -545,39 +548,46 @@ static void do_test_display_crc(data_t *data, struct chamelium_port *port,
 	frame_id = igt_fb_convert(&frame_fb, &fb, fourcc);
 	igt_assert(frame_id > 0);
 
-	fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
-							&fb);
+	if (check == CHAMELIUM_CHECK_CRC)
+		fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
+								&fb);
 
 	enable_output(data, port, output, mode, &frame_fb);
 
-	/* We want to keep the display running for a little bit, since
-	 * there's always the potential the driver isn't able to keep
-	 * the display running properly for very long
-	 */
-	chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
-	crc = chamelium_read_captured_crcs(data->chamelium,
-					   &captured_frame_count);
+	if (check == CHAMELIUM_CHECK_CRC) {
+		igt_crc_t *expected_crc;
+		igt_crc_t *crc;
 
-	igt_assert(captured_frame_count == count);
+		/* We want to keep the display running for a little bit, since
+		 * there's always the potential the driver isn't able to keep
+		 * the display running properly for very long
+		 */
+		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
+		crc = chamelium_read_captured_crcs(data->chamelium,
+						   &captured_frame_count);
 
-	igt_debug("Captured %d frames\n", captured_frame_count);
+		igt_assert(captured_frame_count == count);
 
-	expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
+		igt_debug("Captured %d frames\n", captured_frame_count);
 
-	for (i = 0; i < captured_frame_count; i++)
-		chamelium_assert_crc_eq_or_dump(data->chamelium,
-						expected_crc, &crc[i],
-						&fb, i);
+		expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
 
-	free(expected_crc);
-	free(crc);
+		for (i = 0; i < captured_frame_count; i++)
+			chamelium_assert_crc_eq_or_dump(data->chamelium,
+							expected_crc, &crc[i],
+							&fb, i);
+
+		free(expected_crc);
+		free(crc);
+	}
 
 	igt_remove_fb(data->drm_fd, &frame_fb);
 	igt_remove_fb(data->drm_fd, &fb);
 }
 
-static void test_display_crc_one_mode(data_t *data, struct chamelium_port *port,
-				      uint32_t fourcc, int count)
+static void test_display_one_mode(data_t *data, struct chamelium_port *port,
+				  uint32_t fourcc, enum chamelium_check check,
+				  int count)
 {
 	igt_output_t *output;
 	drmModeConnector *connector;
@@ -590,13 +600,15 @@ static void test_display_crc_one_mode(data_t *data, struct chamelium_port *port,
 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
 	igt_assert(primary);
 
-	do_test_display_crc(data, port, output, &connector->modes[0], fourcc, count);
+	do_test_display(data, port, output, &connector->modes[0], fourcc,
+			check, count);
 
 	drmModeFreeConnector(connector);
 }
 
-static void test_display_crc_all_modes(data_t *data, struct chamelium_port *port,
-				       uint32_t fourcc, int count)
+static void test_display_all_modes(data_t *data, struct chamelium_port *port,
+				   uint32_t fourcc, enum chamelium_check check,
+				   int count)
 {
 	igt_output_t *output;
 	igt_plane_t *primary;
@@ -613,7 +625,7 @@ static void test_display_crc_all_modes(data_t *data, struct chamelium_port *port
 	for (i = 0; i < connector->count_modes; i++) {
 		drmModeModeInfo *mode = &connector->modes[i];
 
-		do_test_display_crc(data, port, output, mode, fourcc, count);
+		do_test_display(data, port, output, mode, fourcc, check, count);
 	}
 
 	drmModeFreeConnector(connector);
@@ -874,16 +886,16 @@ igt_main
 							edid_id, alt_edid_id);
 
 		connector_subtest("dp-crc-single", DisplayPort)
-			test_display_crc_all_modes(&data, port,
-						   DRM_FORMAT_XRGB8888, 1);
+			test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
+					       CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("dp-crc-fast", DisplayPort)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_XRGB8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("dp-crc-multiple", DisplayPort)
-			test_display_crc_all_modes(&data, port,
-						   DRM_FORMAT_XRGB8888, 3);
+			test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
+					       CHAMELIUM_CHECK_CRC, 3);
 
 		connector_subtest("dp-frame-dump", DisplayPort)
 			test_display_frame_dump(&data, port);
@@ -941,56 +953,56 @@ igt_main
 							edid_id, alt_edid_id);
 
 		connector_subtest("hdmi-crc-single", HDMIA)
-			test_display_crc_all_modes(&data, port,
-						   DRM_FORMAT_XRGB8888, 1);
+			test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
+					       CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-fast", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_XRGB8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-multiple", HDMIA)
-			test_display_crc_all_modes(&data, port,
-						   DRM_FORMAT_XRGB8888, 3);
+			test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
+					       CHAMELIUM_CHECK_CRC, 3);
 
 		connector_subtest("hdmi-crc-argb8888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_ARGB8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_ARGB8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-abgr8888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_ABGR8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_ABGR8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-xrgb8888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_XRGB8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_XRGB8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-xbgr8888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_XBGR8888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_XBGR8888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-rgb888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_RGB888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_RGB888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-bgr888", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_BGR888, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_BGR888,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-rgb565", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_RGB565, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_RGB565,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-bgr565", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_BGR565, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_BGR565,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-argb1555", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_ARGB1555, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_ARGB1555,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-crc-xrgb1555", HDMIA)
-			test_display_crc_one_mode(&data, port,
-						  DRM_FORMAT_XRGB1555, 1);
+			test_display_one_mode(&data, port, DRM_FORMAT_XRGB1555,
+					      CHAMELIUM_CHECK_CRC, 1);
 
 		connector_subtest("hdmi-frame-dump", HDMIA)
 			test_display_frame_dump(&data, port);
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (10 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:14   ` Lyude Paul
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests Maxime Ripard
  2019-01-25 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for igt: chamelium: Test YUV buffers using the Chamelium (rev7) Patchwork
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The VGA tests were run so far as part of a separate function. However,
the only difference between that function and the do_test_display
function was the kind of comparison we wanted to use. Indeed, VGA
being an analog output, we can't rely on a pixel perfect image, and
thus only compare the CRCs, but we need to make some more advanced
comparison.

Let's add a new check method, add support for the analog check to
do_test_display and remove the old version.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 tests/kms_chamelium.c | 92 ++++++++++++++++---------------------------
 1 file changed, 33 insertions(+), 59 deletions(-)

diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 8230cb852cfb..eaea9c18832a 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -528,6 +528,7 @@ static int chamelium_get_pattern_fb(data_t *data, size_t width, size_t height,
 }
 
 enum chamelium_check {
+	CHAMELIUM_CHECK_ANALOG,
 	CHAMELIUM_CHECK_CRC,
 };
 
@@ -579,6 +580,18 @@ static void do_test_display(data_t *data, struct chamelium_port *port,
 
 		free(expected_crc);
 		free(crc);
+	} else if (check == CHAMELIUM_CHECK_ANALOG) {
+		struct chamelium_frame_dump *dump;
+
+		igt_assert(count == 1);
+
+		dump = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
+						  0, 0);
+		chamelium_crop_analog_frame(dump, mode->hdisplay,
+					    mode->vdisplay);
+		chamelium_assert_analog_frame_match_or_dump(data->chamelium,
+							    port, dump, &fb);
+		chamelium_destroy_frame_dump(dump);
 	}
 
 	igt_remove_fb(data->drm_fd, &frame_fb);
@@ -589,8 +602,9 @@ static void test_display_one_mode(data_t *data, struct chamelium_port *port,
 				  uint32_t fourcc, enum chamelium_check check,
 				  int count)
 {
-	igt_output_t *output;
 	drmModeConnector *connector;
+	drmModeModeInfo *mode;
+	igt_output_t *output;
 	igt_plane_t *primary;
 
 	reset_state(data, port);
@@ -600,8 +614,14 @@ static void test_display_one_mode(data_t *data, struct chamelium_port *port,
 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
 	igt_assert(primary);
 
-	do_test_display(data, port, output, &connector->modes[0], fourcc,
-			check, count);
+	mode = &connector->modes[0];
+	if (check == CHAMELIUM_CHECK_ANALOG) {
+		bool bridge = check_analog_bridge(data, port);
+
+		igt_assert(!(bridge && prune_vga_mode(data, mode)));
+	}
+
+	do_test_display(data, port, output, mode, fourcc, check, count);
 
 	drmModeFreeConnector(connector);
 }
@@ -613,6 +633,7 @@ static void test_display_all_modes(data_t *data, struct chamelium_port *port,
 	igt_output_t *output;
 	igt_plane_t *primary;
 	drmModeConnector *connector;
+	bool bridge;
 	int i;
 
 	reset_state(data, port);
@@ -622,9 +643,16 @@ static void test_display_all_modes(data_t *data, struct chamelium_port *port,
 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
 	igt_assert(primary);
 
+	if (check == CHAMELIUM_CHECK_ANALOG)
+		bridge = check_analog_bridge(data, port);
+
 	for (i = 0; i < connector->count_modes; i++) {
 		drmModeModeInfo *mode = &connector->modes[i];
 
+		if (check == CHAMELIUM_CHECK_ANALOG && bridge &&
+		    prune_vga_mode(data, mode))
+			continue;
+
 		do_test_display(data, port, output, mode, fourcc, check, count);
 	}
 
@@ -675,61 +703,6 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
 	drmModeFreeConnector(connector);
 }
 
-static void
-test_analog_frame_dump(data_t *data, struct chamelium_port *port)
-{
-	igt_output_t *output;
-	igt_plane_t *primary;
-	struct igt_fb fb;
-	struct chamelium_frame_dump *frame;
-	drmModeModeInfo *mode;
-	drmModeConnector *connector;
-	int fb_id, i;
-	bool bridge;
-
-	reset_state(data, port);
-
-	output = prepare_output(data, port);
-	connector = chamelium_port_get_connector(data->chamelium, port, false);
-	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
-	igt_assert(primary);
-
-	bridge = check_analog_bridge(data, port);
-
-	for (i = 0; i < connector->count_modes; i++) {
-		mode = &connector->modes[i];
-
-		if (bridge && prune_vga_mode(data, mode))
-			continue;
-
-		fb_id = igt_create_color_pattern_fb(data->drm_fd,
-						    mode->hdisplay, mode->vdisplay,
-						    DRM_FORMAT_XRGB8888,
-						    LOCAL_DRM_FORMAT_MOD_NONE,
-						    0, 0, 0, &fb);
-		igt_assert(fb_id > 0);
-
-		enable_output(data, port, output, mode, &fb);
-
-		igt_debug("Reading frame dumps from Chamelium...\n");
-
-		frame = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
-						   0, 0);
-
-		chamelium_crop_analog_frame(frame, mode->hdisplay,
-					    mode->vdisplay);
-
-		chamelium_assert_analog_frame_match_or_dump(data->chamelium,
-							    port, frame, &fb);
-
-		chamelium_destroy_frame_dump(frame);
-
-		igt_remove_fb(data->drm_fd, &fb);
-	}
-
-	drmModeFreeConnector(connector);
-}
-
 static void
 test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
 {
@@ -1041,7 +1014,8 @@ igt_main
 			test_hpd_without_ddc(&data, port);
 
 		connector_subtest("vga-frame-dump", VGA)
-			test_analog_frame_dump(&data, port);
+			test_display_all_modes(&data, port, DRM_FORMAT_XRGB8888,
+					       CHAMELIUM_CHECK_ANALOG, 1);
 	}
 
 	igt_subtest_group {
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (11 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display Maxime Ripard
@ 2019-01-25 14:58 ` Maxime Ripard
  2019-01-29 20:14   ` Lyude Paul
  2019-01-25 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for igt: chamelium: Test YUV buffers using the Chamelium (rev7) Patchwork
  13 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-25 14:58 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

The NV12, NV16, NV21, NV61, YUV420, YVU420, YUV422 and YVU422 are YUV
formats that are currently supported in IGT.

We'll want to test those formats in addition to the RGB formats, so
let's add some subtests. One thing worth noting is some hardware isn't
able to output a pixel-perfect image, so we do the same kind of
comparison than for VGA.

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 tests/kms_chamelium.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index eaea9c18832a..64f87d3ae474 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -977,6 +977,38 @@ igt_main
 			test_display_one_mode(&data, port, DRM_FORMAT_XRGB1555,
 					      CHAMELIUM_CHECK_CRC, 1);
 
+		connector_subtest("hdmi-cmp-nv12", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_NV12,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-nv16", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_NV16,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-nv21", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_NV21,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-nv61", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_NV61,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-yu12", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_YUV420,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-yu16", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_YUV422,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-yv12", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_YVU420,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
+		connector_subtest("hdmi-cmp-yv16", HDMIA)
+			test_display_one_mode(&data, port, DRM_FORMAT_YVU422,
+					      CHAMELIUM_CHECK_ANALOG, 1);
+
 		connector_subtest("hdmi-frame-dump", HDMIA)
 			test_display_frame_dump(&data, port);
 	}
-- 
2.20.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
@ 2019-01-25 15:34   ` Paul Kocialkowski
  2019-01-29 20:10   ` Lyude Paul
  2019-02-05  9:40   ` Paul Kocialkowski
  2 siblings, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-01-25 15:34 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> We only need to allocate a buffer using the GEM API when we're in the
> condition that we currently test, and that we're running on i915.
> 
> All the other cases can be handled by a fallback to a dumb buffer
> allocation. Let's simplify the code a bit to reflect that.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> ---
>  lib/igt_fb.c | 25 ++++++++-----------------
>  1 file changed, 8 insertions(+), 17 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 65aa99ecf7ae..43e527d1a3dd 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -533,7 +533,8 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	unsigned *strides = &fb->strides[0];
>  	int fd = fb->fd;
>  
> -	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format)) {
> +	if (is_i915_device(fd) &&
> +	   (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format))) {
>  		uint64_t size;
>  
>  		size = calc_fb_size(fb);
> @@ -543,23 +544,12 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  			fb->size = size;
>  
>  		fb->is_dumb = false;
> +		fb->gem_handle = gem_create(fd, fb->size);
> +		gem_set_tiling(fd, fb->gem_handle,
> +			       igt_fb_mod_to_tiling(fb->tiling),
> +			       fb->strides[0]);
>  
> -		if (is_i915_device(fd)) {
> -
> -			fb->gem_handle = gem_create(fd, fb->size);
> -
> -			gem_set_tiling(fd, fb->gem_handle,
> -				       igt_fb_mod_to_tiling(fb->tiling),
> -				       fb->strides[0]);
> -			clear_yuv_buffer(fd);
> -
> -			return fb->gem_handle;
> -		} else {
> -			bool driver_has_gem_api = false;
> -
> -			igt_require(driver_has_gem_api);
> -			return -EINVAL;
> -		}
> +		goto out;
>  	}
>  
>  	/*
> @@ -593,6 +583,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
>  					     bpp, strides, &fb->size);
>  
> +out:
>  	if (igt_format_is_yuv(fb->drm_format))
>  		clear_yuv_buffer(fb);
>  
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [igt-dev] ✗ Fi.CI.BAT: failure for igt: chamelium: Test YUV buffers using the Chamelium (rev7)
  2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
                   ` (12 preceding siblings ...)
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests Maxime Ripard
@ 2019-01-25 15:50 ` Patchwork
  13 siblings, 0 replies; 40+ messages in thread
From: Patchwork @ 2019-01-25 15:50 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: igt-dev

== Series Details ==

Series: igt: chamelium: Test YUV buffers using the Chamelium (rev7)
URL   : https://patchwork.freedesktop.org/series/53468/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_5484 -> IGTPW_2294
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_2294 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_2294, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/53468/revisions/7/mbox/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_2294:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_addfb_basic@addfb25-y-tiled-small:
    - fi-kbl-r:           PASS -> FAIL +37

  * igt@kms_addfb_basic@bo-too-small:
    - fi-cfl-guc:         PASS -> FAIL +31
    - fi-skl-gvtdvm:      PASS -> FAIL +33
    - fi-kbl-7567u:       PASS -> FAIL +3

  * igt@kms_addfb_basic@bo-too-small-due-to-tiling:
    - fi-apl-guc:         PASS -> FAIL +31
    - fi-kbl-guc:         PASS -> FAIL +3
    - fi-kbl-8809g:       PASS -> FAIL +3

  * igt@kms_addfb_basic@too-high:
    - fi-glk-j4005:       PASS -> FAIL +36
    - fi-gdg-551:         PASS -> FAIL +24

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-hsw-4770r:       PASS -> FAIL +35
    - fi-cfl-8700k:       PASS -> FAIL +36

  * igt@kms_cursor_legacy@basic-flip-after-cursor-varying-size:
    - fi-skl-guc:         PASS -> FAIL +32
    - fi-whl-u:           PASS -> FAIL +37

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - fi-snb-2520m:       PASS -> FAIL +28

  * igt@kms_cursor_legacy@basic-flip-before-cursor-varying-size:
    - fi-bsw-n3050:       NOTRUN -> FAIL +23
    - fi-skl-6700k2:      PASS -> FAIL +37
    - fi-hsw-4770:        PASS -> FAIL +36

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-ilk-650:         PASS -> FAIL +28
    - fi-pnv-d510:        PASS -> FAIL +24
    - fi-skl-6770hq:      PASS -> FAIL +36

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-kbl-x1275:       PASS -> FAIL +36

  * igt@kms_flip@basic-flip-vs-wf_vblank:
    - fi-hsw-peppy:       PASS -> FAIL +36
    - fi-skl-6260u:       PASS -> FAIL +36

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-b:
    - fi-bxt-j4205:       PASS -> FAIL +36
    - fi-skl-6700hq:      PASS -> FAIL +37

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a:
    - fi-ivb-3520m:       PASS -> FAIL +34

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-a-frame-sequence:
    - fi-elk-e7500:       PASS -> FAIL +24
    - fi-byt-n2820:       PASS -> FAIL +28

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-b:
    - fi-bdw-5557u:       PASS -> FAIL +35

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-b-frame-sequence:
    - fi-bdw-gvtdvm:      PASS -> FAIL +32

  * igt@kms_pipe_crc_basic@read-crc-pipe-a:
    - fi-bwr-2160:        PASS -> FAIL +24

  * igt@kms_pipe_crc_basic@read-crc-pipe-b:
    - fi-byt-clapper:     PASS -> FAIL +29
    - fi-cfl-8109u:       PASS -> FAIL +37

  * igt@pm_rpm@basic-pci-d3-state:
    - fi-kbl-7560u:       PASS -> FAIL +37
    - fi-byt-j1900:       PASS -> FAIL +29

  * igt@pm_rpm@basic-rte:
    - fi-skl-iommu:       PASS -> FAIL +36

  
#### Warnings ####

  * igt@pm_rpm@basic-pci-d3-state:
    - fi-pnv-d510:        {SKIP} [fdo#109271] -> FAIL +2
    - fi-gdg-551:         {SKIP} [fdo#109271] -> FAIL +2

  * igt@pm_rpm@basic-rte:
    - fi-skl-gvtdvm:      {SKIP} [fdo#109271] -> FAIL +2
    - fi-elk-e7500:       {SKIP} [fdo#109271] -> FAIL +2
    - fi-ilk-650:         {SKIP} [fdo#109271] -> FAIL +2
    - fi-bdw-gvtdvm:      {SKIP} [fdo#109271] -> FAIL +2
    - fi-snb-2520m:       {SKIP} [fdo#109271] -> FAIL +2
    - fi-bwr-2160:        {SKIP} [fdo#109271] -> FAIL +2

  * igt@pm_rpm@module-reload:
    - fi-ivb-3520m:       {SKIP} [fdo#109271] -> FAIL +2

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
    - {fi-icl-u3}:        PASS -> FAIL +38

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
    - {fi-icl-u2}:        PASS -> FAIL +38

  
Known issues
------------

  Here are the changes found in IGTPW_2294 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-blb-e6850:       PASS -> INCOMPLETE [fdo#107718]

  * igt@i915_module_load@reload:
    - fi-hsw-peppy:       PASS -> DMESG-WARN [fdo#102614]

  * igt@kms_chamelium@hdmi-crc-fast:
    - fi-skl-6700k2:      PASS -> FAIL [fdo#108767]
    - fi-kbl-7567u:       PASS -> FAIL [fdo#108767]

  * igt@pm_rpm@module-reload:
    - fi-byt-clapper:     PASS -> FAIL [fdo#108675]
    - fi-byt-j1900:       PASS -> FAIL [fdo#108675]
    - fi-byt-n2820:       PASS -> FAIL [fdo#108675]

  
#### Possible fixes ####

  * igt@kms_busy@basic-flip-b:
    - fi-gdg-551:         FAIL [fdo#103182] -> PASS

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103182]: https://bugs.freedesktop.org/show_bug.cgi?id=103182
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#108675]: https://bugs.freedesktop.org/show_bug.cgi?id=108675
  [fdo#108767]: https://bugs.freedesktop.org/show_bug.cgi?id=108767
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278


Participating hosts (44 -> 40)
------------------------------

  Additional (1): fi-bsw-n3050 
  Missing    (5): fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-kbl-7500u fi-ctg-p8600 


Build changes
-------------

    * IGT: IGT_4790 -> IGTPW_2294

  CI_DRM_5484: 9f66ac94341eb12501097f9f8991c86aee70981c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2294: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2294/
  IGT_4790: dcdf4b04e16312f8f52ad389388d834f9d74b8f0 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@kms_chamelium@hdmi-cmp-nv12
+igt@kms_chamelium@hdmi-cmp-nv16
+igt@kms_chamelium@hdmi-cmp-nv21
+igt@kms_chamelium@hdmi-cmp-nv61
+igt@kms_chamelium@hdmi-cmp-yu12
+igt@kms_chamelium@hdmi-cmp-yu16
+igt@kms_chamelium@hdmi-cmp-yv12
+igt@kms_chamelium@hdmi-cmp-yv16

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2294/
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path Maxime Ripard
@ 2019-01-25 16:16   ` Deepak Singh Rawat
  2019-01-30 14:18     ` Maxime Ripard
  2019-01-29 19:46   ` Lyude Paul
  1 sibling, 1 reply; 40+ messages in thread
From: Deepak Singh Rawat @ 2019-01-25 16:16 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The else condition is not needed, since all the other conditions
> return
> when they are done.
> 
> Move the KMS dumb buffer allocation outside of the outer else
> condition,
> this will also allow to ease later changes.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index d69c3fb2d38d..270db8d6dc90 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -557,15 +557,24 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  			igt_require(driver_has_gem_api);
>  			return -EINVAL;
>  		}
> -	} else {
> -		fb->is_dumb = true;
> -
> -		fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb-
> >height,
> -						     fb->plane_bpp[0],
> -						     &fb->strides[0],
> &fb->size);
> -
> -		return fb->gem_handle;
>  	}
> +
> +	/*
> +	 * The current dumb buffer allocation API doesn't really allow
> to
> +	 * specify a custom size or stride. Yet the caller is free to
> specify
> +	 * them, so we need to make sure to error out in this case.
> +	 */
> +	igt_assert(fb->size == 0);
> +	igt_assert(fb->strides[0] == 0);

Hi Maxime, thanks for doing this. I am not an expert but do you think
this should be igt_skip instead? Tests will simply fail where they
should really be skipping if driver don't support the feature.

> +
> +	fb->size = calc_fb_size(fb);
> +
> +	fb->is_dumb = true;
> +	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
> +					     fb->plane_bpp[0],
> +					     &fb->strides[0], &fb-
> >size);
> +
> +	return fb->gem_handle;
>  }
>  
>  /**

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
@ 2019-01-29 19:42   ` Lyude Paul
  2019-01-29 20:07   ` Ville Syrjälä
  2019-02-05 12:53   ` Paul Kocialkowski
  2 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 19:42 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Acked-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The current way we work when we want to support a new YUV format to IGT, we
> also need to add new function to convert to and from XRGB8888.
> 
> This doesn't really scale however, and creates a lot of code to maintain.
> In order to work around this, create a generic function to convert to RGB
> and one to convert from RGB.
> 
> The only thing that is needed now is to add new parameters, and that's it.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 537 ++++++++++++++++-----------------------------------
>  1 file changed, 171 insertions(+), 366 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 1a5c338ea532..45691fd441d9 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -1577,424 +1577,237 @@ static void convert_src_put(const struct
> fb_convert *cvt,
>  		free(src_buf);
>  }
>  
> -static void convert_nv12_to_rgb24(struct fb_convert *cvt)
> +struct yuv_parameters {
> +	unsigned	y_inc;
> +	unsigned	uv_inc;
> +	unsigned	y_stride;
> +	unsigned	uv_stride;
> +	unsigned	y_offset;
> +	unsigned	u_offset;
> +	unsigned	v_offset;
> +};
> +
> +static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters
> *params)
>  {
> -	int i, j;
> -	const uint8_t *y, *uv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int planar_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb-
> >color_encoding,
> -						    cvt->src.fb->color_range);
> -	uint8_t *buf;
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_NV12 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	y = buf + cvt->src.fb->offsets[0];
> -	uv = buf + cvt->src.fb->offsets[1];
> -
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 yuv[4];
> -			struct igt_vec4 rgb[4];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[2].d[0] = y[j * 2 + 0 + planar_stride];
> -			yuv[3].d[0] = y[j * 2 + 1 + planar_stride];
> -
> -			yuv[0].d[1] = yuv[1].d[1] = yuv[2].d[1] = yuv[3].d[1]
> = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = yuv[2].d[2] = yuv[3].d[2]
> = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = yuv[2].d[3] = yuv[3].d[3]
> = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -			rgb[2] = igt_matrix_transform(&m, &yuv[2]);
> -			rgb[3] = igt_matrix_transform(&m, &yuv[3]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[2]);
> -			write_rgb(&rgb24[j * 8 + 4 + rgb24_stride], &rgb[3]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 0 + planar_stride];
> +	igt_assert(igt_format_is_yuv(fb->drm_format));
>  
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_inc = 1;
> +		params->uv_inc = 2;
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[1]);
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +		params->y_inc = 2;
> +		params->uv_inc = 4;
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_inc = 4;
> +		params->uv_inc = 4;
> +		break;
>  	}
>  
> -	if (cvt->dst.fb->height & 1) {
> -		/* Convert last row */
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[1];
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[0];
> +		break;
> +	}
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[0]);
> -		}
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[1];
> +		params->v_offset = fb->offsets[1] + 1;
> +		break;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> +	case DRM_FORMAT_YUYV:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 1;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  
> -			yuv.d[0] = y[j * 2 + 0];
> -			yuv.d[1] = uv[j * 2 + 0];
> -			yuv.d[2] = uv[j * 2 + 1];
> -			yuv.d[3] = 1.0f;
> +	case DRM_FORMAT_YVYU:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 3;
> +		params->v_offset = fb->offsets[0] + 1;
> +		break;
>  
> -			rgb = igt_matrix_transform(&m, &yuv);
> +	case DRM_FORMAT_UYVY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0];
> +		params->v_offset = fb->offsets[0] + 2;
> +		break;
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> -		}
> +	case DRM_FORMAT_VYUY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0];
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  	}
> -
> -	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_yuv444_to_rgb24(struct fb_convert *cvt)
> +static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *src_fmt =
> +		lookup_drm_format(cvt->src.fb->drm_format);
>  	int i, j;
> -	uint8_t *yuv24;
> +	uint8_t bpp = 4;
> +	uint8_t *y, *u, *v;
>  	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned rgb24_stride = cvt->dst.fb->strides[0], xyuv_stride = cvt-
> >src.fb->strides[0];
> -	uint8_t *buf = malloc(cvt->src.fb->size);
> +	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb-
> >color_encoding,
>  						    cvt->src.fb->color_range);
> +	uint8_t *buf;
> +	struct yuv_parameters params = { };
>  
> -	/*
> -	 * 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, cvt->src.ptr + cvt->src.fb->offsets[0], cvt-
> >src.fb->size);
> -	yuv24 = buf;
> +	igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> +		   igt_format_is_yuv(cvt->src.fb->drm_format));
> +
> +	buf = convert_src_get(cvt);
> +	get_yuv_parameters(cvt->src.fb, &params);
> +	y = buf + params.y_offset;
> +	u = buf + params.u_offset;
> +	v = buf + params.v_offset;
>  
>  	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *y_tmp = y;
> +		const uint8_t *u_tmp = u;
> +		const uint8_t *v_tmp = v;
> +		uint8_t *rgb_tmp = rgb24;
> +
>  		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			float y, u, v;
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			v = yuv24[i * xyuv_stride + j * 4];
> -			u = yuv24[i * xyuv_stride + j * 4 + 1];
> -			y = yuv24[i * xyuv_stride + j * 4 + 2];
> -			yuv.d[0] = y;
> -			yuv.d[1] = u;
> -			yuv.d[2] = v;
> +			struct igt_vec4 rgb, yuv;
> +
> +			yuv.d[0] = *y_tmp;
> +			yuv.d[1] = *u_tmp;
> +			yuv.d[2] = *v_tmp;
>  			yuv.d[3] = 1.0f;
>  
>  			rgb = igt_matrix_transform(&m, &yuv);
> +			write_rgb(rgb_tmp, &rgb);
>  
> -			write_rgb(&rgb24[i * rgb24_stride + j * 4], &rgb);
> -		}
> -	}
> -
> -	free(buf);
> -}
> -
> -
> -static void convert_rgb24_to_yuv444(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *rgb24;
> -	uint8_t *yuv444 = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	unsigned int rgb24_stride = cvt->src.fb->strides[0], xyuv_stride =
> cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb-
> >color_encoding,
> -						    cvt->dst.fb->color_range);
> -
> -	rgb24 = cvt->src.ptr;
> +			rgb_tmp += bpp;
> +			y_tmp += params.y_inc;
>  
> -	igt_assert_f(cvt->dst.fb->drm_format == DRM_FORMAT_XYUV8888,
> -		     "Conversion not implemented for !XYUV packed formats\n");
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[i * rgb24_stride + j * 4]);
> +			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
> +				u_tmp += params.uv_inc;
> +				v_tmp += params.uv_inc;
> +			}
> +		}
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +		rgb24 += rgb24_stride;
> +		y += params.y_stride;
>  
> -			yuv444[i * xyuv_stride + j * 4] = yuv.d[2];
> -			yuv444[i * xyuv_stride + j * 4 + 1] = yuv.d[1];
> -			yuv444[i * xyuv_stride + j * 4 + 2] = yuv.d[0];
> +		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
>  	}
> +
> +	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_rgb24_to_nv12(struct fb_convert *cvt)
> +static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *dst_fmt =
> +		lookup_drm_format(cvt->dst.fb->drm_format);
>  	int i, j;
> -	uint8_t *y = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	uint8_t *uv = cvt->dst.ptr + cvt->dst.fb->offsets[1];
> +	uint8_t *y, *u, *v;
>  	const uint8_t *rgb24 = cvt->src.ptr;
> +	uint8_t bpp = 4;
>  	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned planar_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb-
> >color_encoding,
>  						    cvt->dst.fb->color_range);
> +	struct yuv_parameters params = { };
>  
>  	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_NV12);
> +		   igt_format_is_yuv(cvt->dst.fb->drm_format));
>  
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 rgb[4];
> -			struct igt_vec4 yuv[4];
> +	get_yuv_parameters(cvt->dst.fb, &params);
> +	y = cvt->dst.ptr + params.y_offset;
> +	u = cvt->dst.ptr + params.u_offset;
> +	v = cvt->dst.ptr + params.v_offset;
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -			read_rgb(&rgb[2], &rgb24[j * 8 + 0 + rgb24_stride]);
> -			read_rgb(&rgb[3], &rgb24[j * 8 + 4 + rgb24_stride]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> -			yuv[2] = igt_matrix_transform(&m, &rgb[2]);
> -			yuv[3] = igt_matrix_transform(&m, &rgb[3]);
> -
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[2].d[0];
> -			y[j * 2 + 1 + planar_stride] = yuv[3].d[0];
> +	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *rgb_tmp = rgb24;
> +		uint8_t *y_tmp = y;
> +		uint8_t *u_tmp = u;
> +		uint8_t *v_tmp = v;
>  
> -			/*
> -			 * We assume the MPEG2 chroma siting convention, where
> -			 * pixel center for Cb'Cr' is between the left top and
> -			 * bottom pixel in a 2x2 block, so take the average.
> -			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[2].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[2].d[2]) / 2.0f;
> -		}
> +		for (j = 0; j < cvt->dst.fb->width; j++) {
> +			const uint8_t *pair_rgb24 = rgb_tmp;
> +			struct igt_vec4 pair_rgb, rgb;
> +			struct igt_vec4 pair_yuv, yuv;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> +			read_rgb(&rgb, rgb_tmp);
> +			yuv = igt_matrix_transform(&m, &rgb);
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 0 + rgb24_stride]);
> +			rgb_tmp += bpp;
>  
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			*y_tmp = yuv.d[0];
> +			y_tmp += params.y_inc;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[1].d[0];
> +			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
> +				continue;
>  
>  			/*
>  			 * We assume the MPEG2 chroma siting convention, where
>  			 * pixel center for Cb'Cr' is between the left top and
>  			 * bottom pixel in a 2x2 block, so take the average.
> +			 *
> +			 * Therefore, if we use subsampling, we only really
> care
> +			 * about two pixels all the time, either the two
> +			 * subsequent pixels horizontally, vertically, or the
> +			 * two corners in a 2x2 block.
> +			 *
> +			 * The only corner case is when we have an odd number
> of
> +			 * pixels, but this can be handled pretty easily by
> not
> +			 * incrementing the paired pixel pointer in the
> +			 * direction it's odd in.
>  			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> -	}
> -
> -	/* Last row cannot be interpolated between 2 pixels, take the single
> value */
> -	if (cvt->dst.fb->height & 1) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			if (j != (cvt->dst.fb->width - 1))
> +				pair_rgb24 += (dst_fmt->hsub - 1) * bpp;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			uv[j * 2 + 0] = yuv[0].d[1];
> -			uv[j * 2 + 1] = yuv[0].d[2];
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> +			if (i != (cvt->dst.fb->height - 1))
> +				pair_rgb24 += rgb24_stride * (dst_fmt->vsub -
> 1);
>  
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> +			read_rgb(&pair_rgb, pair_rgb24);
> +			pair_yuv = igt_matrix_transform(&m, &pair_rgb);
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +			*u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
> +			*v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
>  
> -			y[j * 2 + 0] = yuv.d[0];
> -			uv[j * 2 + 0] = yuv.d[1];
> -			uv[j * 2 + 1] = yuv.d[2];
> -		}
> -	}
> -}
> -
> -/* { Y0, U, Y1, V } */
> -static const unsigned char swizzle_yuyv[] = { 0, 1, 2, 3 };
> -static const unsigned char swizzle_yvyu[] = { 0, 3, 2, 1 };
> -static const unsigned char swizzle_uyvy[] = { 1, 0, 3, 2 };
> -static const unsigned char swizzle_vyuy[] = { 1, 2, 3, 0 };
> -
> -static const unsigned char *yuyv_swizzle(uint32_t format)
> -{
> -	switch (format) {
> -	default:
> -	case DRM_FORMAT_YUYV:
> -		return swizzle_yuyv;
> -	case DRM_FORMAT_YVYU:
> -		return swizzle_yvyu;
> -	case DRM_FORMAT_UYVY:
> -		return swizzle_uyvy;
> -	case DRM_FORMAT_VYUY:
> -		return swizzle_vyuy;
> -	}
> -}
> -
> -static void convert_yuyv_to_rgb24(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	const uint8_t *yuyv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int yuyv_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb-
> >color_encoding,
> -						    cvt->src.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->src.fb->drm_format);
> -	uint8_t *buf;
> -
> -	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_VYUY) &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	yuyv = buf;
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = yuyv[j * 4 + swz[0]];
> -			yuv[1].d[0] = yuyv[j * 4 + swz[2]];
> -			yuv[0].d[1] = yuv[1].d[1] = yuyv[j * 4 + swz[1]];
> -			yuv[0].d[2] = yuv[1].d[2] = yuyv[j * 4 + swz[3]];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			yuv.d[0] = yuyv[j * 4 + swz[0]];
> -			yuv.d[1] = yuyv[j * 4 + swz[1]];
> -			yuv.d[2] = yuyv[j * 4 + swz[3]];
> -			yuv.d[3] = 1.0f;
> -
> -			rgb = igt_matrix_transform(&m, &yuv);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> +			u_tmp += params.uv_inc;
> +			v_tmp += params.uv_inc;
>  		}
>  
>  		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
> -	}
> -
> -	convert_src_put(cvt, buf);
> -}
> -
> -static void convert_rgb24_to_yuyv(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *yuyv = cvt->dst.ptr;
> -	const uint8_t *rgb24 = cvt->src.ptr;
> -	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned yuyv_stride = cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb-
> >color_encoding,
> -						    cvt->dst.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->dst.fb->drm_format);
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   (cvt->dst.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_VYUY));
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +		y += params.y_stride;
>  
> -			yuyv[j * 4 + swz[0]] = yuv[0].d[0];
> -			yuyv[j * 4 + swz[2]] = yuv[1].d[0];
> -			yuyv[j * 4 + swz[1]] = (yuv[0].d[1] + yuv[1].d[1]) /
> 2.0f;
> -			yuyv[j * 4 + swz[3]] = (yuv[0].d[2] + yuv[1].d[2]) /
> 2.0f;
> +		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> -
> -			yuv = igt_matrix_transform(&m, &rgb);
> -
> -			yuyv[j * 4 + swz[0]] = yuv.d[0];
> -			yuyv[j * 4 + swz[1]] = yuv.d[1];
> -			yuyv[j * 4 + swz[3]] = yuv.d[2];
> -		}
> -
> -		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
>  	}
>  }
>  
> @@ -2046,31 +1859,23 @@ static void fb_convert(struct fb_convert *cvt)
>  	} else if (cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->src.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_yuv444_to_rgb24(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_nv12_to_rgb24(cvt);
> -			return;
> -		case DRM_FORMAT_YUYV:
> -		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_yuyv_to_rgb24(cvt);
> +		case DRM_FORMAT_YUYV:
> +		case DRM_FORMAT_YVYU:
> +			convert_yuv_to_rgb24(cvt);
>  			return;
>  		}
>  	} else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->dst.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_rgb24_to_yuv444(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_rgb24_to_nv12(cvt);
> -			return;
>  		case DRM_FORMAT_YUYV:
>  		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_rgb24_to_yuyv(cvt);
> +			convert_rgb24_to_yuv(cvt);
>  			return;
>  		}
>  	}
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms Maxime Ripard
@ 2019-01-29 19:42   ` Lyude Paul
  2019-02-05 12:52   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 19:42 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> Aligning the width on 64 pixels only make sense on intel platforms, make
> sure to add a check against this.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index e23908e28c07..1a5c338ea532 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -204,7 +204,11 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int
> fb_bpp,
>  {
>  	switch (tiling) {
>  	case LOCAL_DRM_FORMAT_MOD_NONE:
> -		*width_ret = 64;
> +		if (is_i915_device(fd))
> +			*width_ret = 64;
> +		else
> +			*width_ret = 1;
> +
>  		*height_ret = 1;
>  		break;
>  	case LOCAL_I915_FORMAT_MOD_X_TILED:
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
@ 2019-01-29 19:42   ` Lyude Paul
  2019-02-05 12:52   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 19:42 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> In order to improve the YUV support, let's add the horizontal and vertical
> subsampling parameters to the IGT formats.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 35 +++++++++++++++++++++++++++++------
>  1 file changed, 29 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 5cd1829a3ce4..e23908e28c07 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -71,85 +71,104 @@ static const struct format_desc_struct {
>  	int depth;
>  	int num_planes;
>  	int plane_bpp[4];
> +	uint8_t hsub;
> +	uint8_t vsub;
>  } format_desc[] = {
>  	{ .name = "ARGB1555", .depth = -1, .drm_id = DRM_FORMAT_ARGB1555,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_a1r5g5b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB1555", .depth = -1, .drm_id = DRM_FORMAT_XRGB1555,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_x1r5g5b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "RGB565", .depth = 16, .drm_id = DRM_FORMAT_RGB565,
>  	  .cairo_id = CAIRO_FORMAT_RGB16_565,
>  	  .pixman_id = PIXMAN_r5g6b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "BGR565", .depth = -1, .drm_id = DRM_FORMAT_BGR565,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_b5g6r5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "BGR888", .depth = -1, .drm_id = DRM_FORMAT_BGR888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 24, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "RGB888", .depth = -1, .drm_id = DRM_FORMAT_RGB888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 24, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XYUV8888", .depth = -1, .drm_id = DRM_FORMAT_XYUV8888,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .pixman_id = PIXMAN_x8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XBGR8888", .depth = -1, .drm_id = DRM_FORMAT_XBGR8888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_x8b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB2101010", .depth = 30, .drm_id =
> DRM_FORMAT_XRGB2101010,
>  	  .cairo_id = CAIRO_FORMAT_RGB30,
>  	  .pixman_id = PIXMAN_x2r10g10b10,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "ARGB8888", .depth = 32, .drm_id = DRM_FORMAT_ARGB8888,
>  	  .cairo_id = CAIRO_FORMAT_ARGB32,
>  	  .pixman_id = PIXMAN_a8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "ABGR8888", .depth = -1, .drm_id = DRM_FORMAT_ABGR8888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_a8b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "NV12", .depth = -1, .drm_id = DRM_FORMAT_NV12,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 2, .plane_bpp = { 8, 16, },
> +	  .hsub = 2, .vsub = 2,
>  	},
>  	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "YVYU", .depth = -1, .drm_id = DRM_FORMAT_YVYU,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "UYVY", .depth = -1, .drm_id = DRM_FORMAT_UYVY,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "VYUY", .depth = -1, .drm_id = DRM_FORMAT_VYUY,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  };
>  #define for_each_format(f)	\
> @@ -239,10 +258,12 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int
> fb_bpp,
>  
>  static unsigned fb_plane_width(const struct igt_fb *fb, int plane)
>  {
> -	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
> -		return DIV_ROUND_UP(fb->width, 2);
> +	const struct format_desc_struct *format = lookup_drm_format(fb-
> >drm_format);
>  
> -	return fb->width;
> +	if (plane == 0)
> +		return fb->width;
> +
> +	return DIV_ROUND_UP(fb->width, format->hsub);
>  }
>  
>  static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
> @@ -254,10 +275,12 @@ static unsigned fb_plane_bpp(const struct igt_fb *fb,
> int plane)
>  
>  static unsigned fb_plane_height(const struct igt_fb *fb, int plane)
>  {
> -	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
> -		return DIV_ROUND_UP(fb->height, 2);
> +	const struct format_desc_struct *format = lookup_drm_format(fb-
> >drm_format);
>  
> -	return fb->height;
> +	if (plane == 0)
> +		return fb->height;
> +
> +	return DIV_ROUND_UP(fb->height, format->vsub);
>  }
>  
>  static int fb_num_planes(const struct igt_fb *fb)
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function Maxime Ripard
@ 2019-01-29 19:43   ` Lyude Paul
  2019-02-05 12:53   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 19:43 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The YUV buffer allocation path for the i915 driver also has some code to
> clear a YUV buffer.
> 
> As that is going to be useful for all the other drivers, let's move it to
> a separate function.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 80 +++++++++++++++++++++++++++-------------------------
>  1 file changed, 42 insertions(+), 38 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 45691fd441d9..d69c3fb2d38d 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -484,6 +484,47 @@ uint64_t igt_fb_tiling_to_mod(uint64_t tiling)
>  	}
>  }
>  
> +static void clear_yuv_buffer(struct igt_fb *fb)
> +{
> +	bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
> +	void *ptr;
> +
> +	igt_assert(igt_format_is_yuv(fb->drm_format));
> +
> +	/* Ensure the framebuffer is preallocated */
> +	ptr = igt_fb_map_buffer(fb->fd, fb);
> +	igt_assert(*(uint32_t *)ptr == 0);
> +
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		memset(ptr + fb->offsets[0],
> +		       full_range ? 0x00 : 0x10,
> +		       fb->strides[0] * fb->plane_height[0]);
> +		memset(ptr + fb->offsets[1],
> +		       0x80,
> +		       fb->strides[1] * fb->plane_height[1]);
> +		break;
> +	case DRM_FORMAT_XYUV8888:
> +		wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 :
> 0x00108080,
> +			fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> +		break;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0x80008000 : 0x80108010,
> +			fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> +		break;
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0x00800080 : 0x10801080,
> +			fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> +		break;
> +	}
> +
> +	igt_fb_unmap_buffer(fb, ptr);
> +}
> +
>  /* helpers to create nice-looking framebuffers */
>  static int create_bo_for_fb(struct igt_fb *fb)
>  {
> @@ -501,50 +542,13 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  		fb->is_dumb = false;
>  
>  		if (is_i915_device(fd)) {
> -			void *ptr;
> -			bool full_range = fb->color_range ==
> IGT_COLOR_YCBCR_FULL_RANGE;
>  
>  			fb->gem_handle = gem_create(fd, fb->size);
>  
>  			gem_set_tiling(fd, fb->gem_handle,
>  				       igt_fb_mod_to_tiling(fb->tiling),
>  				       fb->strides[0]);
> -
> -			gem_set_domain(fd, fb->gem_handle,
> -				       I915_GEM_DOMAIN_GTT,
> I915_GEM_DOMAIN_GTT);
> -
> -			/* Ensure the framebuffer is preallocated */
> -			ptr = gem_mmap__gtt(fd, fb->gem_handle,
> -					    fb->size, PROT_READ | PROT_WRITE);
> -			igt_assert(*(uint32_t *)ptr == 0);
> -
> -			switch (fb->drm_format) {
> -			case DRM_FORMAT_NV12:
> -				memset(ptr + fb->offsets[0],
> -				       full_range ? 0x00 : 0x10,
> -				       fb->strides[0] * fb->plane_height[0]);
> -				memset(ptr + fb->offsets[1],
> -				       0x80,
> -				       fb->strides[1] * fb->plane_height[1]);
> -				break;
> -			case DRM_FORMAT_XYUV8888:
> -				wmemset(ptr + fb->offsets[0], full_range ?
> 0x00008080 : 0x00108080,
> -					fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> -				break;
> -			case DRM_FORMAT_YUYV:
> -			case DRM_FORMAT_YVYU:
> -				wmemset(ptr + fb->offsets[0],
> -					full_range ? 0x80008000 : 0x80108010,
> -					fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> -				break;
> -			case DRM_FORMAT_UYVY:
> -			case DRM_FORMAT_VYUY:
> -				wmemset(ptr + fb->offsets[0],
> -					full_range ? 0x00800080 : 0x10801080,
> -					fb->strides[0] * fb->plane_height[0] /
> sizeof(wchar_t));
> -				break;
> -			}
> -			gem_munmap(ptr, fb->size);
> +			clear_yuv_buffer(fd);
>  
>  			return fb->gem_handle;
>  		} else {
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path Maxime Ripard
  2019-01-25 16:16   ` Deepak Singh Rawat
@ 2019-01-29 19:46   ` Lyude Paul
  2019-01-30 15:25     ` Maxime Ripard
  1 sibling, 1 reply; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 19:46 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The else condition is not needed, since all the other conditions return
> when they are done.
> 
> Move the KMS dumb buffer allocation outside of the outer else condition,
> this will also allow to ease later changes.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index d69c3fb2d38d..270db8d6dc90 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -557,15 +557,24 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  			igt_require(driver_has_gem_api);
>  			return -EINVAL;
>  		}
> -	} else {
> -		fb->is_dumb = true;
> -
> -		fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb-
> >height,
> -						     fb->plane_bpp[0],
> -						     &fb->strides[0], &fb-
> >size);
> -
> -		return fb->gem_handle;
>  	}
> +
> +	/*
> +	 * The current dumb buffer allocation API doesn't really allow to
> +	 * specify a custom size or stride. Yet the caller is free to specify
> +	 * them, so we need to make sure to error out in this case.
> +	 */
> +	igt_assert(fb->size == 0);
> +	igt_assert(fb->strides[0] == 0);
> +
> +	fb->size = calc_fb_size(fb);

^ Is this supposed to be part of a seperate patch?

> +
> +	fb->is_dumb = true;
> +	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
> +					     fb->plane_bpp[0],
> +					     &fb->strides[0], &fb->size);
> +
> +	return fb->gem_handle;
>  }
>  
>  /**
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
@ 2019-01-29 20:07   ` Ville Syrjälä
  2019-01-30 15:06     ` Maxime Ripard
  2019-02-05 12:53   ` Paul Kocialkowski
  2 siblings, 1 reply; 40+ messages in thread
From: Ville Syrjälä @ 2019-01-29 20:07 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Petri Latvala, eben, igt-dev, Thomas Petazzoni

On Fri, Jan 25, 2019 at 03:58:32PM +0100, Maxime Ripard wrote:
> The current way we work when we want to support a new YUV format to IGT, we
> also need to add new function to convert to and from XRGB8888.
> 
> This doesn't really scale however, and creates a lot of code to maintain.
> In order to work around this, create a generic function to convert to RGB
> and one to convert from RGB.
> 
> The only thing that is needed now is to add new parameters, and that's it.

What's the performance impact of this?

> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 537 ++++++++++++++++-----------------------------------
>  1 file changed, 171 insertions(+), 366 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 1a5c338ea532..45691fd441d9 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -1577,424 +1577,237 @@ static void convert_src_put(const struct fb_convert *cvt,
>  		free(src_buf);
>  }
>  
> -static void convert_nv12_to_rgb24(struct fb_convert *cvt)
> +struct yuv_parameters {
> +	unsigned	y_inc;
> +	unsigned	uv_inc;
> +	unsigned	y_stride;
> +	unsigned	uv_stride;
> +	unsigned	y_offset;
> +	unsigned	u_offset;
> +	unsigned	v_offset;
> +};
> +
> +static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  {
> -	int i, j;
> -	const uint8_t *y, *uv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int planar_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
> -						    cvt->src.fb->color_range);
> -	uint8_t *buf;
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_NV12 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	y = buf + cvt->src.fb->offsets[0];
> -	uv = buf + cvt->src.fb->offsets[1];
> -
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 yuv[4];
> -			struct igt_vec4 rgb[4];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[2].d[0] = y[j * 2 + 0 + planar_stride];
> -			yuv[3].d[0] = y[j * 2 + 1 + planar_stride];
> -
> -			yuv[0].d[1] = yuv[1].d[1] = yuv[2].d[1] = yuv[3].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = yuv[2].d[2] = yuv[3].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = yuv[2].d[3] = yuv[3].d[3] = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -			rgb[2] = igt_matrix_transform(&m, &yuv[2]);
> -			rgb[3] = igt_matrix_transform(&m, &yuv[3]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[2]);
> -			write_rgb(&rgb24[j * 8 + 4 + rgb24_stride], &rgb[3]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 0 + planar_stride];
> +	igt_assert(igt_format_is_yuv(fb->drm_format));
>  
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_inc = 1;
> +		params->uv_inc = 2;
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[1]);
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +		params->y_inc = 2;
> +		params->uv_inc = 4;
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_inc = 4;
> +		params->uv_inc = 4;
> +		break;
>  	}
>  
> -	if (cvt->dst.fb->height & 1) {
> -		/* Convert last row */
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[1];
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[0];
> +		break;
> +	}
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[0]);
> -		}
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[1];
> +		params->v_offset = fb->offsets[1] + 1;
> +		break;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> +	case DRM_FORMAT_YUYV:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 1;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  
> -			yuv.d[0] = y[j * 2 + 0];
> -			yuv.d[1] = uv[j * 2 + 0];
> -			yuv.d[2] = uv[j * 2 + 1];
> -			yuv.d[3] = 1.0f;
> +	case DRM_FORMAT_YVYU:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 3;
> +		params->v_offset = fb->offsets[0] + 1;
> +		break;
>  
> -			rgb = igt_matrix_transform(&m, &yuv);
> +	case DRM_FORMAT_UYVY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0];
> +		params->v_offset = fb->offsets[0] + 2;
> +		break;
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> -		}
> +	case DRM_FORMAT_VYUY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0];
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  	}
> -
> -	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_yuv444_to_rgb24(struct fb_convert *cvt)
> +static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *src_fmt =
> +		lookup_drm_format(cvt->src.fb->drm_format);
>  	int i, j;
> -	uint8_t *yuv24;
> +	uint8_t bpp = 4;
> +	uint8_t *y, *u, *v;
>  	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned rgb24_stride = cvt->dst.fb->strides[0], xyuv_stride = cvt->src.fb->strides[0];
> -	uint8_t *buf = malloc(cvt->src.fb->size);
> +	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
>  						    cvt->src.fb->color_range);
> +	uint8_t *buf;
> +	struct yuv_parameters params = { };
>  
> -	/*
> -	 * 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, cvt->src.ptr + cvt->src.fb->offsets[0], cvt->src.fb->size);
> -	yuv24 = buf;
> +	igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> +		   igt_format_is_yuv(cvt->src.fb->drm_format));
> +
> +	buf = convert_src_get(cvt);
> +	get_yuv_parameters(cvt->src.fb, &params);
> +	y = buf + params.y_offset;
> +	u = buf + params.u_offset;
> +	v = buf + params.v_offset;
>  
>  	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *y_tmp = y;
> +		const uint8_t *u_tmp = u;
> +		const uint8_t *v_tmp = v;
> +		uint8_t *rgb_tmp = rgb24;
> +
>  		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			float y, u, v;
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			v = yuv24[i * xyuv_stride + j * 4];
> -			u = yuv24[i * xyuv_stride + j * 4 + 1];
> -			y = yuv24[i * xyuv_stride + j * 4 + 2];
> -			yuv.d[0] = y;
> -			yuv.d[1] = u;
> -			yuv.d[2] = v;
> +			struct igt_vec4 rgb, yuv;
> +
> +			yuv.d[0] = *y_tmp;
> +			yuv.d[1] = *u_tmp;
> +			yuv.d[2] = *v_tmp;
>  			yuv.d[3] = 1.0f;
>  
>  			rgb = igt_matrix_transform(&m, &yuv);
> +			write_rgb(rgb_tmp, &rgb);
>  
> -			write_rgb(&rgb24[i * rgb24_stride + j * 4], &rgb);
> -		}
> -	}
> -
> -	free(buf);
> -}
> -
> -
> -static void convert_rgb24_to_yuv444(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *rgb24;
> -	uint8_t *yuv444 = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	unsigned int rgb24_stride = cvt->src.fb->strides[0], xyuv_stride = cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
> -						    cvt->dst.fb->color_range);
> -
> -	rgb24 = cvt->src.ptr;
> +			rgb_tmp += bpp;
> +			y_tmp += params.y_inc;
>  
> -	igt_assert_f(cvt->dst.fb->drm_format == DRM_FORMAT_XYUV8888,
> -		     "Conversion not implemented for !XYUV packed formats\n");
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[i * rgb24_stride + j * 4]);
> +			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
> +				u_tmp += params.uv_inc;
> +				v_tmp += params.uv_inc;
> +			}
> +		}
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +		rgb24 += rgb24_stride;
> +		y += params.y_stride;
>  
> -			yuv444[i * xyuv_stride + j * 4] = yuv.d[2];
> -			yuv444[i * xyuv_stride + j * 4 + 1] = yuv.d[1];
> -			yuv444[i * xyuv_stride + j * 4 + 2] = yuv.d[0];
> +		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
>  	}
> +
> +	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_rgb24_to_nv12(struct fb_convert *cvt)
> +static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *dst_fmt =
> +		lookup_drm_format(cvt->dst.fb->drm_format);
>  	int i, j;
> -	uint8_t *y = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	uint8_t *uv = cvt->dst.ptr + cvt->dst.fb->offsets[1];
> +	uint8_t *y, *u, *v;
>  	const uint8_t *rgb24 = cvt->src.ptr;
> +	uint8_t bpp = 4;
>  	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned planar_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
>  						    cvt->dst.fb->color_range);
> +	struct yuv_parameters params = { };
>  
>  	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_NV12);
> +		   igt_format_is_yuv(cvt->dst.fb->drm_format));
>  
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 rgb[4];
> -			struct igt_vec4 yuv[4];
> +	get_yuv_parameters(cvt->dst.fb, &params);
> +	y = cvt->dst.ptr + params.y_offset;
> +	u = cvt->dst.ptr + params.u_offset;
> +	v = cvt->dst.ptr + params.v_offset;
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -			read_rgb(&rgb[2], &rgb24[j * 8 + 0 + rgb24_stride]);
> -			read_rgb(&rgb[3], &rgb24[j * 8 + 4 + rgb24_stride]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> -			yuv[2] = igt_matrix_transform(&m, &rgb[2]);
> -			yuv[3] = igt_matrix_transform(&m, &rgb[3]);
> -
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[2].d[0];
> -			y[j * 2 + 1 + planar_stride] = yuv[3].d[0];
> +	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *rgb_tmp = rgb24;
> +		uint8_t *y_tmp = y;
> +		uint8_t *u_tmp = u;
> +		uint8_t *v_tmp = v;
>  
> -			/*
> -			 * We assume the MPEG2 chroma siting convention, where
> -			 * pixel center for Cb'Cr' is between the left top and
> -			 * bottom pixel in a 2x2 block, so take the average.
> -			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[2].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[2].d[2]) / 2.0f;
> -		}
> +		for (j = 0; j < cvt->dst.fb->width; j++) {
> +			const uint8_t *pair_rgb24 = rgb_tmp;
> +			struct igt_vec4 pair_rgb, rgb;
> +			struct igt_vec4 pair_yuv, yuv;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> +			read_rgb(&rgb, rgb_tmp);
> +			yuv = igt_matrix_transform(&m, &rgb);
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 0 + rgb24_stride]);
> +			rgb_tmp += bpp;
>  
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			*y_tmp = yuv.d[0];
> +			y_tmp += params.y_inc;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[1].d[0];
> +			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
> +				continue;
>  
>  			/*
>  			 * We assume the MPEG2 chroma siting convention, where
>  			 * pixel center for Cb'Cr' is between the left top and
>  			 * bottom pixel in a 2x2 block, so take the average.
> +			 *
> +			 * Therefore, if we use subsampling, we only really care
> +			 * about two pixels all the time, either the two
> +			 * subsequent pixels horizontally, vertically, or the
> +			 * two corners in a 2x2 block.
> +			 *
> +			 * The only corner case is when we have an odd number of
> +			 * pixels, but this can be handled pretty easily by not
> +			 * incrementing the paired pixel pointer in the
> +			 * direction it's odd in.
>  			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> -	}
> -
> -	/* Last row cannot be interpolated between 2 pixels, take the single value */
> -	if (cvt->dst.fb->height & 1) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			if (j != (cvt->dst.fb->width - 1))
> +				pair_rgb24 += (dst_fmt->hsub - 1) * bpp;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			uv[j * 2 + 0] = yuv[0].d[1];
> -			uv[j * 2 + 1] = yuv[0].d[2];
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> +			if (i != (cvt->dst.fb->height - 1))
> +				pair_rgb24 += rgb24_stride * (dst_fmt->vsub - 1);
>  
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> +			read_rgb(&pair_rgb, pair_rgb24);
> +			pair_yuv = igt_matrix_transform(&m, &pair_rgb);
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +			*u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
> +			*v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
>  
> -			y[j * 2 + 0] = yuv.d[0];
> -			uv[j * 2 + 0] = yuv.d[1];
> -			uv[j * 2 + 1] = yuv.d[2];
> -		}
> -	}
> -}
> -
> -/* { Y0, U, Y1, V } */
> -static const unsigned char swizzle_yuyv[] = { 0, 1, 2, 3 };
> -static const unsigned char swizzle_yvyu[] = { 0, 3, 2, 1 };
> -static const unsigned char swizzle_uyvy[] = { 1, 0, 3, 2 };
> -static const unsigned char swizzle_vyuy[] = { 1, 2, 3, 0 };
> -
> -static const unsigned char *yuyv_swizzle(uint32_t format)
> -{
> -	switch (format) {
> -	default:
> -	case DRM_FORMAT_YUYV:
> -		return swizzle_yuyv;
> -	case DRM_FORMAT_YVYU:
> -		return swizzle_yvyu;
> -	case DRM_FORMAT_UYVY:
> -		return swizzle_uyvy;
> -	case DRM_FORMAT_VYUY:
> -		return swizzle_vyuy;
> -	}
> -}
> -
> -static void convert_yuyv_to_rgb24(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	const uint8_t *yuyv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int yuyv_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
> -						    cvt->src.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->src.fb->drm_format);
> -	uint8_t *buf;
> -
> -	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_VYUY) &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	yuyv = buf;
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = yuyv[j * 4 + swz[0]];
> -			yuv[1].d[0] = yuyv[j * 4 + swz[2]];
> -			yuv[0].d[1] = yuv[1].d[1] = yuyv[j * 4 + swz[1]];
> -			yuv[0].d[2] = yuv[1].d[2] = yuyv[j * 4 + swz[3]];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			yuv.d[0] = yuyv[j * 4 + swz[0]];
> -			yuv.d[1] = yuyv[j * 4 + swz[1]];
> -			yuv.d[2] = yuyv[j * 4 + swz[3]];
> -			yuv.d[3] = 1.0f;
> -
> -			rgb = igt_matrix_transform(&m, &yuv);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> +			u_tmp += params.uv_inc;
> +			v_tmp += params.uv_inc;
>  		}
>  
>  		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
> -	}
> -
> -	convert_src_put(cvt, buf);
> -}
> -
> -static void convert_rgb24_to_yuyv(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *yuyv = cvt->dst.ptr;
> -	const uint8_t *rgb24 = cvt->src.ptr;
> -	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned yuyv_stride = cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
> -						    cvt->dst.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->dst.fb->drm_format);
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   (cvt->dst.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_VYUY));
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +		y += params.y_stride;
>  
> -			yuyv[j * 4 + swz[0]] = yuv[0].d[0];
> -			yuyv[j * 4 + swz[2]] = yuv[1].d[0];
> -			yuyv[j * 4 + swz[1]] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
> -			yuyv[j * 4 + swz[3]] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
> +		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> -
> -			yuv = igt_matrix_transform(&m, &rgb);
> -
> -			yuyv[j * 4 + swz[0]] = yuv.d[0];
> -			yuyv[j * 4 + swz[1]] = yuv.d[1];
> -			yuyv[j * 4 + swz[3]] = yuv.d[2];
> -		}
> -
> -		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
>  	}
>  }
>  
> @@ -2046,31 +1859,23 @@ static void fb_convert(struct fb_convert *cvt)
>  	} else if (cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->src.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_yuv444_to_rgb24(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_nv12_to_rgb24(cvt);
> -			return;
> -		case DRM_FORMAT_YUYV:
> -		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_yuyv_to_rgb24(cvt);
> +		case DRM_FORMAT_YUYV:
> +		case DRM_FORMAT_YVYU:
> +			convert_yuv_to_rgb24(cvt);
>  			return;
>  		}
>  	} else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->dst.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_rgb24_to_yuv444(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_rgb24_to_nv12(cvt);
> -			return;
>  		case DRM_FORMAT_YUYV:
>  		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_rgb24_to_yuyv(cvt);
> +			convert_rgb24_to_yuv(cvt);
>  			return;
>  		}
>  	}
> -- 
> 2.20.1

-- 
Ville Syrjälä
Intel
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer Maxime Ripard
@ 2019-01-29 20:08   ` Lyude Paul
  2019-01-30 15:38     ` Maxime Ripard
  0 siblings, 1 reply; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:08 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The dumb buffer allocation API only considers a single plane, and even
> though allocating multi-planar buffers through it is allowed, the stride it
> gives back is the the width times the bpp passed as an argument.
> 
> That doesn't work in our case, since the bpp is going to be the one we give
> as an argument, but split over three planes so the stride doesn't match
> anymore.
> 
> A proper fix for this would be to have a better dumb buffer allocation API,
> but for the time being, let's do it that way.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 1c52aebb674e..048d274e5d36 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -530,6 +530,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  {
>  	const struct format_desc_struct *fmt = lookup_drm_format(fb-
> >drm_format);
>  	unsigned int plane, bpp;
> +	unsigned *strides = &fb->strides[0];
>  	int fd = fb->fd;
>  
>  	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb-
> >drm_format)) {
> @@ -575,8 +576,22 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  				    plane ? fmt->hsub * fmt->vsub : 1);
>  
>  	fb->is_dumb = true;
> +
> +	/*
> +	 * We can't really pass the stride array here since the dumb
> +	 * buffer allocation is assuming that it operates on one
> +	 * plane, and therefore will calculate the stride as if each
> +	 * pixels were stored on a single plane.

nitpick: s/each pixels were/each pixel was/

> +	 *
> +	 * This might cause issues at some point on drivers that would
> +	 * change the stride of YUV buffers, but we haven't
> +	 * encountered any yet.
> +	 */
Is it possible to add an igt_assert to check for this? Either way, with those
changes:

Reviewed-by: Lyude Paul <lyude@redhat.com>

> +	if (fb->num_planes > 1)
> +		strides = NULL;
> +
>  	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
> -					     bpp, &fb->strides[0], &fb->size);
> +					     bpp, strides, &fb->size);
>  
>  	return fb->gem_handle;
>  }
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers Maxime Ripard
@ 2019-01-29 20:08   ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:08 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> YUV dumb buffers, just like i915 GEM buffers also need to be cleared once
> allocated. Make sure it happens.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 048d274e5d36..65aa99ecf7ae 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -593,6 +593,9 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
>  					     bpp, strides, &fb->size);
>  
> +	if (igt_format_is_yuv(fb->drm_format))
> +		clear_yuv_buffer(fb);
> +
>  	return fb->gem_handle;
>  }
>  
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
  2019-01-25 15:34   ` Paul Kocialkowski
@ 2019-01-29 20:10   ` Lyude Paul
  2019-02-05  9:40   ` Paul Kocialkowski
  2 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:10 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> We only need to allocate a buffer using the GEM API when we're in the
> condition that we currently test, and that we're running on i915.
> 
> All the other cases can be handled by a fallback to a dumb buffer
> allocation. Let's simplify the code a bit to reflect that.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 25 ++++++++-----------------
>  1 file changed, 8 insertions(+), 17 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 65aa99ecf7ae..43e527d1a3dd 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -533,7 +533,8 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	unsigned *strides = &fb->strides[0];
>  	int fd = fb->fd;
>  
> -	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb-
> >drm_format)) {
> +	if (is_i915_device(fd) &&
> +	   (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb-
> >drm_format))) {
>  		uint64_t size;
>  
>  		size = calc_fb_size(fb);
> @@ -543,23 +544,12 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  			fb->size = size;
>  
>  		fb->is_dumb = false;
> +		fb->gem_handle = gem_create(fd, fb->size);
> +		gem_set_tiling(fd, fb->gem_handle,
> +			       igt_fb_mod_to_tiling(fb->tiling),
> +			       fb->strides[0]);
>  
> -		if (is_i915_device(fd)) {
> -
> -			fb->gem_handle = gem_create(fd, fb->size);
> -
> -			gem_set_tiling(fd, fb->gem_handle,
> -				       igt_fb_mod_to_tiling(fb->tiling),
> -				       fb->strides[0]);
> -			clear_yuv_buffer(fd);
> -
> -			return fb->gem_handle;
> -		} else {
> -			bool driver_has_gem_api = false;
> -
> -			igt_require(driver_has_gem_api);
> -			return -EINVAL;
> -		}
> +		goto out;
>  	}
>  
>  	/*
> @@ -593,6 +583,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
>  					     bpp, strides, &fb->size);
>  
> +out:
>  	if (igt_format_is_yuv(fb->drm_format))
>  		clear_yuv_buffer(fb);
>  
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats Maxime Ripard
@ 2019-01-29 20:11   ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:11 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> Thanks to the previous reworks, we can now add new YUV formats pretty
> easily. This patch adds support for the NV12, NV16, NV21, NV61, YUV420,
> YVU420, YUV422 and YVU422 formats.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 98 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 43e527d1a3dd..7ed1397c08fa 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -150,6 +150,21 @@ static const struct format_desc_struct {
>  	  .num_planes = 2, .plane_bpp = { 8, 16, },
>  	  .hsub = 2, .vsub = 2,
>  	},
> +	{ .name = "NV16", .depth = -1, .drm_id = DRM_FORMAT_NV16,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 2, .plane_bpp = { 8, 16, },
> +	  .hsub = 2, .vsub = 1,
> +	},
> +	{ .name = "NV21", .depth = -1, .drm_id = DRM_FORMAT_NV21,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 2, .plane_bpp = { 8, 16, },
> +	  .hsub = 2, .vsub = 2,
> +	},
> +	{ .name = "NV61", .depth = -1, .drm_id = DRM_FORMAT_NV61,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 2, .plane_bpp = { 8, 16, },
> +	  .hsub = 2, .vsub = 1,
> +	},
>  	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> @@ -170,6 +185,26 @@ static const struct format_desc_struct {
>  	  .num_planes = 1, .plane_bpp = { 16, },
>  	  .hsub = 2, .vsub = 1,
>  	},
> +	{ .name = "YU12", .depth = -1, .drm_id = DRM_FORMAT_YUV420,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
> +	  .hsub = 2, .vsub = 2,
> +	},
> +	{ .name = "YU16", .depth = -1, .drm_id = DRM_FORMAT_YUV422,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
> +	  .hsub = 2, .vsub = 1,
> +	},
> +	{ .name = "YV12", .depth = -1, .drm_id = DRM_FORMAT_YVU420,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
> +	  .hsub = 2, .vsub = 2,
> +	},
> +	{ .name = "YV16", .depth = -1, .drm_id = DRM_FORMAT_YVU422,
> +	  .cairo_id = CAIRO_FORMAT_RGB24,
> +	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
> +	  .hsub = 2, .vsub = 1,
> +	},
>  };
>  #define for_each_format(f)	\
>  	for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
> @@ -1619,10 +1654,21 @@ static void get_yuv_parameters(struct igt_fb *fb,
> struct yuv_parameters *params)
>  
>  	switch (fb->drm_format) {
>  	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_NV16:
> +	case DRM_FORMAT_NV21:
> +	case DRM_FORMAT_NV61:
>  		params->y_inc = 1;
>  		params->uv_inc = 2;
>  		break;
>  
> +	case DRM_FORMAT_YUV420:
> +	case DRM_FORMAT_YUV422:
> +	case DRM_FORMAT_YVU420:
> +	case DRM_FORMAT_YVU422:
> +		params->y_inc = 1;
> +		params->uv_inc = 1;
> +		break;
> +
>  	case DRM_FORMAT_YUYV:
>  	case DRM_FORMAT_YVYU:
>  	case DRM_FORMAT_UYVY:
> @@ -1639,6 +1685,13 @@ static void get_yuv_parameters(struct igt_fb *fb,
> struct yuv_parameters *params)
>  
>  	switch (fb->drm_format) {
>  	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_NV16:
> +	case DRM_FORMAT_NV21:
> +	case DRM_FORMAT_NV61:
> +	case DRM_FORMAT_YUV420:
> +	case DRM_FORMAT_YUV422:
> +	case DRM_FORMAT_YVU420:
> +	case DRM_FORMAT_YVU422:
>  		params->y_stride = fb->strides[0];
>  		params->uv_stride = fb->strides[1];
>  		break;
> @@ -1655,11 +1708,33 @@ static void get_yuv_parameters(struct igt_fb *fb,
> struct yuv_parameters *params)
>  
>  	switch (fb->drm_format) {
>  	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_NV16:
>  		params->y_offset = fb->offsets[0];
>  		params->u_offset = fb->offsets[1];
>  		params->v_offset = fb->offsets[1] + 1;
>  		break;
>  
> +	case DRM_FORMAT_NV21:
> +	case DRM_FORMAT_NV61:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[1] + 1;
> +		params->v_offset = fb->offsets[1];
> +		break;
> +
> +	case DRM_FORMAT_YUV420:
> +	case DRM_FORMAT_YUV422:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[1];
> +		params->v_offset = fb->offsets[2];
> +		break;
> +
> +	case DRM_FORMAT_YVU420:
> +	case DRM_FORMAT_YVU422:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[2];
> +		params->v_offset = fb->offsets[1];
> +		break;
> +
>  	case DRM_FORMAT_YUYV:
>  		params->y_offset = fb->offsets[0];
>  		params->u_offset = fb->offsets[0] + 1;
> @@ -1886,9 +1961,16 @@ static void fb_convert(struct fb_convert *cvt)
>  		switch (cvt->src.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
>  		case DRM_FORMAT_NV12:
> +		case DRM_FORMAT_NV16:
> +		case DRM_FORMAT_NV21:
> +		case DRM_FORMAT_NV61:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> +		case DRM_FORMAT_YUV420:
> +		case DRM_FORMAT_YUV422:
>  		case DRM_FORMAT_YUYV:
> +		case DRM_FORMAT_YVU420:
> +		case DRM_FORMAT_YVU422:
>  		case DRM_FORMAT_YVYU:
>  			convert_yuv_to_rgb24(cvt);
>  			return;
> @@ -1897,10 +1979,17 @@ static void fb_convert(struct fb_convert *cvt)
>  		switch (cvt->dst.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
>  		case DRM_FORMAT_NV12:
> -		case DRM_FORMAT_YUYV:
> -		case DRM_FORMAT_YVYU:
> +		case DRM_FORMAT_NV16:
> +		case DRM_FORMAT_NV21:
> +		case DRM_FORMAT_NV61:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> +		case DRM_FORMAT_YUV420:
> +		case DRM_FORMAT_YUV422:
> +		case DRM_FORMAT_YUYV:
> +		case DRM_FORMAT_YVU420:
> +		case DRM_FORMAT_YVU422:
> +		case DRM_FORMAT_YVYU:
>  			convert_rgb24_to_yuv(cvt);
>  			return;
>  		}
> @@ -2247,6 +2336,13 @@ bool igt_format_is_yuv(uint32_t drm_format)
>  {
>  	switch (drm_format) {
>  	case DRM_FORMAT_NV12:
> +	case DRM_FORMAT_NV16:
> +	case DRM_FORMAT_NV21:
> +	case DRM_FORMAT_NV61:
> +	case DRM_FORMAT_YUV420:
> +	case DRM_FORMAT_YUV422:
> +	case DRM_FORMAT_YVU420:
> +	case DRM_FORMAT_YVU422:
>  	case DRM_FORMAT_YUYV:
>  	case DRM_FORMAT_YVYU:
>  	case DRM_FORMAT_UYVY:
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests Maxime Ripard
@ 2019-01-29 20:13   ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:13 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The various tests in kms_chamelium are really variants of one another
> but share little code.
> 
> In addition to the duplication, this gets in the way of the
> introduction of more tests, or to be able to run all the tests on all
> the output, which isn't the case at the moment, with the HDMI and DP
> tests and the VGA tests being different.
> 
> Start by introducing a check parameter to the do_test_display
> function, that will tell which test method we want to use to compare
> the frames.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  tests/kms_chamelium.c | 134 +++++++++++++++++++++++-------------------
>  1 file changed, 73 insertions(+), 61 deletions(-)
> 
> diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
> index 2d848c2f0620..8230cb852cfb 100644
> --- a/tests/kms_chamelium.c
> +++ b/tests/kms_chamelium.c
> @@ -527,12 +527,15 @@ static int chamelium_get_pattern_fb(data_t *data,
> size_t width, size_t height,
>  	return fb_id;
>  }
>  
> -static void do_test_display_crc(data_t *data, struct chamelium_port *port,
> -				igt_output_t *output, drmModeModeInfo *mode,
> -				uint32_t fourcc, int count)
> +enum chamelium_check {
> +	CHAMELIUM_CHECK_CRC,
> +};
> +
> +static void do_test_display(data_t *data, struct chamelium_port *port,
> +			    igt_output_t *output, drmModeModeInfo *mode,
> +			    uint32_t fourcc, enum chamelium_check check,
> +			    int count)
>  {
> -	igt_crc_t *crc;
> -	igt_crc_t *expected_crc;
>  	struct chamelium_fb_crc_async_data *fb_crc;
>  	struct igt_fb frame_fb, fb;
>  	int i, fb_id, captured_frame_count;
> @@ -545,39 +548,46 @@ static void do_test_display_crc(data_t *data, struct
> chamelium_port *port,
>  	frame_id = igt_fb_convert(&frame_fb, &fb, fourcc);
>  	igt_assert(frame_id > 0);
>  
> -	fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
> -							&fb);
> +	if (check == CHAMELIUM_CHECK_CRC)
> +		fb_crc = chamelium_calculate_fb_crc_async_start(data->drm_fd,
> +								&fb);
>  
>  	enable_output(data, port, output, mode, &frame_fb);
>  
> -	/* We want to keep the display running for a little bit, since
> -	 * there's always the potential the driver isn't able to keep
> -	 * the display running properly for very long
> -	 */
> -	chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
> -	crc = chamelium_read_captured_crcs(data->chamelium,
> -					   &captured_frame_count);
> +	if (check == CHAMELIUM_CHECK_CRC) {
> +		igt_crc_t *expected_crc;
> +		igt_crc_t *crc;
>  
> -	igt_assert(captured_frame_count == count);
> +		/* We want to keep the display running for a little bit, since
> +		 * there's always the potential the driver isn't able to keep
> +		 * the display running properly for very long
> +		 */
> +		chamelium_capture(data->chamelium, port, 0, 0, 0, 0, count);
> +		crc = chamelium_read_captured_crcs(data->chamelium,
> +						   &captured_frame_count);
>  
> -	igt_debug("Captured %d frames\n", captured_frame_count);
> +		igt_assert(captured_frame_count == count);
>  
> -	expected_crc = chamelium_calculate_fb_crc_async_finish(fb_crc);
> +		igt_debug("Captured %d frames\n", captured_frame_count);
>  
> -	for (i = 0; i < captured_frame_count; i++)
> -		chamelium_assert_crc_eq_or_dump(data->chamelium,
> -						expected_crc, &crc[i],
> -						&fb, i);
> +		expected_crc =
> chamelium_calculate_fb_crc_async_finish(fb_crc);
>  
> -	free(expected_crc);
> -	free(crc);
> +		for (i = 0; i < captured_frame_count; i++)
> +			chamelium_assert_crc_eq_or_dump(data->chamelium,
> +							expected_crc, &crc[i],
> +							&fb, i);
> +
> +		free(expected_crc);
> +		free(crc);
> +	}
>  
>  	igt_remove_fb(data->drm_fd, &frame_fb);
>  	igt_remove_fb(data->drm_fd, &fb);
>  }
>  
> -static void test_display_crc_one_mode(data_t *data, struct chamelium_port
> *port,
> -				      uint32_t fourcc, int count)
> +static void test_display_one_mode(data_t *data, struct chamelium_port
> *port,
> +				  uint32_t fourcc, enum chamelium_check check,
> +				  int count)
>  {
>  	igt_output_t *output;
>  	drmModeConnector *connector;
> @@ -590,13 +600,15 @@ static void test_display_crc_one_mode(data_t *data,
> struct chamelium_port *port,
>  	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
>  	igt_assert(primary);
>  
> -	do_test_display_crc(data, port, output, &connector->modes[0], fourcc,
> count);
> +	do_test_display(data, port, output, &connector->modes[0], fourcc,
> +			check, count);
>  
>  	drmModeFreeConnector(connector);
>  }
>  
> -static void test_display_crc_all_modes(data_t *data, struct chamelium_port
> *port,
> -				       uint32_t fourcc, int count)
> +static void test_display_all_modes(data_t *data, struct chamelium_port
> *port,
> +				   uint32_t fourcc, enum chamelium_check
> check,
> +				   int count)
>  {
>  	igt_output_t *output;
>  	igt_plane_t *primary;
> @@ -613,7 +625,7 @@ static void test_display_crc_all_modes(data_t *data,
> struct chamelium_port *port
>  	for (i = 0; i < connector->count_modes; i++) {
>  		drmModeModeInfo *mode = &connector->modes[i];
>  
> -		do_test_display_crc(data, port, output, mode, fourcc, count);
> +		do_test_display(data, port, output, mode, fourcc, check,
> count);
>  	}
>  
>  	drmModeFreeConnector(connector);
> @@ -874,16 +886,16 @@ igt_main
>  							edid_id, alt_edid_id);
>  
>  		connector_subtest("dp-crc-single", DisplayPort)
> -			test_display_crc_all_modes(&data, port,
> -						   DRM_FORMAT_XRGB8888, 1);
> +			test_display_all_modes(&data, port,
> DRM_FORMAT_XRGB8888,
> +					       CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("dp-crc-fast", DisplayPort)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_XRGB8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_XRGB8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("dp-crc-multiple", DisplayPort)
> -			test_display_crc_all_modes(&data, port,
> -						   DRM_FORMAT_XRGB8888, 3);
> +			test_display_all_modes(&data, port,
> DRM_FORMAT_XRGB8888,
> +					       CHAMELIUM_CHECK_CRC, 3);
>  
>  		connector_subtest("dp-frame-dump", DisplayPort)
>  			test_display_frame_dump(&data, port);
> @@ -941,56 +953,56 @@ igt_main
>  							edid_id, alt_edid_id);
>  
>  		connector_subtest("hdmi-crc-single", HDMIA)
> -			test_display_crc_all_modes(&data, port,
> -						   DRM_FORMAT_XRGB8888, 1);
> +			test_display_all_modes(&data, port,
> DRM_FORMAT_XRGB8888,
> +					       CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-fast", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_XRGB8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_XRGB8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-multiple", HDMIA)
> -			test_display_crc_all_modes(&data, port,
> -						   DRM_FORMAT_XRGB8888, 3);
> +			test_display_all_modes(&data, port,
> DRM_FORMAT_XRGB8888,
> +					       CHAMELIUM_CHECK_CRC, 3);
>  
>  		connector_subtest("hdmi-crc-argb8888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_ARGB8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_ARGB8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-abgr8888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_ABGR8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_ABGR8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-xrgb8888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_XRGB8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_XRGB8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-xbgr8888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_XBGR8888, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_XBGR8888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-rgb888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_RGB888, 1);
> +			test_display_one_mode(&data, port, DRM_FORMAT_RGB888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-bgr888", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_BGR888, 1);
> +			test_display_one_mode(&data, port, DRM_FORMAT_BGR888,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-rgb565", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_RGB565, 1);
> +			test_display_one_mode(&data, port, DRM_FORMAT_RGB565,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-bgr565", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_BGR565, 1);
> +			test_display_one_mode(&data, port, DRM_FORMAT_BGR565,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-argb1555", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_ARGB1555, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_ARGB1555,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-crc-xrgb1555", HDMIA)
> -			test_display_crc_one_mode(&data, port,
> -						  DRM_FORMAT_XRGB1555, 1);
> +			test_display_one_mode(&data, port,
> DRM_FORMAT_XRGB1555,
> +					      CHAMELIUM_CHECK_CRC, 1);
>  
>  		connector_subtest("hdmi-frame-dump", HDMIA)
>  			test_display_frame_dump(&data, port);
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display Maxime Ripard
@ 2019-01-29 20:14   ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:14 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Good thinking!

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The VGA tests were run so far as part of a separate function. However,
> the only difference between that function and the do_test_display
> function was the kind of comparison we wanted to use. Indeed, VGA
> being an analog output, we can't rely on a pixel perfect image, and
> thus only compare the CRCs, but we need to make some more advanced
> comparison.
> 
> Let's add a new check method, add support for the analog check to
> do_test_display and remove the old version.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  tests/kms_chamelium.c | 92 ++++++++++++++++---------------------------
>  1 file changed, 33 insertions(+), 59 deletions(-)
> 
> diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
> index 8230cb852cfb..eaea9c18832a 100644
> --- a/tests/kms_chamelium.c
> +++ b/tests/kms_chamelium.c
> @@ -528,6 +528,7 @@ static int chamelium_get_pattern_fb(data_t *data, size_t
> width, size_t height,
>  }
>  
>  enum chamelium_check {
> +	CHAMELIUM_CHECK_ANALOG,
>  	CHAMELIUM_CHECK_CRC,
>  };
>  
> @@ -579,6 +580,18 @@ static void do_test_display(data_t *data, struct
> chamelium_port *port,
>  
>  		free(expected_crc);
>  		free(crc);
> +	} else if (check == CHAMELIUM_CHECK_ANALOG) {
> +		struct chamelium_frame_dump *dump;
> +
> +		igt_assert(count == 1);
> +
> +		dump = chamelium_port_dump_pixels(data->chamelium, port, 0, 0,
> +						  0, 0);
> +		chamelium_crop_analog_frame(dump, mode->hdisplay,
> +					    mode->vdisplay);
> +		chamelium_assert_analog_frame_match_or_dump(data->chamelium,
> +							    port, dump, &fb);
> +		chamelium_destroy_frame_dump(dump);
>  	}
>  
>  	igt_remove_fb(data->drm_fd, &frame_fb);
> @@ -589,8 +602,9 @@ static void test_display_one_mode(data_t *data, struct
> chamelium_port *port,
>  				  uint32_t fourcc, enum chamelium_check check,
>  				  int count)
>  {
> -	igt_output_t *output;
>  	drmModeConnector *connector;
> +	drmModeModeInfo *mode;
> +	igt_output_t *output;
>  	igt_plane_t *primary;
>  
>  	reset_state(data, port);
> @@ -600,8 +614,14 @@ static void test_display_one_mode(data_t *data, struct
> chamelium_port *port,
>  	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
>  	igt_assert(primary);
>  
> -	do_test_display(data, port, output, &connector->modes[0], fourcc,
> -			check, count);
> +	mode = &connector->modes[0];
> +	if (check == CHAMELIUM_CHECK_ANALOG) {
> +		bool bridge = check_analog_bridge(data, port);
> +
> +		igt_assert(!(bridge && prune_vga_mode(data, mode)));
> +	}
> +
> +	do_test_display(data, port, output, mode, fourcc, check, count);
>  
>  	drmModeFreeConnector(connector);
>  }
> @@ -613,6 +633,7 @@ static void test_display_all_modes(data_t *data, struct
> chamelium_port *port,
>  	igt_output_t *output;
>  	igt_plane_t *primary;
>  	drmModeConnector *connector;
> +	bool bridge;
>  	int i;
>  
>  	reset_state(data, port);
> @@ -622,9 +643,16 @@ static void test_display_all_modes(data_t *data, struct
> chamelium_port *port,
>  	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
>  	igt_assert(primary);
>  
> +	if (check == CHAMELIUM_CHECK_ANALOG)
> +		bridge = check_analog_bridge(data, port);
> +
>  	for (i = 0; i < connector->count_modes; i++) {
>  		drmModeModeInfo *mode = &connector->modes[i];
>  
> +		if (check == CHAMELIUM_CHECK_ANALOG && bridge &&
> +		    prune_vga_mode(data, mode))
> +			continue;
> +
>  		do_test_display(data, port, output, mode, fourcc, check,
> count);
>  	}
>  
> @@ -675,61 +703,6 @@ test_display_frame_dump(data_t *data, struct
> chamelium_port *port)
>  	drmModeFreeConnector(connector);
>  }
>  
> -static void
> -test_analog_frame_dump(data_t *data, struct chamelium_port *port)
> -{
> -	igt_output_t *output;
> -	igt_plane_t *primary;
> -	struct igt_fb fb;
> -	struct chamelium_frame_dump *frame;
> -	drmModeModeInfo *mode;
> -	drmModeConnector *connector;
> -	int fb_id, i;
> -	bool bridge;
> -
> -	reset_state(data, port);
> -
> -	output = prepare_output(data, port);
> -	connector = chamelium_port_get_connector(data->chamelium, port,
> false);
> -	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> -	igt_assert(primary);
> -
> -	bridge = check_analog_bridge(data, port);
> -
> -	for (i = 0; i < connector->count_modes; i++) {
> -		mode = &connector->modes[i];
> -
> -		if (bridge && prune_vga_mode(data, mode))
> -			continue;
> -
> -		fb_id = igt_create_color_pattern_fb(data->drm_fd,
> -						    mode->hdisplay, mode-
> >vdisplay,
> -						    DRM_FORMAT_XRGB8888,
> -						    LOCAL_DRM_FORMAT_MOD_NONE,
> -						    0, 0, 0, &fb);
> -		igt_assert(fb_id > 0);
> -
> -		enable_output(data, port, output, mode, &fb);
> -
> -		igt_debug("Reading frame dumps from Chamelium...\n");
> -
> -		frame = chamelium_port_dump_pixels(data->chamelium, port, 0,
> 0,
> -						   0, 0);
> -
> -		chamelium_crop_analog_frame(frame, mode->hdisplay,
> -					    mode->vdisplay);
> -
> -		chamelium_assert_analog_frame_match_or_dump(data->chamelium,
> -							    port, frame, &fb);
> -
> -		chamelium_destroy_frame_dump(frame);
> -
> -		igt_remove_fb(data->drm_fd, &fb);
> -	}
> -
> -	drmModeFreeConnector(connector);
> -}
> -
>  static void
>  test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
>  {
> @@ -1041,7 +1014,8 @@ igt_main
>  			test_hpd_without_ddc(&data, port);
>  
>  		connector_subtest("vga-frame-dump", VGA)
> -			test_analog_frame_dump(&data, port);
> +			test_display_all_modes(&data, port,
> DRM_FORMAT_XRGB8888,
> +					       CHAMELIUM_CHECK_ANALOG, 1);
>  	}
>  
>  	igt_subtest_group {
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests Maxime Ripard
@ 2019-01-29 20:14   ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-29 20:14 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, Thomas Petazzoni, eben

Reviewed-by: Lyude Paul <lyude@redhat.com>

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The NV12, NV16, NV21, NV61, YUV420, YVU420, YUV422 and YVU422 are YUV
> formats that are currently supported in IGT.
> 
> We'll want to test those formats in addition to the RGB formats, so
> let's add some subtests. One thing worth noting is some hardware isn't
> able to output a pixel-perfect image, so we do the same kind of
> comparison than for VGA.
> 
> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  tests/kms_chamelium.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
> index eaea9c18832a..64f87d3ae474 100644
> --- a/tests/kms_chamelium.c
> +++ b/tests/kms_chamelium.c
> @@ -977,6 +977,38 @@ igt_main
>  			test_display_one_mode(&data, port,
> DRM_FORMAT_XRGB1555,
>  					      CHAMELIUM_CHECK_CRC, 1);
>  
> +		connector_subtest("hdmi-cmp-nv12", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_NV12,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-nv16", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_NV16,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-nv21", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_NV21,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-nv61", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_NV61,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-yu12", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_YUV420,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-yu16", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_YUV422,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-yv12", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_YVU420,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
> +		connector_subtest("hdmi-cmp-yv16", HDMIA)
> +			test_display_one_mode(&data, port, DRM_FORMAT_YVU422,
> +					      CHAMELIUM_CHECK_ANALOG, 1);
> +
>  		connector_subtest("hdmi-frame-dump", HDMIA)
>  			test_display_frame_dump(&data, port);
>  	}
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path
  2019-01-25 16:16   ` Deepak Singh Rawat
@ 2019-01-30 14:18     ` Maxime Ripard
  0 siblings, 0 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-30 14:18 UTC (permalink / raw)
  To: Deepak Singh Rawat; +Cc: igt-dev, Petri Latvala, Thomas Petazzoni, eben


[-- Attachment #1.1: Type: text/plain, Size: 2070 bytes --]

Hi!

On Fri, Jan 25, 2019 at 08:16:52AM -0800, Deepak Singh Rawat wrote:
> On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> > The else condition is not needed, since all the other conditions
> > return
> > when they are done.
> > 
> > Move the KMS dumb buffer allocation outside of the outer else
> > condition,
> > this will also allow to ease later changes.
> > 
> > Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  lib/igt_fb.c | 25 +++++++++++++++++--------
> >  1 file changed, 17 insertions(+), 8 deletions(-)
> > 
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index d69c3fb2d38d..270db8d6dc90 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -557,15 +557,24 @@ static int create_bo_for_fb(struct igt_fb *fb)
> >  			igt_require(driver_has_gem_api);
> >  			return -EINVAL;
> >  		}
> > -	} else {
> > -		fb->is_dumb = true;
> > -
> > -		fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb-
> > >height,
> > -						     fb->plane_bpp[0],
> > -						     &fb->strides[0],
> > &fb->size);
> > -
> > -		return fb->gem_handle;
> >  	}
> > +
> > +	/*
> > +	 * The current dumb buffer allocation API doesn't really allow
> > to
> > +	 * specify a custom size or stride. Yet the caller is free to
> > specify
> > +	 * them, so we need to make sure to error out in this case.
> > +	 */
> > +	igt_assert(fb->size == 0);
> > +	igt_assert(fb->strides[0] == 0);
> 
> Hi Maxime, thanks for doing this. I am not an expert but do you think
> this should be igt_skip instead? Tests will simply fail where they
> should really be skipping if driver don't support the feature.

That's a good suggestion :)

I'm not sure what the proper behaviour here is though. Both approaches
make sense I guess, but skiping the test would hide that issue under
the carpet which might or might not be an issue, I don't know.

Maxime

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

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
  2019-01-29 20:07   ` Ville Syrjälä
@ 2019-01-30 15:06     ` Maxime Ripard
  0 siblings, 0 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-30 15:06 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Petri Latvala, eben, igt-dev, Thomas Petazzoni


[-- Attachment #1.1: Type: text/plain, Size: 4565 bytes --]

Hi Ville,

On Tue, Jan 29, 2019 at 10:07:36PM +0200, Ville Syrjälä wrote:
> On Fri, Jan 25, 2019 at 03:58:32PM +0100, Maxime Ripard wrote:
> > The current way we work when we want to support a new YUV format to IGT, we
> > also need to add new function to convert to and from XRGB8888.
> > 
> > This doesn't really scale however, and creates a lot of code to maintain.
> > In order to work around this, create a generic function to convert to RGB
> > and one to convert from RGB.
> > 
> > The only thing that is needed now is to add new parameters, and that's it.
> 
> What's the performance impact of this?

I just measured one test on a old laptop we have here (with an i7 4600U):

The first run is with the current code (note that the message is wrong
and its milliseconds, not seconds):

./build/tests/kms_plane --run-subtest pixel-format-pipe-a-planes 
IGT-Version: 1.23-g1c1612bd (x86_64) (Linux: 4.18.0-1-amd64 x86_64)
Starting subtest: pixel-format-pipe-A-planes
Testing format XR24 (0x34325258) on A.0
Testing format RG16 (0x36314752) on A.0
Testing format XR30 (0x30335258) on A.0
Testing format XR24 (0x34325258) on A.1
Testing format YUYV (0x56595559) on A.1
took 79.655000 seconds to execute
took 76.913000 seconds to execute
took 77.148000 seconds to execute
took 76.004000 seconds to execute
took 77.223000 seconds to execute
took 76.348000 seconds to execute
took 74.939000 seconds to execute
took 76.563000 seconds to execute
Testing format YVYU (0x55595659) on A.1
took 75.744000 seconds to execute
took 76.446000 seconds to execute
took 75.803000 seconds to execute
took 76.711000 seconds to execute
took 75.568000 seconds to execute
took 78.681000 seconds to execute
took 77.757000 seconds to execute
took 76.557000 seconds to execute
Testing format UYVY (0x59565955) on A.1
took 77.667000 seconds to execute
took 76.608000 seconds to execute
took 77.551000 seconds to execute
took 76.773000 seconds to execute
took 77.498000 seconds to execute
took 72.944000 seconds to execute
took 72.988000 seconds to execute
took 77.015000 seconds to execute
Testing format VYUY (0x59555956) on A.1
took 77.795000 seconds to execute
took 72.955000 seconds to execute
took 72.945000 seconds to execute
took 77.114000 seconds to execute
took 77.893000 seconds to execute
took 72.930000 seconds to execute
took 72.949000 seconds to execute
took 73.089000 seconds to execute
Testing format AR24 (0x34325241) on A.2
Subtest pixel-format-pipe-A-planes: SUCCESS (12.297s)

This is the same test, with the new conversion code:

./build/tests/kms_plane --run-subtest pixel-format-pipe-a-planes 
IGT-Version: 1.23-gec936cad (x86_64) (Linux: 4.18.0-1-amd64 x86_64)
Starting subtest: pixel-format-pipe-A-planes
Testing format XR24 (0x34325258) on A.0
Testing format RG16 (0x36314752) on A.0
Testing format XR30 (0x30335258) on A.0
Testing format XR24 (0x34325258) on A.1
Testing format YUYV (0x56595559) on A.1
took 79.515000 seconds to execute
took 79.751000 seconds to execute
took 79.271000 seconds to execute
took 75.816000 seconds to execute
took 75.774000 seconds to execute
took 79.381000 seconds to execute
took 78.029000 seconds to execute
took 78.134000 seconds to execute
Testing format YVYU (0x55595659) on A.1
took 78.705000 seconds to execute
took 78.814000 seconds to execute
took 78.498000 seconds to execute
took 78.636000 seconds to execute
took 78.821000 seconds to execute
took 78.706000 seconds to execute
took 78.662000 seconds to execute
took 78.800000 seconds to execute
Testing format UYVY (0x59565955) on A.1
took 78.731000 seconds to execute
took 78.949000 seconds to execute
took 79.031000 seconds to execute
took 79.433000 seconds to execute
took 77.495000 seconds to execute
took 79.217000 seconds to execute
took 78.766000 seconds to execute
took 78.944000 seconds to execute
Testing format VYUY (0x59555956) on A.1
took 74.723000 seconds to execute
took 79.081000 seconds to execute
took 78.154000 seconds to execute
took 78.163000 seconds to execute
took 78.282000 seconds to execute
took 78.346000 seconds to execute
took 78.326000 seconds to execute
took 78.272000 seconds to execute
Testing format AR24 (0x34325241) on A.2
Subtest pixel-format-pipe-A-planes: SUCCESS (13.881s)

So it looks like we're losing 2-3ms per conversion (on a 1920x1080
frame). It seems pretty negligible to me, but you're the jugde here :)

Maxime

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

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path
  2019-01-29 19:46   ` Lyude Paul
@ 2019-01-30 15:25     ` Maxime Ripard
  0 siblings, 0 replies; 40+ messages in thread
From: Maxime Ripard @ 2019-01-30 15:25 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev, Petri Latvala, Thomas Petazzoni, eben


[-- Attachment #1.1: Type: text/plain, Size: 1751 bytes --]

Hi!

On Tue, Jan 29, 2019 at 02:46:55PM -0500, Lyude Paul wrote:
> On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> > The else condition is not needed, since all the other conditions return
> > when they are done.
> > 
> > Move the KMS dumb buffer allocation outside of the outer else condition,
> > this will also allow to ease later changes.
> > 
> > Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  lib/igt_fb.c | 25 +++++++++++++++++--------
> >  1 file changed, 17 insertions(+), 8 deletions(-)
> > 
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index d69c3fb2d38d..270db8d6dc90 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -557,15 +557,24 @@ static int create_bo_for_fb(struct igt_fb *fb)
> >  			igt_require(driver_has_gem_api);
> >  			return -EINVAL;
> >  		}
> > -	} else {
> > -		fb->is_dumb = true;
> > -
> > -		fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb-
> > >height,
> > -						     fb->plane_bpp[0],
> > -						     &fb->strides[0], &fb-
> > >size);
> > -
> > -		return fb->gem_handle;
> >  	}
> > +
> > +	/*
> > +	 * The current dumb buffer allocation API doesn't really allow to
> > +	 * specify a custom size or stride. Yet the caller is free to specify
> > +	 * them, so we need to make sure to error out in this case.
> > +	 */
> > +	igt_assert(fb->size == 0);
> > +	igt_assert(fb->strides[0] == 0);
> > +
> > +	fb->size = calc_fb_size(fb);
> 
> ^ Is this supposed to be part of a seperate patch?

Yeah, definitely, I'll split it in another patch, thanks!
Maxime

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

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer
  2019-01-29 20:08   ` Lyude Paul
@ 2019-01-30 15:38     ` Maxime Ripard
  2019-01-31 18:42       ` Lyude Paul
  0 siblings, 1 reply; 40+ messages in thread
From: Maxime Ripard @ 2019-01-30 15:38 UTC (permalink / raw)
  To: Lyude Paul; +Cc: igt-dev, Petri Latvala, Thomas Petazzoni, eben


[-- Attachment #1.1: Type: text/plain, Size: 2479 bytes --]

Hi!

On Tue, Jan 29, 2019 at 03:08:10PM -0500, Lyude Paul wrote:
> On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> > The dumb buffer allocation API only considers a single plane, and even
> > though allocating multi-planar buffers through it is allowed, the stride it
> > gives back is the the width times the bpp passed as an argument.
> > 
> > That doesn't work in our case, since the bpp is going to be the one we give
> > as an argument, but split over three planes so the stride doesn't match
> > anymore.
> > 
> > A proper fix for this would be to have a better dumb buffer allocation API,
> > but for the time being, let's do it that way.
> > 
> > Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  lib/igt_fb.c | 17 ++++++++++++++++-
> >  1 file changed, 16 insertions(+), 1 deletion(-)
> > 
> > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > index 1c52aebb674e..048d274e5d36 100644
> > --- a/lib/igt_fb.c
> > +++ b/lib/igt_fb.c
> > @@ -530,6 +530,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
> >  {
> >  	const struct format_desc_struct *fmt = lookup_drm_format(fb-
> > >drm_format);
> >  	unsigned int plane, bpp;
> > +	unsigned *strides = &fb->strides[0];
> >  	int fd = fb->fd;
> >  
> >  	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb-
> > >drm_format)) {
> > @@ -575,8 +576,22 @@ static int create_bo_for_fb(struct igt_fb *fb)
> >  				    plane ? fmt->hsub * fmt->vsub : 1);
> >  
> >  	fb->is_dumb = true;
> > +
> > +	/*
> > +	 * We can't really pass the stride array here since the dumb
> > +	 * buffer allocation is assuming that it operates on one
> > +	 * plane, and therefore will calculate the stride as if each
> > +	 * pixels were stored on a single plane.
> 
> nitpick: s/each pixels were/each pixel was/
> 
> > +	 *
> > +	 * This might cause issues at some point on drivers that would
> > +	 * change the stride of YUV buffers, but we haven't
> > +	 * encountered any yet.
> > +	 */
> Is it possible to add an igt_assert to check for this? Either way, with those
> changes:

I'm not sure we can test this actually. If we don't pass any pointer,
then we don't get a stride back, and if we do then we will always get
a stride that is wrong for what we're trying to do :/

Maxime

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

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer
  2019-01-30 15:38     ` Maxime Ripard
@ 2019-01-31 18:42       ` Lyude Paul
  0 siblings, 0 replies; 40+ messages in thread
From: Lyude Paul @ 2019-01-31 18:42 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: igt-dev, Petri Latvala, Thomas Petazzoni, eben

On Wed, 2019-01-30 at 16:38 +0100, Maxime Ripard wrote:
> Hi!
> 
> On Tue, Jan 29, 2019 at 03:08:10PM -0500, Lyude Paul wrote:
> > On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> > > The dumb buffer allocation API only considers a single plane, and even
> > > though allocating multi-planar buffers through it is allowed, the stride
> > > it
> > > gives back is the the width times the bpp passed as an argument.
> > > 
> > > That doesn't work in our case, since the bpp is going to be the one we
> > > give
> > > as an argument, but split over three planes so the stride doesn't match
> > > anymore.
> > > 
> > > A proper fix for this would be to have a better dumb buffer allocation
> > > API,
> > > but for the time being, let's do it that way.
> > > 
> > > Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > ---
> > >  lib/igt_fb.c | 17 ++++++++++++++++-
> > >  1 file changed, 16 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> > > index 1c52aebb674e..048d274e5d36 100644
> > > --- a/lib/igt_fb.c
> > > +++ b/lib/igt_fb.c
> > > @@ -530,6 +530,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
> > >  {
> > >  	const struct format_desc_struct *fmt = lookup_drm_format(fb-
> > > > drm_format);
> > >  	unsigned int plane, bpp;
> > > +	unsigned *strides = &fb->strides[0];
> > >  	int fd = fb->fd;
> > >  
> > >  	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb-
> > > > drm_format)) {
> > > @@ -575,8 +576,22 @@ static int create_bo_for_fb(struct igt_fb *fb)
> > >  				    plane ? fmt->hsub * fmt->vsub : 1);
> > >  
> > >  	fb->is_dumb = true;
> > > +
> > > +	/*
> > > +	 * We can't really pass the stride array here since the dumb
> > > +	 * buffer allocation is assuming that it operates on one
> > > +	 * plane, and therefore will calculate the stride as if each
> > > +	 * pixels were stored on a single plane.
> > 
> > nitpick: s/each pixels were/each pixel was/
> > 
> > > +	 *
> > > +	 * This might cause issues at some point on drivers that would
> > > +	 * change the stride of YUV buffers, but we haven't
> > > +	 * encountered any yet.
> > > +	 */
> > Is it possible to add an igt_assert to check for this? Either way, with
> > those
> > changes:
> 
> I'm not sure we can test this actually. If we don't pass any pointer,
> then we don't get a stride back, and if we do then we will always get
> a stride that is wrong for what we're trying to do :/
Ah, makes sense
> 
> Maxime
> 
-- 
Cheers,
	Lyude Paul

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
  2019-01-25 15:34   ` Paul Kocialkowski
  2019-01-29 20:10   ` Lyude Paul
@ 2019-02-05  9:40   ` Paul Kocialkowski
  2 siblings, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-02-05  9:40 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> We only need to allocate a buffer using the GEM API when we're in the
> condition that we currently test, and that we're running on i915.
> 
> All the other cases can be handled by a fallback to a dumb buffer
> allocation. Let's simplify the code a bit to reflect that.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> ---
>  lib/igt_fb.c | 25 ++++++++-----------------
>  1 file changed, 8 insertions(+), 17 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 65aa99ecf7ae..43e527d1a3dd 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -533,7 +533,8 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	unsigned *strides = &fb->strides[0];
>  	int fd = fb->fd;
>  
> -	if (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format)) {
> +	if (is_i915_device(fd) &&
> +	   (fb->tiling || fb->size || fb->strides[0] || igt_format_is_yuv(fb->drm_format))) {
>  		uint64_t size;
>  
>  		size = calc_fb_size(fb);
> @@ -543,23 +544,12 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  			fb->size = size;
>  
>  		fb->is_dumb = false;
> +		fb->gem_handle = gem_create(fd, fb->size);
> +		gem_set_tiling(fd, fb->gem_handle,
> +			       igt_fb_mod_to_tiling(fb->tiling),
> +			       fb->strides[0]);
>  
> -		if (is_i915_device(fd)) {
> -
> -			fb->gem_handle = gem_create(fd, fb->size);
> -
> -			gem_set_tiling(fd, fb->gem_handle,
> -				       igt_fb_mod_to_tiling(fb->tiling),
> -				       fb->strides[0]);
> -			clear_yuv_buffer(fd);
> -
> -			return fb->gem_handle;
> -		} else {
> -			bool driver_has_gem_api = false;
> -
> -			igt_require(driver_has_gem_api);
> -			return -EINVAL;
> -		}
> +		goto out;
>  	}
>  
>  	/*
> @@ -593,6 +583,7 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  	fb->gem_handle = kmstest_dumb_create(fd, fb->width, fb->height,
>  					     bpp, strides, &fb->size);
>  
> +out:
>  	if (igt_format_is_yuv(fb->drm_format))
>  		clear_yuv_buffer(fb);
>  
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
@ 2019-02-05 12:52   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-02-05 12:52 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> In order to improve the YUV support, let's add the horizontal and vertical
> subsampling parameters to the IGT formats.

Pushed, thanks!

Cheers,

Paul

> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 35 +++++++++++++++++++++++++++++------
>  1 file changed, 29 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 5cd1829a3ce4..e23908e28c07 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -71,85 +71,104 @@ static const struct format_desc_struct {
>  	int depth;
>  	int num_planes;
>  	int plane_bpp[4];
> +	uint8_t hsub;
> +	uint8_t vsub;
>  } format_desc[] = {
>  	{ .name = "ARGB1555", .depth = -1, .drm_id = DRM_FORMAT_ARGB1555,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_a1r5g5b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB1555", .depth = -1, .drm_id = DRM_FORMAT_XRGB1555,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_x1r5g5b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "RGB565", .depth = 16, .drm_id = DRM_FORMAT_RGB565,
>  	  .cairo_id = CAIRO_FORMAT_RGB16_565,
>  	  .pixman_id = PIXMAN_r5g6b5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "BGR565", .depth = -1, .drm_id = DRM_FORMAT_BGR565,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_b5g6r5,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "BGR888", .depth = -1, .drm_id = DRM_FORMAT_BGR888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 24, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "RGB888", .depth = -1, .drm_id = DRM_FORMAT_RGB888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 24, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XYUV8888", .depth = -1, .drm_id = DRM_FORMAT_XYUV8888,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .pixman_id = PIXMAN_x8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XBGR8888", .depth = -1, .drm_id = DRM_FORMAT_XBGR8888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_x8b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "XRGB2101010", .depth = 30, .drm_id = DRM_FORMAT_XRGB2101010,
>  	  .cairo_id = CAIRO_FORMAT_RGB30,
>  	  .pixman_id = PIXMAN_x2r10g10b10,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "ARGB8888", .depth = 32, .drm_id = DRM_FORMAT_ARGB8888,
>  	  .cairo_id = CAIRO_FORMAT_ARGB32,
>  	  .pixman_id = PIXMAN_a8r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "ABGR8888", .depth = -1, .drm_id = DRM_FORMAT_ABGR8888,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .pixman_id = PIXMAN_a8b8g8r8,
>  	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
>  	},
>  	{ .name = "NV12", .depth = -1, .drm_id = DRM_FORMAT_NV12,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 2, .plane_bpp = { 8, 16, },
> +	  .hsub = 2, .vsub = 2,
>  	},
>  	{ .name = "YUYV", .depth = -1, .drm_id = DRM_FORMAT_YUYV,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "YVYU", .depth = -1, .drm_id = DRM_FORMAT_YVYU,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "UYVY", .depth = -1, .drm_id = DRM_FORMAT_UYVY,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  	{ .name = "VYUY", .depth = -1, .drm_id = DRM_FORMAT_VYUY,
>  	  .cairo_id = CAIRO_FORMAT_RGB24,
>  	  .num_planes = 1, .plane_bpp = { 16, },
> +	  .hsub = 2, .vsub = 1,
>  	},
>  };
>  #define for_each_format(f)	\
> @@ -239,10 +258,12 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int fb_bpp,
>  
>  static unsigned fb_plane_width(const struct igt_fb *fb, int plane)
>  {
> -	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
> -		return DIV_ROUND_UP(fb->width, 2);
> +	const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
>  
> -	return fb->width;
> +	if (plane == 0)
> +		return fb->width;
> +
> +	return DIV_ROUND_UP(fb->width, format->hsub);
>  }
>  
>  static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
> @@ -254,10 +275,12 @@ static unsigned fb_plane_bpp(const struct igt_fb *fb, int plane)
>  
>  static unsigned fb_plane_height(const struct igt_fb *fb, int plane)
>  {
> -	if (fb->drm_format == DRM_FORMAT_NV12 && plane == 1)
> -		return DIV_ROUND_UP(fb->height, 2);
> +	const struct format_desc_struct *format = lookup_drm_format(fb->drm_format);
>  
> -	return fb->height;
> +	if (plane == 0)
> +		return fb->height;
> +
> +	return DIV_ROUND_UP(fb->height, format->vsub);
>  }
>  
>  static int fb_num_planes(const struct igt_fb *fb)
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
@ 2019-02-05 12:52   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-02-05 12:52 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> Aligning the width on 64 pixels only make sense on intel platforms, make
> sure to add a check against this.

Pushed, thanks!

Cheers,

Paul

> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index e23908e28c07..1a5c338ea532 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -204,7 +204,11 @@ void igt_get_fb_tile_size(int fd, uint64_t tiling, int fb_bpp,
>  {
>  	switch (tiling) {
>  	case LOCAL_DRM_FORMAT_MOD_NONE:
> -		*width_ret = 64;
> +		if (is_i915_device(fd))
> +			*width_ret = 64;
> +		else
> +			*width_ret = 1;
> +
>  		*height_ret = 1;
>  		break;
>  	case LOCAL_I915_FORMAT_MOD_X_TILED:
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
  2019-01-29 19:42   ` Lyude Paul
  2019-01-29 20:07   ` Ville Syrjälä
@ 2019-02-05 12:53   ` Paul Kocialkowski
  2 siblings, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-02-05 12:53 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The current way we work when we want to support a new YUV format to IGT, we
> also need to add new function to convert to and from XRGB8888.
> 
> This doesn't really scale however, and creates a lot of code to maintain.
> In order to work around this, create a generic function to convert to RGB
> and one to convert from RGB.
> 
> The only thing that is needed now is to add new parameters, and that's it.

Pushed, thanks!

Cheers,

Paul

> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 537 ++++++++++++++++-----------------------------------
>  1 file changed, 171 insertions(+), 366 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 1a5c338ea532..45691fd441d9 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -1577,424 +1577,237 @@ static void convert_src_put(const struct fb_convert *cvt,
>  		free(src_buf);
>  }
>  
> -static void convert_nv12_to_rgb24(struct fb_convert *cvt)
> +struct yuv_parameters {
> +	unsigned	y_inc;
> +	unsigned	uv_inc;
> +	unsigned	y_stride;
> +	unsigned	uv_stride;
> +	unsigned	y_offset;
> +	unsigned	u_offset;
> +	unsigned	v_offset;
> +};
> +
> +static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  {
> -	int i, j;
> -	const uint8_t *y, *uv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int planar_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
> -						    cvt->src.fb->color_range);
> -	uint8_t *buf;
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_NV12 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	y = buf + cvt->src.fb->offsets[0];
> -	uv = buf + cvt->src.fb->offsets[1];
> -
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 yuv[4];
> -			struct igt_vec4 rgb[4];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[2].d[0] = y[j * 2 + 0 + planar_stride];
> -			yuv[3].d[0] = y[j * 2 + 1 + planar_stride];
> -
> -			yuv[0].d[1] = yuv[1].d[1] = yuv[2].d[1] = yuv[3].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = yuv[2].d[2] = yuv[3].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = yuv[2].d[3] = yuv[3].d[3] = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -			rgb[2] = igt_matrix_transform(&m, &yuv[2]);
> -			rgb[3] = igt_matrix_transform(&m, &yuv[3]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[2]);
> -			write_rgb(&rgb24[j * 8 + 4 + rgb24_stride], &rgb[3]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 0 + planar_stride];
> +	igt_assert(igt_format_is_yuv(fb->drm_format));
>  
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_inc = 1;
> +		params->uv_inc = 2;
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 0 + rgb24_stride], &rgb[1]);
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +		params->y_inc = 2;
> +		params->uv_inc = 4;
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_inc = 4;
> +		params->uv_inc = 4;
> +		break;
>  	}
>  
> -	if (cvt->dst.fb->height & 1) {
> -		/* Convert last row */
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = y[j * 2 + 0];
> -			yuv[1].d[0] = y[j * 2 + 1];
> -			yuv[0].d[1] = yuv[1].d[1] = uv[j * 2 + 0];
> -			yuv[0].d[2] = yuv[1].d[2] = uv[j * 2 + 1];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[1];
> +		break;
>  
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_stride = fb->strides[0];
> +		params->uv_stride = fb->strides[0];
> +		break;
> +	}
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[0]);
> -		}
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[1];
> +		params->v_offset = fb->offsets[1] + 1;
> +		break;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> +	case DRM_FORMAT_YUYV:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 1;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  
> -			yuv.d[0] = y[j * 2 + 0];
> -			yuv.d[1] = uv[j * 2 + 0];
> -			yuv.d[2] = uv[j * 2 + 1];
> -			yuv.d[3] = 1.0f;
> +	case DRM_FORMAT_YVYU:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 3;
> +		params->v_offset = fb->offsets[0] + 1;
> +		break;
>  
> -			rgb = igt_matrix_transform(&m, &yuv);
> +	case DRM_FORMAT_UYVY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0];
> +		params->v_offset = fb->offsets[0] + 2;
> +		break;
>  
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> -		}
> +	case DRM_FORMAT_VYUY:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0];
> +		break;
> +
> +	case DRM_FORMAT_XYUV8888:
> +		params->y_offset = fb->offsets[0] + 1;
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0] + 3;
> +		break;
>  	}
> -
> -	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_yuv444_to_rgb24(struct fb_convert *cvt)
> +static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *src_fmt =
> +		lookup_drm_format(cvt->src.fb->drm_format);
>  	int i, j;
> -	uint8_t *yuv24;
> +	uint8_t bpp = 4;
> +	uint8_t *y, *u, *v;
>  	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned rgb24_stride = cvt->dst.fb->strides[0], xyuv_stride = cvt->src.fb->strides[0];
> -	uint8_t *buf = malloc(cvt->src.fb->size);
> +	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
>  						    cvt->src.fb->color_range);
> +	uint8_t *buf;
> +	struct yuv_parameters params = { };
>  
> -	/*
> -	 * 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, cvt->src.ptr + cvt->src.fb->offsets[0], cvt->src.fb->size);
> -	yuv24 = buf;
> +	igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> +		   igt_format_is_yuv(cvt->src.fb->drm_format));
> +
> +	buf = convert_src_get(cvt);
> +	get_yuv_parameters(cvt->src.fb, &params);
> +	y = buf + params.y_offset;
> +	u = buf + params.u_offset;
> +	v = buf + params.v_offset;
>  
>  	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *y_tmp = y;
> +		const uint8_t *u_tmp = u;
> +		const uint8_t *v_tmp = v;
> +		uint8_t *rgb_tmp = rgb24;
> +
>  		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			float y, u, v;
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			v = yuv24[i * xyuv_stride + j * 4];
> -			u = yuv24[i * xyuv_stride + j * 4 + 1];
> -			y = yuv24[i * xyuv_stride + j * 4 + 2];
> -			yuv.d[0] = y;
> -			yuv.d[1] = u;
> -			yuv.d[2] = v;
> +			struct igt_vec4 rgb, yuv;
> +
> +			yuv.d[0] = *y_tmp;
> +			yuv.d[1] = *u_tmp;
> +			yuv.d[2] = *v_tmp;
>  			yuv.d[3] = 1.0f;
>  
>  			rgb = igt_matrix_transform(&m, &yuv);
> +			write_rgb(rgb_tmp, &rgb);
>  
> -			write_rgb(&rgb24[i * rgb24_stride + j * 4], &rgb);
> -		}
> -	}
> -
> -	free(buf);
> -}
> -
> -
> -static void convert_rgb24_to_yuv444(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *rgb24;
> -	uint8_t *yuv444 = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	unsigned int rgb24_stride = cvt->src.fb->strides[0], xyuv_stride = cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
> -						    cvt->dst.fb->color_range);
> -
> -	rgb24 = cvt->src.ptr;
> +			rgb_tmp += bpp;
> +			y_tmp += params.y_inc;
>  
> -	igt_assert_f(cvt->dst.fb->drm_format == DRM_FORMAT_XYUV8888,
> -		     "Conversion not implemented for !XYUV packed formats\n");
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width; j++) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[i * rgb24_stride + j * 4]);
> +			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
> +				u_tmp += params.uv_inc;
> +				v_tmp += params.uv_inc;
> +			}
> +		}
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +		rgb24 += rgb24_stride;
> +		y += params.y_stride;
>  
> -			yuv444[i * xyuv_stride + j * 4] = yuv.d[2];
> -			yuv444[i * xyuv_stride + j * 4 + 1] = yuv.d[1];
> -			yuv444[i * xyuv_stride + j * 4 + 2] = yuv.d[0];
> +		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
>  	}
> +
> +	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_rgb24_to_nv12(struct fb_convert *cvt)
> +static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>  {
> +	const struct format_desc_struct *dst_fmt =
> +		lookup_drm_format(cvt->dst.fb->drm_format);
>  	int i, j;
> -	uint8_t *y = cvt->dst.ptr + cvt->dst.fb->offsets[0];
> -	uint8_t *uv = cvt->dst.ptr + cvt->dst.fb->offsets[1];
> +	uint8_t *y, *u, *v;
>  	const uint8_t *rgb24 = cvt->src.ptr;
> +	uint8_t bpp = 4;
>  	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned planar_stride = cvt->dst.fb->strides[0];
>  	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
>  						    cvt->dst.fb->color_range);
> +	struct yuv_parameters params = { };
>  
>  	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_NV12);
> +		   igt_format_is_yuv(cvt->dst.fb->drm_format));
>  
> -	for (i = 0; i < cvt->dst.fb->height / 2; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x2 pixel blocks */
> -			struct igt_vec4 rgb[4];
> -			struct igt_vec4 yuv[4];
> +	get_yuv_parameters(cvt->dst.fb, &params);
> +	y = cvt->dst.ptr + params.y_offset;
> +	u = cvt->dst.ptr + params.u_offset;
> +	v = cvt->dst.ptr + params.v_offset;
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -			read_rgb(&rgb[2], &rgb24[j * 8 + 0 + rgb24_stride]);
> -			read_rgb(&rgb[3], &rgb24[j * 8 + 4 + rgb24_stride]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> -			yuv[2] = igt_matrix_transform(&m, &rgb[2]);
> -			yuv[3] = igt_matrix_transform(&m, &rgb[3]);
> -
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[2].d[0];
> -			y[j * 2 + 1 + planar_stride] = yuv[3].d[0];
> +	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint8_t *rgb_tmp = rgb24;
> +		uint8_t *y_tmp = y;
> +		uint8_t *u_tmp = u;
> +		uint8_t *v_tmp = v;
>  
> -			/*
> -			 * We assume the MPEG2 chroma siting convention, where
> -			 * pixel center for Cb'Cr' is between the left top and
> -			 * bottom pixel in a 2x2 block, so take the average.
> -			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[2].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[2].d[2]) / 2.0f;
> -		}
> +		for (j = 0; j < cvt->dst.fb->width; j++) {
> +			const uint8_t *pair_rgb24 = rgb_tmp;
> +			struct igt_vec4 pair_rgb, rgb;
> +			struct igt_vec4 pair_yuv, yuv;
>  
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert 1x2 pixel block */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> +			read_rgb(&rgb, rgb_tmp);
> +			yuv = igt_matrix_transform(&m, &rgb);
>  
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 0 + rgb24_stride]);
> +			rgb_tmp += bpp;
>  
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			*y_tmp = yuv.d[0];
> +			y_tmp += params.y_inc;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 0 + planar_stride] = yuv[1].d[0];
> +			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
> +				continue;
>  
>  			/*
>  			 * We assume the MPEG2 chroma siting convention, where
>  			 * pixel center for Cb'Cr' is between the left top and
>  			 * bottom pixel in a 2x2 block, so take the average.
> +			 *
> +			 * Therefore, if we use subsampling, we only really care
> +			 * about two pixels all the time, either the two
> +			 * subsequent pixels horizontally, vertically, or the
> +			 * two corners in a 2x2 block.
> +			 *
> +			 * The only corner case is when we have an odd number of
> +			 * pixels, but this can be handled pretty easily by not
> +			 * incrementing the paired pixel pointer in the
> +			 * direction it's odd in.
>  			 */
> -			uv[j * 2 + 0] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
> -			uv[j * 2 + 1] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
> -		}
> -
> -		rgb24 += 2 * rgb24_stride;
> -		y += 2 * planar_stride;
> -		uv += planar_stride;
> -	}
> -
> -	/* Last row cannot be interpolated between 2 pixels, take the single value */
> -	if (cvt->dst.fb->height & 1) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +			if (j != (cvt->dst.fb->width - 1))
> +				pair_rgb24 += (dst_fmt->hsub - 1) * bpp;
>  
> -			y[j * 2 + 0] = yuv[0].d[0];
> -			y[j * 2 + 1] = yuv[1].d[0];
> -			uv[j * 2 + 0] = yuv[0].d[1];
> -			uv[j * 2 + 1] = yuv[0].d[2];
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			/* Convert single pixel */
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> +			if (i != (cvt->dst.fb->height - 1))
> +				pair_rgb24 += rgb24_stride * (dst_fmt->vsub - 1);
>  
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> +			read_rgb(&pair_rgb, pair_rgb24);
> +			pair_yuv = igt_matrix_transform(&m, &pair_rgb);
>  
> -			yuv = igt_matrix_transform(&m, &rgb);
> +			*u_tmp = (yuv.d[1] + pair_yuv.d[1]) / 2.0f;
> +			*v_tmp = (yuv.d[2] + pair_yuv.d[2]) / 2.0f;
>  
> -			y[j * 2 + 0] = yuv.d[0];
> -			uv[j * 2 + 0] = yuv.d[1];
> -			uv[j * 2 + 1] = yuv.d[2];
> -		}
> -	}
> -}
> -
> -/* { Y0, U, Y1, V } */
> -static const unsigned char swizzle_yuyv[] = { 0, 1, 2, 3 };
> -static const unsigned char swizzle_yvyu[] = { 0, 3, 2, 1 };
> -static const unsigned char swizzle_uyvy[] = { 1, 0, 3, 2 };
> -static const unsigned char swizzle_vyuy[] = { 1, 2, 3, 0 };
> -
> -static const unsigned char *yuyv_swizzle(uint32_t format)
> -{
> -	switch (format) {
> -	default:
> -	case DRM_FORMAT_YUYV:
> -		return swizzle_yuyv;
> -	case DRM_FORMAT_YVYU:
> -		return swizzle_yvyu;
> -	case DRM_FORMAT_UYVY:
> -		return swizzle_uyvy;
> -	case DRM_FORMAT_VYUY:
> -		return swizzle_vyuy;
> -	}
> -}
> -
> -static void convert_yuyv_to_rgb24(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	const uint8_t *yuyv;
> -	uint8_t *rgb24 = cvt->dst.ptr;
> -	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
> -	unsigned int yuyv_stride = cvt->src.fb->strides[0];
> -	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
> -						    cvt->src.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->src.fb->drm_format);
> -	uint8_t *buf;
> -
> -	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->src.fb->drm_format == DRM_FORMAT_VYUY) &&
> -		   cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888);
> -
> -	buf = convert_src_get(cvt);
> -	yuyv = buf;
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 yuv[2];
> -			struct igt_vec4 rgb[2];
> -
> -			yuv[0].d[0] = yuyv[j * 4 + swz[0]];
> -			yuv[1].d[0] = yuyv[j * 4 + swz[2]];
> -			yuv[0].d[1] = yuv[1].d[1] = yuyv[j * 4 + swz[1]];
> -			yuv[0].d[2] = yuv[1].d[2] = yuyv[j * 4 + swz[3]];
> -			yuv[0].d[3] = yuv[1].d[3] = 1.0f;
> -
> -			rgb[0] = igt_matrix_transform(&m, &yuv[0]);
> -			rgb[1] = igt_matrix_transform(&m, &yuv[1]);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb[0]);
> -			write_rgb(&rgb24[j * 8 + 4], &rgb[1]);
> -		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 yuv;
> -			struct igt_vec4 rgb;
> -
> -			yuv.d[0] = yuyv[j * 4 + swz[0]];
> -			yuv.d[1] = yuyv[j * 4 + swz[1]];
> -			yuv.d[2] = yuyv[j * 4 + swz[3]];
> -			yuv.d[3] = 1.0f;
> -
> -			rgb = igt_matrix_transform(&m, &yuv);
> -
> -			write_rgb(&rgb24[j * 8 + 0], &rgb);
> +			u_tmp += params.uv_inc;
> +			v_tmp += params.uv_inc;
>  		}
>  
>  		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
> -	}
> -
> -	convert_src_put(cvt, buf);
> -}
> -
> -static void convert_rgb24_to_yuyv(struct fb_convert *cvt)
> -{
> -	int i, j;
> -	uint8_t *yuyv = cvt->dst.ptr;
> -	const uint8_t *rgb24 = cvt->src.ptr;
> -	unsigned rgb24_stride = cvt->src.fb->strides[0];
> -	unsigned yuyv_stride = cvt->dst.fb->strides[0];
> -	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->dst.fb->color_encoding,
> -						    cvt->dst.fb->color_range);
> -	const unsigned char *swz = yuyv_swizzle(cvt->dst.fb->drm_format);
> -
> -	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
> -		   (cvt->dst.fb->drm_format == DRM_FORMAT_YUYV ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_UYVY ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_YVYU ||
> -		    cvt->dst.fb->drm_format == DRM_FORMAT_VYUY));
> -
> -	for (i = 0; i < cvt->dst.fb->height; i++) {
> -		for (j = 0; j < cvt->dst.fb->width / 2; j++) {
> -			/* Convert 2x1 pixel blocks */
> -			struct igt_vec4 rgb[2];
> -			struct igt_vec4 yuv[2];
> -
> -			read_rgb(&rgb[0], &rgb24[j * 8 + 0]);
> -			read_rgb(&rgb[1], &rgb24[j * 8 + 4]);
> -
> -			yuv[0] = igt_matrix_transform(&m, &rgb[0]);
> -			yuv[1] = igt_matrix_transform(&m, &rgb[1]);
> +		y += params.y_stride;
>  
> -			yuyv[j * 4 + swz[0]] = yuv[0].d[0];
> -			yuyv[j * 4 + swz[2]] = yuv[1].d[0];
> -			yuyv[j * 4 + swz[1]] = (yuv[0].d[1] + yuv[1].d[1]) / 2.0f;
> -			yuyv[j * 4 + swz[3]] = (yuv[0].d[2] + yuv[1].d[2]) / 2.0f;
> +		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
> +			u += params.uv_stride;
> +			v += params.uv_stride;
>  		}
> -
> -		if (cvt->dst.fb->width & 1) {
> -			struct igt_vec4 rgb;
> -			struct igt_vec4 yuv;
> -
> -			read_rgb(&rgb, &rgb24[j * 8 + 0]);
> -
> -			yuv = igt_matrix_transform(&m, &rgb);
> -
> -			yuyv[j * 4 + swz[0]] = yuv.d[0];
> -			yuyv[j * 4 + swz[1]] = yuv.d[1];
> -			yuyv[j * 4 + swz[3]] = yuv.d[2];
> -		}
> -
> -		rgb24 += rgb24_stride;
> -		yuyv += yuyv_stride;
>  	}
>  }
>  
> @@ -2046,31 +1859,23 @@ static void fb_convert(struct fb_convert *cvt)
>  	} else if (cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->src.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_yuv444_to_rgb24(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_nv12_to_rgb24(cvt);
> -			return;
> -		case DRM_FORMAT_YUYV:
> -		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_yuyv_to_rgb24(cvt);
> +		case DRM_FORMAT_YUYV:
> +		case DRM_FORMAT_YVYU:
> +			convert_yuv_to_rgb24(cvt);
>  			return;
>  		}
>  	} else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
>  		switch (cvt->dst.fb->drm_format) {
>  		case DRM_FORMAT_XYUV8888:
> -			convert_rgb24_to_yuv444(cvt);
> -			return;
>  		case DRM_FORMAT_NV12:
> -			convert_rgb24_to_nv12(cvt);
> -			return;
>  		case DRM_FORMAT_YUYV:
>  		case DRM_FORMAT_YVYU:
>  		case DRM_FORMAT_UYVY:
>  		case DRM_FORMAT_VYUY:
> -			convert_rgb24_to_yuyv(cvt);
> +			convert_rgb24_to_yuv(cvt);
>  			return;
>  		}
>  	}
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function
  2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function Maxime Ripard
  2019-01-29 19:43   ` Lyude Paul
@ 2019-02-05 12:53   ` Paul Kocialkowski
  1 sibling, 0 replies; 40+ messages in thread
From: Paul Kocialkowski @ 2019-02-05 12:53 UTC (permalink / raw)
  To: Maxime Ripard, igt-dev; +Cc: Petri Latvala, eben, Thomas Petazzoni

Hi,

On Fri, 2019-01-25 at 15:58 +0100, Maxime Ripard wrote:
> The YUV buffer allocation path for the i915 driver also has some code to
> clear a YUV buffer.
> 
> As that is going to be useful for all the other drivers, let's move it to
> a separate function.

Pushed, thanks!

Cheers,

Paul

> Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  lib/igt_fb.c | 80 +++++++++++++++++++++++++++-------------------------
>  1 file changed, 42 insertions(+), 38 deletions(-)
> 
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 45691fd441d9..d69c3fb2d38d 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -484,6 +484,47 @@ uint64_t igt_fb_tiling_to_mod(uint64_t tiling)
>  	}
>  }
>  
> +static void clear_yuv_buffer(struct igt_fb *fb)
> +{
> +	bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
> +	void *ptr;
> +
> +	igt_assert(igt_format_is_yuv(fb->drm_format));
> +
> +	/* Ensure the framebuffer is preallocated */
> +	ptr = igt_fb_map_buffer(fb->fd, fb);
> +	igt_assert(*(uint32_t *)ptr == 0);
> +
> +	switch (fb->drm_format) {
> +	case DRM_FORMAT_NV12:
> +		memset(ptr + fb->offsets[0],
> +		       full_range ? 0x00 : 0x10,
> +		       fb->strides[0] * fb->plane_height[0]);
> +		memset(ptr + fb->offsets[1],
> +		       0x80,
> +		       fb->strides[1] * fb->plane_height[1]);
> +		break;
> +	case DRM_FORMAT_XYUV8888:
> +		wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 : 0x00108080,
> +			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +		break;
> +	case DRM_FORMAT_YUYV:
> +	case DRM_FORMAT_YVYU:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0x80008000 : 0x80108010,
> +			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +		break;
> +	case DRM_FORMAT_UYVY:
> +	case DRM_FORMAT_VYUY:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0x00800080 : 0x10801080,
> +			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +		break;
> +	}
> +
> +	igt_fb_unmap_buffer(fb, ptr);
> +}
> +
>  /* helpers to create nice-looking framebuffers */
>  static int create_bo_for_fb(struct igt_fb *fb)
>  {
> @@ -501,50 +542,13 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  		fb->is_dumb = false;
>  
>  		if (is_i915_device(fd)) {
> -			void *ptr;
> -			bool full_range = fb->color_range == IGT_COLOR_YCBCR_FULL_RANGE;
>  
>  			fb->gem_handle = gem_create(fd, fb->size);
>  
>  			gem_set_tiling(fd, fb->gem_handle,
>  				       igt_fb_mod_to_tiling(fb->tiling),
>  				       fb->strides[0]);
> -
> -			gem_set_domain(fd, fb->gem_handle,
> -				       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> -
> -			/* Ensure the framebuffer is preallocated */
> -			ptr = gem_mmap__gtt(fd, fb->gem_handle,
> -					    fb->size, PROT_READ | PROT_WRITE);
> -			igt_assert(*(uint32_t *)ptr == 0);
> -
> -			switch (fb->drm_format) {
> -			case DRM_FORMAT_NV12:
> -				memset(ptr + fb->offsets[0],
> -				       full_range ? 0x00 : 0x10,
> -				       fb->strides[0] * fb->plane_height[0]);
> -				memset(ptr + fb->offsets[1],
> -				       0x80,
> -				       fb->strides[1] * fb->plane_height[1]);
> -				break;
> -			case DRM_FORMAT_XYUV8888:
> -				wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 : 0x00108080,
> -					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> -				break;
> -			case DRM_FORMAT_YUYV:
> -			case DRM_FORMAT_YVYU:
> -				wmemset(ptr + fb->offsets[0],
> -					full_range ? 0x80008000 : 0x80108010,
> -					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> -				break;
> -			case DRM_FORMAT_UYVY:
> -			case DRM_FORMAT_VYUY:
> -				wmemset(ptr + fb->offsets[0],
> -					full_range ? 0x00800080 : 0x10801080,
> -					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> -				break;
> -			}
> -			gem_munmap(ptr, fb->size);
> +			clear_yuv_buffer(fd);
>  
>  			return fb->gem_handle;
>  		} else {
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2019-02-05 13:04 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-25 14:58 [igt-dev] [PATCH i-g-t v5 00/13] igt: chamelium: Test YUV buffers using the Chamelium Maxime Ripard
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 01/13] igt: fb: Add subsampling parameters to the formats Maxime Ripard
2019-01-29 19:42   ` Lyude Paul
2019-02-05 12:52   ` Paul Kocialkowski
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 02/13] igt: fb: Reduce tile size alignment for non intel platforms Maxime Ripard
2019-01-29 19:42   ` Lyude Paul
2019-02-05 12:52   ` Paul Kocialkowski
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function Maxime Ripard
2019-01-29 19:42   ` Lyude Paul
2019-01-29 20:07   ` Ville Syrjälä
2019-01-30 15:06     ` Maxime Ripard
2019-02-05 12:53   ` Paul Kocialkowski
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 04/13] igt: fb: Move i915 YUV buffer clearing code to a function Maxime Ripard
2019-01-29 19:43   ` Lyude Paul
2019-02-05 12:53   ` Paul Kocialkowski
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 05/13] igt: fb: Refactor dumb buffer allocation path Maxime Ripard
2019-01-25 16:16   ` Deepak Singh Rawat
2019-01-30 14:18     ` Maxime Ripard
2019-01-29 19:46   ` Lyude Paul
2019-01-30 15:25     ` Maxime Ripard
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 06/13] igt: fb: Account for all planes bpp Maxime Ripard
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 07/13] igt: fb: Don't pass the stride when allocating a dumb, multi-planar buffer Maxime Ripard
2019-01-29 20:08   ` Lyude Paul
2019-01-30 15:38     ` Maxime Ripard
2019-01-31 18:42       ` Lyude Paul
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 08/13] igt: fb: Clear YUV dumb buffers Maxime Ripard
2019-01-29 20:08   ` Lyude Paul
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 09/13] igt: fb: Rework YUV i915 allocation path Maxime Ripard
2019-01-25 15:34   ` Paul Kocialkowski
2019-01-29 20:10   ` Lyude Paul
2019-02-05  9:40   ` Paul Kocialkowski
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 10/13] igt: fb: Add a bunch of new YUV formats Maxime Ripard
2019-01-29 20:11   ` Lyude Paul
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 11/13] igt: tests: chamelium: Start to unify tests Maxime Ripard
2019-01-29 20:13   ` Lyude Paul
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 12/13] igt: tests: chamelium: Convert VGA tests to do_test_display Maxime Ripard
2019-01-29 20:14   ` Lyude Paul
2019-01-25 14:58 ` [igt-dev] [PATCH i-g-t v5 13/13] igt: tests: chamelium: Add YUV formats tests Maxime Ripard
2019-01-29 20:14   ` Lyude Paul
2019-01-25 15:50 ` [igt-dev] ✗ Fi.CI.BAT: failure for igt: chamelium: Test YUV buffers using the Chamelium (rev7) Patchwork

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.