1 // SPDX-License-Identifier: GPL-2.0+
3 #include <kunit/test.h>
5 #include <drm/drm_device.h>
6 #include <drm/drm_drv.h>
7 #include <drm/drm_file.h>
8 #include <drm/drm_format_helper.h>
9 #include <drm/drm_fourcc.h>
10 #include <drm/drm_framebuffer.h>
11 #include <drm/drm_gem_framebuffer_helper.h>
12 #include <drm/drm_kunit_helpers.h>
13 #include <drm/drm_mode.h>
14 #include <drm/drm_print.h>
15 #include <drm/drm_rect.h>
17 #include "../drm_crtc_internal.h"
19 #define TEST_BUF_SIZE 50
21 #define TEST_USE_DEFAULT_PITCH 0
23 static unsigned char fmtcnv_state_mem[PAGE_SIZE];
24 static struct drm_format_conv_state fmtcnv_state =
25 DRM_FORMAT_CONV_STATE_INIT_PREALLOCATED(fmtcnv_state_mem, sizeof(fmtcnv_state_mem));
27 struct convert_to_gray8_result {
28 unsigned int dst_pitch;
29 const u8 expected[TEST_BUF_SIZE];
32 struct convert_to_rgb332_result {
33 unsigned int dst_pitch;
34 const u8 expected[TEST_BUF_SIZE];
37 struct convert_to_rgb565_result {
38 unsigned int dst_pitch;
39 const u16 expected[TEST_BUF_SIZE];
40 const u16 expected_swab[TEST_BUF_SIZE];
43 struct convert_to_xrgb1555_result {
44 unsigned int dst_pitch;
45 const u16 expected[TEST_BUF_SIZE];
48 struct convert_to_argb1555_result {
49 unsigned int dst_pitch;
50 const u16 expected[TEST_BUF_SIZE];
53 struct convert_to_rgba5551_result {
54 unsigned int dst_pitch;
55 const u16 expected[TEST_BUF_SIZE];
58 struct convert_to_rgb888_result {
59 unsigned int dst_pitch;
60 const u8 expected[TEST_BUF_SIZE];
63 struct convert_to_argb8888_result {
64 unsigned int dst_pitch;
65 const u32 expected[TEST_BUF_SIZE];
68 struct convert_to_xrgb2101010_result {
69 unsigned int dst_pitch;
70 const u32 expected[TEST_BUF_SIZE];
73 struct convert_to_argb2101010_result {
74 unsigned int dst_pitch;
75 const u32 expected[TEST_BUF_SIZE];
78 struct convert_to_mono_result {
79 unsigned int dst_pitch;
80 const u8 expected[TEST_BUF_SIZE];
83 struct fb_swab_result {
84 unsigned int dst_pitch;
85 const u32 expected[TEST_BUF_SIZE];
88 struct convert_to_xbgr8888_result {
89 unsigned int dst_pitch;
90 const u32 expected[TEST_BUF_SIZE];
93 struct convert_to_abgr8888_result {
94 unsigned int dst_pitch;
95 const u32 expected[TEST_BUF_SIZE];
98 struct convert_xrgb8888_case {
101 struct drm_rect clip;
102 const u32 xrgb8888[TEST_BUF_SIZE];
103 struct convert_to_gray8_result gray8_result;
104 struct convert_to_rgb332_result rgb332_result;
105 struct convert_to_rgb565_result rgb565_result;
106 struct convert_to_xrgb1555_result xrgb1555_result;
107 struct convert_to_argb1555_result argb1555_result;
108 struct convert_to_rgba5551_result rgba5551_result;
109 struct convert_to_rgb888_result rgb888_result;
110 struct convert_to_argb8888_result argb8888_result;
111 struct convert_to_xrgb2101010_result xrgb2101010_result;
112 struct convert_to_argb2101010_result argb2101010_result;
113 struct convert_to_mono_result mono_result;
114 struct fb_swab_result swab_result;
115 struct convert_to_xbgr8888_result xbgr8888_result;
116 struct convert_to_abgr8888_result abgr8888_result;
119 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
121 .name = "single_pixel_source_buffer",
123 .clip = DRM_RECT_INIT(0, 0, 1, 1),
124 .xrgb8888 = { 0x01FF0000 },
126 .dst_pitch = TEST_USE_DEFAULT_PITCH,
127 .expected = { 0x4C },
130 .dst_pitch = TEST_USE_DEFAULT_PITCH,
131 .expected = { 0xE0 },
134 .dst_pitch = TEST_USE_DEFAULT_PITCH,
135 .expected = { 0xF800 },
136 .expected_swab = { 0x00F8 },
139 .dst_pitch = TEST_USE_DEFAULT_PITCH,
140 .expected = { 0x7C00 },
143 .dst_pitch = TEST_USE_DEFAULT_PITCH,
144 .expected = { 0xFC00 },
147 .dst_pitch = TEST_USE_DEFAULT_PITCH,
148 .expected = { 0xF801 },
151 .dst_pitch = TEST_USE_DEFAULT_PITCH,
152 .expected = { 0x00, 0x00, 0xFF },
155 .dst_pitch = TEST_USE_DEFAULT_PITCH,
156 .expected = { 0xFFFF0000 },
158 .xrgb2101010_result = {
159 .dst_pitch = TEST_USE_DEFAULT_PITCH,
160 .expected = { 0x3FF00000 },
162 .argb2101010_result = {
163 .dst_pitch = TEST_USE_DEFAULT_PITCH,
164 .expected = { 0xFFF00000 },
167 .dst_pitch = TEST_USE_DEFAULT_PITCH,
171 .dst_pitch = TEST_USE_DEFAULT_PITCH,
172 .expected = { 0x0000FF01 },
175 .dst_pitch = TEST_USE_DEFAULT_PITCH,
176 .expected = { 0x010000FF },
179 .dst_pitch = TEST_USE_DEFAULT_PITCH,
180 .expected = { 0xFF0000FF },
184 .name = "single_pixel_clip_rectangle",
186 .clip = DRM_RECT_INIT(1, 1, 1, 1),
188 0x00000000, 0x00000000,
189 0x00000000, 0x10FF0000,
192 .dst_pitch = TEST_USE_DEFAULT_PITCH,
193 .expected = { 0x4C },
196 .dst_pitch = TEST_USE_DEFAULT_PITCH,
197 .expected = { 0xE0 },
200 .dst_pitch = TEST_USE_DEFAULT_PITCH,
201 .expected = { 0xF800 },
202 .expected_swab = { 0x00F8 },
205 .dst_pitch = TEST_USE_DEFAULT_PITCH,
206 .expected = { 0x7C00 },
209 .dst_pitch = TEST_USE_DEFAULT_PITCH,
210 .expected = { 0xFC00 },
213 .dst_pitch = TEST_USE_DEFAULT_PITCH,
214 .expected = { 0xF801 },
217 .dst_pitch = TEST_USE_DEFAULT_PITCH,
218 .expected = { 0x00, 0x00, 0xFF },
221 .dst_pitch = TEST_USE_DEFAULT_PITCH,
222 .expected = { 0xFFFF0000 },
224 .xrgb2101010_result = {
225 .dst_pitch = TEST_USE_DEFAULT_PITCH,
226 .expected = { 0x3FF00000 },
228 .argb2101010_result = {
229 .dst_pitch = TEST_USE_DEFAULT_PITCH,
230 .expected = { 0xFFF00000 },
233 .dst_pitch = TEST_USE_DEFAULT_PITCH,
237 .dst_pitch = TEST_USE_DEFAULT_PITCH,
238 .expected = { 0x0000FF10 },
241 .dst_pitch = TEST_USE_DEFAULT_PITCH,
242 .expected = { 0x100000FF },
245 .dst_pitch = TEST_USE_DEFAULT_PITCH,
246 .expected = { 0xFF0000FF },
250 /* Well known colors: White, black, red, green, blue, magenta,
251 * yellow and cyan. Different values for the X in XRGB8888 to
252 * make sure it is ignored. Partial clip area.
254 .name = "well_known_colors",
256 .clip = DRM_RECT_INIT(1, 1, 2, 4),
258 0x00000000, 0x00000000, 0x00000000, 0x00000000,
259 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
260 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
261 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
262 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
265 .dst_pitch = TEST_USE_DEFAULT_PITCH,
274 .dst_pitch = TEST_USE_DEFAULT_PITCH,
283 .dst_pitch = TEST_USE_DEFAULT_PITCH,
298 .dst_pitch = TEST_USE_DEFAULT_PITCH,
307 .dst_pitch = TEST_USE_DEFAULT_PITCH,
316 .dst_pitch = TEST_USE_DEFAULT_PITCH,
325 .dst_pitch = TEST_USE_DEFAULT_PITCH,
327 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
328 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
329 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
330 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
334 .dst_pitch = TEST_USE_DEFAULT_PITCH,
336 0xFFFFFFFF, 0xFF000000,
337 0xFFFF0000, 0xFF00FF00,
338 0xFF0000FF, 0xFFFF00FF,
339 0xFFFFFF00, 0xFF00FFFF,
342 .xrgb2101010_result = {
343 .dst_pitch = TEST_USE_DEFAULT_PITCH,
345 0x3FFFFFFF, 0x00000000,
346 0x3FF00000, 0x000FFC00,
347 0x000003FF, 0x3FF003FF,
348 0x3FFFFC00, 0x000FFFFF,
351 .argb2101010_result = {
352 .dst_pitch = TEST_USE_DEFAULT_PITCH,
354 0xFFFFFFFF, 0xC0000000,
355 0xFFF00000, 0xC00FFC00,
356 0xC00003FF, 0xFFF003FF,
357 0xFFFFFC00, 0xC00FFFFF,
361 .dst_pitch = TEST_USE_DEFAULT_PITCH,
370 .dst_pitch = TEST_USE_DEFAULT_PITCH,
372 0xFFFFFF11, 0x00000022,
373 0x0000FF33, 0x00FF0044,
374 0xFF000055, 0xFF00FF66,
375 0x00FFFF77, 0xFFFF0088,
379 .dst_pitch = TEST_USE_DEFAULT_PITCH,
381 0x11FFFFFF, 0x22000000,
382 0x330000FF, 0x4400FF00,
383 0x55FF0000, 0x66FF00FF,
384 0x7700FFFF, 0x88FFFF00,
388 .dst_pitch = TEST_USE_DEFAULT_PITCH,
390 0xFFFFFFFF, 0xFF000000,
391 0xFF0000FF, 0xFF00FF00,
392 0xFFFF0000, 0xFFFF00FF,
393 0xFF00FFFF, 0xFFFFFF00,
398 /* Randomly picked colors. Full buffer within the clip area. */
399 .name = "destination_pitch",
401 .clip = DRM_RECT_INIT(0, 0, 3, 3),
403 0xA10E449C, 0xB1114D05, 0xC1A8F303,
404 0xD16CF073, 0xA20E449C, 0xB2114D05,
405 0xC2A80303, 0xD26CF073, 0xA30E449C,
410 0x3C, 0x33, 0xC4, 0x00, 0x00,
411 0xBB, 0x3C, 0x33, 0x00, 0x00,
412 0x34, 0xBB, 0x3C, 0x00, 0x00,
418 0x0A, 0x08, 0xBC, 0x00, 0x00,
419 0x7D, 0x0A, 0x08, 0x00, 0x00,
420 0xA0, 0x7D, 0x0A, 0x00, 0x00,
426 0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
427 0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
428 0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
431 0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
432 0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
433 0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
439 0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
440 0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
441 0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
447 0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
448 0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
449 0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
455 0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
456 0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
457 0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
463 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0xF3, 0xA8,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x03, 0x03, 0xA8, 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
475 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
476 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
479 .xrgb2101010_result = {
482 0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
483 0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
484 0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
487 .argb2101010_result = {
490 0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
491 0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
492 0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
506 0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x00000000, 0x00000000,
507 0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x00000000, 0x00000000,
508 0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x00000000, 0x00000000,
514 0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x00000000, 0x00000000,
515 0xD173F06C, 0xA29C440E, 0xB2054D11, 0x00000000, 0x00000000,
516 0xC20303A8, 0xD273F06C, 0xA39C440E, 0x00000000, 0x00000000,
522 0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x00000000, 0x00000000,
523 0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x00000000, 0x00000000,
524 0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x00000000, 0x00000000,
531 * conversion_buf_size - Return the destination buffer size required to convert
533 * @dst_format: destination buffer pixel format (DRM_FORMAT_*)
534 * @dst_pitch: Number of bytes between two consecutive scanlines within dst
535 * @clip: Clip rectangle area to convert
538 * The size of the destination buffer or negative value on error.
540 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
541 const struct drm_rect *clip, int plane)
543 const struct drm_format_info *dst_fi = drm_format_info(dst_format);
549 dst_pitch = drm_format_info_min_pitch(dst_fi, plane, drm_rect_width(clip));
551 return dst_pitch * drm_rect_height(clip);
554 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
559 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
563 for (n = 0; n < buf_size; n++)
564 dst[n] = le16_to_cpu(buf[n]);
569 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
574 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
578 for (n = 0; n < buf_size; n++)
579 dst[n] = le32_to_cpu((__force __le32)buf[n]);
584 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
589 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
593 for (n = 0; n < buf_size; n++)
594 dst[n] = cpu_to_le32(buf[n]);
599 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
602 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
605 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
606 convert_xrgb8888_case_desc);
608 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
610 const struct convert_xrgb8888_case *params = test->param_value;
611 const struct convert_to_gray8_result *result = ¶ms->gray8_result;
614 __le32 *xrgb8888 = NULL;
615 struct iosys_map dst, src;
617 struct drm_framebuffer fb = {
618 .format = drm_format_info(DRM_FORMAT_XRGB8888),
619 .pitches = { params->pitch, 0, 0 },
622 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
624 KUNIT_ASSERT_GT(test, dst_size, 0);
626 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
627 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
628 iosys_map_set_vaddr(&dst, buf);
630 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
631 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
632 iosys_map_set_vaddr(&src, xrgb8888);
634 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
635 NULL : &result->dst_pitch;
637 drm_fb_xrgb8888_to_gray8(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
638 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
641 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
643 const struct convert_xrgb8888_case *params = test->param_value;
644 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result;
647 __le32 *xrgb8888 = NULL;
648 struct iosys_map dst, src;
650 struct drm_framebuffer fb = {
651 .format = drm_format_info(DRM_FORMAT_XRGB8888),
652 .pitches = { params->pitch, 0, 0 },
655 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
657 KUNIT_ASSERT_GT(test, dst_size, 0);
659 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
660 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
661 iosys_map_set_vaddr(&dst, buf);
663 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
664 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
665 iosys_map_set_vaddr(&src, xrgb8888);
667 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
668 NULL : &result->dst_pitch;
670 drm_fb_xrgb8888_to_rgb332(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
671 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
674 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
676 const struct convert_xrgb8888_case *params = test->param_value;
677 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result;
680 __le32 *xrgb8888 = NULL;
681 struct iosys_map dst, src;
683 struct drm_framebuffer fb = {
684 .format = drm_format_info(DRM_FORMAT_XRGB8888),
685 .pitches = { params->pitch, 0, 0 },
688 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
690 KUNIT_ASSERT_GT(test, dst_size, 0);
692 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
693 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
694 iosys_map_set_vaddr(&dst, buf);
696 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
697 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
698 iosys_map_set_vaddr(&src, xrgb8888);
700 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
701 NULL : &result->dst_pitch;
703 drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip,
704 &fmtcnv_state, false);
705 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
706 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
708 buf = dst.vaddr; /* restore original value of buf */
709 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,
710 &fmtcnv_state, true);
711 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
712 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
715 memset(buf, 0, dst_size);
719 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, ¶ms->clip,
722 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
724 KUNIT_EXPECT_FALSE(test, blit_result);
725 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
728 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
730 const struct convert_xrgb8888_case *params = test->param_value;
731 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result;
734 __le32 *xrgb8888 = NULL;
735 struct iosys_map dst, src;
737 struct drm_framebuffer fb = {
738 .format = drm_format_info(DRM_FORMAT_XRGB8888),
739 .pitches = { params->pitch, 0, 0 },
742 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
744 KUNIT_ASSERT_GT(test, dst_size, 0);
746 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
747 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
748 iosys_map_set_vaddr(&dst, buf);
750 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
751 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
752 iosys_map_set_vaddr(&src, xrgb8888);
754 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
755 NULL : &result->dst_pitch;
757 drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
758 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
759 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
761 buf = dst.vaddr; /* restore original value of buf */
762 memset(buf, 0, dst_size);
766 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, ¶ms->clip,
769 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
771 KUNIT_EXPECT_FALSE(test, blit_result);
772 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
775 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
777 const struct convert_xrgb8888_case *params = test->param_value;
778 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result;
781 __le32 *xrgb8888 = NULL;
782 struct iosys_map dst, src;
784 struct drm_framebuffer fb = {
785 .format = drm_format_info(DRM_FORMAT_XRGB8888),
786 .pitches = { params->pitch, 0, 0 },
789 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
791 KUNIT_ASSERT_GT(test, dst_size, 0);
793 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
794 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
795 iosys_map_set_vaddr(&dst, buf);
797 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
798 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
799 iosys_map_set_vaddr(&src, xrgb8888);
801 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
802 NULL : &result->dst_pitch;
804 drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
805 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
806 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
808 buf = dst.vaddr; /* restore original value of buf */
809 memset(buf, 0, dst_size);
813 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, ¶ms->clip,
816 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
818 KUNIT_EXPECT_FALSE(test, blit_result);
819 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
822 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
824 const struct convert_xrgb8888_case *params = test->param_value;
825 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result;
828 __le32 *xrgb8888 = NULL;
829 struct iosys_map dst, src;
831 struct drm_framebuffer fb = {
832 .format = drm_format_info(DRM_FORMAT_XRGB8888),
833 .pitches = { params->pitch, 0, 0 },
836 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
838 KUNIT_ASSERT_GT(test, dst_size, 0);
840 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
841 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
842 iosys_map_set_vaddr(&dst, buf);
844 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
845 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
846 iosys_map_set_vaddr(&src, xrgb8888);
848 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
849 NULL : &result->dst_pitch;
851 drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
852 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
853 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
855 buf = dst.vaddr; /* restore original value of buf */
856 memset(buf, 0, dst_size);
860 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, ¶ms->clip,
863 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
865 KUNIT_EXPECT_FALSE(test, blit_result);
866 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
869 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
871 const struct convert_xrgb8888_case *params = test->param_value;
872 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result;
875 __le32 *xrgb8888 = NULL;
876 struct iosys_map dst, src;
878 struct drm_framebuffer fb = {
879 .format = drm_format_info(DRM_FORMAT_XRGB8888),
880 .pitches = { params->pitch, 0, 0 },
883 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
885 KUNIT_ASSERT_GT(test, dst_size, 0);
887 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
888 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
889 iosys_map_set_vaddr(&dst, buf);
891 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
892 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
893 iosys_map_set_vaddr(&src, xrgb8888);
896 * RGB888 expected results are already in little-endian
897 * order, so there's no need to convert the test output.
899 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
900 NULL : &result->dst_pitch;
902 drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
903 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
905 buf = dst.vaddr; /* restore original value of buf */
906 memset(buf, 0, dst_size);
910 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, ¶ms->clip,
913 KUNIT_EXPECT_FALSE(test, blit_result);
914 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
917 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
919 const struct convert_xrgb8888_case *params = test->param_value;
920 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result;
923 __le32 *xrgb8888 = NULL;
924 struct iosys_map dst, src;
926 struct drm_framebuffer fb = {
927 .format = drm_format_info(DRM_FORMAT_XRGB8888),
928 .pitches = { params->pitch, 0, 0 },
931 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
932 result->dst_pitch, ¶ms->clip, 0);
933 KUNIT_ASSERT_GT(test, dst_size, 0);
935 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
936 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
937 iosys_map_set_vaddr(&dst, buf);
939 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
940 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
941 iosys_map_set_vaddr(&src, xrgb8888);
943 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
944 NULL : &result->dst_pitch;
946 drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
947 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
948 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
950 buf = dst.vaddr; /* restore original value of buf */
951 memset(buf, 0, dst_size);
955 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, ¶ms->clip,
958 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
960 KUNIT_EXPECT_FALSE(test, blit_result);
961 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
964 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
966 const struct convert_xrgb8888_case *params = test->param_value;
967 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result;
970 __le32 *xrgb8888 = NULL;
971 struct iosys_map dst, src;
973 struct drm_framebuffer fb = {
974 .format = drm_format_info(DRM_FORMAT_XRGB8888),
975 .pitches = { params->pitch, 0, 0 },
978 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
979 result->dst_pitch, ¶ms->clip, 0);
980 KUNIT_ASSERT_GT(test, dst_size, 0);
982 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
983 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
984 iosys_map_set_vaddr(&dst, buf);
986 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
987 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
988 iosys_map_set_vaddr(&src, xrgb8888);
990 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
991 NULL : &result->dst_pitch;
993 drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
994 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
995 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
997 buf = dst.vaddr; /* restore original value of buf */
998 memset(buf, 0, dst_size);
1000 int blit_result = 0;
1002 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb,
1003 ¶ms->clip, &fmtcnv_state);
1005 KUNIT_EXPECT_FALSE(test, blit_result);
1006 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1009 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1011 const struct convert_xrgb8888_case *params = test->param_value;
1012 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result;
1015 __le32 *xrgb8888 = NULL;
1016 struct iosys_map dst, src;
1018 struct drm_framebuffer fb = {
1019 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1020 .pitches = { params->pitch, 0, 0 },
1023 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1024 result->dst_pitch, ¶ms->clip, 0);
1025 KUNIT_ASSERT_GT(test, dst_size, 0);
1027 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1028 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1029 iosys_map_set_vaddr(&dst, buf);
1031 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1032 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1033 iosys_map_set_vaddr(&src, xrgb8888);
1035 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1036 NULL : &result->dst_pitch;
1038 drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1039 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1040 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1042 buf = dst.vaddr; /* restore original value of buf */
1043 memset(buf, 0, dst_size);
1045 int blit_result = 0;
1047 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb,
1048 ¶ms->clip, &fmtcnv_state);
1050 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1052 KUNIT_EXPECT_FALSE(test, blit_result);
1053 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1056 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1058 const struct convert_xrgb8888_case *params = test->param_value;
1059 const struct convert_to_mono_result *result = ¶ms->mono_result;
1062 __le32 *xrgb8888 = NULL;
1063 struct iosys_map dst, src;
1065 struct drm_framebuffer fb = {
1066 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1067 .pitches = { params->pitch, 0, 0 },
1070 dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip, 0);
1072 KUNIT_ASSERT_GT(test, dst_size, 0);
1074 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1075 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1076 iosys_map_set_vaddr(&dst, buf);
1078 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1079 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1080 iosys_map_set_vaddr(&src, xrgb8888);
1082 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1083 NULL : &result->dst_pitch;
1085 drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1086 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1089 static void drm_test_fb_swab(struct kunit *test)
1091 const struct convert_xrgb8888_case *params = test->param_value;
1092 const struct fb_swab_result *result = ¶ms->swab_result;
1095 __le32 *xrgb8888 = NULL;
1096 struct iosys_map dst, src;
1098 struct drm_framebuffer fb = {
1099 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1100 .pitches = { params->pitch, 0, 0 },
1103 dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, ¶ms->clip, 0);
1105 KUNIT_ASSERT_GT(test, dst_size, 0);
1107 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1108 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1109 iosys_map_set_vaddr(&dst, buf);
1111 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1112 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1113 iosys_map_set_vaddr(&src, xrgb8888);
1115 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1116 NULL : &result->dst_pitch;
1118 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);
1119 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1120 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1122 buf = dst.vaddr; /* restore original value of buf */
1123 memset(buf, 0, dst_size);
1127 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN,
1128 &src, &fb, ¶ms->clip, &fmtcnv_state);
1129 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1131 KUNIT_EXPECT_FALSE(test, blit_result);
1132 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1135 memset(buf, 0, dst_size);
1137 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, ¶ms->clip,
1139 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1141 KUNIT_EXPECT_FALSE(test, blit_result);
1142 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1145 memset(buf, 0, dst_size);
1147 struct drm_format_info mock_format = *fb.format;
1149 mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1150 fb.format = &mock_format;
1152 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, ¶ms->clip,
1154 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1156 KUNIT_EXPECT_FALSE(test, blit_result);
1157 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1160 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1162 const struct convert_xrgb8888_case *params = test->param_value;
1163 const struct convert_to_abgr8888_result *result = ¶ms->abgr8888_result;
1166 __le32 *xrgb8888 = NULL;
1167 struct iosys_map dst, src;
1169 struct drm_framebuffer fb = {
1170 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1171 .pitches = { params->pitch, 0, 0 },
1174 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1176 KUNIT_ASSERT_GT(test, dst_size, 0);
1178 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1179 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1180 iosys_map_set_vaddr(&dst, buf);
1182 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1184 iosys_map_set_vaddr(&src, xrgb8888);
1186 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1187 NULL : &result->dst_pitch;
1189 int blit_result = 0;
1191 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, ¶ms->clip,
1194 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1196 KUNIT_EXPECT_FALSE(test, blit_result);
1197 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1200 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1202 const struct convert_xrgb8888_case *params = test->param_value;
1203 const struct convert_to_xbgr8888_result *result = ¶ms->xbgr8888_result;
1206 __le32 *xrgb8888 = NULL;
1207 struct iosys_map dst, src;
1209 struct drm_framebuffer fb = {
1210 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1211 .pitches = { params->pitch, 0, 0 },
1214 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1216 KUNIT_ASSERT_GT(test, dst_size, 0);
1218 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1219 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1220 iosys_map_set_vaddr(&dst, buf);
1222 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1223 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1224 iosys_map_set_vaddr(&src, xrgb8888);
1226 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1227 NULL : &result->dst_pitch;
1229 int blit_result = 0;
1231 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, ¶ms->clip,
1234 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1236 KUNIT_EXPECT_FALSE(test, blit_result);
1237 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1240 struct clip_offset_case {
1244 struct drm_rect clip;
1245 unsigned int expected_offset;
1248 static struct clip_offset_case clip_offset_cases[] = {
1250 .name = "pass through",
1251 .pitch = TEST_USE_DEFAULT_PITCH,
1252 .format = DRM_FORMAT_XRGB8888,
1253 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1254 .expected_offset = 0
1257 .name = "horizontal offset",
1258 .pitch = TEST_USE_DEFAULT_PITCH,
1259 .format = DRM_FORMAT_XRGB8888,
1260 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1261 .expected_offset = 4,
1264 .name = "vertical offset",
1265 .pitch = TEST_USE_DEFAULT_PITCH,
1266 .format = DRM_FORMAT_XRGB8888,
1267 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1268 .expected_offset = 12,
1271 .name = "horizontal and vertical offset",
1272 .pitch = TEST_USE_DEFAULT_PITCH,
1273 .format = DRM_FORMAT_XRGB8888,
1274 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1275 .expected_offset = 16,
1278 .name = "horizontal offset (custom pitch)",
1280 .format = DRM_FORMAT_XRGB8888,
1281 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1282 .expected_offset = 4,
1285 .name = "vertical offset (custom pitch)",
1287 .format = DRM_FORMAT_XRGB8888,
1288 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1289 .expected_offset = 20,
1292 .name = "horizontal and vertical offset (custom pitch)",
1294 .format = DRM_FORMAT_XRGB8888,
1295 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1296 .expected_offset = 24,
1300 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1302 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1305 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1307 static void drm_test_fb_clip_offset(struct kunit *test)
1309 const struct clip_offset_case *params = test->param_value;
1310 const struct drm_format_info *format_info = drm_format_info(params->format);
1312 unsigned int offset;
1313 unsigned int pitch = params->pitch;
1315 if (pitch == TEST_USE_DEFAULT_PITCH)
1316 pitch = drm_format_info_min_pitch(format_info, 0,
1317 drm_rect_width(¶ms->clip));
1320 * Assure that the pitch is not zero, because this will inevitable cause the
1321 * wrong expected result
1323 KUNIT_ASSERT_NE(test, pitch, 0);
1325 offset = drm_fb_clip_offset(pitch, format_info, ¶ms->clip);
1327 KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1330 struct fb_build_fourcc_list_case {
1332 u32 native_fourccs[TEST_BUF_SIZE];
1333 size_t native_fourccs_size;
1334 u32 expected[TEST_BUF_SIZE];
1335 size_t expected_fourccs_size;
1338 static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
1340 .name = "no native formats",
1341 .native_fourccs = { },
1342 .native_fourccs_size = 0,
1343 .expected = { DRM_FORMAT_XRGB8888 },
1344 .expected_fourccs_size = 1,
1347 .name = "XRGB8888 as native format",
1348 .native_fourccs = { DRM_FORMAT_XRGB8888 },
1349 .native_fourccs_size = 1,
1350 .expected = { DRM_FORMAT_XRGB8888 },
1351 .expected_fourccs_size = 1,
1354 .name = "remove duplicates",
1356 DRM_FORMAT_XRGB8888,
1357 DRM_FORMAT_XRGB8888,
1361 DRM_FORMAT_XRGB8888,
1365 DRM_FORMAT_XRGB8888,
1368 DRM_FORMAT_XRGB8888,
1370 .native_fourccs_size = 11,
1372 DRM_FORMAT_XRGB8888,
1376 .expected_fourccs_size = 3,
1379 .name = "convert alpha formats",
1381 DRM_FORMAT_ARGB1555,
1382 DRM_FORMAT_ABGR1555,
1383 DRM_FORMAT_RGBA5551,
1384 DRM_FORMAT_BGRA5551,
1385 DRM_FORMAT_ARGB8888,
1386 DRM_FORMAT_ABGR8888,
1387 DRM_FORMAT_RGBA8888,
1388 DRM_FORMAT_BGRA8888,
1389 DRM_FORMAT_ARGB2101010,
1390 DRM_FORMAT_ABGR2101010,
1391 DRM_FORMAT_RGBA1010102,
1392 DRM_FORMAT_BGRA1010102,
1394 .native_fourccs_size = 12,
1396 DRM_FORMAT_XRGB1555,
1397 DRM_FORMAT_XBGR1555,
1398 DRM_FORMAT_RGBX5551,
1399 DRM_FORMAT_BGRX5551,
1400 DRM_FORMAT_XRGB8888,
1401 DRM_FORMAT_XBGR8888,
1402 DRM_FORMAT_RGBX8888,
1403 DRM_FORMAT_BGRX8888,
1404 DRM_FORMAT_XRGB2101010,
1405 DRM_FORMAT_XBGR2101010,
1406 DRM_FORMAT_RGBX1010102,
1407 DRM_FORMAT_BGRX1010102,
1409 .expected_fourccs_size = 12,
1412 .name = "random formats",
1415 DRM_FORMAT_ARGB1555,
1416 DRM_FORMAT_ABGR16161616F,
1419 DRM_FORMAT_XRGB1555,
1420 DRM_FORMAT_RGBA5551,
1421 DRM_FORMAT_BGR565_A8,
1423 DRM_FORMAT_XYUV8888,
1425 .native_fourccs_size = 10,
1428 DRM_FORMAT_XRGB1555,
1429 DRM_FORMAT_ABGR16161616F,
1432 DRM_FORMAT_RGBX5551,
1433 DRM_FORMAT_BGR565_A8,
1435 DRM_FORMAT_XYUV8888,
1436 DRM_FORMAT_XRGB8888,
1438 .expected_fourccs_size = 10,
1442 static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
1444 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1447 KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1449 static void drm_test_fb_build_fourcc_list(struct kunit *test)
1451 const struct fb_build_fourcc_list_case *params = test->param_value;
1452 u32 fourccs_out[TEST_BUF_SIZE] = {0};
1453 size_t nfourccs_out;
1454 struct drm_device *drm;
1457 dev = drm_kunit_helper_alloc_device(test);
1458 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1460 drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
1461 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1463 nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs,
1464 params->native_fourccs_size,
1465 fourccs_out, TEST_BUF_SIZE);
1467 KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
1468 KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
1471 struct fb_memcpy_case {
1474 struct drm_rect clip;
1475 unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1476 const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1477 unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1478 const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1481 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1482 * have a cpp != 4 the values are stored together on the same u32 number in a
1483 * way so the order in memory is correct in a little-endian machine.
1485 * Because of that, on some occasions, parts of a u32 will not be part of the
1486 * test, to make this explicit the 0xFF byte is used on those parts.
1489 static struct fb_memcpy_case fb_memcpy_cases[] = {
1491 .name = "single_pixel_source_buffer",
1492 .format = DRM_FORMAT_XRGB8888,
1493 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1494 .src_pitches = { 1 * 4 },
1495 .src = {{ 0x01020304 }},
1496 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1497 .expected = {{ 0x01020304 }},
1500 .name = "single_pixel_source_buffer",
1501 .format = DRM_FORMAT_XRGB8888_A8,
1502 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1503 .src_pitches = { 1 * 4, 1 },
1508 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1515 .name = "single_pixel_source_buffer",
1516 .format = DRM_FORMAT_YUV444,
1517 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1518 .src_pitches = { 1, 1, 1 },
1524 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1532 .name = "single_pixel_clip_rectangle",
1533 .format = DRM_FORMAT_XBGR8888,
1534 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1535 .src_pitches = { 2 * 4 },
1538 0x00000000, 0x00000000,
1539 0x00000000, 0x01020304,
1542 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1548 .name = "single_pixel_clip_rectangle",
1549 .format = DRM_FORMAT_XRGB8888_A8,
1550 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1551 .src_pitches = { 2 * 4, 2 * 1 },
1554 0x00000000, 0x00000000,
1555 0x00000000, 0x01020304,
1559 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1566 .name = "single_pixel_clip_rectangle",
1567 .format = DRM_FORMAT_YUV444,
1568 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1569 .src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1575 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1583 .name = "well_known_colors",
1584 .format = DRM_FORMAT_XBGR8888,
1585 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1586 .src_pitches = { 4 * 4 },
1589 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1590 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1591 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1592 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1593 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1596 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1599 0x11FFFFFF, 0x22000000,
1600 0x33FF0000, 0x4400FF00,
1601 0x550000FF, 0x66FF00FF,
1602 0x77FFFF00, 0x8800FFFF,
1607 .name = "well_known_colors",
1608 .format = DRM_FORMAT_XRGB8888_A8,
1609 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1610 .src_pitches = { 4 * 4, 4 * 1 },
1613 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1614 0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1615 0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1616 0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1617 0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1627 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1630 0xFFFFFFFF, 0xFF000000,
1631 0xFFFF0000, 0xFF00FF00,
1632 0xFF0000FF, 0xFFFF00FF,
1633 0xFFFFFF00, 0xFF00FFFF,
1642 .name = "well_known_colors",
1643 .format = DRM_FORMAT_YUV444,
1644 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1645 .src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1669 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1686 .name = "destination_pitch",
1687 .format = DRM_FORMAT_XBGR8888,
1688 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1689 .src_pitches = { 3 * 4 },
1692 0xA10E449C, 0xB1114D05, 0xC1A8F303,
1693 0xD16CF073, 0xA20E449C, 0xB2114D05,
1694 0xC2A80303, 0xD26CF073, 0xA30E449C,
1697 .dst_pitches = { 5 * 4 },
1700 0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1701 0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1702 0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1707 .name = "destination_pitch",
1708 .format = DRM_FORMAT_XRGB8888_A8,
1709 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1710 .src_pitches = { 3 * 4, 3 * 1 },
1713 0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1714 0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1715 0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1723 .dst_pitches = { 5 * 4, 5 * 1 },
1726 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1727 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1728 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1739 .name = "destination_pitch",
1740 .format = DRM_FORMAT_YUV444,
1741 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1742 .src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1760 .dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1784 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1786 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1789 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1791 static void drm_test_fb_memcpy(struct kunit *test)
1793 const struct fb_memcpy_case *params = test->param_value;
1794 size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1795 u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1796 __le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1797 __le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1798 struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1799 struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1801 struct drm_framebuffer fb = {
1802 .format = drm_format_info(params->format),
1805 memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1807 for (size_t i = 0; i < fb.format->num_planes; i++) {
1808 dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1810 KUNIT_ASSERT_GT(test, dst_size[i], 0);
1812 buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1813 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1814 iosys_map_set_vaddr(&dst[i], buf[i]);
1816 src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1817 iosys_map_set_vaddr(&src[i], src_cp[i]);
1820 const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1821 params->dst_pitches;
1823 drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip);
1825 for (size_t i = 0; i < fb.format->num_planes; i++) {
1826 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1827 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1828 "Failed expectation on plane %zu", i);
1830 memset(buf[i], 0, dst_size[i]);
1835 blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, ¶ms->clip,
1838 KUNIT_EXPECT_FALSE(test, blit_result);
1839 for (size_t i = 0; i < fb.format->num_planes; i++) {
1840 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1841 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1842 "Failed expectation on plane %zu", i);
1846 static struct kunit_case drm_format_helper_test_cases[] = {
1847 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1848 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1849 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1850 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1851 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1852 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1853 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1854 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1855 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1856 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1857 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1858 KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1859 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1860 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1861 KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1862 KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),
1863 KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1867 static struct kunit_suite drm_format_helper_test_suite = {
1868 .name = "drm_format_helper_test",
1869 .test_cases = drm_format_helper_test_cases,
1872 kunit_test_suite(drm_format_helper_test_suite);
1874 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1875 MODULE_LICENSE("GPL");