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

Lisovskiy, Stanislav stanislav.lisovskiy at intel.com
Fri Sep 7 08:31:41 UTC 2018


On Wed, 2018-09-05 at 15:49 +0300, Ville Syrjälä wrote:
> 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.

Correct. I've noticed it as well, also forgot to add support 
to igt_format_is_yuv function. I have fixed that stuff, however
as I look probably many cases will still fail, until XYUV support
is not merged to kernel, otherwirse drmModeAddFB2 just fails.
Just wanted to check if IGT will work, without kernel patches merged
 - looks like not. 

> 
> > +			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
> 
> 
-- 
Best Regards,

Lisovskiy Stanislav


More information about the igt-dev mailing list