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

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Tue Dec 18 12:56:13 UTC 2018


Op 17-12-2018 om 15:30 schreef Stanislav Lisovskiy:
> 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".
>
> v8: Change naming from DRM_FORMAT_XYUV to DRM_FORMAT_XYUV8888
>
> v9: Fixed compilation errors by rebasing to recent master.
>
> v10: Adding reference to correspondent kernel commit with the new format
>      in include/drm-uapi
>
> v11: Removed unnecessary sizeof's in rgb <=> yuv444 convert functions.
>
> v12: Rebased against master branch, fixed rebase conflict caused by
>      new fb_convert functions. Removed drm kernel commit reference
>      as it is still not merged, so doesn't make sense to use it.
>
> v13: Resolved one more rebase conflict.
>
> Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy at intel.com>
> ---
>  include/drm-uapi/drm_fourcc.h |  2 +-
>  lib/igt_fb.c                  | 89 +++++++++++++++++++++++++++++++++++
>  2 files changed, 90 insertions(+), 1 deletion(-)
>
> diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
> index 0b44260a..4ddf754b 100644
> --- a/include/drm-uapi/drm_fourcc.h
> +++ b/include/drm-uapi/drm_fourcc.h
> @@ -151,7 +151,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_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 */
>  
>  /*
>   * packed YCbCr420 2x2 tiled formats
> diff --git a/lib/igt_fb.c b/lib/igt_fb.c
> index 2462d6ba..57264844 100644
> --- a/lib/igt_fb.c
> +++ b/lib/igt_fb.c
> @@ -102,6 +102,10 @@ static const struct format_desc_struct {
>  	  .pixman_id = PIXMAN_r8g8b8,
>  	  .num_planes = 1, .plane_bpp = { 24, },
>  	},
> +	{ .name = "XYUV8888", .depth = -1, .drm_id = DRM_FORMAT_XYUV8888,
> +	  .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,
>  	  .pixman_id = PIXMAN_x8r8g8b8,
> @@ -496,6 +500,10 @@ static int create_bo_for_fb(struct igt_fb *fb)
>  				       0x80,
>  				       fb->strides[1] * fb->plane_height[1]);
>  				break;
> +			case DRM_FORMAT_XYUV8888:
> +				wmemset(ptr + fb->offsets[0], full_range ? 0x00008080 : 0x00108080,
> +					fb->strides[0] * fb->plane_height[0] / sizeof(wchar_t));
> +				break;
>  			case DRM_FORMAT_YUYV:
>  			case DRM_FORMAT_YVYU:
>  				wmemset(ptr + fb->offsets[0],
> @@ -1649,6 +1657,79 @@ static void convert_nv12_to_rgb24(struct fb_convert *cvt)
>  	convert_src_put(cvt, buf);
>  }
>  
> +static void convert_yuv444_to_rgb24(struct fb_convert *cvt)
> +{
> +	int i, j;
> +	uint8_t *yuv24;
> +	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);
> +	struct igt_mat4 m = igt_ycbcr_to_rgb_matrix(cvt->src.fb->color_encoding,
> +						    cvt->src.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, cvt->src.ptr + cvt->src.fb->offsets[0], cvt->src.fb->size);
> +	yuv24 = buf;
> +
> +	for (i = 0; i < cvt->dst.fb->height; i++) {
> +		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;
> +			yuv.d[3] = 1.0f;
> +
> +			rgb = igt_matrix_transform(&m, &yuv);
> +
> +			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;
> +
> +	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;
> +			float y, u, v;
> +
> +			read_rgb(&rgb, &rgb24[i * rgb24_stride + j * 4]);
> +
> +			yuv = igt_matrix_transform(&m, &rgb);
> +
> +			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];
> +		}
> +	}
> +}
> +
>  static void convert_rgb24_to_nv12(struct fb_convert *cvt)
>  {
>  	int i, j;
> @@ -1934,6 +2015,9 @@ static void fb_convert(struct fb_convert *cvt)
>  		return;
>  	} 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;
> @@ -1946,6 +2030,9 @@ static void fb_convert(struct fb_convert *cvt)
>  		}
>  	} 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;
> @@ -2037,6 +2124,7 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
>  				    blit, destroy_cairo_surface__convert);
>  }
>  
> +
>  /**
>   * igt_fb_map_buffer:
>   * @fd: open drm file descriptor
> @@ -2302,6 +2390,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_XYUV8888:
>  		return true;
>  	default:
>  		return false;

Would be nice if this was extended to AYUV as well, but oh well.

Pushed. :)



More information about the igt-dev mailing list