[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