[PATCH i-g-t 7/9] lib/igt_fb: Add DRM_FORMAT_R1 support

Louis Chauvet louis.chauvet at bootlin.com
Wed Mar 6 17:28:41 UTC 2024


Add the DRM_FORMAT_R1 to rgb24 conversion to allow this format in tests.

Introduce a small helper to be able to filter the black and white formats.

Use this new helper to skip black and white format in tests/kms_plane to
avoid pointless tests (testing black and white format with something else
than black or white will always be a failure).

Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>
---
 lib/igt_fb.c      | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_fb.h      |   1 +
 tests/kms_plane.c |   3 ++
 3 files changed, 109 insertions(+)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index b6f28cf3ee52..65342e6a4df8 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -377,6 +377,10 @@ static const struct format_desc_struct {
 	  .pixman_id = PIXMAN_rgba_float,
 	  .num_planes = 1, .plane_bpp = { 128 },
 	},
+	{ .name = "R1", .depth = -1, .drm_id = DRM_FORMAT_R1,
+		.cairo_id = CAIRO_FORMAT_RGB24, .convert = true,
+		.num_planes=1, .plane_bpp = { 1 },
+	},
 };
 #define for_each_format(f)	\
 	for (f = format_desc; f - format_desc < ARRAY_SIZE(format_desc); f++)
@@ -3572,6 +3576,51 @@ static void get_yuv_parameters(struct igt_fb *fb, struct yuv_parameters *params)
 	}
 }
 
+static void convert_r1_to_rgb24(struct fb_convert *cvt)
+{
+	const struct format_desc_struct *src_fmt =
+		lookup_drm_format(cvt->src.fb->drm_format);
+	uint8_t *buf;
+	int i, j;
+	unsigned int rgb24_stride = cvt->dst.fb->strides[0];
+	unsigned int gray_stride = cvt->src.fb->strides[0];
+	uint8_t *rgb24 = cvt->dst.ptr;
+	uint8_t *gray = cvt->src.ptr;
+	igt_assert(cvt->dst.fb->drm_format == DRM_FORMAT_XRGB8888 &&
+		   cvt->src.fb->drm_format == DRM_FORMAT_R1);
+
+	buf = convert_src_get(cvt);
+	for (i = 0; i < cvt->dst.fb->height; i++) {
+		uint8_t *rgb_tmp = rgb24;
+		uint8_t *gray_tmp = gray;
+		size_t bit_offset = 0;
+
+		for (j = 0; j < cvt->dst.fb->width; j++) {
+			struct igt_vec4 rgb;
+			float v = 0.0f;
+			if (*gray_tmp & (0x1 << bit_offset)) {
+				v = 1.0f;
+			}
+
+			rgb.d[0] = v;
+			rgb.d[1] = v;
+			rgb.d[2] = v;
+			rgb.d[3] = 1.0f;
+			write_rgb(rgb_tmp, &rgb);
+
+			bit_offset += 1;
+			if (bit_offset >= 8) {
+				bit_offset = 0;
+				gray_tmp += 1;
+			}
+		}
+
+		rgb24 += rgb24_stride;
+		gray += gray_stride;
+	}
+	convert_src_put(cvt, buf);
+}
+
 static void convert_yuv_to_rgb24(struct fb_convert *cvt)
 {
 	const struct format_desc_struct *src_fmt =
@@ -3635,6 +3684,45 @@ static void convert_yuv_to_rgb24(struct fb_convert *cvt)
 	convert_src_put(cvt, buf);
 }
 
