[igt-dev] [PATCH i-g-t v7] lib/igt_fb: Added XYUV format support for testing

Stanislav Lisovskiy stanislav.lisovskiy at intel.com
Thu Sep 13 10:33:48 UTC 2018


XYUV format support has been added to DRM, modified
IGT to reflect those changes.

v2: Fixed merge conflict, started to use new yuv<=>rgb
    conversion functions.

v3: Fixed kms_available_modes_crc test to support new XYUV
    format. Fixed a problem, where test complains that two
    outputs might use same pipe at the same time.

v4: Fixed convertion procedure in igt_fb to support XYUV
    properly.

v5: Fixed a coding typo.

v6: Set depth equal to -1 for XYUV format in order to prevent
    it to be used by igt_bpp_depth_to_drm_format, as we do not
    want YUV formats to be used in that case.

v7: Fix "black" color initialization for create_bo_for_fb with
    proper value. Changed naming "planar_stride" to "xyuv_stride".

Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
---
 include/drm-uapi/drm_fourcc.h |  1 +
 lib/igt_fb.c                  | 89 +++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
index e04613d3..0bf66de2 100644
--- a/include/drm-uapi/drm_fourcc.h
+++ b/include/drm-uapi/drm_fourcc.h
@@ -112,6 +112,7 @@ extern "C" {
 #define DRM_FORMAT_VYUY		fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */
 
 #define DRM_FORMAT_AYUV		fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define DRM_FORMAT_XYUV		fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */
 
 /*
  * 2 plane RGB + A
diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index ae71d967..58daf34f 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -72,6 +72,10 @@ static struct format_desc_struct {
 	  .cairo_id = CAIRO_FORMAT_RGB16_565,
 	  .num_planes = 1, .plane_bpp = { 16, },
 	},
+	{ .name = "XYUV", .depth = -1, .drm_id = DRM_FORMAT_XYUV,
+	  .cairo_id = CAIRO_FORMAT_RGB24,
+	  .num_planes = 1, .plane_bpp = { 32, },
+	},
 	{ .name = "XRGB8888", .depth = 24, .drm_id = DRM_FORMAT_XRGB8888,
 	  .cairo_id = CAIRO_FORMAT_RGB24,
 	  .num_planes = 1, .plane_bpp = { 32, },
@@ -415,6 +419,10 @@ static int create_bo_for_fb(int fd, int width, int height,
 				memset(ptr + offsets[1], 0x80,
 				       calculated_stride * height/2);
 				break;
+			case DRM_FORMAT_XYUV:
+				wmemset(ptr, full_range ? 0x00008080 : 0x00108080,
+					calculated_stride * height / sizeof(wchar_t));
+				break;
 			case DRM_FORMAT_YUYV:
 			case DRM_FORMAT_YVYU:
 				wmemset(ptr, full_range ? 0x80008000 : 0x80108010,
@@ -1500,6 +1508,79 @@ static void convert_nv12_to_rgb24(struct igt_fb *fb, struct fb_convert_blit_uplo
 	free(buf);
 }
 
+static void convert_yuv444_to_rgb24(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
+{
+	int i, j;
+	uint8_t *yuv24;
+	uint8_t *rgb24 = blit->rgb24.map;
+	unsigned rgb24_stride = blit->rgb24.stride, xyuv_stride = blit->linear.stride;
+	uint8_t *buf = malloc(blit->linear.size);
+	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(fb->color_encoding,
+						    fb->color_range);
+
+	/*
+	 * Reading from the BO is awfully slow because of lack of read caching,
+	 * it's faster to copy the whole BO to a temporary buffer and convert
+	 * from there.
+	 */
+	igt_memcpy_from_wc(buf, blit->linear.map, blit->linear.size);
+	yuv24 = &buf[blit->linear.offsets[0]];
+
+	for (i = 0; i < fb->plane_height[0]; i++) {
+		for (j = 0; j < fb->plane_width[0]; j++) {
+			float y, u, v;
+			struct igt_vec4 yuv;
+			struct igt_vec4 rgb;
+
+			v = yuv24[i * xyuv_stride + j*sizeof(uint32_t)];
+			u = yuv24[i * xyuv_stride + j*sizeof(uint32_t) + 1];
+			y = yuv24[i * xyuv_stride + j*sizeof(uint32_t) + 2];
+			yuv.d[0] = y;
+			yuv.d[1] = u;
+			yuv.d[2] = v;
+			yuv.d[3] = 1.0f;
+
+			rgb = igt_matrix_transform(&m, &yuv);
+
+			write_rgb(&rgb24[i * rgb24_stride + j*sizeof(uint32_t)], &rgb);
+		}
+	}
+
+	free(buf);
+}
+
+
+static void convert_rgb24_to_yuv444(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
+{
+	int i, j;
+	uint8_t *rgb24;
+	uint8_t *yuv444 = blit->linear.map;
+	unsigned rgb24_stride = blit->rgb24.stride, xyuv_stride = blit->linear.stride;
+	struct igt_mat4 m = igt_rgb_to_ycbcr_matrix(fb->color_encoding,
+						    fb->color_range);
+
+	rgb24 = blit->rgb24.map;
+
+	for (i = 0; i < fb->plane_height[0]; i++) {
+		for (j = 0; j < fb->plane_width[0]; j++) {
+			struct igt_vec4 rgb;
+			struct igt_vec4 yuv;
+			float y, u, v;
+
+			read_rgb(&rgb, &rgb24[i * rgb24_stride + j*sizeof(uint32_t)]);
+
+			yuv = igt_matrix_transform(&m, &rgb);
+
+			yuv444[i * xyuv_stride + j*sizeof(uint32_t)] = yuv.d[2];
+			yuv444[i * xyuv_stride + j*sizeof(uint32_t) + 1] = yuv.d[1];
+			yuv444[i * xyuv_stride + j*sizeof(uint32_t) + 2] = yuv.d[0];
+		}
+	}
+}
+
+
+
+
 static void convert_rgb24_to_nv12(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
 {
 	int i, j;
@@ -1756,6 +1837,9 @@ static void destroy_cairo_surface__convert(void *arg)
 	case DRM_FORMAT_VYUY:
 		convert_rgb24_to_yuyv(fb, blit, yuyv_swizzle(fb->drm_format));
 		break;
+	case DRM_FORMAT_XYUV:
+		convert_rgb24_to_yuv444(fb, blit);
+		break;
 	default:
 		igt_assert_f(false, "Conversion not implemented for formats 0x%x\n",
 			     fb->drm_format);
@@ -1809,6 +1893,9 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
 	case DRM_FORMAT_VYUY:
 		convert_yuyv_to_rgb24(fb, blit, yuyv_swizzle(fb->drm_format));
 		break;
+	case DRM_FORMAT_XYUV:
+		convert_yuv444_to_rgb24(fb, blit);
+		break;
 	default:
 		igt_assert_f(false, "Conversion not implemented for formats 0x%x\n",
 			     fb->drm_format);
@@ -1825,6 +1912,7 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
 				    blit, destroy_cairo_surface__convert);
 }
 
+
 /**
  * igt_get_cairo_surface:
  * @fd: open drm file descriptor
@@ -2011,6 +2099,7 @@ bool igt_format_is_yuv(uint32_t drm_format)
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_XYUV:
 		return true;
 	default:
 		return false;
-- 
2.17.0



More information about the igt-dev mailing list