All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime.ripard@bootlin.com>
To: igt-dev@lists.freedesktop.org
Cc: Petri Latvala <petri.latvala@intel.com>,
	eben@raspberrypi.org,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: [igt-dev] [PATCH i-g-t v5 03/13] igt: fb: generic YUV convertion function
Date: Fri, 25 Jan 2019 15:58:32 +0100	[thread overview]
Message-ID: <20190125145842.15738-4-maxime.ripard@bootlin.com> (raw)
In-Reply-To: <20190125145842.15738-1-maxime.ripard@bootlin.com>

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

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

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

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

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

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

  parent reply	other threads:[~2019-01-25 14:58 UTC|newest]

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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190125145842.15738-4-maxime.ripard@bootlin.com \
    --to=maxime.ripard@bootlin.com \
    --cc=eben@raspberrypi.org \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=petri.latvala@intel.com \
    --cc=thomas.petazzoni@bootlin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.