+static void convert_rgb24_to_r1(struct fb_convert *cvt)
+{
+	int i, j;
+	unsigned int rgb24_stride = cvt->src.fb->strides[0];
+	unsigned int gray_stride = cvt->dst.fb->strides[0];
+	uint8_t *gray = cvt->dst.ptr;
+	uint8_t *rgb24 = cvt->src.ptr;
+	igt_assert(cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888 &&
+		   cvt->dst.fb->drm_format == DRM_FORMAT_R1);
+
+	for (i = 0; i < cvt->dst.fb->height; i++) {
+		uint8_t *rgb_tmp = rgb24;
+		uint8_t *gray_tmp = gray;
+		size_t bit_offset = 0;
+
+		for (j = 0; j < cvt->dst.fb->width; j++) {
+			struct igt_vec4 rgb;
+			uint8_t val = 0;
+			read_rgb(&rgb, rgb_tmp);
+			float mean = rgb.d[0] + rgb.d[1] + rgb.d[2];
+			if (mean >= (255.0 * 3.0) / 2.0) {
+				val = 1;
+			}
+			*gray_tmp |= (*gray_tmp & 0x1 << bit_offset) | val << bit_offset;
+
+			bit_offset += 1;
+			if (bit_offset >= 8) {
+				bit_offset = 0;
+				gray_tmp += 1;
+			}
+			rgb_tmp += 4;
+		}
+
+
+		rgb24 += rgb24_stride;
+		gray += gray_stride;
+	}
+}
+
 static void convert_rgb24_to_yuv(struct fb_convert *cvt)
 {
 	const struct format_desc_struct *dst_fmt =
@@ -4255,6 +4343,9 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_YVYU:
 			convert_yuv_to_rgb24(cvt);
 			return;
+		case DRM_FORMAT_R1:
+			convert_r1_to_rgb24(cvt);
+			return;
 		}
 	} else if (cvt->src.fb->drm_format == DRM_FORMAT_XRGB8888) {
 		switch (cvt->dst.fb->drm_format) {
@@ -4275,6 +4366,9 @@ static void fb_convert(struct fb_convert *cvt)
 		case DRM_FORMAT_YVYU:
 			convert_rgb24_to_yuv(cvt);
 			return;
+		case DRM_FORMAT_R1:
+			convert_rgb24_to_r1(cvt);
+			return;
 		}
 	} else if (cvt->dst.fb->drm_format == IGT_FORMAT_FLOAT) {
 		switch (cvt->src.fb->drm_format) {
@@ -4874,6 +4968,17 @@ bool igt_format_is_yuv(uint32_t drm_format)
 	}
 }
 
+bool igt_format_is_black_white(uint32_t drm_format)
+{
+	switch (drm_format) {
+	case DRM_FORMAT_R1:
+	case DRM_FORMAT_D1:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /**
  * igt_format_is_fp16
  * @drm_format: drm fourcc
diff --git a/lib/igt_fb.h b/lib/igt_fb.h
index 834aaef54dea..a4315233eb7e 100644
--- a/lib/igt_fb.h
+++ b/lib/igt_fb.h
@@ -214,6 +214,7 @@ uint32_t igt_drm_format_to_bpp(uint32_t drm_format);
 const char *igt_format_str(uint32_t drm_format);
 bool igt_fb_supported_format(uint32_t drm_format);
 bool igt_format_is_yuv(uint32_t drm_format);
+bool igt_format_is_black_white(uint32_t drm_format);
 bool igt_format_is_yuv_semiplanar(uint32_t format);
 
 uint32_t igt_drm_format_str_to_format(const char *drm_format);
diff --git a/tests/kms_plane.c b/tests/kms_plane.c
index bb8229124b8c..2baaeef7bbc8 100644
--- a/tests/kms_plane.c
+++ b/tests/kms_plane.c
@@ -1091,6 +1091,9 @@ static bool test_format_plane(data_t *data, enum pipe pipe,
 		    f.modifier == ref.modifier)
 			continue;
 
+		if (igt_format_is_black_white(f.format))
+			continue;
+
 		/* test each format "class" only once in non-extended tests */
 		if (!data->extended && f.modifier != DRM_FORMAT_MOD_LINEAR) {
 			struct format_mod rf = {

-- 
2.43.0



More information about the igt-dev mailing list