All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests.
@ 2019-03-27  9:29 Maarten Lankhorst
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3 Maarten Lankhorst
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Maarten Lankhorst @ 2019-03-27  9:29 UTC (permalink / raw)
  To: igt-dev

Add Y21x/Y41x/XVYU hdr format support, and some tests to excercise these features.

Test-with: 20190322135954.20434-1-maarten.lankhorst@linux.intel.com

Maarten Lankhorst (3):
  lib/igt_fb: Add support for Y21x formats as well, v3.
  lib/igt_fb: Add support for Y410/Y416 formats, v4.
  tests/kms_yuv: Add yuv specific tests, v3.

 include/drm-uapi/drm_fourcc.h |  51 +-
 lib/igt_color_encoding.c      |   9 +
 lib/igt_fb.c                  | 309 ++++++++++++-
 tests/Makefile.sources        |   1 +
 tests/kms_yuv.c               | 843 ++++++++++++++++++++++++++++++++++
 tests/meson.build             |   1 +
 6 files changed, 1188 insertions(+), 26 deletions(-)
 create mode 100644 tests/kms_yuv.c

-- 
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] 10+ messages in thread

* [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3.
  2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
@ 2019-03-27  9:29 ` Maarten Lankhorst
  2019-03-27 17:21   ` Ville Syrjälä
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4 Maarten Lankhorst
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Maarten Lankhorst @ 2019-03-27  9:29 UTC (permalink / raw)
  To: igt-dev

Those formats are packed like YUYV, but only 16 bits per component.

Changes since v1:
- Rebase on top of upstream YUV changes.
Changes since v2:
- Use drm_fourcc.h from upstream.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 include/drm-uapi/drm_fourcc.h | 51 ++++++++++++++++++++++++++++++++++-
 lib/igt_color_encoding.c      |  3 +++
 lib/igt_fb.c                  | 46 +++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
index bab20298f422..3feeaa3f987a 100644
--- a/include/drm-uapi/drm_fourcc.h
+++ b/include/drm-uapi/drm_fourcc.h
@@ -144,6 +144,17 @@ extern "C" {
 #define DRM_FORMAT_RGBA1010102	fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
 #define DRM_FORMAT_BGRA1010102	fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
 
+/*
+ * Floating point 64bpp RGB
+ * IEEE 754-2008 binary16 half-precision float
+ * [15:0] sign:exponent:mantissa 1:5:10
+ */
+#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H') /* [63:0] x:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */
+
+#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') /* [63:0] A:R:G:B 16:16:16:16 little endian */
+#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
+
 /* packed YCbCr */
 #define DRM_FORMAT_YUYV		fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
 #define DRM_FORMAT_YVYU		fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
@@ -151,7 +162,29 @@ extern "C" {
 #define DRM_FORMAT_VYUY		fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
 
 #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
-#define DRM_FORMAT_XYUV8888		fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XYUV8888	fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_VUY888	fourcc_code('V', 'U', '2', '4') /* [23:0] Cr:Cb:Y 8:8:8 little endian */
+#define DRM_FORMAT_VUY101010	fourcc_code('V', 'U', '3', '0') /* Y followed by U then V, 10:10:10. Non-linear modifier only */
+
+/*
+ * packed Y2xx indicate for each component, xx valid data occupy msb
+ * 16-xx padding occupy lsb
+ */
+#define DRM_FORMAT_Y210         fourcc_code('Y', '2', '1', '0') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels */
+#define DRM_FORMAT_Y212         fourcc_code('Y', '2', '1', '2') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels */
+#define DRM_FORMAT_Y216         fourcc_code('Y', '2', '1', '6') /* [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels */
+
+/*
+ * packed Y4xx indicate for each component, xx valid data occupy msb
+ * 16-xx padding occupy lsb except Y410
+ */
+#define DRM_FORMAT_Y410         fourcc_code('Y', '4', '1', '0') /* [31:0] A:Cr:Y:Cb 2:10:10:10 little endian */
+#define DRM_FORMAT_Y412         fourcc_code('Y', '4', '1', '2') /* [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */
+#define DRM_FORMAT_Y416         fourcc_code('Y', '4', '1', '6') /* [63:0] A:Cr:Y:Cb 16:16:16:16 little endian */
+
+#define DRM_FORMAT_XVYU2101010	fourcc_code('X', 'V', '3', '0') /* [31:0] X:Cr:Y:Cb 2:10:10:10 little endian */
+#define DRM_FORMAT_XVYU12_16161616	fourcc_code('X', 'V', '3', '6') /* [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */
+#define DRM_FORMAT_XVYU16161616	fourcc_code('X', 'V', '4', '8') /* [63:0] X:Cr:Y:Cb 16:16:16:16 little endian */
 
 /*
  * packed YCbCr420 2x2 tiled formats
@@ -167,6 +200,15 @@ extern "C" {
 /* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
 #define DRM_FORMAT_X0L2		fourcc_code('X', '0', 'L', '2')
 
+/*
+ * 1-plane YUV 4:2:0
+ * In these formats, the component ordering is specified (Y, followed by U
+ * then V), but the exact Linear layout is undefined.
+ * These formats can only be used with a non-Linear modifier.
+ */
+#define DRM_FORMAT_YUV420_8BIT	fourcc_code('Y', 'U', '0', '8')
+#define DRM_FORMAT_YUV420_10BIT	fourcc_code('Y', 'U', '1', '0')
+
 /*
  * 2 plane RGB + A
  * index 0 = RGB plane, same format as the corresponding non _A8 format has
@@ -195,6 +237,13 @@ extern "C" {
 #define DRM_FORMAT_NV24		fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
 #define DRM_FORMAT_NV42		fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
 
+/*
+ * 2 plane YCbCr MSB aligned
+ * index 0 = Y plane, [15:0] Y:x [10:6] little endian
+ * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian
+ */
+#define DRM_FORMAT_P210		fourcc_code('P', '2', '1', '0') /* 2x1 subsampled Cr:Cb plane, 10 bit per channel */
+
 /*
  * 2 plane YCbCr MSB aligned
  * index 0 = Y plane, [15:0] Y:x [10:6] little endian
diff --git a/lib/igt_color_encoding.c b/lib/igt_color_encoding.c
index cc76a9919242..9f9dc1439ee4 100644
--- a/lib/igt_color_encoding.c
+++ b/lib/igt_color_encoding.c
@@ -151,6 +151,9 @@ static const struct color_encoding_format {
 	{ DRM_FORMAT_P010, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 	{ DRM_FORMAT_P012, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 	{ DRM_FORMAT_P016, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_Y210, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_Y212, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_Y216, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 };
 
 static const struct color_encoding_format *lookup_fourcc(uint32_t fourcc)
diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index bad1d1fbb4d7..1e0bcb9ea2cd 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -236,6 +236,21 @@ static const struct format_desc_struct {
 	  .num_planes = 2, .plane_bpp = { 16, 32 },
 	  .vsub = 2, .hsub = 2,
 	},
+	{ .name = "Y210", .depth = -1, .drm_id = DRM_FORMAT_Y210,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 2, .vsub = 1,
+	},
+	{ .name = "Y212", .depth = -1, .drm_id = DRM_FORMAT_Y212,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 2, .vsub = 1,
+	},
+	{ .name = "Y216", .depth = -1, .drm_id = DRM_FORMAT_Y216,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 2, .vsub = 1,
+	},
 	{ .name = "IGT-FLOAT", .depth = -1, .drm_id = IGT_FORMAT_FLOAT,
 	  .cairo_id = CAIRO_FORMAT_INVALID,
 	  .num_planes = 1, .plane_bpp = { 128 },
@@ -661,6 +676,14 @@ static void clear_yuv_buffer(struct igt_fb *fb)
 		wmemset(ptr + fb->offsets[1], 0x80008000,
 			fb->strides[1] * fb->plane_height[1] / sizeof(wchar_t));
 		break;
+	case DRM_FORMAT_Y210:
+	case DRM_FORMAT_Y212:
+	case DRM_FORMAT_Y216:
+		wmemset(ptr + fb->offsets[0],
+			full_range ? 0x80000000 : 0x80001000,
+			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
+		break;
+
 	}
 
 	igt_fb_unmap_buffer(fb, ptr);
@@ -1911,6 +1934,9 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_Y210:
+	case DRM_FORMAT_Y212:
+	case DRM_FORMAT_Y216:
 		params->y_inc = 2;
 		params->uv_inc = 4;
 		break;
@@ -1941,6 +1967,9 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_Y210:
+	case DRM_FORMAT_Y212:
+	case DRM_FORMAT_Y216:
 	case DRM_FORMAT_XYUV8888:
 		params->y_stride = fb->strides[0];
 		params->uv_stride = fb->strides[0];
@@ -2008,6 +2037,14 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 		params->v_offset = fb->offsets[0];
 		break;
 
+	case DRM_FORMAT_Y210:
+	case DRM_FORMAT_Y212:
+	case DRM_FORMAT_Y216:
+		params->y_offset = fb->offsets[0];
+		params->u_offset = fb->offsets[0] + 2;
+		params->v_offset = fb->offsets[0] + 6;
+		break;
+
 	case DRM_FORMAT_XYUV8888:
 		params->y_offset = fb->offsets[0] + 1;
 		params->u_offset = fb->offsets[0] + 2;
@@ -2423,6 +2460,9 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_P010:
 		case DRM_FORMAT_P012:
 		case DRM_FORMAT_P016:
+		case DRM_FORMAT_Y210:
+		case DRM_FORMAT_Y212:
+		case DRM_FORMAT_Y216:
 			convert_yuv16_to_float(cvt);
 			return;
 		}
@@ -2431,6 +2471,9 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_P010:
 		case DRM_FORMAT_P012:
 		case DRM_FORMAT_P016:
+		case DRM_FORMAT_Y210:
+		case DRM_FORMAT_Y212:
+		case DRM_FORMAT_Y216:
 			convert_float_to_yuv16(cvt);
 			return;
 		}
@@ -2895,6 +2938,9 @@ bool igt_format_is_yuv(uint32_t drm_format)
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
+	case DRM_FORMAT_Y210:
+	case DRM_FORMAT_Y212:
+	case DRM_FORMAT_Y216:
 	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] 10+ messages in thread

* [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4.
  2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3 Maarten Lankhorst
@ 2019-03-27  9:29 ` Maarten Lankhorst
  2019-03-27 17:20   ` Ville Syrjälä
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3 Maarten Lankhorst
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Maarten Lankhorst @ 2019-03-27  9:29 UTC (permalink / raw)
  To: igt-dev

Y410 is packed with compressed a channel and only 32 bpp, like
10 bits RGB formats. Y416 is a packed 16 bits per component format.

Changes since v1:
- Rebase on top of upstream YUV changes.
Changes since v2:
- Discard alpha channel, not used upstream.
Changes since v3:
- Handle the XVYU formats and Y41x formats correctly.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_color_encoding.c |   6 +
 lib/igt_fb.c             | 263 +++++++++++++++++++++++++++++++++++----
 2 files changed, 244 insertions(+), 25 deletions(-)

diff --git a/lib/igt_color_encoding.c b/lib/igt_color_encoding.c
index 9f9dc1439ee4..7de6d5abd690 100644
--- a/lib/igt_color_encoding.c
+++ b/lib/igt_color_encoding.c
@@ -154,6 +154,12 @@ static const struct color_encoding_format {
 	{ DRM_FORMAT_Y210, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 	{ DRM_FORMAT_Y212, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 	{ DRM_FORMAT_Y216, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_Y410, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
+	{ DRM_FORMAT_Y412, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_Y416, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_XVYU2101010, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
+	{ DRM_FORMAT_XVYU12_16161616, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
+	{ DRM_FORMAT_XVYU16161616, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
 };
 
 static const struct color_encoding_format *lookup_fourcc(uint32_t fourcc)
diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 1e0bcb9ea2cd..2d55687a7aa3 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -221,6 +221,36 @@ static const struct format_desc_struct {
 	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
 	  .hsub = 2, .vsub = 1,
 	},
+	{ .name = "Y410", .depth = -1, .drm_id = DRM_FORMAT_Y410,
+	  .cairo_id = CAIRO_FORMAT_RGBA128F,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
+	},
+	{ .name = "Y412", .depth = -1, .drm_id = DRM_FORMAT_Y412,
+	  .cairo_id = CAIRO_FORMAT_RGBA128F,
+	  .num_planes = 1, .plane_bpp = { 64, },
+	  .hsub = 1, .vsub = 1,
+	},
+	{ .name = "Y416", .depth = -1, .drm_id = DRM_FORMAT_Y416,
+	  .cairo_id = CAIRO_FORMAT_RGBA128F,
+	  .num_planes = 1, .plane_bpp = { 64, },
+	  .hsub = 1, .vsub = 1,
+	},
+	{ .name = "XV30", .depth = -1, .drm_id = DRM_FORMAT_XVYU2101010,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	  .hsub = 1, .vsub = 1,
+	},
+	{ .name = "XV36", .depth = -1, .drm_id = DRM_FORMAT_XVYU12_16161616,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 64, },
+	  .hsub = 1, .vsub = 1,
+	},
+	{ .name = "XV48", .depth = -1, .drm_id = DRM_FORMAT_XVYU16161616,
+	  .cairo_id = CAIRO_FORMAT_RGB96F,
+	  .num_planes = 1, .plane_bpp = { 64, },
+	  .hsub = 1, .vsub = 1,
+	},
 	{ .name = "P010", .depth = -1, .drm_id = DRM_FORMAT_P010,
 	  .cairo_id = CAIRO_FORMAT_RGB96F,
 	  .num_planes = 2, .plane_bpp = { 16, 32 },
@@ -684,6 +714,33 @@ static void clear_yuv_buffer(struct igt_fb *fb)
 			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
 		break;
 
+	case DRM_FORMAT_XVYU2101010:
+	case DRM_FORMAT_Y410:
+		wmemset(ptr + fb->offsets[0],
+			full_range ? 0xe0000200 : 0xe0010200,
+		fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
+		break;
+
+	case DRM_FORMAT_XVYU12_16161616:
+	case DRM_FORMAT_XVYU16161616:
+	case DRM_FORMAT_Y412:
+	case DRM_FORMAT_Y416: {
+		struct ayuv16 { uint16_t u, y, v, a; };
+		const struct ayuv16 pixel = {
+			.a = 0xffff,
+			.v = full_range ? 0 : 0x1000,
+			.y = 0x8000,
+			.u = full_range ? 0 : 0x1000
+		};
+
+		for (int i = 0; i < fb->plane_height[0]; i++) {
+			struct ayuv16 *cur = ptr + fb->offsets[0] + fb->strides[0] * i;
+
+			for (int j = 0; j < fb->plane_width[0]; j++)
+				*cur++ = pixel;
+		}
+		break;
+		}
 	}
 
 	igt_fb_unmap_buffer(fb, ptr);
@@ -1897,10 +1954,11 @@ static void convert_src_put(const struct fb_convert *cvt,
 }
 
 struct yuv_parameters {
-	unsigned	y_inc;
+	unsigned	ay_inc;
 	unsigned	uv_inc;
-	unsigned	y_stride;
+	unsigned	ay_stride;
 	unsigned	uv_stride;
+	unsigned	a_offset;
 	unsigned	y_offset;
 	unsigned	u_offset;
 	unsigned	v_offset;
@@ -1918,7 +1976,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
-		params->y_inc = 1;
+		params->ay_inc = 1;
 		params->uv_inc = 2;
 		break;
 
@@ -1926,7 +1984,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_YUV422:
 	case DRM_FORMAT_YVU420:
 	case DRM_FORMAT_YVU422:
-		params->y_inc = 1;
+		params->ay_inc = 1;
 		params->uv_inc = 1;
 		break;
 
@@ -1937,12 +1995,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_Y210:
 	case DRM_FORMAT_Y212:
 	case DRM_FORMAT_Y216:
-		params->y_inc = 2;
+		params->ay_inc = 2;
 		params->uv_inc = 4;
 		break;
 
+	case DRM_FORMAT_XVYU12_16161616:
+	case DRM_FORMAT_XVYU16161616:
+	case DRM_FORMAT_Y412:
+	case DRM_FORMAT_Y416:
 	case DRM_FORMAT_XYUV8888:
-		params->y_inc = 4;
+		params->ay_inc = 4;
 		params->uv_inc = 4;
 		break;
 	}
@@ -1959,7 +2021,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
-		params->y_stride = fb->strides[0];
+		params->ay_stride = fb->strides[0];
 		params->uv_stride = fb->strides[1];
 		break;
 
@@ -1971,7 +2033,11 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	case DRM_FORMAT_Y212:
 	case DRM_FORMAT_Y216:
 	case DRM_FORMAT_XYUV8888:
-		params->y_stride = fb->strides[0];
+	case DRM_FORMAT_XVYU12_16161616:
+	case DRM_FORMAT_XVYU16161616:
+	case DRM_FORMAT_Y412:
+	case DRM_FORMAT_Y416:
+		params->ay_stride = fb->strides[0];
 		params->uv_stride = fb->strides[0];
 		break;
 	}
@@ -2045,6 +2111,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 		params->v_offset = fb->offsets[0] + 6;
 		break;
 
+	case DRM_FORMAT_XVYU12_16161616:
+	case DRM_FORMAT_XVYU16161616:
+	case DRM_FORMAT_Y412:
+	case DRM_FORMAT_Y416:
+		params->a_offset = fb->offsets[0] + 6;
+		params->y_offset = fb->offsets[0] + 2;
+		params->u_offset = fb->offsets[0];
+		params->v_offset = fb->offsets[0] + 4;
+		break;
+
 	case DRM_FORMAT_XYUV8888:
 		params->y_offset = fb->offsets[0] + 1;
 		params->u_offset = fb->offsets[0] + 2;
@@ -2096,7 +2172,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
 			write_rgb(rgb_tmp, &rgb);
 
 			rgb_tmp += bpp;
-			y_tmp += params.y_inc;
+			y_tmp += params.ay_inc;
 
 			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
 				u_tmp += params.uv_inc;
@@ -2105,7 +2181,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
 		}
 
 		rgb24 += rgb24_stride;
-		y += params.y_stride;
+		y += params.ay_stride;
 
 		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
 			u += params.uv_stride;
@@ -2156,7 +2232,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
 			rgb_tmp += bpp;
 
 			*y_tmp = yuv.d[0];
-			y_tmp += params.y_inc;
+			y_tmp += params.ay_inc;
 
 			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
 				continue;
@@ -2193,7 +2269,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
 		}
 
 		rgb24 += rgb24_stride;
-		y += params.y_stride;
+		y += params.ay_stride;
 
 		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
 			u += params.uv_stride;
@@ -2217,13 +2293,13 @@ static void write_rgbf(float *rgb24, const struct igt_vec4 *rgb)
 	rgb24[2] = rgb->d[2];
 }
 
-static void convert_yuv16_to_float(struct fb_convert *cvt)
+static void convert_yuv16_to_float(struct fb_convert *cvt, bool alpha)
 {
 	const struct format_desc_struct *src_fmt =
 		lookup_drm_format(cvt->src.fb->drm_format);
 	int i, j;
-	uint8_t fpp = 3;
-	uint16_t *y, *u, *v;
+	uint8_t fpp = alpha ? 4 : 3;
+	uint16_t *a, *y, *u, *v;
 	float *ptr = cvt->dst.ptr;
 	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
 	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
@@ -2242,11 +2318,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
 		   !(params.u_offset % sizeof(*buf)) &&
 		   !(params.v_offset % sizeof(*buf)));
 
+	a = buf + params.a_offset / sizeof(*buf);
 	y = buf + params.y_offset / sizeof(*buf);
 	u = buf + params.u_offset / sizeof(*buf);
 	v = buf + params.v_offset / sizeof(*buf);
 
 	for (i = 0; i < cvt->dst.fb->height; i++) {
+		const uint16_t *a_tmp = a;
 		const uint16_t *y_tmp = y;
 		const uint16_t *u_tmp = u;
 		const uint16_t *v_tmp = v;
@@ -2263,8 +2341,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
 			rgb = igt_matrix_transform(&m, &yuv);
 			write_rgbf(rgb_tmp, &rgb);
 
+			if (alpha) {
+				rgb_tmp[3] = ((float)*a_tmp) / 65535.f;
+				a_tmp += params.ay_inc;
+			}
+
 			rgb_tmp += fpp;
-			y_tmp += params.y_inc;
+			y_tmp += params.ay_inc;
 
 			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
 				u_tmp += params.uv_inc;
@@ -2273,7 +2356,9 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
 		}
 
 		ptr += float_stride;
-		y += params.y_stride / sizeof(*y);
+
+		a += params.ay_stride / sizeof(*a);
+		y += params.ay_stride / sizeof(*y);
 
 		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
 			u += params.uv_stride / sizeof(*u);
@@ -2284,14 +2369,14 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
 	convert_src_put(cvt, buf);
 }
 
-static void convert_float_to_yuv16(struct fb_convert *cvt)
+static void convert_float_to_yuv16(struct fb_convert *cvt, bool alpha)
 {
 	const struct format_desc_struct *dst_fmt =
 		lookup_drm_format(cvt->dst.fb->drm_format);
 	int i, j;
-	uint16_t *y, *u, *v;
+	uint16_t *a, *y, *u, *v;
 	const float *ptr = cvt->src.ptr;
-	uint8_t fpp = 3;
+	uint8_t fpp = alpha ? 4 : 3;
 	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
 	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
 						    cvt->dst.fb->drm_format,
@@ -2303,16 +2388,19 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
 		   igt_format_is_yuv(cvt->dst.fb->drm_format));
 
 	get_yuv_parameters(cvt->dst.fb, &params);
-	igt_assert(!(params.y_offset % sizeof(*y)) &&
+	igt_assert(!(params.a_offset % sizeof(*a)) &&
+		   !(params.y_offset % sizeof(*y)) &&
 		   !(params.u_offset % sizeof(*u)) &&
 		   !(params.v_offset % sizeof(*v)));
 
+	a = cvt->dst.ptr + params.a_offset;
 	y = cvt->dst.ptr + params.y_offset;
 	u = cvt->dst.ptr + params.u_offset;
 	v = cvt->dst.ptr + params.v_offset;
 
 	for (i = 0; i < cvt->dst.fb->height; i++) {
 		const float *rgb_tmp = ptr;
+		uint16_t *a_tmp = a;
 		uint16_t *y_tmp = y;
 		uint16_t *u_tmp = u;
 		uint16_t *v_tmp = v;
@@ -2325,10 +2413,15 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
 			read_rgbf(&rgb, rgb_tmp);
 			yuv = igt_matrix_transform(&m, &rgb);
 
+			if (alpha) {
+				*a_tmp = rgb_tmp[3] * 65535.f + .5f;
+				a_tmp += params.ay_inc;
+			}
+
 			rgb_tmp += fpp;
 
 			*y_tmp = yuv.d[0];
-			y_tmp += params.y_inc;
+			y_tmp += params.ay_inc;
 
 			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
 				continue;
@@ -2365,7 +2458,8 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
 		}
 
 		ptr += float_stride;
-		y += params.y_stride / sizeof(*y);
+		a += params.ay_stride / sizeof(*a);
+		y += params.ay_stride / sizeof(*y);
 
 		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
 			u += params.uv_stride / sizeof(*u);
@@ -2374,6 +2468,95 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
 	}
 }
 
+static void convert_Y410_to_float(struct fb_convert *cvt, bool alpha)
+{
+	int i, j;
+	const uint32_t *uyv;
+	uint32_t *buf;
+	float *ptr = cvt->dst.ptr;
+	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
+	unsigned int uyv_stride = cvt->src.fb->strides[0] / sizeof(*uyv);
+	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
+						    cvt->dst.fb->drm_format,
+						    cvt->src.fb->color_encoding,
+						    cvt->src.fb->color_range);
+	unsigned bpp = alpha ? 4 : 3;
+
+	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_Y410 ||
+		    cvt->src.fb->drm_format == DRM_FORMAT_XVYU2101010) &&
+		   cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT);
+
+	uyv = buf = convert_src_get(cvt);
+
+	for (i = 0; i < cvt->dst.fb->height; i++) {
+		for (j = 0; j < cvt->dst.fb->width; j++) {
+			/* Convert 2x1 pixel blocks */
+			struct igt_vec4 yuv;
+			struct igt_vec4 rgb;
+
+			yuv.d[0] = uyv[j] & 0x3ff;
+			yuv.d[1] = (uyv[j] >> 10) & 0x3ff;
+			yuv.d[2] = (uyv[j] >> 20) & 0x3ff;
+			yuv.d[3] = 1.f;
+
+			rgb = igt_matrix_transform(&m, &yuv);
+
+			write_rgbf(&ptr[j * bpp], &rgb);
+			if (alpha)
+				ptr[j * bpp + 3] = (float)(uyv[j] >> 30) / 3.f;
+		}
+
+		ptr += float_stride;
+		uyv += uyv_stride;
+	}
+
+	convert_src_put(cvt, buf);
+}
+
+static void convert_float_to_Y410(struct fb_convert *cvt, bool alpha)
+{
+	int i, j;
+	uint32_t *uyv = cvt->dst.ptr;
+	const float *ptr = cvt->src.ptr;
+	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
+	unsigned uyv_stride = cvt->dst.fb->strides[0] / sizeof(*uyv);
+	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
+						    cvt->dst.fb->drm_format,
+						    cvt->dst.fb->color_encoding,
+						    cvt->dst.fb->color_range);
+	unsigned bpp = alpha ? 4 : 3;
+
+	igt_assert(cvt->src.fb->drm_format == IGT_FORMAT_FLOAT &&
+		   (cvt->dst.fb->drm_format == DRM_FORMAT_Y410 ||
+		    cvt->dst.fb->drm_format == DRM_FORMAT_XVYU2101010));
+
+	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;
+			uint8_t a = 0;
+			uint16_t y, cb, cr;
+
+			read_rgbf(&rgb, &ptr[j * bpp]);
+			if (alpha)
+				 a = ptr[j * bpp + 3] * 3.f + .5f;
+
+			yuv = igt_matrix_transform(&m, &rgb);
+			cr = yuv.d[0];
+			y = yuv.d[1];
+			cb = yuv.d[2];
+
+			uyv[j] = ((cr & 0x3ff) << 0) |
+				  ((y & 0x3ff) << 10) |
+				  ((cb & 0x3ff) << 20) |
+				  (a << 30);
+		}
+
+		ptr += float_stride;
+		uyv += uyv_stride;
+	}
+}
+
 static void convert_pixman(struct fb_convert *cvt)
 {
 	pixman_format_code_t src_pixman = drm_format_to_pixman(cvt->src.fb->drm_format);
@@ -2463,7 +2646,19 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_Y210:
 		case DRM_FORMAT_Y212:
 		case DRM_FORMAT_Y216:
-			convert_yuv16_to_float(cvt);
+		case DRM_FORMAT_XVYU12_16161616:
+		case DRM_FORMAT_XVYU16161616:
+			convert_yuv16_to_float(cvt, false);
+			return;
+		case DRM_FORMAT_Y410:
+			convert_Y410_to_float(cvt, true);
+			return;
+		case DRM_FORMAT_XVYU2101010:
+			convert_Y410_to_float(cvt, false);
+			return;
+		case DRM_FORMAT_Y412:
+		case DRM_FORMAT_Y416:
+			convert_yuv16_to_float(cvt, true);
 			return;
 		}
 	} else if (cvt->src.fb->drm_format == IGT_FORMAT_FLOAT) {
@@ -2474,7 +2669,19 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_Y210:
 		case DRM_FORMAT_Y212:
 		case DRM_FORMAT_Y216:
-			convert_float_to_yuv16(cvt);
+		case DRM_FORMAT_XVYU12_16161616:
+		case DRM_FORMAT_XVYU16161616:
+			convert_float_to_yuv16(cvt, false);
+			return;
+		case DRM_FORMAT_Y410:
+			convert_float_to_Y410(cvt, true);
+			return;
+		case DRM_FORMAT_XVYU2101010:
+			convert_float_to_Y410(cvt, false);
+			return;
+		case DRM_FORMAT_Y412:
+		case DRM_FORMAT_Y416:
+			convert_float_to_yuv16(cvt, true);
 			return;
 		}
 	}
