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

Ville Syrjälä ville.syrjala at linux.intel.com
Wed Sep 5 12:49:16 UTC 2018


On Wed, Sep 05, 2018 at 03:03:00PM +0300, Stanislav Lisovskiy wrote:
> 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.
> 
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> ---
>  include/drm-uapi/drm_fourcc.h   |  1 +
>  lib/igt_fb.c                    | 93 +++++++++++++++++++++++++++++++++
>  tests/kms_available_modes_crc.c |  2 +
>  3 files changed, 96 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..2d0311ae 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 = 24, .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, },
> @@ -1500,6 +1504,88 @@ 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, planar_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 * planar_stride + j*sizeof(uint32_t)];
> +			u = yuv24[i * planar_stride + j*sizeof(uint32_t) + 1];
> +			y = yuv24[i * planar_stride + j*sizeof(uint32_t) + 2];
> +			yuv.d[0] = v;
> +			yuv.d[1] = u;
> +			yuv.d[2] = y;

This should be [0]=y [1]=u [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, planar_stride = blit->linear.stride;
> +	uint8_t *buf = malloc(blit->linear.size);
> +	struct igt_mat4 m = igt_rgb_to_ycbcr_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->rgb24.map, blit->linear.size);
> +	rgb24 = &buf[blit->linear.offsets[0]];
> +
> +	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 * planar_stride + j*sizeof(uint32_t)] = yuv.d[0];
> +			yuv444[i * planar_stride + j*sizeof(uint32_t) + 1] = yuv.d[1];
> +			yuv444[i * planar_stride + j*sizeof(uint32_t) + 2] = yuv.d[2];

And looks like the vector elements are swapped here as well.

Also you should add xuyv handling to create_bo_for_fb() so that a
freshly allocated xuyv fb contains all black.

> +		}
> +	}
> +
> +	free(buf);
> +}
> +
> +
> +
> +
>  static void convert_rgb24_to_nv12(struct igt_fb *fb, struct fb_convert_blit_upload *blit)
>  {
>  	int i, j;
> @@ -1756,6 +1842,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 +1898,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 +1917,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
> diff --git a/tests/kms_available_modes_crc.c b/tests/kms_available_modes_crc.c
> index b67b4f83..514bf372 100644
> --- a/tests/kms_available_modes_crc.c
> +++ b/tests/kms_available_modes_crc.c

This should be a separate patch.

> @@ -150,6 +150,7 @@ static const struct {
>  	{ DRM_FORMAT_YVYU, 0, BYTES_PP_4, 0x80eb80eb},
>  	{ DRM_FORMAT_VYUY, 0, BYTES_PP_4, 0xeb80eb80},
>  	{ DRM_FORMAT_UYVY, 0, BYTES_PP_4, 0xeb80eb80},
> +	{ DRM_FORMAT_XYUV, 0, BYTES_PP_4, 0xffffffff},
>  
>  	/*
>  	 * (semi-)planar formats
> @@ -479,6 +480,7 @@ test_available_modes(data_t* data)
>  		}
>  		igt_pipe_crc_stop(data->pipe_crc);
>  		igt_pipe_crc_free(data->pipe_crc);
> +		igt_output_set_pipe(output, PIPE_NONE);
>  		igt_display_commit2(&data->display, data->commit);
>  	}
>  	igt_assert(invalids == 0);
> -- 
> 2.17.0
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Ville Syrjälä
Intel


More information about the igt-dev mailing list