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 struct convert_to_gray8_result {
24 unsigned int dst_pitch;
25 const u8 expected[TEST_BUF_SIZE];
28 struct convert_to_rgb332_result {
29 unsigned int dst_pitch;
30 const u8 expected[TEST_BUF_SIZE];
33 struct convert_to_rgb565_result {
34 unsigned int dst_pitch;
35 const u16 expected[TEST_BUF_SIZE];
36 const u16 expected_swab[TEST_BUF_SIZE];
39 struct convert_to_xrgb1555_result {
40 unsigned int dst_pitch;
41 const u16 expected[TEST_BUF_SIZE];
44 struct convert_to_argb1555_result {
45 unsigned int dst_pitch;
46 const u16 expected[TEST_BUF_SIZE];
49 struct convert_to_rgba5551_result {
50 unsigned int dst_pitch;
51 const u16 expected[TEST_BUF_SIZE];
54 struct convert_to_rgb888_result {
55 unsigned int dst_pitch;
56 const u8 expected[TEST_BUF_SIZE];
59 struct convert_to_argb8888_result {
60 unsigned int dst_pitch;
61 const u32 expected[TEST_BUF_SIZE];
64 struct convert_to_xrgb2101010_result {
65 unsigned int dst_pitch;
66 const u32 expected[TEST_BUF_SIZE];
69 struct convert_to_argb2101010_result {
70 unsigned int dst_pitch;
71 const u32 expected[TEST_BUF_SIZE];
74 struct convert_to_mono_result {
75 unsigned int dst_pitch;
76 const u8 expected[TEST_BUF_SIZE];
79 struct fb_swab_result {
80 unsigned int dst_pitch;
81 const u32 expected[TEST_BUF_SIZE];
84 struct convert_to_xbgr8888_result {
85 unsigned int dst_pitch;
86 const u32 expected[TEST_BUF_SIZE];
89 struct convert_to_abgr8888_result {
90 unsigned int dst_pitch;
91 const u32 expected[TEST_BUF_SIZE];
94 struct convert_xrgb8888_case {
98 const u32 xrgb8888[TEST_BUF_SIZE];
99 struct convert_to_gray8_result gray8_result;
100 struct convert_to_rgb332_result rgb332_result;
101 struct convert_to_rgb565_result rgb565_result;
102 struct convert_to_xrgb1555_result xrgb1555_result;
103 struct convert_to_argb1555_result argb1555_result;
104 struct convert_to_rgba5551_result rgba5551_result;
105 struct convert_to_rgb888_result rgb888_result;
106 struct convert_to_argb8888_result argb8888_result;
107 struct convert_to_xrgb2101010_result xrgb2101010_result;
108 struct convert_to_argb2101010_result argb2101010_result;
109 struct convert_to_mono_result mono_result;
110 struct fb_swab_result swab_result;
111 struct convert_to_xbgr8888_result xbgr8888_result;
112 struct convert_to_abgr8888_result abgr8888_result;
115 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
117 .name = "single_pixel_source_buffer",
119 .clip = DRM_RECT_INIT(0, 0, 1, 1),
120 .xrgb8888 = { 0x01FF0000 },
122 .dst_pitch = TEST_USE_DEFAULT_PITCH,
123 .expected = { 0x4C },
126 .dst_pitch = TEST_USE_DEFAULT_PITCH,
127 .expected = { 0xE0 },
130 .dst_pitch = TEST_USE_DEFAULT_PITCH,
131 .expected = { 0xF800 },
132 .expected_swab = { 0x00F8 },
135 .dst_pitch = TEST_USE_DEFAULT_PITCH,
136 .expected = { 0x7C00 },
139 .dst_pitch = TEST_USE_DEFAULT_PITCH,
140 .expected = { 0xFC00 },
143 .dst_pitch = TEST_USE_DEFAULT_PITCH,
144 .expected = { 0xF801 },
147 .dst_pitch = TEST_USE_DEFAULT_PITCH,
148 .expected = { 0x00, 0x00, 0xFF },
151 .dst_pitch = TEST_USE_DEFAULT_PITCH,
152 .expected = { 0xFFFF0000 },
154 .xrgb2101010_result = {
155 .dst_pitch = TEST_USE_DEFAULT_PITCH,
156 .expected = { 0x3FF00000 },
158 .argb2101010_result = {
159 .dst_pitch = TEST_USE_DEFAULT_PITCH,
160 .expected = { 0xFFF00000 },
163 .dst_pitch = TEST_USE_DEFAULT_PITCH,
167 .dst_pitch = TEST_USE_DEFAULT_PITCH,
168 .expected = { 0x0000FF01 },
171 .dst_pitch = TEST_USE_DEFAULT_PITCH,
172 .expected = { 0x010000FF },
175 .dst_pitch = TEST_USE_DEFAULT_PITCH,
176 .expected = { 0xFF0000FF },
180 .name = "single_pixel_clip_rectangle",
182 .clip = DRM_RECT_INIT(1, 1, 1, 1),
184 0x00000000, 0x00000000,
185 0x00000000, 0x10FF0000,
188 .dst_pitch = TEST_USE_DEFAULT_PITCH,
189 .expected = { 0x4C },
192 .dst_pitch = TEST_USE_DEFAULT_PITCH,
193 .expected = { 0xE0 },
196 .dst_pitch = TEST_USE_DEFAULT_PITCH,
197 .expected = { 0xF800 },
198 .expected_swab = { 0x00F8 },
201 .dst_pitch = TEST_USE_DEFAULT_PITCH,
202 .expected = { 0x7C00 },
205 .dst_pitch = TEST_USE_DEFAULT_PITCH,
206 .expected = { 0xFC00 },
209 .dst_pitch = TEST_USE_DEFAULT_PITCH,
210 .expected = { 0xF801 },
213 .dst_pitch = TEST_USE_DEFAULT_PITCH,
214 .expected = { 0x00, 0x00, 0xFF },
217 .dst_pitch = TEST_USE_DEFAULT_PITCH,
218 .expected = { 0xFFFF0000 },
220 .xrgb2101010_result = {
221 .dst_pitch = TEST_USE_DEFAULT_PITCH,
222 .expected = { 0x3FF00000 },
224 .argb2101010_result = {
225 .dst_pitch = TEST_USE_DEFAULT_PITCH,
226 .expected = { 0xFFF00000 },
229 .dst_pitch = TEST_USE_DEFAULT_PITCH,
233 .dst_pitch = TEST_USE_DEFAULT_PITCH,
234 .expected = { 0x0000FF10 },
237 .dst_pitch = TEST_USE_DEFAULT_PITCH,
238 .expected = { 0x100000FF },
241 .dst_pitch = TEST_USE_DEFAULT_PITCH,
242 .expected = { 0xFF0000FF },
246 /* Well known colors: White, black, red, green, blue, magenta,
247 * yellow and cyan. Different values for the X in XRGB8888 to
248 * make sure it is ignored. Partial clip area.
250 .name = "well_known_colors",
252 .clip = DRM_RECT_INIT(1, 1, 2, 4),
254 0x00000000, 0x00000000, 0x00000000, 0x00000000,
255 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
256 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
257 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
258 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
261 .dst_pitch = TEST_USE_DEFAULT_PITCH,
270 .dst_pitch = TEST_USE_DEFAULT_PITCH,
279 .dst_pitch = TEST_USE_DEFAULT_PITCH,
294 .dst_pitch = TEST_USE_DEFAULT_PITCH,
303 .dst_pitch = TEST_USE_DEFAULT_PITCH,
312 .dst_pitch = TEST_USE_DEFAULT_PITCH,
321 .dst_pitch = TEST_USE_DEFAULT_PITCH,
323 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
325 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
326 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
330 .dst_pitch = TEST_USE_DEFAULT_PITCH,
332 0xFFFFFFFF, 0xFF000000,
333 0xFFFF0000, 0xFF00FF00,
334 0xFF0000FF, 0xFFFF00FF,
335 0xFFFFFF00, 0xFF00FFFF,
338 .xrgb2101010_result = {
339 .dst_pitch = TEST_USE_DEFAULT_PITCH,
341 0x3FFFFFFF, 0x00000000,
342 0x3FF00000, 0x000FFC00,
343 0x000003FF, 0x3FF003FF,
344 0x3FFFFC00, 0x000FFFFF,
347 .argb2101010_result = {
348 .dst_pitch = TEST_USE_DEFAULT_PITCH,
350 0xFFFFFFFF, 0xC0000000,
351 0xFFF00000, 0xC00FFC00,
352 0xC00003FF, 0xFFF003FF,
353 0xFFFFFC00, 0xC00FFFFF,
357 .dst_pitch = TEST_USE_DEFAULT_PITCH,
366 .dst_pitch = TEST_USE_DEFAULT_PITCH,
368 0xFFFFFF11, 0x00000022,
369 0x0000FF33, 0x00FF0044,
370 0xFF000055, 0xFF00FF66,
371 0x00FFFF77, 0xFFFF0088,
375 .dst_pitch = TEST_USE_DEFAULT_PITCH,
377 0x11FFFFFF, 0x22000000,
378 0x330000FF, 0x4400FF00,
379 0x55FF0000, 0x66FF00FF,
380 0x7700FFFF, 0x88FFFF00,
384 .dst_pitch = TEST_USE_DEFAULT_PITCH,
386 0xFFFFFFFF, 0xFF000000,
387 0xFF0000FF, 0xFF00FF00,
388 0xFFFF0000, 0xFFFF00FF,
389 0xFF00FFFF, 0xFFFFFF00,
394 /* Randomly picked colors. Full buffer within the clip area. */
395 .name = "destination_pitch",
397 .clip = DRM_RECT_INIT(0, 0, 3, 3),
399 0xA10E449C, 0xB1114D05, 0xC1A8F303,
400 0xD16CF073, 0xA20E449C, 0xB2114D05,
401 0xC2A80303, 0xD26CF073, 0xA30E449C,
406 0x3C, 0x33, 0xC4, 0x00, 0x00,
407 0xBB, 0x3C, 0x33, 0x00, 0x00,
408 0x34, 0xBB, 0x3C, 0x00, 0x00,
414 0x0A, 0x08, 0xBC, 0x00, 0x00,
415 0x7D, 0x0A, 0x08, 0x00, 0x00,
416 0xA0, 0x7D, 0x0A, 0x00, 0x00,
422 0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
423 0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
424 0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
427 0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
428 0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
429 0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
435 0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
436 0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
437 0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
443 0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
444 0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
445 0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
451 0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
452 0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
453 0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
459 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0xF3, 0xA8,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x03, 0x03, 0xA8, 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
471 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
472 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
475 .xrgb2101010_result = {
478 0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
479 0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
480 0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
483 .argb2101010_result = {
486 0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
487 0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
488 0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
502 0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x00000000, 0x00000000,
503 0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x00000000, 0x00000000,
504 0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x00000000, 0x00000000,
510 0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x00000000, 0x00000000,
511 0xD173F06C, 0xA29C440E, 0xB2054D11, 0x00000000, 0x00000000,
512 0xC20303A8, 0xD273F06C, 0xA39C440E, 0x00000000, 0x00000000,
518 0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x00000000, 0x00000000,
519 0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x00000000, 0x00000000,
520 0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x00000000, 0x00000000,
527 * conversion_buf_size - Return the destination buffer size required to convert
529 * @dst_format: destination buffer pixel format (DRM_FORMAT_*)
530 * @dst_pitch: Number of bytes between two consecutive scanlines within dst
531 * @clip: Clip rectangle area to convert
534 * The size of the destination buffer or negative value on error.
536 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
537 const struct drm_rect *clip, int plane)
539 const struct drm_format_info *dst_fi = drm_format_info(dst_format);
545 dst_pitch = drm_format_info_min_pitch(dst_fi, plane, drm_rect_width(clip));
547 return dst_pitch * drm_rect_height(clip);
550 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
555 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
559 for (n = 0; n < buf_size; n++)
560 dst[n] = le16_to_cpu(buf[n]);
565 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
570 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
574 for (n = 0; n < buf_size; n++)
575 dst[n] = le32_to_cpu((__force __le32)buf[n]);
580 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
585 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
589 for (n = 0; n < buf_size; n++)
590 dst[n] = cpu_to_le32(buf[n]);
595 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
598 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
601 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
602 convert_xrgb8888_case_desc);
604 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
606 const struct convert_xrgb8888_case *params = test->param_value;
607 const struct convert_to_gray8_result *result = ¶ms->gray8_result;
610 __le32 *xrgb8888 = NULL;
611 struct iosys_map dst, src;
613 struct drm_framebuffer fb = {
614 .format = drm_format_info(DRM_FORMAT_XRGB8888),
615 .pitches = { params->pitch, 0, 0 },
618 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
620 KUNIT_ASSERT_GT(test, dst_size, 0);
622 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
623 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
624 iosys_map_set_vaddr(&dst, buf);
626 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
627 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
628 iosys_map_set_vaddr(&src, xrgb8888);
630 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
631 NULL : &result->dst_pitch;
633 drm_fb_xrgb8888_to_gray8(&dst, dst_pitch, &src, &fb, ¶ms->clip);
635 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
638 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
640 const struct convert_xrgb8888_case *params = test->param_value;
641 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result;
644 __le32 *xrgb8888 = NULL;
645 struct iosys_map dst, src;
647 struct drm_framebuffer fb = {
648 .format = drm_format_info(DRM_FORMAT_XRGB8888),
649 .pitches = { params->pitch, 0, 0 },
652 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
654 KUNIT_ASSERT_GT(test, dst_size, 0);
656 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
657 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
658 iosys_map_set_vaddr(&dst, buf);
660 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
661 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
662 iosys_map_set_vaddr(&src, xrgb8888);
664 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
665 NULL : &result->dst_pitch;
667 drm_fb_xrgb8888_to_rgb332(&dst, dst_pitch, &src, &fb, ¶ms->clip);
668 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
671 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
673 const struct convert_xrgb8888_case *params = test->param_value;
674 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result;
677 __le32 *xrgb8888 = NULL;
678 struct iosys_map dst, src;
680 struct drm_framebuffer fb = {
681 .format = drm_format_info(DRM_FORMAT_XRGB8888),
682 .pitches = { params->pitch, 0, 0 },
685 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
687 KUNIT_ASSERT_GT(test, dst_size, 0);
689 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
690 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
691 iosys_map_set_vaddr(&dst, buf);
693 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
694 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
695 iosys_map_set_vaddr(&src, xrgb8888);
697 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
698 NULL : &result->dst_pitch;
700 drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, ¶ms->clip, false);
701 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
702 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
704 buf = dst.vaddr; /* restore original value of buf */
705 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true);
706 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
707 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
710 memset(buf, 0, dst_size);
714 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, ¶ms->clip);
716 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
718 KUNIT_EXPECT_FALSE(test, blit_result);
719 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
722 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
724 const struct convert_xrgb8888_case *params = test->param_value;
725 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result;
728 __le32 *xrgb8888 = NULL;
729 struct iosys_map dst, src;
731 struct drm_framebuffer fb = {
732 .format = drm_format_info(DRM_FORMAT_XRGB8888),
733 .pitches = { params->pitch, 0, 0 },
736 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
738 KUNIT_ASSERT_GT(test, dst_size, 0);
740 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
741 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
742 iosys_map_set_vaddr(&dst, buf);
744 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
745 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
746 iosys_map_set_vaddr(&src, xrgb8888);
748 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
749 NULL : &result->dst_pitch;
751 drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip);
752 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
753 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
755 buf = dst.vaddr; /* restore original value of buf */
756 memset(buf, 0, dst_size);
760 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, ¶ms->clip);
762 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
764 KUNIT_EXPECT_FALSE(test, blit_result);
765 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
768 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
770 const struct convert_xrgb8888_case *params = test->param_value;
771 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result;
774 __le32 *xrgb8888 = NULL;
775 struct iosys_map dst, src;
777 struct drm_framebuffer fb = {
778 .format = drm_format_info(DRM_FORMAT_XRGB8888),
779 .pitches = { params->pitch, 0, 0 },
782 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
784 KUNIT_ASSERT_GT(test, dst_size, 0);
786 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
787 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
788 iosys_map_set_vaddr(&dst, buf);
790 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
791 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
792 iosys_map_set_vaddr(&src, xrgb8888);
794 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
795 NULL : &result->dst_pitch;
797 drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip);
798 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
799 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
801 buf = dst.vaddr; /* restore original value of buf */
802 memset(buf, 0, dst_size);
806 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, ¶ms->clip);
808 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
810 KUNIT_EXPECT_FALSE(test, blit_result);
811 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
814 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
816 const struct convert_xrgb8888_case *params = test->param_value;
817 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result;
820 __le32 *xrgb8888 = NULL;
821 struct iosys_map dst, src;
823 struct drm_framebuffer fb = {
824 .format = drm_format_info(DRM_FORMAT_XRGB8888),
825 .pitches = { params->pitch, 0, 0 },
828 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
830 KUNIT_ASSERT_GT(test, dst_size, 0);
832 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
833 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
834 iosys_map_set_vaddr(&dst, buf);
836 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
837 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
838 iosys_map_set_vaddr(&src, xrgb8888);
840 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
841 NULL : &result->dst_pitch;
843 drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip);
844 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
845 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
847 buf = dst.vaddr; /* restore original value of buf */
848 memset(buf, 0, dst_size);
852 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, ¶ms->clip);
854 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
856 KUNIT_EXPECT_FALSE(test, blit_result);
857 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
860 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
862 const struct convert_xrgb8888_case *params = test->param_value;
863 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result;
866 __le32 *xrgb8888 = NULL;
867 struct iosys_map dst, src;
869 struct drm_framebuffer fb = {
870 .format = drm_format_info(DRM_FORMAT_XRGB8888),
871 .pitches = { params->pitch, 0, 0 },
874 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
876 KUNIT_ASSERT_GT(test, dst_size, 0);
878 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
879 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
880 iosys_map_set_vaddr(&dst, buf);
882 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
883 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
884 iosys_map_set_vaddr(&src, xrgb8888);
887 * RGB888 expected results are already in little-endian
888 * order, so there's no need to convert the test output.
890 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
891 NULL : &result->dst_pitch;
893 drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip);
894 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
896 buf = dst.vaddr; /* restore original value of buf */
897 memset(buf, 0, dst_size);
901 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, ¶ms->clip);
903 KUNIT_EXPECT_FALSE(test, blit_result);
904 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
907 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
909 const struct convert_xrgb8888_case *params = test->param_value;
910 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result;
913 __le32 *xrgb8888 = NULL;
914 struct iosys_map dst, src;
916 struct drm_framebuffer fb = {
917 .format = drm_format_info(DRM_FORMAT_XRGB8888),
918 .pitches = { params->pitch, 0, 0 },
921 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
922 result->dst_pitch, ¶ms->clip, 0);
923 KUNIT_ASSERT_GT(test, dst_size, 0);
925 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
926 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
927 iosys_map_set_vaddr(&dst, buf);
929 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
930 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
931 iosys_map_set_vaddr(&src, xrgb8888);
933 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
934 NULL : &result->dst_pitch;
936 drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip);
937 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
938 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
940 buf = dst.vaddr; /* restore original value of buf */
941 memset(buf, 0, dst_size);
945 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, ¶ms->clip);
947 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
949 KUNIT_EXPECT_FALSE(test, blit_result);
950 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
953 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
955 const struct convert_xrgb8888_case *params = test->param_value;
956 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result;
959 __le32 *xrgb8888 = NULL;
960 struct iosys_map dst, src;
962 struct drm_framebuffer fb = {
963 .format = drm_format_info(DRM_FORMAT_XRGB8888),
964 .pitches = { params->pitch, 0, 0 },
967 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
968 result->dst_pitch, ¶ms->clip, 0);
969 KUNIT_ASSERT_GT(test, dst_size, 0);
971 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
972 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
973 iosys_map_set_vaddr(&dst, buf);
975 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
976 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
977 iosys_map_set_vaddr(&src, xrgb8888);
979 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
980 NULL : &result->dst_pitch;
982 drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip);
983 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
984 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
986 buf = dst.vaddr; /* restore original value of buf */
987 memset(buf, 0, dst_size);
991 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb,
994 KUNIT_EXPECT_FALSE(test, blit_result);
995 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
998 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1000 const struct convert_xrgb8888_case *params = test->param_value;
1001 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result;
1004 __le32 *xrgb8888 = NULL;
1005 struct iosys_map dst, src;
1007 struct drm_framebuffer fb = {
1008 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1009 .pitches = { params->pitch, 0, 0 },
1012 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1013 result->dst_pitch, ¶ms->clip, 0);
1014 KUNIT_ASSERT_GT(test, dst_size, 0);
1016 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1017 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1018 iosys_map_set_vaddr(&dst, buf);
1020 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1021 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1022 iosys_map_set_vaddr(&src, xrgb8888);
1024 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1025 NULL : &result->dst_pitch;
1027 drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip);
1028 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1029 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1031 buf = dst.vaddr; /* restore original value of buf */
1032 memset(buf, 0, dst_size);
1034 int blit_result = 0;
1036 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb,
1039 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1041 KUNIT_EXPECT_FALSE(test, blit_result);
1042 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1045 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1047 const struct convert_xrgb8888_case *params = test->param_value;
1048 const struct convert_to_mono_result *result = ¶ms->mono_result;
1051 __le32 *xrgb8888 = NULL;
1052 struct iosys_map dst, src;
1054 struct drm_framebuffer fb = {
1055 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1056 .pitches = { params->pitch, 0, 0 },
1059 dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip, 0);
1061 KUNIT_ASSERT_GT(test, dst_size, 0);
1063 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1064 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1065 iosys_map_set_vaddr(&dst, buf);
1067 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1068 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1069 iosys_map_set_vaddr(&src, xrgb8888);
1071 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1072 NULL : &result->dst_pitch;
1074 drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, ¶ms->clip);
1075 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1078 static void drm_test_fb_swab(struct kunit *test)
1080 const struct convert_xrgb8888_case *params = test->param_value;
1081 const struct fb_swab_result *result = ¶ms->swab_result;
1084 __le32 *xrgb8888 = NULL;
1085 struct iosys_map dst, src;
1087 struct drm_framebuffer fb = {
1088 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1089 .pitches = { params->pitch, 0, 0 },
1092 dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, ¶ms->clip, 0);
1094 KUNIT_ASSERT_GT(test, dst_size, 0);
1096 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1097 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1098 iosys_map_set_vaddr(&dst, buf);
1100 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1101 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1102 iosys_map_set_vaddr(&src, xrgb8888);
1104 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1105 NULL : &result->dst_pitch;
1107 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false);
1108 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1109 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1111 buf = dst.vaddr; /* restore original value of buf */
1112 memset(buf, 0, dst_size);
1116 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN,
1117 &src, &fb, ¶ms->clip);
1118 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1120 KUNIT_EXPECT_FALSE(test, blit_result);
1121 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1124 memset(buf, 0, dst_size);
1126 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, ¶ms->clip);
1127 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1129 KUNIT_EXPECT_FALSE(test, blit_result);
1130 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1133 memset(buf, 0, dst_size);
1135 struct drm_format_info mock_format = *fb.format;
1137 mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1138 fb.format = &mock_format;
1140 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, ¶ms->clip);
1141 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1143 KUNIT_EXPECT_FALSE(test, blit_result);
1144 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1147 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1149 const struct convert_xrgb8888_case *params = test->param_value;
1150 const struct convert_to_abgr8888_result *result = ¶ms->abgr8888_result;
1153 __le32 *xrgb8888 = NULL;
1154 struct iosys_map dst, src;
1156 struct drm_framebuffer fb = {
1157 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1158 .pitches = { params->pitch, 0, 0 },
1161 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1163 KUNIT_ASSERT_GT(test, dst_size, 0);
1165 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1166 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1167 iosys_map_set_vaddr(&dst, buf);
1169 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1170 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1171 iosys_map_set_vaddr(&src, xrgb8888);
1173 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1174 NULL : &result->dst_pitch;
1176 int blit_result = 0;
1178 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, ¶ms->clip);
1180 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1182 KUNIT_EXPECT_FALSE(test, blit_result);
1183 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1186 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1188 const struct convert_xrgb8888_case *params = test->param_value;
1189 const struct convert_to_xbgr8888_result *result = ¶ms->xbgr8888_result;
1192 __le32 *xrgb8888 = NULL;
1193 struct iosys_map dst, src;
1195 struct drm_framebuffer fb = {
1196 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1197 .pitches = { params->pitch, 0, 0 },
1200 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1202 KUNIT_ASSERT_GT(test, dst_size, 0);
1204 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1205 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1206 iosys_map_set_vaddr(&dst, buf);
1208 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1209 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1210 iosys_map_set_vaddr(&src, xrgb8888);
1212 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1213 NULL : &result->dst_pitch;
1215 int blit_result = 0;
1217 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, ¶ms->clip);
1219 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1221 KUNIT_EXPECT_FALSE(test, blit_result);
1222 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1225 struct clip_offset_case {
1229 struct drm_rect clip;
1230 unsigned int expected_offset;
1233 static struct clip_offset_case clip_offset_cases[] = {
1235 .name = "pass through",
1236 .pitch = TEST_USE_DEFAULT_PITCH,
1237 .format = DRM_FORMAT_XRGB8888,
1238 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1239 .expected_offset = 0
1242 .name = "horizontal offset",
1243 .pitch = TEST_USE_DEFAULT_PITCH,
1244 .format = DRM_FORMAT_XRGB8888,
1245 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1246 .expected_offset = 4,
1249 .name = "vertical offset",
1250 .pitch = TEST_USE_DEFAULT_PITCH,
1251 .format = DRM_FORMAT_XRGB8888,
1252 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1253 .expected_offset = 12,
1256 .name = "horizontal and vertical offset",
1257 .pitch = TEST_USE_DEFAULT_PITCH,
1258 .format = DRM_FORMAT_XRGB8888,
1259 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1260 .expected_offset = 16,
1263 .name = "horizontal offset (custom pitch)",
1265 .format = DRM_FORMAT_XRGB8888,
1266 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1267 .expected_offset = 4,
1270 .name = "vertical offset (custom pitch)",
1272 .format = DRM_FORMAT_XRGB8888,
1273 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1274 .expected_offset = 20,
1277 .name = "horizontal and vertical offset (custom pitch)",
1279 .format = DRM_FORMAT_XRGB8888,
1280 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1281 .expected_offset = 24,
1285 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1287 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1290 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1292 static void drm_test_fb_clip_offset(struct kunit *test)
1294 const struct clip_offset_case *params = test->param_value;
1295 const struct drm_format_info *format_info = drm_format_info(params->format);
1297 unsigned int offset;
1298 unsigned int pitch = params->pitch;
1300 if (pitch == TEST_USE_DEFAULT_PITCH)
1301 pitch = drm_format_info_min_pitch(format_info, 0,
1302 drm_rect_width(¶ms->clip));
1305 * Assure that the pitch is not zero, because this will inevitable cause the
1306 * wrong expected result
1308 KUNIT_ASSERT_NE(test, pitch, 0);
1310 offset = drm_fb_clip_offset(pitch, format_info, ¶ms->clip);
1312 KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1315 struct fb_build_fourcc_list_case {
1317 u32 native_fourccs[TEST_BUF_SIZE];
1318 size_t native_fourccs_size;
1319 u32 expected[TEST_BUF_SIZE];
1320 size_t expected_fourccs_size;
1323 static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
1325 .name = "no native formats",
1326 .native_fourccs = { },
1327 .native_fourccs_size = 0,
1328 .expected = { DRM_FORMAT_XRGB8888 },
1329 .expected_fourccs_size = 1,
1332 .name = "XRGB8888 as native format",
1333 .native_fourccs = { DRM_FORMAT_XRGB8888 },
1334 .native_fourccs_size = 1,
1335 .expected = { DRM_FORMAT_XRGB8888 },
1336 .expected_fourccs_size = 1,
1339 .name = "remove duplicates",
1341 DRM_FORMAT_XRGB8888,
1342 DRM_FORMAT_XRGB8888,
1346 DRM_FORMAT_XRGB8888,
1350 DRM_FORMAT_XRGB8888,
1353 DRM_FORMAT_XRGB8888,
1355 .native_fourccs_size = 11,
1357 DRM_FORMAT_XRGB8888,
1361 .expected_fourccs_size = 3,
1364 .name = "convert alpha formats",
1366 DRM_FORMAT_ARGB1555,
1367 DRM_FORMAT_ABGR1555,
1368 DRM_FORMAT_RGBA5551,
1369 DRM_FORMAT_BGRA5551,
1370 DRM_FORMAT_ARGB8888,
1371 DRM_FORMAT_ABGR8888,
1372 DRM_FORMAT_RGBA8888,
1373 DRM_FORMAT_BGRA8888,
1374 DRM_FORMAT_ARGB2101010,
1375 DRM_FORMAT_ABGR2101010,
1376 DRM_FORMAT_RGBA1010102,
1377 DRM_FORMAT_BGRA1010102,
1379 .native_fourccs_size = 12,
1381 DRM_FORMAT_XRGB1555,
1382 DRM_FORMAT_XBGR1555,
1383 DRM_FORMAT_RGBX5551,
1384 DRM_FORMAT_BGRX5551,
1385 DRM_FORMAT_XRGB8888,
1386 DRM_FORMAT_XBGR8888,
1387 DRM_FORMAT_RGBX8888,
1388 DRM_FORMAT_BGRX8888,
1389 DRM_FORMAT_XRGB2101010,
1390 DRM_FORMAT_XBGR2101010,
1391 DRM_FORMAT_RGBX1010102,
1392 DRM_FORMAT_BGRX1010102,
1394 .expected_fourccs_size = 12,
1397 .name = "random formats",
1400 DRM_FORMAT_ARGB1555,
1401 DRM_FORMAT_ABGR16161616F,
1404 DRM_FORMAT_XRGB1555,
1405 DRM_FORMAT_RGBA5551,
1406 DRM_FORMAT_BGR565_A8,
1408 DRM_FORMAT_XYUV8888,
1410 .native_fourccs_size = 10,
1413 DRM_FORMAT_XRGB1555,
1414 DRM_FORMAT_ABGR16161616F,
1417 DRM_FORMAT_RGBX5551,
1418 DRM_FORMAT_BGR565_A8,
1420 DRM_FORMAT_XYUV8888,
1421 DRM_FORMAT_XRGB8888,
1423 .expected_fourccs_size = 10,
1427 static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
1429 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1432 KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1434 static void drm_test_fb_build_fourcc_list(struct kunit *test)
1436 const struct fb_build_fourcc_list_case *params = test->param_value;
1437 u32 fourccs_out[TEST_BUF_SIZE] = {0};
1438 size_t nfourccs_out;
1439 struct drm_device *drm;
1442 dev = drm_kunit_helper_alloc_device(test);
1443 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1445 drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
1446 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1448 nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs,
1449 params->native_fourccs_size,
1450 fourccs_out, TEST_BUF_SIZE);
1452 KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
1453 KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
1456 struct fb_memcpy_case {
1459 struct drm_rect clip;
1460 unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1461 const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1462 unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1463 const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1466 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1467 * have a cpp != 4 the values are stored together on the same u32 number in a
1468 * way so the order in memory is correct in a little-endian machine.
1470 * Because of that, on some occasions, parts of a u32 will not be part of the
1471 * test, to make this explicit the 0xFF byte is used on those parts.
1474 static struct fb_memcpy_case fb_memcpy_cases[] = {
1476 .name = "single_pixel_source_buffer",
1477 .format = DRM_FORMAT_XRGB8888,
1478 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1479 .src_pitches = { 1 * 4 },
1480 .src = {{ 0x01020304 }},
1481 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1482 .expected = {{ 0x01020304 }},
1485 .name = "single_pixel_source_buffer",
1486 .format = DRM_FORMAT_XRGB8888_A8,
1487 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1488 .src_pitches = { 1 * 4, 1 },
1493 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1500 .name = "single_pixel_source_buffer",
1501 .format = DRM_FORMAT_YUV444,
1502 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1503 .src_pitches = { 1, 1, 1 },
1509 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1517 .name = "single_pixel_clip_rectangle",
1518 .format = DRM_FORMAT_XBGR8888,
1519 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1520 .src_pitches = { 2 * 4 },
1523 0x00000000, 0x00000000,
1524 0x00000000, 0x01020304,
1527 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1533 .name = "single_pixel_clip_rectangle",
1534 .format = DRM_FORMAT_XRGB8888_A8,
1535 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1536 .src_pitches = { 2 * 4, 2 * 1 },
1539 0x00000000, 0x00000000,
1540 0x00000000, 0x01020304,
1544 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1551 .name = "single_pixel_clip_rectangle",
1552 .format = DRM_FORMAT_YUV444,
1553 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1554 .src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1560 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1568 .name = "well_known_colors",
1569 .format = DRM_FORMAT_XBGR8888,
1570 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1571 .src_pitches = { 4 * 4 },
1574 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1575 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1576 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1577 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1578 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1581 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1584 0x11FFFFFF, 0x22000000,
1585 0x33FF0000, 0x4400FF00,
1586 0x550000FF, 0x66FF00FF,
1587 0x77FFFF00, 0x8800FFFF,
1592 .name = "well_known_colors",
1593 .format = DRM_FORMAT_XRGB8888_A8,
1594 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1595 .src_pitches = { 4 * 4, 4 * 1 },
1598 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1599 0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1600 0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1601 0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1602 0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1612 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1615 0xFFFFFFFF, 0xFF000000,
1616 0xFFFF0000, 0xFF00FF00,
1617 0xFF0000FF, 0xFFFF00FF,
1618 0xFFFFFF00, 0xFF00FFFF,
1627 .name = "well_known_colors",
1628 .format = DRM_FORMAT_YUV444,
1629 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1630 .src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1654 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1671 .name = "destination_pitch",
1672 .format = DRM_FORMAT_XBGR8888,
1673 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1674 .src_pitches = { 3 * 4 },
1677 0xA10E449C, 0xB1114D05, 0xC1A8F303,
1678 0xD16CF073, 0xA20E449C, 0xB2114D05,
1679 0xC2A80303, 0xD26CF073, 0xA30E449C,
1682 .dst_pitches = { 5 * 4 },
1685 0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1686 0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1687 0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1692 .name = "destination_pitch",
1693 .format = DRM_FORMAT_XRGB8888_A8,
1694 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1695 .src_pitches = { 3 * 4, 3 * 1 },
1698 0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1699 0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1700 0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1708 .dst_pitches = { 5 * 4, 5 * 1 },
1711 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1712 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1713 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1724 .name = "destination_pitch",
1725 .format = DRM_FORMAT_YUV444,
1726 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1727 .src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1745 .dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1769 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1771 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1774 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1776 static void drm_test_fb_memcpy(struct kunit *test)
1778 const struct fb_memcpy_case *params = test->param_value;
1779 size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1780 u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1781 __le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1782 __le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1783 struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1784 struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1786 struct drm_framebuffer fb = {
1787 .format = drm_format_info(params->format),
1790 memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1792 for (size_t i = 0; i < fb.format->num_planes; i++) {
1793 dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1795 KUNIT_ASSERT_GT(test, dst_size[i], 0);
1797 buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1798 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1799 iosys_map_set_vaddr(&dst[i], buf[i]);
1801 src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1802 iosys_map_set_vaddr(&src[i], src_cp[i]);
1805 const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1806 params->dst_pitches;
1808 drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip);
1810 for (size_t i = 0; i < fb.format->num_planes; i++) {
1811 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1812 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1813 "Failed expectation on plane %zu", i);
1815 memset(buf[i], 0, dst_size[i]);
1820 blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, ¶ms->clip);
1822 KUNIT_EXPECT_FALSE(test, blit_result);
1823 for (size_t i = 0; i < fb.format->num_planes; i++) {
1824 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1825 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1826 "Failed expectation on plane %zu", i);
1830 static struct kunit_case drm_format_helper_test_cases[] = {
1831 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1832 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1833 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1834 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1835 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1836 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1837 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1838 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1839 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1840 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1841 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1842 KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1843 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1844 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1845 KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1846 KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),
1847 KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1851 static struct kunit_suite drm_format_helper_test_suite = {
1852 .name = "drm_format_helper_test",
1853 .test_cases = drm_format_helper_test_cases,
1856 kunit_test_suite(drm_format_helper_test_suite);
1858 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1859 MODULE_LICENSE("GPL");