@@ -2941,6 +3148,12 @@ bool igt_format_is_yuv(uint32_t drm_format)
 	case DRM_FORMAT_Y210:
 	case DRM_FORMAT_Y212:
 	case DRM_FORMAT_Y216:
+	case DRM_FORMAT_XVYU2101010:
+	case DRM_FORMAT_XVYU12_16161616:
+	case DRM_FORMAT_XVYU16161616:
+	case DRM_FORMAT_Y410:
+	case DRM_FORMAT_Y412:
+	case DRM_FORMAT_Y416:
 	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] 10+ messages in thread

* [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3.
  2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3 Maarten Lankhorst
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4 Maarten Lankhorst
@ 2019-03-27  9:29 ` Maarten Lankhorst
  2019-03-27 17:34   ` Ville Syrjälä
  2019-03-27 10:55 ` [igt-dev] ✓ Fi.CI.BAT: success for Add support for more YUV tests Patchwork
  2019-03-27 20:52 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  4 siblings, 1 reply; 10+ messages in thread
From: Maarten Lankhorst @ 2019-03-27  9:29 UTC (permalink / raw)
  To: igt-dev

Add tests excercising switching between various scaled/unscaled
transitions to and from various nv12 formats, since some of the
workarounds mention this may fail.

We also add NV12 specific clipping/scaling tests, to make sure
that YUV src coordinates are always programmed as a multiple of 2
correctly, and verify scaling/clipping works with CRC tests.

crop-scale-bug shows a corruption when scaling and cropping at the
same time.

The subpixel clip test rotates and clips a rectangle on each side,
which should produce the same CRC as when that part of the rectangle
is hidden by a cursor and a whole 2x2 pixel is hidden.

Changes since v1:
- Reset plane position to 0,0 at the start of yuv_valid_width_plane().
- Handle Swati's feedback.
Changes since v2:
- Skip 90°/270° rotation in tests when formats don't support it.
- Add all new HDR formats to test.
- Use igt_plane_has_format_mod.
- Support tests on !i915 by checking if X/Y tiling modifiers are supported.
- Do not enable untested planes to prevent exhausing memory bandwidth
  and available NV12 Y planes in the rgb-switch-scaled test.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 tests/Makefile.sources |   1 +
 tests/kms_yuv.c        | 843 +++++++++++++++++++++++++++++++++++++++++
 tests/meson.build      |   1 +
 3 files changed, 845 insertions(+)
 create mode 100644 tests/kms_yuv.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 71ccf00af256..5eb46087e362 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -74,6 +74,7 @@ TESTS_progs = \
 	kms_universal_plane \
 	kms_vblank \
 	kms_vrr \
+	kms_yuv \
 	meta_test \
 	perf \
 	perf_pmu \
diff --git a/tests/kms_yuv.c b/tests/kms_yuv.c
new file mode 100644
index 000000000000..ce9e4ade334f
--- /dev/null
+++ b/tests/kms_yuv.c
@@ -0,0 +1,843 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+ */
+#include "config.h"
+
+#include "igt.h"
+#include <cairo.h>
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+typedef struct {
+	igt_display_t display;
+
+	igt_pipe_crc_t *pipe_crc;
+	struct igt_fb fb[6];
+} data_t;
+
+static uint64_t x_modifier = LOCAL_DRM_FORMAT_MOD_NONE;
+static uint64_t y_modifier = LOCAL_DRM_FORMAT_MOD_NONE;
+
+static bool pipe_supports_format(igt_display_t *display, enum pipe pipe, uint32_t format, uint64_t tiling)
+{
+	igt_plane_t *plane;
+
+	for_each_plane_on_pipe(display, pipe, plane)
+		if (igt_plane_has_format_mod(plane, format, tiling))
+			return true;
+
+	return false;
+}
+
+static void remove_fbs(data_t *data)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(data->fb); i++)
+		igt_remove_fb(data->display.drm_fd, &data->fb[i]);
+}
+
+static void prepare_crtc(data_t *data, enum pipe pipe, igt_output_t *output)
+{
+	igt_display_t *display = &data->display;
+
+	remove_fbs(data);
+	igt_display_reset(display);
+	igt_output_set_pipe(output, pipe);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	igt_pipe_crc_free(data->pipe_crc);
+	data->pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+}
+
+static void set_fb(igt_plane_t *plane, struct igt_fb *fb, bool scaled)
+{
+	igt_plane_set_fb(plane, fb);
+
+	if (scaled && fb)
+		igt_fb_set_size(fb, plane, fb->width, 16);
+
+	if (fb && fb->modifier == y_modifier) { // TODO
+		igt_plane_set_rotation(plane, IGT_ROTATION_90);
+		igt_plane_set_size(plane, fb->height, fb->width);
+	} else
+		igt_plane_set_rotation(plane, IGT_ROTATION_0);
+}
+
+static void yuv_rgb_switch(data_t *data, enum pipe pipe, igt_output_t *output, bool scaled, unsigned format)
+{
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	igt_display_t *display = &data->display;
+	igt_plane_t *plane;
+	int i;
+	igt_crc_t ref_crc[4], crc;
+	bool valid[4] = {};
+
+	prepare_crtc(data, pipe, output);
+
+	igt_create_pattern_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
+			      format, x_modifier, &data->fb[0]);
+
+	igt_create_pattern_fb(display->drm_fd, mode->vdisplay, mode->hdisplay,
+			      format, y_modifier, &data->fb[1]);
+
+	igt_create_pattern_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
+			      DRM_FORMAT_XRGB8888, x_modifier, &data->fb[2]);
+
+	igt_create_pattern_fb(display->drm_fd, mode->vdisplay, mode->hdisplay,
+			      DRM_FORMAT_XRGB8888, y_modifier, &data->fb[3]);
+
+	for_each_plane_on_pipe(display, pipe, plane) {
+		const int seq[] = {
+			2, 0, 2, 1, 3, 1, 3
+		};
+
+		if (!igt_plane_has_format_mod(plane, format, data->fb[0].modifier))
+			continue;
+
+		/* Collect reference crc with toggle in between. */
+		for (i = 0; i < ARRAY_SIZE(ref_crc); i++) {
+			set_fb(plane, &data->fb[i], scaled);
+
+			if (i != 1)
+				igt_display_commit2(display, COMMIT_ATOMIC);
+			else if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
+				continue;
+
+			igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc[i]);
+			valid[i] = true;
+
+			set_fb(plane, NULL, scaled);
+			igt_display_commit2(display, COMMIT_ATOMIC);
+		}
+
+		for (i = 0; i < ARRAY_SIZE(seq); i++) {
+			int j = seq[i];
+
+			if (!valid[j])
+				continue;
+
+			set_fb(plane, &data->fb[j], scaled);
+			igt_display_commit2(display, COMMIT_ATOMIC);
+
+			igt_pipe_crc_collect_crc(data->pipe_crc, &crc);
+			igt_assert_crc_equal(&ref_crc[j], &crc);
+		}
+
+		/* We only have few scalers, don't use 1 for unused planes */
+		igt_plane_set_fb(plane, NULL);
+	}
+}
+
+#define assert_collected_crc_equal(pipe_crc, crc, ref_crc) \
+	do { \
+		igt_pipe_crc_get_current(display->drm_fd, pipe_crc, crc);	\
+		igt_assert_crc_equal(ref_crc, crc);	\
+	} while (0)
+
+static void set_src_coords(igt_plane_t *plane, struct igt_fb *fb,
+			   igt_rotation_t rot, int vis, int hidden)
+{
+	switch (rot) {
+	case IGT_ROTATION_0:
+		igt_fb_set_position(fb, plane, fb->width / 2 - vis, fb->height / 2 - vis);
+		break;
+	case IGT_ROTATION_90:
+		igt_fb_set_position(fb, plane, fb->width / 2 - hidden, fb->height / 2 - vis);
+		break;
+	case IGT_ROTATION_180:
+		igt_fb_set_position(fb, plane, fb->width / 2 - hidden, fb->height / 2 - hidden);
+		break;
+	case IGT_ROTATION_270:
+		igt_fb_set_position(fb, plane, fb->width / 2 - vis, fb->height / 2 - hidden);
+		break;
+	default: igt_assert(0);
+	}
+	igt_fb_set_size(fb, plane, vis + hidden, vis + hidden);
+}
+
+static void yuv_valid_width_plane(data_t *data, drmModeModeInfo *mode,
+				  igt_plane_t *plane, igt_rotation_t rot,
+				  igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc;
+	struct igt_fb *clip_fb = &data->fb[2];
+	int i, ret;
+
+	/* Just clipping.. */
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_rotation(plane, rot);
+	if (rot & (IGT_ROTATION_90 | IGT_ROTATION_270))
+		igt_plane_set_size(plane, clip_fb->height, clip_fb->width);
+	igt_plane_set_position(plane, mode->hdisplay - clip_fb->width / 2, mode->vdisplay - clip_fb->height / 2);
+	if ((rot == IGT_ROTATION_90 || rot == IGT_ROTATION_270) &&
+	    igt_display_try_commit2(display, COMMIT_ATOMIC) < 0) {
+		igt_debug("This rotation not available for this format.\n");
+		return;
+	}
+
+	igt_display_commit2(display, COMMIT_ATOMIC);
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+	/* Clipping and scaling. */
+	igt_fb_set_position(clip_fb, plane, clip_fb->width / 2 - 16, clip_fb->height / 2 - 16);
+	igt_fb_set_size(clip_fb, plane, 32, 32);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+	/* Try nvalid < 8 src visible. */
+	set_src_coords(plane, clip_fb, rot, 4, 4);
+	igt_display_try_commit2(display, COMMIT_ATOMIC);
+
+	/* Try different alignments for x/y to see if any hit underruns */
+	for (i = 1; i < 4; i++) {
+		set_src_coords(plane, clip_fb, rot, 16 + 2 * i, 16 - 2 * i);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+		assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+		/* And also show more of the screen */
+		set_src_coords(plane, clip_fb, rot, 16 + i, 16 + i);
+		ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
+
+		if (ret == -EINVAL) {
+			igt_assert(i % 2 || rot == IGT_ROTATION_270 || rot == (IGT_ROTATION_90 | IGT_REFLECT_X));
+			continue;
+		} else
+			igt_assert_eq(ret, 0);
+		assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	}
+
+	/*
+	 * As a final test, try with 16 src visible, and various invisible
+	 * components to check clipping doesn't drop the visible src below 16.
+	 */
+	for (i = 0; i < 16; i += 4) {
+		set_src_coords(plane, clip_fb, rot, 16, i);
+		if (rot & (IGT_ROTATION_90 | IGT_ROTATION_270))
+			igt_plane_set_size(plane, (clip_fb->height / 32) * (16 + i),
+					   (clip_fb->width / 32) * (16 + i));
+		else
+			igt_plane_set_size(plane, (clip_fb->width / 32) * (16 + i),
+					   (clip_fb->height / 32) * (16 + i));
+		igt_display_commit2(display, COMMIT_ATOMIC);
+		assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	}
+}
+
+static void yuv_valid_width(data_t *data, enum pipe pipe, igt_output_t *output, unsigned format)
+{
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	igt_display_t *display = &data->display;
+	igt_plane_t *plane;
+	struct igt_fb *clip_fb = &data->fb[2];
+	struct igt_fb *ref_fb = &data->fb[3];
+
+	prepare_crtc(data, pipe, output);
+
+	igt_create_fb(display->drm_fd, 64, 64, format,
+		      LOCAL_I915_FORMAT_MOD_Y_TILED, ref_fb);
+
+	igt_create_fb(display->drm_fd, 2 * ref_fb->width,
+		      2 * ref_fb->height, format,
+		      LOCAL_I915_FORMAT_MOD_Y_TILED, clip_fb);
+
+	igt_pipe_crc_start(data->pipe_crc);
+
+	for_each_plane_on_pipe(display, pipe, plane) {
+		igt_crc_t ref_crc[4];
+		cairo_t *cr;
+		static const double colors[4][3] = {
+			{ 1., 0., 0. },
+			{ 0., 1., 0. },
+			{ 0., 0., 1. },
+			{ 1., 1., 1. }
+		};
+		int i;
+
+		if (!igt_plane_has_format_mod(plane, format, data->fb[0].modifier))
+			continue;
+
+		/* Draw the FB that will be used for clipping tests. */
+		cr = igt_get_cairo_ctx(display->drm_fd, clip_fb);
+		igt_paint_color(cr, 0, 0, clip_fb->width / 2, clip_fb->height / 2,
+				colors[0][0], colors[0][1], colors[0][2]);
+
+		igt_paint_color(cr, clip_fb->width / 2, 0,
+				clip_fb->width / 2, clip_fb->height / 2,
+				colors[1][0], colors[1][1], colors[1][2]);
+
+		igt_paint_color(cr, clip_fb->width / 2, clip_fb->height / 2,
+				clip_fb->width / 2, clip_fb->height / 2,
+				colors[2][0], colors[2][1], colors[2][2]);
+
+		igt_paint_color(cr, 0, clip_fb->height / 2,
+				clip_fb->width / 2, clip_fb->height / 2,
+				colors[3][0], colors[3][1], colors[3][2]);
+
+		igt_put_cairo_ctx(display->drm_fd, clip_fb, cr);
+
+		/* Draw all reference FB's to collect the CRC. */
+		for (i = 0; i < 4; i++) {
+			cr = igt_get_cairo_ctx(display->drm_fd, ref_fb);
+			igt_paint_color(cr, 0, 0, ref_fb->width, ref_fb->height,
+					colors[i][0], colors[i][1], colors[i][2]);
+			igt_put_cairo_ctx(display->drm_fd, &data->fb[3], cr);
+
+			if (!i) {
+				igt_plane_set_fb(plane, ref_fb);
+				igt_plane_set_position(plane, mode->hdisplay - ref_fb->width, mode->vdisplay - ref_fb->height);
+				igt_display_commit2(display, COMMIT_ATOMIC);
+			} else {
+				igt_dirty_fb(display->drm_fd, ref_fb);
+				igt_wait_for_vblank(display->drm_fd, pipe);
+			}
+
+			igt_pipe_crc_drain(data->pipe_crc);
+			igt_pipe_crc_get_single(data->pipe_crc, &ref_crc[i]);
+		}
+
+		igt_plane_set_fb(plane, NULL);
+		igt_plane_set_position(plane, 0, 0);
+
+		yuv_valid_width_plane(data, mode, plane, IGT_ROTATION_0, &ref_crc[0]);
+		yuv_valid_width_plane(data, mode, plane, IGT_ROTATION_90, &ref_crc[1]);
+		yuv_valid_width_plane(data, mode, plane, IGT_ROTATION_180, &ref_crc[2]);
+		yuv_valid_width_plane(data, mode, plane, IGT_ROTATION_270, &ref_crc[3]);
+
+		igt_plane_set_fb(plane, NULL);
+	}
+}
+
+static bool yuv_commit_rotated(igt_display_t *display, igt_rotation_t rot)
+{
+	if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0) {
+		igt_debug("Skipping rotated test, alignment is wrong.\n");
+		return false;
+	}
+
+	return true;
+}
+
+static void yuv_crop_scale_bug_plane(data_t *data, drmModeModeInfo *mode,
+				      igt_plane_t *plane, struct igt_fb *fb,
+				      igt_rotation_t rot, igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc;
+	int ofs[] = { 0, 1, -1, 2, -2 };
+	int i, j;
+
+	igt_plane_set_fb(plane, fb);
+	igt_plane_set_rotation(plane, rot);
+	igt_plane_set_position(plane, 64, 64);
+	igt_plane_set_size(plane, 256, 256);
+
+	igt_fb_set_position(fb, plane, fb->width / 4, fb->height / 4);
+	igt_fb_set_size(fb, plane, fb->width / 2, fb->height / 2);
+	if ((rot == IGT_ROTATION_90 || rot == IGT_ROTATION_270) &&
+	    igt_display_try_commit2(display, COMMIT_ATOMIC) < 0) {
+		igt_debug("This rotation not available for this format.\n");
+		return;
+	}
+
+	igt_display_commit2(display, COMMIT_ATOMIC);
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+	/* Make sure boundaries match */
+	igt_fb_set_position(fb, plane, fb->width / 4 - 2, fb->height / 4 - 2);
+	igt_fb_set_size(fb, plane, fb->width / 2 + 4, fb->height / 2 + 4);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+	for (i = 1; i < ARRAY_SIZE(ofs); i++) {
+		igt_debug("Testing with rot %x and extra %i on the left side\n", rot, ofs[i]);
+		igt_fb_set_position(fb, plane, fb->width / 4 + ofs[i], fb->height / 4 - 2);
+		igt_fb_set_size(fb, plane, fb->width / 2 + 2 - ofs[i], fb->height / 2 + 4);
+		if (yuv_commit_rotated(display, rot))
+			assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+		igt_debug("Testing with rot %x and extra %i on the top side\n", rot, ofs[i]);
+		igt_fb_set_position(fb, plane, fb->width / 4 - 2, fb->height / 4 + ofs[i]);
+		igt_fb_set_size(fb, plane, fb->width / 2 + 4, fb->height / 2 + 2 - ofs[i]);
+		if (yuv_commit_rotated(display, rot))
+			assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+		igt_debug("Testing with rot %x and extra %i on the right side\n", rot, ofs[i]);
+		igt_fb_set_position(fb, plane, fb->width / 4 - 2, fb->height / 4);
+		igt_fb_set_size(fb, plane, fb->width / 2 + 2 + ofs[i], fb->height / 2);
+		if (yuv_commit_rotated(display, rot))
+			assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+		igt_debug("Testing with rot %x and extra %i on the bottom side\n", rot, ofs[i]);
+		igt_fb_set_position(fb, plane, fb->width / 4 - 2, fb->height / 4 - 2);
+		igt_fb_set_size(fb, plane, fb->width / 2 + 4, fb->height / 2 + 2 + ofs[i]);
+		if (yuv_commit_rotated(display, rot))
+			assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ofs); i++)
+		for (j = !i; j < ARRAY_SIZE(ofs); j++) {
+			igt_debug("Testing with rot %x and extra (%i, %i) at the edges\n", rot, ofs[i], ofs[j]);
+
+			igt_fb_set_position(fb, plane, fb->width / 4 + ofs[i], fb->height / 4 + ofs[j]);
+			igt_fb_set_size(fb, plane, fb->width / 2 - 2 * ofs[i], fb->height / 2 - 2 * ofs[j]);
+
+			if (yuv_commit_rotated(display, rot))
+				assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+		}
+}
+
+static void draw_clip_fb(igt_display_t *display, struct igt_fb *clip_fb)
+{
+	cairo_t *cr = igt_get_cairo_ctx(display->drm_fd, clip_fb);
+
+	igt_paint_color(cr, 0, 0, clip_fb->width, clip_fb->height, .0, .0, .5);
+	igt_paint_color(cr, clip_fb->width / 4 - 2, clip_fb->height / 4 - 2,
+			clip_fb->width / 2 + 4, clip_fb->height / 2 + 4, 1., 1., 1.);
+
+	igt_put_cairo_ctx(display->drm_fd, clip_fb, cr);
+}
+
+static void yuv_crop_scale_bug(data_t *data, enum pipe pipe, igt_output_t *output, unsigned format)
+{
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	igt_display_t *display = &data->display;
+	igt_plane_t *plane, *primary = igt_pipe_get_plane_type(&display->pipes[pipe], DRM_PLANE_TYPE_PRIMARY);
+	struct igt_fb *ref_fb = &data->fb[2];
+	struct igt_fb *clip_fb = &data->fb[3];
+	struct igt_fb *clip_fb_xtiled = &data->fb[4];
+	struct igt_fb *clip_fb_ytiled = &data->fb[5];
+
+	prepare_crtc(data, pipe, output);
+
+	igt_create_color_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
+			    format, LOCAL_I915_FORMAT_MOD_X_TILED, .5, .5, .5, &data->fb[0]);
+
+	igt_create_color_fb(display->drm_fd, 256, 256, format,
+			    LOCAL_I915_FORMAT_MOD_X_TILED, 1., 1., 1., ref_fb);
+
+	igt_create_fb(display->drm_fd, 80, 128, format,
+		      LOCAL_DRM_FORMAT_MOD_NONE, clip_fb);
+
+	igt_create_fb(display->drm_fd, 80, 128, format,
+		      LOCAL_I915_FORMAT_MOD_X_TILED, clip_fb_xtiled);
+	igt_create_fb(display->drm_fd, 80, 128, format,
+		      LOCAL_I915_FORMAT_MOD_Y_TILED, clip_fb_ytiled);
+
+	draw_clip_fb(display, clip_fb);
+	draw_clip_fb(display, clip_fb_xtiled);
+	draw_clip_fb(display, clip_fb_ytiled);
+
+	igt_plane_set_fb(primary, &data->fb[0]);
+
+	for_each_plane_on_pipe(display, pipe, plane) {
+		igt_crc_t ref_crc;
+
+		if (!igt_plane_has_format_mod(plane, format, data->fb[0].modifier))
+			continue;
+
+		igt_plane_set_fb(plane, ref_fb);
+		igt_plane_set_position(plane, 64, 64);
+		igt_display_commit2(display, COMMIT_ATOMIC);
+
+		igt_pipe_crc_start(data->pipe_crc);
+		igt_pipe_crc_get_single(data->pipe_crc, &ref_crc);
+
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb, IGT_ROTATION_0, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_xtiled, IGT_ROTATION_0, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_ytiled, IGT_ROTATION_0, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_ytiled, IGT_ROTATION_90, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb, IGT_ROTATION_180, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_xtiled, IGT_ROTATION_180, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_ytiled, IGT_ROTATION_180, &ref_crc);
+		yuv_crop_scale_bug_plane(data, mode, plane, clip_fb_ytiled, IGT_ROTATION_270, &ref_crc);
+
+		igt_plane_set_fb(plane, plane != primary ? NULL : &data->fb[0]);
+		break;
+	}
+}
+
+static void yuv_chroma_subpixel_clip_plane_with_cursor(data_t *data,
+							igt_plane_t *plane,
+							struct igt_fb *clip_fb,
+							igt_plane_t *cursor,
+							struct igt_fb *cursor_fb,
+							igt_crc_t *ref_crc,
+							int cursor_x, int cursor_y)
+{
+	igt_display_t *display = &data->display;
+
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_position(plane, 64, 64);
+	igt_plane_set_rotation(plane, IGT_ROTATION_0);
+
+	igt_plane_set_fb(cursor, cursor_fb);
+	igt_plane_set_position(cursor, cursor_x, cursor_y);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	igt_pipe_crc_drain(data->pipe_crc);
+	igt_pipe_crc_get_single(data->pipe_crc, ref_crc);
+
+	igt_plane_set_fb(cursor, NULL);
+}
+
+static bool yuv_chroma_subpixel_clip_plane_right(data_t *data,
+						 igt_rotation_t rotation,
+						 igt_plane_t *plane,
+						 struct igt_fb *clip_fb,
+						 igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc = {};
+
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_position(plane, 64, 64);
+	igt_plane_set_rotation(plane, rotation);
+	igt_plane_set_size(plane, clip_fb->width - 1, clip_fb->height);
+
+	switch (rotation) {
+	case IGT_ROTATION_180:
+		igt_fb_set_position(clip_fb, plane, 1, 0);
+	case IGT_ROTATION_0:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width - 1, clip_fb->height);
+		break;
+
+	case IGT_ROTATION_270:
+		igt_fb_set_position(clip_fb, plane, 0, 1);
+	case IGT_ROTATION_90:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width, clip_fb->height - 1);
+		break;
+	default:
+		igt_assert_f(0, "Unhandled rotation %x\n", rotation);
+	}
+
+	if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
+		return false;
+
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	return true;
+}
+
+static bool yuv_chroma_subpixel_clip_plane_bottom(data_t *data,
+						  igt_rotation_t rotation,
+						  igt_plane_t *plane,
+						  struct igt_fb *clip_fb,
+						  igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc = {};
+
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_position(plane, 64, 64);
+	igt_plane_set_rotation(plane, rotation);
+	igt_plane_set_size(plane, clip_fb->width, clip_fb->height - 1);
+
+	switch (rotation) {
+	case IGT_ROTATION_180:
+		igt_fb_set_position(clip_fb, plane, 0, 1);
+	case IGT_ROTATION_0:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width, clip_fb->height - 1);
+		break;
+
+	case IGT_ROTATION_90:
+		igt_fb_set_position(clip_fb, plane, 1, 0);
+	case IGT_ROTATION_270:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width - 1, clip_fb->height);
+		break;
+	default:
+		igt_assert_f(0, "Unhandled rotation %x\n", rotation);
+	}
+
+	if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
+		return false;
+
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	return true;
+}
+
+static bool yuv_chroma_subpixel_clip_plane_left(data_t *data,
+						igt_rotation_t rotation,
+						igt_plane_t *plane,
+						struct igt_fb *clip_fb,
+						igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc = {};
+
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_position(plane, 65, 64);
+	igt_plane_set_rotation(plane, rotation);
+	igt_plane_set_size(plane, clip_fb->width - 1, clip_fb->height);
+
+	switch (rotation) {
+	case IGT_ROTATION_0:
+		igt_fb_set_position(clip_fb, plane, 1, 0);
+	case IGT_ROTATION_180:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width - 1, clip_fb->height);
+		break;
+
+	case IGT_ROTATION_90:
+		igt_fb_set_position(clip_fb, plane, 0, 1);
+	case IGT_ROTATION_270:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width, clip_fb->height - 1);
+		break;
+	default:
+		igt_assert_f(0, "Unhandled rotation %x\n", rotation);
+	}
+
+	if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
+		return false;
+
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	return true;
+}
+
+
+static bool yuv_chroma_subpixel_clip_plane_top(data_t *data,
+					      igt_rotation_t rotation,
+					      igt_plane_t *plane,
+					      struct igt_fb *clip_fb,
+					      igt_crc_t *ref_crc)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t crc = {};
+
+	igt_plane_set_fb(plane, clip_fb);
+	igt_plane_set_position(plane, 64, 65);
+	igt_plane_set_rotation(plane, rotation);
+	igt_plane_set_size(plane, clip_fb->width, clip_fb->height - 1);
+
+	switch (rotation) {
+	case IGT_ROTATION_0:
+		igt_fb_set_position(clip_fb, plane, 0, 1);
+	case IGT_ROTATION_180:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width, clip_fb->height - 1);
+		break;
+
+	case IGT_ROTATION_270:
+		igt_fb_set_position(clip_fb, plane, 1, 0);
+	case IGT_ROTATION_90:
+		igt_fb_set_size(clip_fb, plane, clip_fb->width - 1, clip_fb->height);
+		break;
+	default:
+		igt_assert_f(0, "Unhandled rotation %x\n", rotation);
+	}
+
+	if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
+		return false;
+
+	assert_collected_crc_equal(data->pipe_crc, &crc, ref_crc);
+	return true;
+}
+
+static void yuv_chroma_subpixel_clip(data_t *data, enum pipe pipe, igt_output_t *output, unsigned format)
+{
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	igt_display_t *display = &data->display;
+	igt_pipe_t *pipe_obj = &display->pipes[pipe];
+	struct igt_fb *bg_fb = &data->fb[0];
+	struct igt_fb *bg_cursor_fb = &data->fb[1];
+	struct igt_fb *black_cursor_fb = &data->fb[2];
+	struct igt_fb *clip_fb = &data->fb[3];
+	igt_plane_t *primary = igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_PRIMARY);
+	igt_plane_t *cursor = igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_CURSOR);
+	igt_plane_t *plane;
+	cairo_t *cr;
+	bool ret = false;
+	bool tiled = igt_display_has_format_mod(display, DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED);
+
+	prepare_crtc(data, pipe, output);
+
+	igt_create_color_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
+			    DRM_FORMAT_XRGB8888, tiled ? LOCAL_I915_FORMAT_MOD_X_TILED : LOCAL_DRM_FORMAT_MOD_NONE,
+			    .0, .0, 1., bg_fb);
+
+	igt_create_color_fb(display->drm_fd, 256, 256,
+		            DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
+			    .0, .0, 1., bg_cursor_fb);
+
+	igt_create_color_fb(display->drm_fd, 256, 256,
+		            DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
+			    .0, .0, .0, black_cursor_fb);
+
+	igt_create_fb(display->drm_fd, 256, 256,
+		      format, tiled ? LOCAL_I915_FORMAT_MOD_Y_TILED : LOCAL_DRM_FORMAT_MOD_NONE, clip_fb);
+
+	/* Draw the FB that will be used for clipping the chroma subpixel test. */
+	cr = igt_get_cairo_ctx(display->drm_fd, clip_fb);
+
+	igt_paint_color(cr, 0, 0, clip_fb->width, clip_fb->height, 1., 0., 0.);
+	igt_paint_color(cr, 2, 2, clip_fb->width - 4, clip_fb->height - 4, 0., 1., 1.);
+	igt_paint_color(cr, 4, 4, clip_fb->width - 8, clip_fb->height - 8, .75, .75, 1.);
+
+	/* White dots in the corners. */
+	igt_paint_color(cr, 0, 0, 6, 6, 1., 1., 1.);
+	igt_paint_color(cr, clip_fb->width - 6, 0, 6, 6, 1., 1., 1.);
+	igt_paint_color(cr, 0, clip_fb->height - 6, 6, 6, 1., 1., 1.);
+	igt_paint_color(cr, clip_fb->width - 6, clip_fb->height - 6, 6, 6, 1., 1., 1.);
+
+	igt_put_cairo_ctx(display->drm_fd, clip_fb, cr);
+
+	igt_pipe_crc_start(data->pipe_crc);
+
+	igt_plane_set_fb(primary, bg_fb);
+	for_each_plane_on_pipe(display, pipe, plane) {
+		struct igt_fb *cursor_fb = plane == primary ? black_cursor_fb : bg_cursor_fb;
+		igt_crc_t ref_crc;
+
+		if (!igt_plane_has_format_mod(plane, format, clip_fb->modifier) || plane == cursor)
+			continue;
+
+		yuv_chroma_subpixel_clip_plane_with_cursor(data, plane, clip_fb, cursor, cursor_fb, &ref_crc, 63 + clip_fb->width, 64);
+		ret |= yuv_chroma_subpixel_clip_plane_right(data, IGT_ROTATION_0, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_right(data, IGT_ROTATION_90, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_right(data, IGT_ROTATION_180, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_right(data, IGT_ROTATION_270, plane, clip_fb, &ref_crc);
+
+		yuv_chroma_subpixel_clip_plane_with_cursor(data, plane, clip_fb, cursor, cursor_fb, &ref_crc, 64, 63 + clip_fb->height);
+		ret |= yuv_chroma_subpixel_clip_plane_bottom(data, IGT_ROTATION_0, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_bottom(data, IGT_ROTATION_90, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_bottom(data, IGT_ROTATION_180, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_bottom(data, IGT_ROTATION_270, plane, clip_fb, &ref_crc);
+
+		yuv_chroma_subpixel_clip_plane_with_cursor(data, plane, clip_fb, cursor, cursor_fb, &ref_crc, 65 - cursor_fb->width, 64);
+		ret |= yuv_chroma_subpixel_clip_plane_left(data, IGT_ROTATION_0, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_left(data, IGT_ROTATION_90, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_left(data, IGT_ROTATION_180, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_left(data, IGT_ROTATION_270, plane, clip_fb, &ref_crc);
+
+		yuv_chroma_subpixel_clip_plane_with_cursor(data, plane, clip_fb, cursor, cursor_fb, &ref_crc, 64, 65 - cursor_fb->height);
+		ret |= yuv_chroma_subpixel_clip_plane_top(data, IGT_ROTATION_0, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_top(data, IGT_ROTATION_90, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_top(data, IGT_ROTATION_180, plane, clip_fb, &ref_crc);
+		ret |= yuv_chroma_subpixel_clip_plane_top(data, IGT_ROTATION_270, plane, clip_fb, &ref_crc);
+
+		/* Reset to defaults */
+		igt_plane_set_position(plane, 0, 0);
+		igt_plane_set_rotation(plane, IGT_ROTATION_0);
+		igt_plane_set_fb(plane, plane == primary ? bg_fb : NULL);
+	}
+
+	igt_require_f(ret, "Could not test subpixel clipping in any corner\n");
+}
+
+static void run_tests_for_pipe(data_t *data, enum pipe pipe,
+			       const char *fstr, unsigned int format)
+{
+	igt_output_t *output;
+	igt_display_t *display = &data->display;
+
+	igt_subtest_group {
+		igt_fixture {
+			igt_display_require_output_on_pipe(display, pipe);
+			igt_require(igt_fb_supported_format(format));
+			igt_require(pipe_supports_format(display, pipe, format, x_modifier));
+		}
+
+		igt_subtest_f("pipe-%s-%s-rgb-switch",
+			kmstest_pipe_name(pipe), fstr)
+			for_each_valid_output_on_pipe(display, pipe, output)
+				yuv_rgb_switch(data, pipe, output, false, format);
+
+		igt_subtest_f("pipe-%s-%s-rgb-scaled-switch",
+			kmstest_pipe_name(pipe), fstr)
+			for_each_valid_output_on_pipe(display, pipe, output)
+				yuv_rgb_switch(data, pipe, output, true, format);
+
+		igt_subtest_f("pipe-%s-%s-valid-width",
+			kmstest_pipe_name(pipe), fstr)
+			for_each_valid_output_on_pipe(display, pipe, output)
+				yuv_valid_width(data, pipe, output, format);
+
+		igt_subtest_f("pipe-%s-%s-crop-scale-bug",
+			kmstest_pipe_name(pipe), fstr)
+			for_each_valid_output_on_pipe(display, pipe, output)
+				yuv_crop_scale_bug(data, pipe, output, format);
+
+		igt_subtest_f("pipe-%s-%s-chroma-subpixel-clip",
+			kmstest_pipe_name(pipe), fstr)
+			for_each_valid_output_on_pipe(display, pipe, output)
+				yuv_chroma_subpixel_clip(data, pipe, output, format);
+	}
+}
+
+igt_main
+{
+	data_t data = {};
+	enum pipe pipe;
+
+	igt_skip_on_simulation();
+
+	igt_fixture {
+		data.display.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+		igt_display_require(&data.display, data.display.drm_fd);
+		igt_require(data.display.is_atomic);
+		igt_require_pipe_crc(data.display.drm_fd);
+
+		if (igt_display_has_format_mod(&data.display, DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED))
+			x_modifier = LOCAL_I915_FORMAT_MOD_X_TILED;
+
+		if (igt_display_has_format_mod(&data.display, DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_Y_TILED))
+			y_modifier = LOCAL_I915_FORMAT_MOD_Y_TILED;
+	}
+
+	for_each_pipe_static(pipe) {
+		run_tests_for_pipe(&data, pipe, "NV12", DRM_FORMAT_NV12);
+		run_tests_for_pipe(&data, pipe, "NV16", DRM_FORMAT_NV16);
+		run_tests_for_pipe(&data, pipe, "NV21", DRM_FORMAT_NV21);
+		run_tests_for_pipe(&data, pipe, "NV61", DRM_FORMAT_NV61);
+		run_tests_for_pipe(&data, pipe, "YUV420", DRM_FORMAT_YUV420);
+		run_tests_for_pipe(&data, pipe, "YUV422", DRM_FORMAT_YUV422);
+		run_tests_for_pipe(&data, pipe, "YVU420", DRM_FORMAT_YVU420);
+		run_tests_for_pipe(&data, pipe, "YVU422", DRM_FORMAT_YVU422);
+		run_tests_for_pipe(&data, pipe, "P010", DRM_FORMAT_P010);
+		run_tests_for_pipe(&data, pipe, "P012", DRM_FORMAT_P012);
+		run_tests_for_pipe(&data, pipe, "P016", DRM_FORMAT_P016);
+		run_tests_for_pipe(&data, pipe, "YUYV", DRM_FORMAT_YUYV);
+		run_tests_for_pipe(&data, pipe, "YVYU", DRM_FORMAT_YVYU);
+		run_tests_for_pipe(&data, pipe, "UYVY", DRM_FORMAT_UYVY);
+		run_tests_for_pipe(&data, pipe, "VYUY", DRM_FORMAT_VYUY);
+		run_tests_for_pipe(&data, pipe, "XYUV8888", DRM_FORMAT_XYUV8888);
+		run_tests_for_pipe(&data, pipe, "Y210", DRM_FORMAT_Y210);
+		run_tests_for_pipe(&data, pipe, "Y212", DRM_FORMAT_Y212);
+		run_tests_for_pipe(&data, pipe, "Y216", DRM_FORMAT_Y216);
+		run_tests_for_pipe(&data, pipe, "Y410", DRM_FORMAT_Y410);
+		run_tests_for_pipe(&data, pipe, "Y412", DRM_FORMAT_Y412);
+		run_tests_for_pipe(&data, pipe, "Y416", DRM_FORMAT_Y416);
+		run_tests_for_pipe(&data, pipe, "XV30", DRM_FORMAT_XVYU2101010);
+		run_tests_for_pipe(&data, pipe, "XV36", DRM_FORMAT_XVYU12_16161616);
+		run_tests_for_pipe(&data, pipe, "XV48", DRM_FORMAT_XVYU16161616);
+	}
+
+	igt_fixture {
+		igt_display_fini(&data.display);
+		close(data.display.drm_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 9015f809ed05..8ca7fe5f4917 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -61,6 +61,7 @@ test_progs = [
 	'kms_universal_plane',
 	'kms_vblank',
 	'kms_vrr',
+	'kms_yuv',
 	'meta_test',
 	'perf',
 	'prime_busy',
-- 
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] 10+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for Add support for more YUV tests.
  2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3 Maarten Lankhorst
@ 2019-03-27 10:55 ` Patchwork
  2019-03-27 20:52 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
  4 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2019-03-27 10:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: igt-dev

== Series Details ==

Series: Add support for more YUV tests.
URL   : https://patchwork.freedesktop.org/series/58630/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5823 -> IGTPW_2716
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/58630/revisions/1/mbox/

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

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

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live_execlists:
    - fi-apl-guc:         PASS -> INCOMPLETE [fdo#103927] / [fdo#109720]

  * igt@i915_selftest@live_hangcheck:
    - fi-ilk-650:         PASS -> INCOMPLETE [fdo#109723]

  * igt@kms_frontbuffer_tracking@basic:
    - fi-byt-clapper:     PASS -> FAIL [fdo#103167]

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
    - fi-byt-clapper:     PASS -> FAIL [fdo#103191] / [fdo#107362]

  * igt@kms_psr@primary_mmap_gtt:
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] +27

  * igt@runner@aborted:
    - fi-apl-guc:         NOTRUN -> FAIL [fdo#108622] / [fdo#109720]

  
#### Possible fixes ####

  * igt@i915_selftest@live_contexts:
    - fi-skl-gvtdvm:      DMESG-FAIL [fdo#110235 ] -> PASS

  * igt@i915_selftest@live_evict:
    - fi-bsw-kefka:       DMESG-WARN [fdo#107709] -> PASS

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

  * igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
    - fi-byt-clapper:     FAIL [fdo#103191] / [fdo#107362] -> PASS

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - fi-blb-e6850:       INCOMPLETE [fdo#107718] -> PASS

  * igt@prime_vgem@basic-fence-flip:
    - fi-ilk-650:         FAIL [fdo#104008] -> PASS

  
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103182]: https://bugs.freedesktop.org/show_bug.cgi?id=103182
  [fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#104008]: https://bugs.freedesktop.org/show_bug.cgi?id=104008
  [fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362
  [fdo#107709]: https://bugs.freedesktop.org/show_bug.cgi?id=107709
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#108622]: https://bugs.freedesktop.org/show_bug.cgi?id=108622
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109720]: https://bugs.freedesktop.org/show_bug.cgi?id=109720
  [fdo#109723]: https://bugs.freedesktop.org/show_bug.cgi?id=109723
  [fdo#110235 ]: https://bugs.freedesktop.org/show_bug.cgi?id=110235 


Participating hosts (43 -> 33)
------------------------------

  Missing    (10): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-icl-u2 fi-bsw-cyan fi-kbl-7500u fi-ivb-3770 fi-pnv-d510 fi-bdw-samus 


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

    * IGT: IGT_4907 -> IGTPW_2716

  CI_DRM_5823: f346d92211072f89a64f917d3b61cb8177a6fe4b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2716: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2716/
  IGT_4907: 7c8f2616fa0fd3ddb16e050c5b7ea9ce707abbe4 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+++ 750 lines
--- 0 lines

== Logs ==

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

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

* Re: [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4.
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4 Maarten Lankhorst
@ 2019-03-27 17:20   ` Ville Syrjälä
  2019-03-28 10:53     ` Maarten Lankhorst
  0 siblings, 1 reply; 10+ messages in thread
From: Ville Syrjälä @ 2019-03-27 17:20 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: igt-dev

On Wed, Mar 27, 2019 at 10:29:29AM +0100, Maarten Lankhorst wrote:
> Y410 is packed with compressed a channel and only 32 bpp, like
> 10 bits RGB formats. Y416 is a packed 16 bits per component format.
> 
> Changes since v1:
> - Rebase on top of upstream YUV changes.
> Changes since v2:
> - Discard alpha channel, not used upstream.
> Changes since v3:
> - Handle the XVYU formats and Y41x formats correctly.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_color_encoding.c |   6 +
>  lib/igt_fb.c             | 263 +++++++++++++++++++++++++++++++++++----
>  2 files changed, 244 insertions(+), 25 deletions(-)
> 
> diff --git a/lib/igt_color_encoding.c b/lib/igt_color_encoding.c
> index 9f9dc1439ee4..7de6d5abd690 100644
> --- a/lib/igt_color_encoding.c
> +++ b/lib/igt_color_encoding.c
> @@ -154,6 +154,12 @@ static const struct color_encoding_format {
>  	{ DRM_FORMAT_Y210, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  	{ DRM_FORMAT_Y212, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  	{ DRM_FORMAT_Y216, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_Y410, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
> +	{ DRM_FORMAT_Y412, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_Y416, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_XVYU2101010, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
> +	{ DRM_FORMAT_XVYU12_16161616, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_XVYU16161616, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  };
>  
>  static const struct color_encoding_format *lookup_fourcc(uint32_t fourcc)
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 1e0bcb9ea2cd..2d55687a7aa3 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -221,6 +221,36 @@ static const struct format_desc_struct {
>  	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
>  	  .hsub = 2, .vsub = 1,
>  	},
> +	{ .name = "Y410", .depth = -1, .drm_id = DRM_FORMAT_Y410,
> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
> +	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
> +	},
> +	{ .name = "Y412", .depth = -1, .drm_id = DRM_FORMAT_Y412,
> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
> +	  .num_planes = 1, .plane_bpp = { 64, },
> +	  .hsub = 1, .vsub = 1,
> +	},
> +	{ .name = "Y416", .depth = -1, .drm_id = DRM_FORMAT_Y416,
> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
> +	  .num_planes = 1, .plane_bpp = { 64, },
> +	  .hsub = 1, .vsub = 1,
> +	},
> +	{ .name = "XV30", .depth = -1, .drm_id = DRM_FORMAT_XVYU2101010,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 1, .vsub = 1,
> +	},
> +	{ .name = "XV36", .depth = -1, .drm_id = DRM_FORMAT_XVYU12_16161616,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 64, },
> +	  .hsub = 1, .vsub = 1,
> +	},
> +	{ .name = "XV48", .depth = -1, .drm_id = DRM_FORMAT_XVYU16161616,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 64, },
> +	  .hsub = 1, .vsub = 1,
> +	},
>  	{ .name = "P010", .depth = -1, .drm_id = DRM_FORMAT_P010,
>  	  .cairo_id = CAIRO_FORMAT_RGB96F,
>  	  .num_planes = 2, .plane_bpp = { 16, 32 },
> @@ -684,6 +714,33 @@ static void clear_yuv_buffer(struct igt_fb *fb)
>  			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
>  		break;
>  
> +	case DRM_FORMAT_XVYU2101010:
> +	case DRM_FORMAT_Y410:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0xe0000200 : 0xe0010200,

For everything else we leave alpha zeroed.

> +		fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +		break;
> +
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +	case DRM_FORMAT_Y412:
> +	case DRM_FORMAT_Y416: {
> +		struct ayuv16 { uint16_t u, y, v, a; };
> +		const struct ayuv16 pixel = {
> +			.a = 0xffff,
> +			.v = full_range ? 0 : 0x1000,
> +			.y = 0x8000,
> +			.u = full_range ? 0 : 0x1000
> +		};
> +
> +		for (int i = 0; i < fb->plane_height[0]; i++) {
> +			struct ayuv16 *cur = ptr + fb->offsets[0] + fb->strides[0] * i;
> +
> +			for (int j = 0; j < fb->plane_width[0]; j++)
> +				*cur++ = pixel;
> +		}

Maybe we want a memset64()?

> +		break;
> +		}
>  	}
>  
>  	igt_fb_unmap_buffer(fb, ptr);
> @@ -1897,10 +1954,11 @@ static void convert_src_put(const struct fb_convert *cvt,
>  }
>  
>  struct yuv_parameters {
> -	unsigned	y_inc;
> +	unsigned	ay_inc;
>  	unsigned	uv_inc;
> -	unsigned	y_stride;
> +	unsigned	ay_stride;
>  	unsigned	uv_stride;
> +	unsigned	a_offset;
>  	unsigned	y_offset;
>  	unsigned	u_offset;
>  	unsigned	v_offset;
> @@ -1918,7 +1976,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_P010:
>  	case DRM_FORMAT_P012:
>  	case DRM_FORMAT_P016:
> -		params->y_inc = 1;
> +		params->ay_inc = 1;
>  		params->uv_inc = 2;
>  		break;
>  
> @@ -1926,7 +1984,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_YUV422:
>  	case DRM_FORMAT_YVU420:
>  	case DRM_FORMAT_YVU422:
> -		params->y_inc = 1;
> +		params->ay_inc = 1;
>  		params->uv_inc = 1;
>  		break;
>  
> @@ -1937,12 +1995,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_Y210:
>  	case DRM_FORMAT_Y212:
>  	case DRM_FORMAT_Y216:
> -		params->y_inc = 2;
> +		params->ay_inc = 2;
>  		params->uv_inc = 4;
>  		break;
>  
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +	case DRM_FORMAT_Y412:
> +	case DRM_FORMAT_Y416:
>  	case DRM_FORMAT_XYUV8888:
> -		params->y_inc = 4;
> +		params->ay_inc = 4;
>  		params->uv_inc = 4;
>  		break;
>  	}
> @@ -1959,7 +2021,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_P010:
>  	case DRM_FORMAT_P012:
>  	case DRM_FORMAT_P016:
> -		params->y_stride = fb->strides[0];
> +		params->ay_stride = fb->strides[0];
>  		params->uv_stride = fb->strides[1];
>  		break;
>  
> @@ -1971,7 +2033,11 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_Y212:
>  	case DRM_FORMAT_Y216:
>  	case DRM_FORMAT_XYUV8888:
> -		params->y_stride = fb->strides[0];
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +	case DRM_FORMAT_Y412:
> +	case DRM_FORMAT_Y416:
> +		params->ay_stride = fb->strides[0];
>  		params->uv_stride = fb->strides[0];
>  		break;
>  	}
> @@ -2045,6 +2111,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  		params->v_offset = fb->offsets[0] + 6;
>  		break;
>  
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +	case DRM_FORMAT_Y412:
> +	case DRM_FORMAT_Y416:
> +		params->a_offset = fb->offsets[0] + 6;
> +		params->y_offset = fb->offsets[0] + 2;
> +		params->u_offset = fb->offsets[0];
> +		params->v_offset = fb->offsets[0] + 4;
> +		break;
> +
>  	case DRM_FORMAT_XYUV8888:
>  		params->y_offset = fb->offsets[0] + 1;
>  		params->u_offset = fb->offsets[0] + 2;
> @@ -2096,7 +2172,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>  			write_rgb(rgb_tmp, &rgb);
>  
>  			rgb_tmp += bpp;
> -			y_tmp += params.y_inc;
> +			y_tmp += params.ay_inc;
>  
>  			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
>  				u_tmp += params.uv_inc;
> @@ -2105,7 +2181,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>  		}
>  
>  		rgb24 += rgb24_stride;
> -		y += params.y_stride;
> +		y += params.ay_stride;
>  
>  		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
>  			u += params.uv_stride;
> @@ -2156,7 +2232,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>  			rgb_tmp += bpp;
>  
>  			*y_tmp = yuv.d[0];
> -			y_tmp += params.y_inc;
> +			y_tmp += params.ay_inc;
>  
>  			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
>  				continue;
> @@ -2193,7 +2269,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>  		}
>  
>  		rgb24 += rgb24_stride;
> -		y += params.y_stride;
> +		y += params.ay_stride;
>  
>  		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
>  			u += params.uv_stride;
> @@ -2217,13 +2293,13 @@ static void write_rgbf(float *rgb24, const struct igt_vec4 *rgb)
>  	rgb24[2] = rgb->d[2];
>  }
>  
> -static void convert_yuv16_to_float(struct fb_convert *cvt)
> +static void convert_yuv16_to_float(struct fb_convert *cvt, bool alpha)
>  {
>  	const struct format_desc_struct *src_fmt =
>  		lookup_drm_format(cvt->src.fb->drm_format);
>  	int i, j;
> -	uint8_t fpp = 3;
> -	uint16_t *y, *u, *v;
> +	uint8_t fpp = alpha ? 4 : 3;
> +	uint16_t *a, *y, *u, *v;
>  	float *ptr = cvt->dst.ptr;
>  	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
>  	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
> @@ -2242,11 +2318,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>  		   !(params.u_offset % sizeof(*buf)) &&
>  		   !(params.v_offset % sizeof(*buf)));
>  
> +	a = buf + params.a_offset / sizeof(*buf);
>  	y = buf + params.y_offset / sizeof(*buf);
>  	u = buf + params.u_offset / sizeof(*buf);
>  	v = buf + params.v_offset / sizeof(*buf);
>  
>  	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		const uint16_t *a_tmp = a;
>  		const uint16_t *y_tmp = y;
>  		const uint16_t *u_tmp = u;
>  		const uint16_t *v_tmp = v;
> @@ -2263,8 +2341,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>  			rgb = igt_matrix_transform(&m, &yuv);
>  			write_rgbf(rgb_tmp, &rgb);
>  
> +			if (alpha) {
> +				rgb_tmp[3] = ((float)*a_tmp) / 65535.f;
> +				a_tmp += params.ay_inc;
> +			}
> +
>  			rgb_tmp += fpp;
> -			y_tmp += params.y_inc;
> +			y_tmp += params.ay_inc;
>  
>  			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
>  				u_tmp += params.uv_inc;
> @@ -2273,7 +2356,9 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>  		}
>  
>  		ptr += float_stride;
> -		y += params.y_stride / sizeof(*y);
> +
> +		a += params.ay_stride / sizeof(*a);
> +		y += params.ay_stride / sizeof(*y);
>  
>  		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
>  			u += params.uv_stride / sizeof(*u);
> @@ -2284,14 +2369,14 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>  	convert_src_put(cvt, buf);
>  }
>  
> -static void convert_float_to_yuv16(struct fb_convert *cvt)
> +static void convert_float_to_yuv16(struct fb_convert *cvt, bool alpha)
>  {
>  	const struct format_desc_struct *dst_fmt =
>  		lookup_drm_format(cvt->dst.fb->drm_format);
>  	int i, j;
> -	uint16_t *y, *u, *v;
> +	uint16_t *a, *y, *u, *v;
>  	const float *ptr = cvt->src.ptr;
> -	uint8_t fpp = 3;
> +	uint8_t fpp = alpha ? 4 : 3;
>  	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
>  	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
>  						    cvt->dst.fb->drm_format,
> @@ -2303,16 +2388,19 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>  		   igt_format_is_yuv(cvt->dst.fb->drm_format));
>  
>  	get_yuv_parameters(cvt->dst.fb, &params);
> -	igt_assert(!(params.y_offset % sizeof(*y)) &&
> +	igt_assert(!(params.a_offset % sizeof(*a)) &&
> +		   !(params.y_offset % sizeof(*y)) &&
>  		   !(params.u_offset % sizeof(*u)) &&
>  		   !(params.v_offset % sizeof(*v)));
>  
> +	a = cvt->dst.ptr + params.a_offset;
>  	y = cvt->dst.ptr + params.y_offset;
>  	u = cvt->dst.ptr + params.u_offset;
>  	v = cvt->dst.ptr + params.v_offset;
>  
>  	for (i = 0; i < cvt->dst.fb->height; i++) {
>  		const float *rgb_tmp = ptr;
> +		uint16_t *a_tmp = a;
>  		uint16_t *y_tmp = y;
>  		uint16_t *u_tmp = u;
>  		uint16_t *v_tmp = v;
> @@ -2325,10 +2413,15 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>  			read_rgbf(&rgb, rgb_tmp);
>  			yuv = igt_matrix_transform(&m, &rgb);
>  
> +			if (alpha) {
> +				*a_tmp = rgb_tmp[3] * 65535.f + .5f;
> +				a_tmp += params.ay_inc;
> +			}
> +
>  			rgb_tmp += fpp;
>  
>  			*y_tmp = yuv.d[0];
> -			y_tmp += params.y_inc;
> +			y_tmp += params.ay_inc;
>  
>  			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
>  				continue;
> @@ -2365,7 +2458,8 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>  		}
>  
>  		ptr += float_stride;
> -		y += params.y_stride / sizeof(*y);
> +		a += params.ay_stride / sizeof(*a);
> +		y += params.ay_stride / sizeof(*y);
>  
>  		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
>  			u += params.uv_stride / sizeof(*u);
> @@ -2374,6 +2468,95 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>  	}
>  }
>  
> +static void convert_Y410_to_float(struct fb_convert *cvt, bool alpha)
> +{
> +	int i, j;
> +	const uint32_t *uyv;
> +	uint32_t *buf;
> +	float *ptr = cvt->dst.ptr;
> +	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
> +	unsigned int uyv_stride = cvt->src.fb->strides[0] / sizeof(*uyv);
> +	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
> +						    cvt->dst.fb->drm_format,
> +						    cvt->src.fb->color_encoding,
> +						    cvt->src.fb->color_range);
> +	unsigned bpp = alpha ? 4 : 3;
> +
> +	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_Y410 ||
> +		    cvt->src.fb->drm_format == DRM_FORMAT_XVYU2101010) &&
> +		   cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT);
> +
> +	uyv = buf = convert_src_get(cvt);
> +
> +	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		for (j = 0; j < cvt->dst.fb->width; j++) {
> +			/* Convert 2x1 pixel blocks */
> +			struct igt_vec4 yuv;
> +			struct igt_vec4 rgb;
> +
> +			yuv.d[0] = uyv[j] & 0x3ff;
> +			yuv.d[1] = (uyv[j] >> 10) & 0x3ff;
> +			yuv.d[2] = (uyv[j] >> 20) & 0x3ff;

These seem to be in the wrong order. At least I think we wanted
[0]=y, [1]=cb, [2]=cr

> +			yuv.d[3] = 1.f;
> +
> +			rgb = igt_matrix_transform(&m, &yuv);
> +
> +			write_rgbf(&ptr[j * bpp], &rgb);
> +			if (alpha)
> +				ptr[j * bpp + 3] = (float)(uyv[j] >> 30) / 3.f;
> +		}
> +
> +		ptr += float_stride;
> +		uyv += uyv_stride;
> +	}
> +
> +	convert_src_put(cvt, buf);
> +}
> +
> +static void convert_float_to_Y410(struct fb_convert *cvt, bool alpha)
> +{
> +	int i, j;
> +	uint32_t *uyv = cvt->dst.ptr;
> +	const float *ptr = cvt->src.ptr;
> +	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
> +	unsigned uyv_stride = cvt->dst.fb->strides[0] / sizeof(*uyv);
> +	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
> +						    cvt->dst.fb->drm_format,
> +						    cvt->dst.fb->color_encoding,
> +						    cvt->dst.fb->color_range);
> +	unsigned bpp = alpha ? 4 : 3;
> +
> +	igt_assert(cvt->src.fb->drm_format == IGT_FORMAT_FLOAT &&
> +		   (cvt->dst.fb->drm_format == DRM_FORMAT_Y410 ||
> +		    cvt->dst.fb->drm_format == DRM_FORMAT_XVYU2101010));
> +
> +	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;
> +			uint8_t a = 0;
> +			uint16_t y, cb, cr;
> +
> +			read_rgbf(&rgb, &ptr[j * bpp]);
> +			if (alpha)
> +				 a = ptr[j * bpp + 3] * 3.f + .5f;
> +
> +			yuv = igt_matrix_transform(&m, &rgb);
> +			cr = yuv.d[0];
> +			y = yuv.d[1];
> +			cb = yuv.d[2];

Same here.

> +
> +			uyv[j] = ((cr & 0x3ff) << 0) |
> +				  ((y & 0x3ff) << 10) |
> +				  ((cb & 0x3ff) << 20) |
> +				  (a << 30);

cb and cr swapped here.

> +		}
> +
> +		ptr += float_stride;
> +		uyv += uyv_stride;
> +	}
> +}
> +
>  static void convert_pixman(struct fb_convert *cvt)
>  {
>  	pixman_format_code_t src_pixman = drm_format_to_pixman(cvt->src.fb->drm_format);
> @@ -2463,7 +2646,19 @@ static void fb_convert(struct fb_convert *cvt)
>  		case DRM_FORMAT_Y210:
>  		case DRM_FORMAT_Y212:
>  		case DRM_FORMAT_Y216:
> -			convert_yuv16_to_float(cvt);
> +		case DRM_FORMAT_XVYU12_16161616:
> +		case DRM_FORMAT_XVYU16161616:
> +			convert_yuv16_to_float(cvt, false);
> +			return;
> +		case DRM_FORMAT_Y410:
> +			convert_Y410_to_float(cvt, true);
> +			return;
> +		case DRM_FORMAT_XVYU2101010:
> +			convert_Y410_to_float(cvt, false);
> +			return;
> +		case DRM_FORMAT_Y412:
> +		case DRM_FORMAT_Y416:
> +			convert_yuv16_to_float(cvt, true);
>  			return;
>  		}
>  	} else if (cvt->src.fb->drm_format == IGT_FORMAT_FLOAT) {
> @@ -2474,7 +2669,19 @@ static void fb_convert(struct fb_convert *cvt)
>  		case DRM_FORMAT_Y210:
>  		case DRM_FORMAT_Y212:
>  		case DRM_FORMAT_Y216:
> -			convert_float_to_yuv16(cvt);
> +		case DRM_FORMAT_XVYU12_16161616:
> +		case DRM_FORMAT_XVYU16161616:
> +			convert_float_to_yuv16(cvt, false);
> +			return;
> +		case DRM_FORMAT_Y410:
> +			convert_float_to_Y410(cvt, true);
> +			return;
> +		case DRM_FORMAT_XVYU2101010:
> +			convert_float_to_Y410(cvt, false);
> +			return;
> +		case DRM_FORMAT_Y412:
> +		case DRM_FORMAT_Y416:
> +			convert_float_to_yuv16(cvt, true);
>  			return;
>  		}
>  	}
> @@ -2941,6 +3148,12 @@ bool igt_format_is_yuv(uint32_t drm_format)
>  	case DRM_FORMAT_Y210:
>  	case DRM_FORMAT_Y212:
>  	case DRM_FORMAT_Y216:
> +	case DRM_FORMAT_XVYU2101010:
> +	case DRM_FORMAT_XVYU12_16161616:
> +	case DRM_FORMAT_XVYU16161616:
> +	case DRM_FORMAT_Y410:
> +	case DRM_FORMAT_Y412:
> +	case DRM_FORMAT_Y416:
>  	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

-- 
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] 10+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3.
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3 Maarten Lankhorst
@ 2019-03-27 17:21   ` Ville Syrjälä
  0 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2019-03-27 17:21 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: igt-dev

On Wed, Mar 27, 2019 at 10:29:28AM +0100, Maarten Lankhorst wrote:
> Those formats are packed like YUYV, but only 16 bits per component.
> 
> Changes since v1:
> - Rebase on top of upstream YUV changes.
> Changes since v2:
> - Use drm_fourcc.h from upstream.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Looks consistent with the existing stuff.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> ---
>  include/drm-uapi/drm_fourcc.h | 51 ++++++++++++++++++++++++++++++++++-
>  lib/igt_color_encoding.c      |  3 +++
>  lib/igt_fb.c                  | 46 +++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+), 1 deletion(-)
> 
> diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
> index bab20298f422..3feeaa3f987a 100644
> --- a/include/drm-uapi/drm_fourcc.h
> +++ b/include/drm-uapi/drm_fourcc.h
> @@ -144,6 +144,17 @@ extern "C" {
>  #define DRM_FORMAT_RGBA1010102	fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */
>  #define DRM_FORMAT_BGRA1010102	fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
>  
> +/*
> + * Floating point 64bpp RGB
> + * IEEE 754-2008 binary16 half-precision float
> + * [15:0] sign:exponent:mantissa 1:5:10
> + */
> +#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H') /* [63:0] x:R:G:B 16:16:16:16 little endian */
> +#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */
> +
> +#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') /* [63:0] A:R:G:B 16:16:16:16 little endian */
> +#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
> +
>  /* packed YCbCr */
>  #define DRM_FORMAT_YUYV		fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
>  #define DRM_FORMAT_YVYU		fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
> @@ -151,7 +162,29 @@ extern "C" {
>  #define DRM_FORMAT_VYUY		fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
>  
>  #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
> -#define DRM_FORMAT_XYUV8888		fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
> +#define DRM_FORMAT_XYUV8888	fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
> +#define DRM_FORMAT_VUY888	fourcc_code('V', 'U', '2', '4') /* [23:0] Cr:Cb:Y 8:8:8 little endian */
> +#define DRM_FORMAT_VUY101010	fourcc_code('V', 'U', '3', '0') /* Y followed by U then V, 10:10:10. Non-linear modifier only */
> +
> +/*
> + * packed Y2xx indicate for each component, xx valid data occupy msb
> + * 16-xx padding occupy lsb
> + */
> +#define DRM_FORMAT_Y210         fourcc_code('Y', '2', '1', '0') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels */
> +#define DRM_FORMAT_Y212         fourcc_code('Y', '2', '1', '2') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels */
> +#define DRM_FORMAT_Y216         fourcc_code('Y', '2', '1', '6') /* [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels */
> +
> +/*
> + * packed Y4xx indicate for each component, xx valid data occupy msb
> + * 16-xx padding occupy lsb except Y410
> + */
> +#define DRM_FORMAT_Y410         fourcc_code('Y', '4', '1', '0') /* [31:0] A:Cr:Y:Cb 2:10:10:10 little endian */
> +#define DRM_FORMAT_Y412         fourcc_code('Y', '4', '1', '2') /* [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */
> +#define DRM_FORMAT_Y416         fourcc_code('Y', '4', '1', '6') /* [63:0] A:Cr:Y:Cb 16:16:16:16 little endian */
> +
> +#define DRM_FORMAT_XVYU2101010	fourcc_code('X', 'V', '3', '0') /* [31:0] X:Cr:Y:Cb 2:10:10:10 little endian */
> +#define DRM_FORMAT_XVYU12_16161616	fourcc_code('X', 'V', '3', '6') /* [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */
> +#define DRM_FORMAT_XVYU16161616	fourcc_code('X', 'V', '4', '8') /* [63:0] X:Cr:Y:Cb 16:16:16:16 little endian */
>  
>  /*
>   * packed YCbCr420 2x2 tiled formats
> @@ -167,6 +200,15 @@ extern "C" {
>  /* [63:0]   X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0  1:1:10:10:10:1:1:10:10:10 little endian */
>  #define DRM_FORMAT_X0L2		fourcc_code('X', '0', 'L', '2')
>  
> +/*
> + * 1-plane YUV 4:2:0
> + * In these formats, the component ordering is specified (Y, followed by U
> + * then V), but the exact Linear layout is undefined.
> + * These formats can only be used with a non-Linear modifier.
> + */
> +#define DRM_FORMAT_YUV420_8BIT	fourcc_code('Y', 'U', '0', '8')
> +#define DRM_FORMAT_YUV420_10BIT	fourcc_code('Y', 'U', '1', '0')
> +
>  /*
>   * 2 plane RGB + A
>   * index 0 = RGB plane, same format as the corresponding non _A8 format has
> @@ -195,6 +237,13 @@ extern "C" {
>  #define DRM_FORMAT_NV24		fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */
>  #define DRM_FORMAT_NV42		fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */
>  
> +/*
> + * 2 plane YCbCr MSB aligned
> + * index 0 = Y plane, [15:0] Y:x [10:6] little endian
> + * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian
> + */
> +#define DRM_FORMAT_P210		fourcc_code('P', '2', '1', '0') /* 2x1 subsampled Cr:Cb plane, 10 bit per channel */
> +
>  /*
>   * 2 plane YCbCr MSB aligned
>   * index 0 = Y plane, [15:0] Y:x [10:6] little endian
> diff --git a/lib/igt_color_encoding.c b/lib/igt_color_encoding.c
> index cc76a9919242..9f9dc1439ee4 100644
> --- a/lib/igt_color_encoding.c
> +++ b/lib/igt_color_encoding.c
> @@ -151,6 +151,9 @@ static const struct color_encoding_format {
>  	{ DRM_FORMAT_P010, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  	{ DRM_FORMAT_P012, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  	{ DRM_FORMAT_P016, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_Y210, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_Y212, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
> +	{ DRM_FORMAT_Y216, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>  };
>  
>  static const struct color_encoding_format *lookup_fourcc(uint32_t fourcc)
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index bad1d1fbb4d7..1e0bcb9ea2cd 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -236,6 +236,21 @@ static const struct format_desc_struct {
>  	  .num_planes = 2, .plane_bpp = { 16, 32 },
>  	  .vsub = 2, .hsub = 2,
>  	},
> +	{ .name = "Y210", .depth = -1, .drm_id = DRM_FORMAT_Y210,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 2, .vsub = 1,
> +	},
> +	{ .name = "Y212", .depth = -1, .drm_id = DRM_FORMAT_Y212,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 2, .vsub = 1,
> +	},
> +	{ .name = "Y216", .depth = -1, .drm_id = DRM_FORMAT_Y216,
> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
> +	  .num_planes = 1, .plane_bpp = { 32, },
> +	  .hsub = 2, .vsub = 1,
> +	},
>  	{ .name = "IGT-FLOAT", .depth = -1, .drm_id = IGT_FORMAT_FLOAT,
>  	  .cairo_id = CAIRO_FORMAT_INVALID,
>  	  .num_planes = 1, .plane_bpp = { 128 },
> @@ -661,6 +676,14 @@ static void clear_yuv_buffer(struct igt_fb *fb)
>  		wmemset(ptr + fb->offsets[1], 0x80008000,
>  			fb->strides[1] * fb->plane_height[1] / sizeof(wchar_t));
>  		break;
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
> +		wmemset(ptr + fb->offsets[0],
> +			full_range ? 0x80000000 : 0x80001000,
> +			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +		break;
> +
>  	}
>  
>  	igt_fb_unmap_buffer(fb, ptr);
> @@ -1911,6 +1934,9 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_YVYU:
>  	case DRM_FORMAT_UYVY:
>  	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
>  		params->y_inc = 2;
>  		params->uv_inc = 4;
>  		break;
> @@ -1941,6 +1967,9 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  	case DRM_FORMAT_YVYU:
>  	case DRM_FORMAT_UYVY:
>  	case DRM_FORMAT_VYUY:
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
>  	case DRM_FORMAT_XYUV8888:
>  		params->y_stride = fb->strides[0];
>  		params->uv_stride = fb->strides[0];
> @@ -2008,6 +2037,14 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>  		params->v_offset = fb->offsets[0];
>  		break;
>  
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
> +		params->y_offset = fb->offsets[0];
> +		params->u_offset = fb->offsets[0] + 2;
> +		params->v_offset = fb->offsets[0] + 6;
> +		break;
> +
>  	case DRM_FORMAT_XYUV8888:
>  		params->y_offset = fb->offsets[0] + 1;
>  		params->u_offset = fb->offsets[0] + 2;
> @@ -2423,6 +2460,9 @@ static void fb_convert(struct fb_convert *cvt)
>  		case DRM_FORMAT_P010:
>  		case DRM_FORMAT_P012:
>  		case DRM_FORMAT_P016:
> +		case DRM_FORMAT_Y210:
> +		case DRM_FORMAT_Y212:
> +		case DRM_FORMAT_Y216:
>  			convert_yuv16_to_float(cvt);
>  			return;
>  		}
> @@ -2431,6 +2471,9 @@ static void fb_convert(struct fb_convert *cvt)
>  		case DRM_FORMAT_P010:
>  		case DRM_FORMAT_P012:
>  		case DRM_FORMAT_P016:
> +		case DRM_FORMAT_Y210:
> +		case DRM_FORMAT_Y212:
> +		case DRM_FORMAT_Y216:
>  			convert_float_to_yuv16(cvt);
>  			return;
>  		}
> @@ -2895,6 +2938,9 @@ bool igt_format_is_yuv(uint32_t drm_format)
>  	case DRM_FORMAT_P010:
>  	case DRM_FORMAT_P012:
>  	case DRM_FORMAT_P016:
> +	case DRM_FORMAT_Y210:
> +	case DRM_FORMAT_Y212:
> +	case DRM_FORMAT_Y216:
>  	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

-- 
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] 10+ messages in thread

* Re: [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3.
  2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3 Maarten Lankhorst
@ 2019-03-27 17:34   ` Ville Syrjälä
  0 siblings, 0 replies; 10+ messages in thread
From: Ville Syrjälä @ 2019-03-27 17:34 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: igt-dev

On Wed, Mar 27, 2019 at 10:29:30AM +0100, Maarten Lankhorst wrote:
> Add tests excercising switching between various scaled/unscaled
> transitions to and from various nv12 formats, since some of the
> workarounds mention this may fail.
> 
> We also add NV12 specific clipping/scaling tests, to make sure
> that YUV src coordinates are always programmed as a multiple of 2
> correctly, and verify scaling/clipping works with CRC tests.
> 
> crop-scale-bug shows a corruption when scaling and cropping at the
> same time.
> 
> The subpixel clip test rotates and clips a rectangle on each side,
> which should produce the same CRC as when that part of the rectangle
> is hidden by a cursor and a whole 2x2 pixel is hidden.
> 
> Changes since v1:
> - Reset plane position to 0,0 at the start of yuv_valid_width_plane().
> - Handle Swati's feedback.
> Changes since v2:
> - Skip 90°/270° rotation in tests when formats don't support it.
> - Add all new HDR formats to test.
> - Use igt_plane_has_format_mod.
> - Support tests on !i915 by checking if X/Y tiling modifiers are supported.
> - Do not enable untested planes to prevent exhausing memory bandwidth
>   and available NV12 Y planes in the rgb-switch-scaled test.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  tests/Makefile.sources |   1 +
>  tests/kms_yuv.c        | 843 +++++++++++++++++++++++++++++++++++++++++
>  tests/meson.build      |   1 +
>  3 files changed, 845 insertions(+)
>  create mode 100644 tests/kms_yuv.c
> 
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 71ccf00af256..5eb46087e362 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -74,6 +74,7 @@ TESTS_progs = \
>  	kms_universal_plane \
>  	kms_vblank \
>  	kms_vrr \
> +	kms_yuv \
>  	meta_test \
>  	perf \
>  	perf_pmu \
> diff --git a/tests/kms_yuv.c b/tests/kms_yuv.c
> new file mode 100644
> index 000000000000..ce9e4ade334f
> --- /dev/null
> +++ b/tests/kms_yuv.c
> @@ -0,0 +1,843 @@
> +/*
> + * Copyright © 2019 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *    Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> + */
> +#include "config.h"
> +
> +#include "igt.h"
> +#include <cairo.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <unistd.h>
> +#include <sys/time.h>
> +
> +typedef struct {
> +	igt_display_t display;
> +
> +	igt_pipe_crc_t *pipe_crc;
> +	struct igt_fb fb[6];
> +} data_t;
> +
> +static uint64_t x_modifier = LOCAL_DRM_FORMAT_MOD_NONE;
> +static uint64_t y_modifier = LOCAL_DRM_FORMAT_MOD_NONE;
> +
> +static bool pipe_supports_format(igt_display_t *display, enum pipe pipe, uint32_t format, uint64_t tiling)
> +{
> +	igt_plane_t *plane;
> +
> +	for_each_plane_on_pipe(display, pipe, plane)
> +		if (igt_plane_has_format_mod(plane, format, tiling))
> +			return true;
> +
> +	return false;
> +}
> +
> +static void remove_fbs(data_t *data)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(data->fb); i++)
> +		igt_remove_fb(data->display.drm_fd, &data->fb[i]);
> +}
> +
> +static void prepare_crtc(data_t *data, enum pipe pipe, igt_output_t *output)
> +{
> +	igt_display_t *display = &data->display;
> +
> +	remove_fbs(data);
> +	igt_display_reset(display);
> +	igt_output_set_pipe(output, pipe);
> +	igt_display_commit2(display, COMMIT_ATOMIC);
> +
> +	igt_pipe_crc_free(data->pipe_crc);
> +	data->pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
> +}
> +
> +static void set_fb(igt_plane_t *plane, struct igt_fb *fb, bool scaled)
> +{
> +	igt_plane_set_fb(plane, fb);
> +
> +	if (scaled && fb)
> +		igt_fb_set_size(fb, plane, fb->width, 16);
> +
> +	if (fb && fb->modifier == y_modifier) { // TODO

Overloading the modifier to also indicate rotation is a bit unexpected.

> +		igt_plane_set_rotation(plane, IGT_ROTATION_90);
> +		igt_plane_set_size(plane, fb->height, fb->width);
> +	} else
> +		igt_plane_set_rotation(plane, IGT_ROTATION_0);
> +}
> +
> +static void yuv_rgb_switch(data_t *data, enum pipe pipe, igt_output_t *output, bool scaled, unsigned format)
> +{
> +	drmModeModeInfo *mode = igt_output_get_mode(output);
> +	igt_display_t *display = &data->display;
> +	igt_plane_t *plane;
> +	int i;
> +	igt_crc_t ref_crc[4], crc;
> +	bool valid[4] = {};
> +
> +	prepare_crtc(data, pipe, output);
> +
> +	igt_create_pattern_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
> +			      format, x_modifier, &data->fb[0]);
> +
> +	igt_create_pattern_fb(display->drm_fd, mode->vdisplay, mode->hdisplay,
> +			      format, y_modifier, &data->fb[1]);
> +
> +	igt_create_pattern_fb(display->drm_fd, mode->hdisplay, mode->vdisplay,
> +			      DRM_FORMAT_XRGB8888, x_modifier, &data->fb[2]);
> +
> +	igt_create_pattern_fb(display->drm_fd, mode->vdisplay, mode->hdisplay,
> +			      DRM_FORMAT_XRGB8888, y_modifier, &data->fb[3]);
> +
> +	for_each_plane_on_pipe(display, pipe, plane) {
> +		const int seq[] = {
> +			2, 0, 2, 1, 3, 1, 3
> +		};
> +
> +		if (!igt_plane_has_format_mod(plane, format, data->fb[0].modifier))
> +			continue;
> +
> +		/* Collect reference crc with toggle in between. */
> +		for (i = 0; i < ARRAY_SIZE(ref_crc); i++) {
> +			set_fb(plane, &data->fb[i], scaled);
> +
> +			if (i != 1)
> +				igt_display_commit2(display, COMMIT_ATOMIC);
> +			else if (igt_display_try_commit2(display, COMMIT_ATOMIC) < 0)
> +				continue;

What's so magical about index 1?

As far as the rest goes it's a bit hard to decode what is being tested.
I'd appreciate some higher level comments about what each subtest is
actually trying to test.

-- 
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] 10+ messages in thread

* [igt-dev] ✓ Fi.CI.IGT: success for Add support for more YUV tests.
  2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2019-03-27 10:55 ` [igt-dev] ✓ Fi.CI.BAT: success for Add support for more YUV tests Patchwork
@ 2019-03-27 20:52 ` Patchwork
  4 siblings, 0 replies; 10+ messages in thread
From: Patchwork @ 2019-03-27 20:52 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: igt-dev

== Series Details ==

Series: Add support for more YUV tests.
URL   : https://patchwork.freedesktop.org/series/58630/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5823_full -> IGTPW_2716_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/58630/revisions/1/mbox/

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

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

### IGT changes ###

#### Possible regressions ####

  * {igt@kms_yuv@pipe-a-vyuy-chroma-subpixel-clip} (NEW):
    - shard-apl:          NOTRUN -> FAIL +11

  * {igt@kms_yuv@pipe-a-vyuy-crop-scale-bug} (NEW):
    - shard-hsw:          NOTRUN -> FAIL +58

  * {igt@kms_yuv@pipe-a-yvyu-crop-scale-bug} (NEW):
    - shard-snb:          NOTRUN -> FAIL +39

  * {igt@kms_yuv@pipe-c-uyvy-chroma-subpixel-clip} (NEW):
    - shard-kbl:          NOTRUN -> FAIL +11

  * {igt@kms_yuv@pipe-c-vyuy-chroma-subpixel-clip} (NEW):
    - shard-glk:          NOTRUN -> FAIL +21

  
New tests
---------

  New tests have been introduced between CI_DRM_5823_full and IGTPW_2716_full:

### New IGT tests (375) ###

  * igt@kms_yuv@pipe-a-nv12-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.49] s

  * igt@kms_yuv@pipe-a-nv12-crop-scale-bug:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 10.81] s

  * igt@kms_yuv@pipe-a-nv12-rgb-scaled-switch:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.46] s

  * igt@kms_yuv@pipe-a-nv12-rgb-switch:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.47] s

  * igt@kms_yuv@pipe-a-nv12-valid-width:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.18] s

  * igt@kms_yuv@pipe-a-nv16-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv16-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv16-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv16-rgb-switch:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv16-valid-width:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv21-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv21-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv21-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv21-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv21-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv61-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv61-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv61-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv61-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-nv61-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-p010-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.50] s

  * igt@kms_yuv@pipe-a-p010-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.37] s

  * igt@kms_yuv@pipe-a-p010-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.40] s

  * igt@kms_yuv@pipe-a-p010-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.38] s

  * igt@kms_yuv@pipe-a-p010-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.20] s

  * igt@kms_yuv@pipe-a-p012-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.16] s

  * igt@kms_yuv@pipe-a-p012-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.39] s

  * igt@kms_yuv@pipe-a-p012-rgb-scaled-switch:
    - Statuses : 1 pass(s) 4 skip(s)
    - Exec time: [0.0, 6.68] s

  * igt@kms_yuv@pipe-a-p012-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.39] s

  * igt@kms_yuv@pipe-a-p012-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.20] s

  * igt@kms_yuv@pipe-a-p016-chroma-subpixel-clip:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-p016-crop-scale-bug:
    - Statuses : 4 skip(s)
    - Exec time: [0.0, 0.37] s

  * igt@kms_yuv@pipe-a-p016-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.39] s

  * igt@kms_yuv@pipe-a-p016-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.41] s

  * igt@kms_yuv@pipe-a-p016-valid-width:
    - Statuses : 1 pass(s) 4 skip(s)
    - Exec time: [0.0, 6.17] s

  * igt@kms_yuv@pipe-a-uyvy-chroma-subpixel-clip:
    - Statuses : 5 fail(s)
    - Exec time: [0.16, 0.52] s

  * igt@kms_yuv@pipe-a-uyvy-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.10, 8.07] s

  * igt@kms_yuv@pipe-a-uyvy-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.22, 11.29] s

  * igt@kms_yuv@pipe-a-uyvy-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.36, 11.26] s

  * igt@kms_yuv@pipe-a-uyvy-valid-width:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.12, 12.18] s

  * igt@kms_yuv@pipe-a-vyuy-chroma-subpixel-clip:
    - Statuses : 4 fail(s)
    - Exec time: [0.02, 0.19] s

  * igt@kms_yuv@pipe-a-vyuy-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.17, 8.06] s

  * igt@kms_yuv@pipe-a-vyuy-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.15, 11.29] s

  * igt@kms_yuv@pipe-a-vyuy-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.37, 11.38] s

  * igt@kms_yuv@pipe-a-vyuy-valid-width:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.09, 12.16] s

  * igt@kms_yuv@pipe-a-xv30-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv30-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv30-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv30-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv30-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv36-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv36-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv36-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv36-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv36-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv48-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv48-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv48-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv48-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xv48-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xyuv8888-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xyuv8888-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xyuv8888-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xyuv8888-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-xyuv8888-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y210-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y210-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y210-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y210-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y210-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y212-chroma-subpixel-clip:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y212-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y212-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y212-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y212-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y216-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y216-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y216-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y216-rgb-switch:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y216-valid-width:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y410-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y410-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y410-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y410-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y410-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y412-chroma-subpixel-clip:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y412-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y412-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y412-rgb-switch:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y412-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y416-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y416-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y416-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y416-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-y416-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv420-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv420-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv420-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv420-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv420-valid-width:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv422-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv422-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv422-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv422-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuv422-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yuyv-chroma-subpixel-clip:
    - Statuses : 5 fail(s)
    - Exec time: [0.03, 1.33] s

  * igt@kms_yuv@pipe-a-yuyv-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.17, 8.06] s

  * igt@kms_yuv@pipe-a-yuyv-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.62, 11.69] s

  * igt@kms_yuv@pipe-a-yuyv-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.34, 11.26] s

  * igt@kms_yuv@pipe-a-yuyv-valid-width:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.14, 12.18] s

  * igt@kms_yuv@pipe-a-yvu420-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu420-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu420-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu420-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu420-valid-width:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu422-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu422-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu422-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu422-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvu422-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-a-yvyu-chroma-subpixel-clip:
    - Statuses : 4 fail(s)
    - Exec time: [0.13, 0.32] s

  * igt@kms_yuv@pipe-a-yvyu-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.21, 8.06] s

  * igt@kms_yuv@pipe-a-yvyu-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.61, 11.54] s

  * igt@kms_yuv@pipe-a-yvyu-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.35, 11.32] s

  * igt@kms_yuv@pipe-a-yvyu-valid-width:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.01, 12.18] s

  * igt@kms_yuv@pipe-b-nv12-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.64] s

  * igt@kms_yuv@pipe-b-nv12-crop-scale-bug:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 10.94] s

  * igt@kms_yuv@pipe-b-nv12-rgb-scaled-switch:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.68] s

  * igt@kms_yuv@pipe-b-nv12-rgb-switch:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.64] s

  * igt@kms_yuv@pipe-b-nv12-valid-width:
    - Statuses : 2 pass(s) 3 skip(s)
    - Exec time: [0.0, 6.31] s

  * igt@kms_yuv@pipe-b-nv16-chroma-subpixel-clip:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv16-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv16-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv16-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv16-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv21-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv21-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv21-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv21-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv21-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv61-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv61-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv61-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv61-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-nv61-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-p010-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.30] s

  * igt@kms_yuv@pipe-b-p010-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.53] s

  * igt@kms_yuv@pipe-b-p010-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.50] s

  * igt@kms_yuv@pipe-b-p010-rgb-switch:
    - Statuses : 1 pass(s) 4 skip(s)
    - Exec time: [0.0, 6.84] s

  * igt@kms_yuv@pipe-b-p010-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.34] s

  * igt@kms_yuv@pipe-b-p012-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.29] s

  * igt@kms_yuv@pipe-b-p012-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.51] s

  * igt@kms_yuv@pipe-b-p012-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.52] s

  * igt@kms_yuv@pipe-b-p012-rgb-switch:
    - Statuses : 4 skip(s)
    - Exec time: [0.0, 0.54] s

  * igt@kms_yuv@pipe-b-p012-valid-width:
    - Statuses : 4 skip(s)
    - Exec time: [0.0, 0.34] s

  * igt@kms_yuv@pipe-b-p016-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.29] s

  * igt@kms_yuv@pipe-b-p016-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.51] s

  * igt@kms_yuv@pipe-b-p016-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.54] s

  * igt@kms_yuv@pipe-b-p016-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.50] s

  * igt@kms_yuv@pipe-b-p016-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.33] s

  * igt@kms_yuv@pipe-b-uyvy-chroma-subpixel-clip:
    - Statuses : 5 fail(s)
    - Exec time: [0.19, 0.44] s

  * igt@kms_yuv@pipe-b-uyvy-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.17, 8.15] s

  * igt@kms_yuv@pipe-b-uyvy-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.56, 11.46] s

  * igt@kms_yuv@pipe-b-uyvy-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.68, 11.71] s

  * igt@kms_yuv@pipe-b-uyvy-valid-width:
    - Statuses : 2 fail(s) 2 pass(s)
    - Exec time: [0.17, 4.58] s

  * igt@kms_yuv@pipe-b-vyuy-chroma-subpixel-clip:
    - Statuses : 5 fail(s)
    - Exec time: [0.17, 1.26] s

  * igt@kms_yuv@pipe-b-vyuy-crop-scale-bug:
    - Statuses : 3 fail(s) 2 pass(s)
    - Exec time: [0.23, 8.18] s

  * igt@kms_yuv@pipe-b-vyuy-rgb-scaled-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.23, 11.82] s

  * igt@kms_yuv@pipe-b-vyuy-rgb-switch:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.59, 11.38] s

  * igt@kms_yuv@pipe-b-vyuy-valid-width:
    - Statuses : 2 fail(s) 3 pass(s)
    - Exec time: [0.17, 12.32] s

  * igt@kms_yuv@pipe-b-xv30-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv30-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv30-rgb-scaled-switch:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv30-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv30-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv36-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv36-crop-scale-bug:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv36-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv36-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv36-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv48-chroma-subpixel-clip:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv48-crop-scale-bug:
    - Statuses : 4 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv48-rgb-scaled-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv48-rgb-switch:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xv48-valid-width:
    - Statuses : 5 skip(s)
    - Exec time: [0.0] s

  * igt@kms_yuv@pipe-b-xyuv8

== Logs ==

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

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

* Re: [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4.
  2019-03-27 17:20   ` Ville Syrjälä
@ 2019-03-28 10:53     ` Maarten Lankhorst
  0 siblings, 0 replies; 10+ messages in thread
From: Maarten Lankhorst @ 2019-03-28 10:53 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: igt-dev

Op 27-03-2019 om 18:20 schreef Ville Syrjälä:
> On Wed, Mar 27, 2019 at 10:29:29AM +0100, Maarten Lankhorst wrote:
>> Y410 is packed with compressed a channel and only 32 bpp, like
>> 10 bits RGB formats. Y416 is a packed 16 bits per component format.
>>
>> Changes since v1:
>> - Rebase on top of upstream YUV changes.
>> Changes since v2:
>> - Discard alpha channel, not used upstream.
>> Changes since v3:
>> - Handle the XVYU formats and Y41x formats correctly.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  lib/igt_color_encoding.c |   6 +
>>  lib/igt_fb.c             | 263 +++++++++++++++++++++++++++++++++++----
>>  2 files changed, 244 insertions(+), 25 deletions(-)
>>
>> diff --git a/lib/igt_color_encoding.c b/lib/igt_color_encoding.c
>> index 9f9dc1439ee4..7de6d5abd690 100644
>> --- a/lib/igt_color_encoding.c
>> +++ b/lib/igt_color_encoding.c
>> @@ -154,6 +154,12 @@ static const struct color_encoding_format {
>>  	{ DRM_FORMAT_Y210, 65472.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>>  	{ DRM_FORMAT_Y212, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>>  	{ DRM_FORMAT_Y216, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>> +	{ DRM_FORMAT_Y410, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
>> +	{ DRM_FORMAT_Y412, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>> +	{ DRM_FORMAT_Y416, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>> +	{ DRM_FORMAT_XVYU2101010, 1023.f, 64.f, 940.f, 64.f, 512.f, 960.f },
>> +	{ DRM_FORMAT_XVYU12_16161616, 65520.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>> +	{ DRM_FORMAT_XVYU16161616, 65535.f, 4096.f, 60160.f, 4096.f, 32768.f, 61440.f },
>>  };
>>  
>>  static const struct color_encoding_format *lookup_fourcc(uint32_t fourcc)
>> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
>> index 1e0bcb9ea2cd..2d55687a7aa3 100644
>> --- a/lib/igt_fb.c
>> +++ b/lib/igt_fb.c
>> @@ -221,6 +221,36 @@ static const struct format_desc_struct {
>>  	  .num_planes = 3, .plane_bpp = { 8, 8, 8, },
>>  	  .hsub = 2, .vsub = 1,
>>  	},
>> +	{ .name = "Y410", .depth = -1, .drm_id = DRM_FORMAT_Y410,
>> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
>> +	  .num_planes = 1, .plane_bpp = { 32, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>> +	{ .name = "Y412", .depth = -1, .drm_id = DRM_FORMAT_Y412,
>> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
>> +	  .num_planes = 1, .plane_bpp = { 64, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>> +	{ .name = "Y416", .depth = -1, .drm_id = DRM_FORMAT_Y416,
>> +	  .cairo_id = CAIRO_FORMAT_RGBA128F,
>> +	  .num_planes = 1, .plane_bpp = { 64, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>> +	{ .name = "XV30", .depth = -1, .drm_id = DRM_FORMAT_XVYU2101010,
>> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
>> +	  .num_planes = 1, .plane_bpp = { 32, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>> +	{ .name = "XV36", .depth = -1, .drm_id = DRM_FORMAT_XVYU12_16161616,
>> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
>> +	  .num_planes = 1, .plane_bpp = { 64, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>> +	{ .name = "XV48", .depth = -1, .drm_id = DRM_FORMAT_XVYU16161616,
>> +	  .cairo_id = CAIRO_FORMAT_RGB96F,
>> +	  .num_planes = 1, .plane_bpp = { 64, },
>> +	  .hsub = 1, .vsub = 1,
>> +	},
>>  	{ .name = "P010", .depth = -1, .drm_id = DRM_FORMAT_P010,
>>  	  .cairo_id = CAIRO_FORMAT_RGB96F,
>>  	  .num_planes = 2, .plane_bpp = { 16, 32 },
>> @@ -684,6 +714,33 @@ static void clear_yuv_buffer(struct igt_fb *fb)
>>  			fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
>>  		break;
>>  
>> +	case DRM_FORMAT_XVYU2101010:
>> +	case DRM_FORMAT_Y410:
>> +		wmemset(ptr + fb->offsets[0],
>> +			full_range ? 0xe0000200 : 0xe0010200,
> For everything else we leave alpha zeroed.
Indeed, looks more like a bug that we do. But oh well can always keep it 0.
>
>> +		fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
>> +		break;
>> +
>> +	case DRM_FORMAT_XVYU12_16161616:
>> +	case DRM_FORMAT_XVYU16161616:
>> +	case DRM_FORMAT_Y412:
>> +	case DRM_FORMAT_Y416: {
>> +		struct ayuv16 { uint16_t u, y, v, a; };
>> +		const struct ayuv16 pixel = {
>> +			.a = 0xffff,
>> +			.v = full_range ? 0 : 0x1000,
>> +			.y = 0x8000,
>> +			.u = full_range ? 0 : 0x1000
>> +		};
>> +
>> +		for (int i = 0; i < fb->plane_height[0]; i++) {
>> +			struct ayuv16 *cur = ptr + fb->offsets[0] + fb->strides[0] * i;
>> +
>> +			for (int j = 0; j < fb->plane_width[0]; j++)
>> +				*cur++ = pixel;
>> +		}
> Maybe we want a memset64()?
Could be useful.
>
>> +		break;
>> +		}
>>  	}
>>  
>>  	igt_fb_unmap_buffer(fb, ptr);
>> @@ -1897,10 +1954,11 @@ static void convert_src_put(const struct fb_convert *cvt,
>>  }
>>  
>>  struct yuv_parameters {
>> -	unsigned	y_inc;
>> +	unsigned	ay_inc;
>>  	unsigned	uv_inc;
>> -	unsigned	y_stride;
>> +	unsigned	ay_stride;
>>  	unsigned	uv_stride;
>> +	unsigned	a_offset;
>>  	unsigned	y_offset;
>>  	unsigned	u_offset;
>>  	unsigned	v_offset;
>> @@ -1918,7 +1976,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  	case DRM_FORMAT_P010:
>>  	case DRM_FORMAT_P012:
>>  	case DRM_FORMAT_P016:
>> -		params->y_inc = 1;
>> +		params->ay_inc = 1;
>>  		params->uv_inc = 2;
>>  		break;
>>  
>> @@ -1926,7 +1984,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  	case DRM_FORMAT_YUV422:
>>  	case DRM_FORMAT_YVU420:
>>  	case DRM_FORMAT_YVU422:
>> -		params->y_inc = 1;
>> +		params->ay_inc = 1;
>>  		params->uv_inc = 1;
>>  		break;
>>  
>> @@ -1937,12 +1995,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  	case DRM_FORMAT_Y210:
>>  	case DRM_FORMAT_Y212:
>>  	case DRM_FORMAT_Y216:
>> -		params->y_inc = 2;
>> +		params->ay_inc = 2;
>>  		params->uv_inc = 4;
>>  		break;
>>  
>> +	case DRM_FORMAT_XVYU12_16161616:
>> +	case DRM_FORMAT_XVYU16161616:
>> +	case DRM_FORMAT_Y412:
>> +	case DRM_FORMAT_Y416:
>>  	case DRM_FORMAT_XYUV8888:
>> -		params->y_inc = 4;
>> +		params->ay_inc = 4;
>>  		params->uv_inc = 4;
>>  		break;
>>  	}
>> @@ -1959,7 +2021,7 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  	case DRM_FORMAT_P010:
>>  	case DRM_FORMAT_P012:
>>  	case DRM_FORMAT_P016:
>> -		params->y_stride = fb->strides[0];
>> +		params->ay_stride = fb->strides[0];
>>  		params->uv_stride = fb->strides[1];
>>  		break;
>>  
>> @@ -1971,7 +2033,11 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  	case DRM_FORMAT_Y212:
>>  	case DRM_FORMAT_Y216:
>>  	case DRM_FORMAT_XYUV8888:
>> -		params->y_stride = fb->strides[0];
>> +	case DRM_FORMAT_XVYU12_16161616:
>> +	case DRM_FORMAT_XVYU16161616:
>> +	case DRM_FORMAT_Y412:
>> +	case DRM_FORMAT_Y416:
>> +		params->ay_stride = fb->strides[0];
>>  		params->uv_stride = fb->strides[0];
>>  		break;
>>  	}
>> @@ -2045,6 +2111,16 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
>>  		params->v_offset = fb->offsets[0] + 6;
>>  		break;
>>  
>> +	case DRM_FORMAT_XVYU12_16161616:
>> +	case DRM_FORMAT_XVYU16161616:
>> +	case DRM_FORMAT_Y412:
>> +	case DRM_FORMAT_Y416:
>> +		params->a_offset = fb->offsets[0] + 6;
>> +		params->y_offset = fb->offsets[0] + 2;
>> +		params->u_offset = fb->offsets[0];
>> +		params->v_offset = fb->offsets[0] + 4;
>> +		break;
>> +
>>  	case DRM_FORMAT_XYUV8888:
>>  		params->y_offset = fb->offsets[0] + 1;
>>  		params->u_offset = fb->offsets[0] + 2;
>> @@ -2096,7 +2172,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>>  			write_rgb(rgb_tmp, &rgb);
>>  
>>  			rgb_tmp += bpp;
>> -			y_tmp += params.y_inc;
>> +			y_tmp += params.ay_inc;
>>  
>>  			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
>>  				u_tmp += params.uv_inc;
>> @@ -2105,7 +2181,7 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
>>  		}
>>  
>>  		rgb24 += rgb24_stride;
>> -		y += params.y_stride;
>> +		y += params.ay_stride;
>>  
>>  		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
>>  			u += params.uv_stride;
>> @@ -2156,7 +2232,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>>  			rgb_tmp += bpp;
>>  
>>  			*y_tmp = yuv.d[0];
>> -			y_tmp += params.y_inc;
>> +			y_tmp += params.ay_inc;
>>  
>>  			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
>>  				continue;
>> @@ -2193,7 +2269,7 @@ static void convert_rgb24_to_yuv(struct fb_convert *cvt)
>>  		}
>>  
>>  		rgb24 += rgb24_stride;
>> -		y += params.y_stride;
>> +		y += params.ay_stride;
>>  
>>  		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
>>  			u += params.uv_stride;
>> @@ -2217,13 +2293,13 @@ static void write_rgbf(float *rgb24, const struct igt_vec4 *rgb)
>>  	rgb24[2] = rgb->d[2];
>>  }
>>  
>> -static void convert_yuv16_to_float(struct fb_convert *cvt)
>> +static void convert_yuv16_to_float(struct fb_convert *cvt, bool alpha)
>>  {
>>  	const struct format_desc_struct *src_fmt =
>>  		lookup_drm_format(cvt->src.fb->drm_format);
>>  	int i, j;
>> -	uint8_t fpp = 3;
>> -	uint16_t *y, *u, *v;
>> +	uint8_t fpp = alpha ? 4 : 3;
>> +	uint16_t *a, *y, *u, *v;
>>  	float *ptr = cvt->dst.ptr;
>>  	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
>>  	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
>> @@ -2242,11 +2318,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>>  		   !(params.u_offset % sizeof(*buf)) &&
>>  		   !(params.v_offset % sizeof(*buf)));
>>  
>> +	a = buf + params.a_offset / sizeof(*buf);
>>  	y = buf + params.y_offset / sizeof(*buf);
>>  	u = buf + params.u_offset / sizeof(*buf);
>>  	v = buf + params.v_offset / sizeof(*buf);
>>  
>>  	for (i = 0; i < cvt->dst.fb->height; i++) {
>> +		const uint16_t *a_tmp = a;
>>  		const uint16_t *y_tmp = y;
>>  		const uint16_t *u_tmp = u;
>>  		const uint16_t *v_tmp = v;
>> @@ -2263,8 +2341,13 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>>  			rgb = igt_matrix_transform(&m, &yuv);
>>  			write_rgbf(rgb_tmp, &rgb);
>>  
>> +			if (alpha) {
>> +				rgb_tmp[3] = ((float)*a_tmp) / 65535.f;
>> +				a_tmp += params.ay_inc;
>> +			}
>> +
>>  			rgb_tmp += fpp;
>> -			y_tmp += params.y_inc;
>> +			y_tmp += params.ay_inc;
>>  
>>  			if ((src_fmt->hsub == 1) || (j % src_fmt->hsub)) {
>>  				u_tmp += params.uv_inc;
>> @@ -2273,7 +2356,9 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>>  		}
>>  
>>  		ptr += float_stride;
>> -		y += params.y_stride / sizeof(*y);
>> +
>> +		a += params.ay_stride / sizeof(*a);
>> +		y += params.ay_stride / sizeof(*y);
>>  
>>  		if ((src_fmt->vsub == 1) || (i % src_fmt->vsub)) {
>>  			u += params.uv_stride / sizeof(*u);
>> @@ -2284,14 +2369,14 @@ static void convert_yuv16_to_float(struct fb_convert *cvt)
>>  	convert_src_put(cvt, buf);
>>  }
>>  
>> -static void convert_float_to_yuv16(struct fb_convert *cvt)
>> +static void convert_float_to_yuv16(struct fb_convert *cvt, bool alpha)
>>  {
>>  	const struct format_desc_struct *dst_fmt =
>>  		lookup_drm_format(cvt->dst.fb->drm_format);
>>  	int i, j;
>> -	uint16_t *y, *u, *v;
>> +	uint16_t *a, *y, *u, *v;
>>  	const float *ptr = cvt->src.ptr;
>> -	uint8_t fpp = 3;
>> +	uint8_t fpp = alpha ? 4 : 3;
>>  	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
>>  	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
>>  						    cvt->dst.fb->drm_format,
>> @@ -2303,16 +2388,19 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>>  		   igt_format_is_yuv(cvt->dst.fb->drm_format));
>>  
>>  	get_yuv_parameters(cvt->dst.fb, &params);
>> -	igt_assert(!(params.y_offset % sizeof(*y)) &&
>> +	igt_assert(!(params.a_offset % sizeof(*a)) &&
>> +		   !(params.y_offset % sizeof(*y)) &&
>>  		   !(params.u_offset % sizeof(*u)) &&
>>  		   !(params.v_offset % sizeof(*v)));
>>  
>> +	a = cvt->dst.ptr + params.a_offset;
>>  	y = cvt->dst.ptr + params.y_offset;
>>  	u = cvt->dst.ptr + params.u_offset;
>>  	v = cvt->dst.ptr + params.v_offset;
>>  
>>  	for (i = 0; i < cvt->dst.fb->height; i++) {
>>  		const float *rgb_tmp = ptr;
>> +		uint16_t *a_tmp = a;
>>  		uint16_t *y_tmp = y;
>>  		uint16_t *u_tmp = u;
>>  		uint16_t *v_tmp = v;
>> @@ -2325,10 +2413,15 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>>  			read_rgbf(&rgb, rgb_tmp);
>>  			yuv = igt_matrix_transform(&m, &rgb);
>>  
>> +			if (alpha) {
>> +				*a_tmp = rgb_tmp[3] * 65535.f + .5f;
>> +				a_tmp += params.ay_inc;
>> +			}
>> +
>>  			rgb_tmp += fpp;
>>  
>>  			*y_tmp = yuv.d[0];
>> -			y_tmp += params.y_inc;
>> +			y_tmp += params.ay_inc;
>>  
>>  			if ((i % dst_fmt->vsub) || (j % dst_fmt->hsub))
>>  				continue;
>> @@ -2365,7 +2458,8 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>>  		}
>>  
>>  		ptr += float_stride;
>> -		y += params.y_stride / sizeof(*y);
>> +		a += params.ay_stride / sizeof(*a);
>> +		y += params.ay_stride / sizeof(*y);
>>  
>>  		if ((i % dst_fmt->vsub) == (dst_fmt->vsub - 1)) {
>>  			u += params.uv_stride / sizeof(*u);
>> @@ -2374,6 +2468,95 @@ static void convert_float_to_yuv16(struct fb_convert *cvt)
>>  	}
>>  }
>>  
>> +static void convert_Y410_to_float(struct fb_convert *cvt, bool alpha)
>> +{
>> +	int i, j;
>> +	const uint32_t *uyv;
>> +	uint32_t *buf;
>> +	float *ptr = cvt->dst.ptr;
>> +	unsigned int float_stride = cvt->dst.fb->strides[0] / sizeof(*ptr);
>> +	unsigned int uyv_stride = cvt->src.fb->strides[0] / sizeof(*uyv);
>> +	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->drm_format,
>> +						    cvt->dst.fb->drm_format,
>> +						    cvt->src.fb->color_encoding,
>> +						    cvt->src.fb->color_range);
>> +	unsigned bpp = alpha ? 4 : 3;
>> +
>> +	igt_assert((cvt->src.fb->drm_format == DRM_FORMAT_Y410 ||
>> +		    cvt->src.fb->drm_format == DRM_FORMAT_XVYU2101010) &&
>> +		   cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT);
>> +
>> +	uyv = buf = convert_src_get(cvt);
>> +
>> +	for (i = 0; i < cvt->dst.fb->height; i++) {
>> +		for (j = 0; j < cvt->dst.fb->width; j++) {
>> +			/* Convert 2x1 pixel blocks */
>> +			struct igt_vec4 yuv;
>> +			struct igt_vec4 rgb;
>> +
>> +			yuv.d[0] = uyv[j] & 0x3ff;
>> +			yuv.d[1] = (uyv[j] >> 10) & 0x3ff;
>> +			yuv.d[2] = (uyv[j] >> 20) & 0x3ff;
> These seem to be in the wrong order. At least I think we wanted
> [0]=y, [1]=cb, [2]=cr
Yes.
>> +			yuv.d[3] = 1.f;
>> +
>> +			rgb = igt_matrix_transform(&m, &yuv);
>> +
>> +			write_rgbf(&ptr[j * bpp], &rgb);
>> +			if (alpha)
>> +				ptr[j * bpp + 3] = (float)(uyv[j] >> 30) / 3.f;
>> +		}
>> +
>> +		ptr += float_stride;
>> +		uyv += uyv_stride;
>> +	}
>> +
>> +	convert_src_put(cvt, buf);
>> +}
>> +
>> +static void convert_float_to_Y410(struct fb_convert *cvt, bool alpha)
>> +{
>> +	int i, j;
>> +	uint32_t *uyv = cvt->dst.ptr;
>> +	const float *ptr = cvt->src.ptr;
>> +	unsigned float_stride = cvt->src.fb->strides[0] / sizeof(*ptr);
>> +	unsigned uyv_stride = cvt->dst.fb->strides[0] / sizeof(*uyv);
>> +	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(cvt->src.fb->drm_format,
>> +						    cvt->dst.fb->drm_format,
>> +						    cvt->dst.fb->color_encoding,
>> +						    cvt->dst.fb->color_range);
>> +	unsigned bpp = alpha ? 4 : 3;
>> +
>> +	igt_assert(cvt->src.fb->drm_format == IGT_FORMAT_FLOAT &&
>> +		   (cvt->dst.fb->drm_format == DRM_FORMAT_Y410 ||
>> +		    cvt->dst.fb->drm_format == DRM_FORMAT_XVYU2101010));
>> +
>> +	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;
>> +			uint8_t a = 0;
>> +			uint16_t y, cb, cr;
>> +
>> +			read_rgbf(&rgb, &ptr[j * bpp]);
>> +			if (alpha)
>> +				 a = ptr[j * bpp + 3] * 3.f + .5f;
>> +
>> +			yuv = igt_matrix_transform(&m, &rgb);
>> +			cr = yuv.d[0];
>> +			y = yuv.d[1];
>> +			cb = yuv.d[2];
> Same here.
>
>> +
>> +			uyv[j] = ((cr & 0x3ff) << 0) |
>> +				  ((y & 0x3ff) << 10) |
>> +				  ((cb & 0x3ff) << 20) |
>> +				  (a << 30);
> cb and cr swapped here.

Indeed, didn't cancel out. ;)

Thanks for catching, I will fix it in the next version and will look at writing a test for kms_yuv to make sure blacks and whites are always correct through crc.

>> +		}
>> +
>> +		ptr += float_stride;
>> +		uyv += uyv_stride;
>> +	}
>> +}
>> +
>>  static void convert_pixman(struct fb_convert *cvt)
>>  {
>>  	pixman_format_code_t src_pixman = drm_format_to_pixman(cvt->src.fb->drm_format);
>> @@ -2463,7 +2646,19 @@ static void fb_convert(struct fb_convert *cvt)
>>  		case DRM_FORMAT_Y210:
>>  		case DRM_FORMAT_Y212:
>>  		case DRM_FORMAT_Y216:
>> -			convert_yuv16_to_float(cvt);
>> +		case DRM_FORMAT_XVYU12_16161616:
>> +		case DRM_FORMAT_XVYU16161616:
>> +			convert_yuv16_to_float(cvt, false);
>> +			return;
>> +		case DRM_FORMAT_Y410:
>> +			convert_Y410_to_float(cvt, true);
>> +			return;
>> +		case DRM_FORMAT_XVYU2101010:
>> +			convert_Y410_to_float(cvt, false);
>> +			return;
>> +		case DRM_FORMAT_Y412:
>> +		case DRM_FORMAT_Y416:
>> +			convert_yuv16_to_float(cvt, true);
>>  			return;
>>  		}
>>  	} else if (cvt->src.fb->drm_format == IGT_FORMAT_FLOAT) {
>> @@ -2474,7 +2669,19 @@ static void fb_convert(struct fb_convert *cvt)
>>  		case DRM_FORMAT_Y210:
>>  		case DRM_FORMAT_Y212:
>>  		case DRM_FORMAT_Y216:
>> -			convert_float_to_yuv16(cvt);
>> +		case DRM_FORMAT_XVYU12_16161616:
>> +		case DRM_FORMAT_XVYU16161616:
>> +			convert_float_to_yuv16(cvt, false);
>> +			return;
>> +		case DRM_FORMAT_Y410:
>> +			convert_float_to_Y410(cvt, true);
>> +			return;
>> +		case DRM_FORMAT_XVYU2101010:
>> +			convert_float_to_Y410(cvt, false);
>> +			return;
>> +		case DRM_FORMAT_Y412:
>> +		case DRM_FORMAT_Y416:
>> +			convert_float_to_yuv16(cvt, true);
>>  			return;
>>  		}
>>  	}
>> @@ -2941,6 +3148,12 @@ bool igt_format_is_yuv(uint32_t drm_format)
>>  	case DRM_FORMAT_Y210:
>>  	case DRM_FORMAT_Y212:
>>  	case DRM_FORMAT_Y216:
>> +	case DRM_FORMAT_XVYU2101010:
>> +	case DRM_FORMAT_XVYU12_16161616:
>> +	case DRM_FORMAT_XVYU16161616:
>> +	case DRM_FORMAT_Y410:
>> +	case DRM_FORMAT_Y412:
>> +	case DRM_FORMAT_Y416:
>>  	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

~Maarten

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

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

end of thread, other threads:[~2019-03-28 10:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-27  9:29 [igt-dev] [PATCH i-g-t 0/3] Add support for more YUV tests Maarten Lankhorst
2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 1/3] lib/igt_fb: Add support for Y21x formats as well, v3 Maarten Lankhorst
2019-03-27 17:21   ` Ville Syrjälä
2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 2/3] lib/igt_fb: Add support for Y410/Y416 formats, v4 Maarten Lankhorst
2019-03-27 17:20   ` Ville Syrjälä
2019-03-28 10:53     ` Maarten Lankhorst
2019-03-27  9:29 ` [igt-dev] [PATCH i-g-t 3/3] tests/kms_yuv: Add yuv specific tests, v3 Maarten Lankhorst
2019-03-27 17:34   ` Ville Syrjälä
2019-03-27 10:55 ` [igt-dev] ✓ Fi.CI.BAT: success for Add support for more YUV tests Patchwork
2019-03-27 20:52 ` [igt-dev] ✓ Fi.CI.IGT: " 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.