1// SPDX-License-Identifier: GPL-2.0+
2
3#include <kunit/test.h>
4
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>
16
17#include "../drm_crtc_internal.h"
18
19#define TEST_BUF_SIZE 50
20
21#define TEST_USE_DEFAULT_PITCH 0
22
23struct convert_to_gray8_result {
24 unsigned int dst_pitch;
25 const u8 expected[TEST_BUF_SIZE];
26};
27
28struct convert_to_rgb332_result {
29 unsigned int dst_pitch;
30 const u8 expected[TEST_BUF_SIZE];
31};
32
33struct convert_to_rgb565_result {
34 unsigned int dst_pitch;
35 const u16 expected[TEST_BUF_SIZE];
36 const u16 expected_swab[TEST_BUF_SIZE];
37};
38
39struct convert_to_xrgb1555_result {
40 unsigned int dst_pitch;
41 const u16 expected[TEST_BUF_SIZE];
42};
43
44struct convert_to_argb1555_result {
45 unsigned int dst_pitch;
46 const u16 expected[TEST_BUF_SIZE];
47};
48
49struct convert_to_rgba5551_result {
50 unsigned int dst_pitch;
51 const u16 expected[TEST_BUF_SIZE];
52};
53
54struct convert_to_rgb888_result {
55 unsigned int dst_pitch;
56 const u8 expected[TEST_BUF_SIZE];
57};
58
59struct convert_to_argb8888_result {
60 unsigned int dst_pitch;
61 const u32 expected[TEST_BUF_SIZE];
62};
63
64struct convert_to_xrgb2101010_result {
65 unsigned int dst_pitch;
66 const u32 expected[TEST_BUF_SIZE];
67};
68
69struct convert_to_argb2101010_result {
70 unsigned int dst_pitch;
71 const u32 expected[TEST_BUF_SIZE];
72};
73
74struct convert_to_mono_result {
75 unsigned int dst_pitch;
76 const u8 expected[TEST_BUF_SIZE];
77};
78
79struct fb_swab_result {
80 unsigned int dst_pitch;
81 const u32 expected[TEST_BUF_SIZE];
82};
83
84struct convert_to_xbgr8888_result {
85 unsigned int dst_pitch;
86 const u32 expected[TEST_BUF_SIZE];
87};
88
89struct convert_to_abgr8888_result {
90 unsigned int dst_pitch;
91 const u32 expected[TEST_BUF_SIZE];
92};
93
94struct convert_xrgb8888_case {
95 const char *name;
96 unsigned int pitch;
97 struct drm_rect clip;
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;
113};
114
115static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
116 {
117 .name = "single_pixel_source_buffer",
118 .pitch = 1 * 4,
119 .clip = DRM_RECT_INIT(0, 0, 1, 1),
120 .xrgb8888 = { 0x01FF0000 },
121 .gray8_result = {
122 .dst_pitch = TEST_USE_DEFAULT_PITCH,
123 .expected = { 0x4C },
124 },
125 .rgb332_result = {
126 .dst_pitch = TEST_USE_DEFAULT_PITCH,
127 .expected = { 0xE0 },
128 },
129 .rgb565_result = {
130 .dst_pitch = TEST_USE_DEFAULT_PITCH,
131 .expected = { 0xF800 },
132 .expected_swab = { 0x00F8 },
133 },
134 .xrgb1555_result = {
135 .dst_pitch = TEST_USE_DEFAULT_PITCH,
136 .expected = { 0x7C00 },
137 },
138 .argb1555_result = {
139 .dst_pitch = TEST_USE_DEFAULT_PITCH,
140 .expected = { 0xFC00 },
141 },
142 .rgba5551_result = {
143 .dst_pitch = TEST_USE_DEFAULT_PITCH,
144 .expected = { 0xF801 },
145 },
146 .rgb888_result = {
147 .dst_pitch = TEST_USE_DEFAULT_PITCH,
148 .expected = { 0x00, 0x00, 0xFF },
149 },
150 .argb8888_result = {
151 .dst_pitch = TEST_USE_DEFAULT_PITCH,
152 .expected = { 0xFFFF0000 },
153 },
154 .xrgb2101010_result = {
155 .dst_pitch = TEST_USE_DEFAULT_PITCH,
156 .expected = { 0x3FF00000 },
157 },
158 .argb2101010_result = {
159 .dst_pitch = TEST_USE_DEFAULT_PITCH,
160 .expected = { 0xFFF00000 },
161 },
162 .mono_result = {
163 .dst_pitch = TEST_USE_DEFAULT_PITCH,
164 .expected = { 0b0 },
165 },
166 .swab_result = {
167 .dst_pitch = TEST_USE_DEFAULT_PITCH,
168 .expected = { 0x0000FF01 },
169 },
170 .xbgr8888_result = {
171 .dst_pitch = TEST_USE_DEFAULT_PITCH,
172 .expected = { 0x010000FF },
173 },
174 .abgr8888_result = {
175 .dst_pitch = TEST_USE_DEFAULT_PITCH,
176 .expected = { 0xFF0000FF },
177 },
178 },
179 {
180 .name = "single_pixel_clip_rectangle",
181 .pitch = 2 * 4,
182 .clip = DRM_RECT_INIT(1, 1, 1, 1),
183 .xrgb8888 = {
184 0x00000000, 0x00000000,
185 0x00000000, 0x10FF0000,
186 },
187 .gray8_result = {
188 .dst_pitch = TEST_USE_DEFAULT_PITCH,
189 .expected = { 0x4C },
190 },
191 .rgb332_result = {
192 .dst_pitch = TEST_USE_DEFAULT_PITCH,
193 .expected = { 0xE0 },
194 },
195 .rgb565_result = {
196 .dst_pitch = TEST_USE_DEFAULT_PITCH,
197 .expected = { 0xF800 },
198 .expected_swab = { 0x00F8 },
199 },
200 .xrgb1555_result = {
201 .dst_pitch = TEST_USE_DEFAULT_PITCH,
202 .expected = { 0x7C00 },
203 },
204 .argb1555_result = {
205 .dst_pitch = TEST_USE_DEFAULT_PITCH,
206 .expected = { 0xFC00 },
207 },
208 .rgba5551_result = {
209 .dst_pitch = TEST_USE_DEFAULT_PITCH,
210 .expected = { 0xF801 },
211 },
212 .rgb888_result = {
213 .dst_pitch = TEST_USE_DEFAULT_PITCH,
214 .expected = { 0x00, 0x00, 0xFF },
215 },
216 .argb8888_result = {
217 .dst_pitch = TEST_USE_DEFAULT_PITCH,
218 .expected = { 0xFFFF0000 },
219 },
220 .xrgb2101010_result = {
221 .dst_pitch = TEST_USE_DEFAULT_PITCH,
222 .expected = { 0x3FF00000 },
223 },
224 .argb2101010_result = {
225 .dst_pitch = TEST_USE_DEFAULT_PITCH,
226 .expected = { 0xFFF00000 },
227 },
228 .mono_result = {
229 .dst_pitch = TEST_USE_DEFAULT_PITCH,
230 .expected = { 0b0 },
231 },
232 .swab_result = {
233 .dst_pitch = TEST_USE_DEFAULT_PITCH,
234 .expected = { 0x0000FF10 },
235 },
236 .xbgr8888_result = {
237 .dst_pitch = TEST_USE_DEFAULT_PITCH,
238 .expected = { 0x100000FF },
239 },
240 .abgr8888_result = {
241 .dst_pitch = TEST_USE_DEFAULT_PITCH,
242 .expected = { 0xFF0000FF },
243 },
244 },
245 {
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.
249 */
250 .name = "well_known_colors",
251 .pitch = 4 * 4,
252 .clip = DRM_RECT_INIT(1, 1, 2, 4),
253 .xrgb8888 = {
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,
259 },
260 .gray8_result = {
261 .dst_pitch = TEST_USE_DEFAULT_PITCH,
262 .expected = {
263 0xFF, 0x00,
264 0x4C, 0x99,
265 0x19, 0x66,
266 0xE5, 0xB2,
267 },
268 },
269 .rgb332_result = {
270 .dst_pitch = TEST_USE_DEFAULT_PITCH,
271 .expected = {
272 0xFF, 0x00,
273 0xE0, 0x1C,
274 0x03, 0xE3,
275 0xFC, 0x1F,
276 },
277 },
278 .rgb565_result = {
279 .dst_pitch = TEST_USE_DEFAULT_PITCH,
280 .expected = {
281 0xFFFF, 0x0000,
282 0xF800, 0x07E0,
283 0x001F, 0xF81F,
284 0xFFE0, 0x07FF,
285 },
286 .expected_swab = {
287 0xFFFF, 0x0000,
288 0x00F8, 0xE007,
289 0x1F00, 0x1FF8,
290 0xE0FF, 0xFF07,
291 },
292 },
293 .xrgb1555_result = {
294 .dst_pitch = TEST_USE_DEFAULT_PITCH,
295 .expected = {
296 0x7FFF, 0x0000,
297 0x7C00, 0x03E0,
298 0x001F, 0x7C1F,
299 0x7FE0, 0x03FF,
300 },
301 },
302 .argb1555_result = {
303 .dst_pitch = TEST_USE_DEFAULT_PITCH,
304 .expected = {
305 0xFFFF, 0x8000,
306 0xFC00, 0x83E0,
307 0x801F, 0xFC1F,
308 0xFFE0, 0x83FF,
309 },
310 },
311 .rgba5551_result = {
312 .dst_pitch = TEST_USE_DEFAULT_PITCH,
313 .expected = {
314 0xFFFF, 0x0001,
315 0xF801, 0x07C1,
316 0x003F, 0xF83F,
317 0xFFC1, 0x07FF,
318 },
319 },
320 .rgb888_result = {
321 .dst_pitch = TEST_USE_DEFAULT_PITCH,
322 .expected = {
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,
327 },
328 },
329 .argb8888_result = {
330 .dst_pitch = TEST_USE_DEFAULT_PITCH,
331 .expected = {
332 0xFFFFFFFF, 0xFF000000,
333 0xFFFF0000, 0xFF00FF00,
334 0xFF0000FF, 0xFFFF00FF,
335 0xFFFFFF00, 0xFF00FFFF,
336 },
337 },
338 .xrgb2101010_result = {
339 .dst_pitch = TEST_USE_DEFAULT_PITCH,
340 .expected = {
341 0x3FFFFFFF, 0x00000000,
342 0x3FF00000, 0x000FFC00,
343 0x000003FF, 0x3FF003FF,
344 0x3FFFFC00, 0x000FFFFF,
345 },
346 },
347 .argb2101010_result = {
348 .dst_pitch = TEST_USE_DEFAULT_PITCH,
349 .expected = {
350 0xFFFFFFFF, 0xC0000000,
351 0xFFF00000, 0xC00FFC00,
352 0xC00003FF, 0xFFF003FF,
353 0xFFFFFC00, 0xC00FFFFF,
354 },
355 },
356 .mono_result = {
357 .dst_pitch = TEST_USE_DEFAULT_PITCH,
358 .expected = {
359 0b01,
360 0b10,
361 0b00,
362 0b11,
363 },
364 },
365 .swab_result = {
366 .dst_pitch = TEST_USE_DEFAULT_PITCH,
367 .expected = {
368 0xFFFFFF11, 0x00000022,
369 0x0000FF33, 0x00FF0044,
370 0xFF000055, 0xFF00FF66,
371 0x00FFFF77, 0xFFFF0088,
372 },
373 },
374 .xbgr8888_result = {
375 .dst_pitch = TEST_USE_DEFAULT_PITCH,
376 .expected = {
377 0x11FFFFFF, 0x22000000,
378 0x330000FF, 0x4400FF00,
379 0x55FF0000, 0x66FF00FF,
380 0x7700FFFF, 0x88FFFF00,
381 },
382 },
383 .abgr8888_result = {
384 .dst_pitch = TEST_USE_DEFAULT_PITCH,
385 .expected = {
386 0xFFFFFFFF, 0xFF000000,
387 0xFF0000FF, 0xFF00FF00,
388 0xFFFF0000, 0xFFFF00FF,
389 0xFF00FFFF, 0xFFFFFF00,
390 },
391 },
392 },
393 {
394 /* Randomly picked colors. Full buffer within the clip area. */
395 .name = "destination_pitch",
396 .pitch = 3 * 4,
397 .clip = DRM_RECT_INIT(0, 0, 3, 3),
398 .xrgb8888 = {
399 0xA10E449C, 0xB1114D05, 0xC1A8F303,
400 0xD16CF073, 0xA20E449C, 0xB2114D05,
401 0xC2A80303, 0xD26CF073, 0xA30E449C,
402 },
403 .gray8_result = {
404 .dst_pitch = 5,
405 .expected = {
406 0x3C, 0x33, 0xC4, 0x00, 0x00,
407 0xBB, 0x3C, 0x33, 0x00, 0x00,
408 0x34, 0xBB, 0x3C, 0x00, 0x00,
409 },
410 },
411 .rgb332_result = {
412 .dst_pitch = 5,
413 .expected = {
414 0x0A, 0x08, 0xBC, 0x00, 0x00,
415 0x7D, 0x0A, 0x08, 0x00, 0x00,
416 0xA0, 0x7D, 0x0A, 0x00, 0x00,
417 },
418 },
419 .rgb565_result = {
420 .dst_pitch = 10,
421 .expected = {
422 0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
423 0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
424 0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
425 },
426 .expected_swab = {
427 0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
428 0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
429 0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
430 },
431 },
432 .xrgb1555_result = {
433 .dst_pitch = 10,
434 .expected = {
435 0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
436 0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
437 0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
438 },
439 },
440 .argb1555_result = {
441 .dst_pitch = 10,
442 .expected = {
443 0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
444 0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
445 0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
446 },
447 },
448 .rgba5551_result = {
449 .dst_pitch = 10,
450 .expected = {
451 0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
452 0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
453 0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
454 },
455 },
456 .rgb888_result = {
457 .dst_pitch = 15,
458 .expected = {
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,
465 },
466 },
467 .argb8888_result = {
468 .dst_pitch = 20,
469 .expected = {
470 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
471 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
472 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
473 },
474 },
475 .xrgb2101010_result = {
476 .dst_pitch = 20,
477 .expected = {
478 0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
479 0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
480 0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
481 },
482 },
483 .argb2101010_result = {
484 .dst_pitch = 20,
485 .expected = {
486 0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
487 0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
488 0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
489 },
490 },
491 .mono_result = {
492 .dst_pitch = 2,
493 .expected = {
494 0b100, 0b000,
495 0b001, 0b000,
496 0b010, 0b000,
497 },
498 },
499 .swab_result = {
500 .dst_pitch = 20,
501 .expected = {
502 0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x00000000, 0x00000000,
503 0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x00000000, 0x00000000,
504 0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x00000000, 0x00000000,
505 },
506 },
507 .xbgr8888_result = {
508 .dst_pitch = 20,
509 .expected = {
510 0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x00000000, 0x00000000,
511 0xD173F06C, 0xA29C440E, 0xB2054D11, 0x00000000, 0x00000000,
512 0xC20303A8, 0xD273F06C, 0xA39C440E, 0x00000000, 0x00000000,
513 },
514 },
515 .abgr8888_result = {
516 .dst_pitch = 20,
517 .expected = {
518 0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x00000000, 0x00000000,
519 0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x00000000, 0x00000000,
520 0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x00000000, 0x00000000,
521 },
522 },
523 },
524};
525
526/*
527 * conversion_buf_size - Return the destination buffer size required to convert
528 * between formats.
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
532 *
533 * Returns:
534 * The size of the destination buffer or negative value on error.
535 */
536static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
537 const struct drm_rect *clip, int plane)
538{
539 const struct drm_format_info *dst_fi = drm_format_info(format: dst_format);
540
541 if (!dst_fi)
542 return -EINVAL;
543
544 if (!dst_pitch)
545 dst_pitch = drm_format_info_min_pitch(info: dst_fi, plane, buffer_width: drm_rect_width(r: clip));
546
547 return dst_pitch * drm_rect_height(r: clip);
548}
549
550static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
551{
552 u16 *dst = NULL;
553 int n;
554
555 dst = kunit_kzalloc(test, size: sizeof(*dst) * buf_size, GFP_KERNEL);
556 if (!dst)
557 return NULL;
558
559 for (n = 0; n < buf_size; n++)
560 dst[n] = le16_to_cpu(buf[n]);
561
562 return dst;
563}
564
565static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
566{
567 u32 *dst = NULL;
568 int n;
569
570 dst = kunit_kzalloc(test, size: sizeof(*dst) * buf_size, GFP_KERNEL);
571 if (!dst)
572 return NULL;
573
574 for (n = 0; n < buf_size; n++)
575 dst[n] = le32_to_cpu((__force __le32)buf[n]);
576
577 return dst;
578}
579
580static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
581{
582 __le32 *dst = NULL;
583 int n;
584
585 dst = kunit_kzalloc(test, size: sizeof(*dst) * buf_size, GFP_KERNEL);
586 if (!dst)
587 return NULL;
588
589 for (n = 0; n < buf_size; n++)
590 dst[n] = cpu_to_le32(buf[n]);
591
592 return dst;
593}
594
595static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
596 char *desc)
597{
598 strscpy(p: desc, q: t->name, KUNIT_PARAM_DESC_SIZE);
599}
600
601KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
602 convert_xrgb8888_case_desc);
603
604static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
605{
606 const struct convert_xrgb8888_case *params = test->param_value;
607 const struct convert_to_gray8_result *result = &params->gray8_result;
608 size_t dst_size;
609 u8 *buf = NULL;
610 __le32 *xrgb8888 = NULL;
611 struct iosys_map dst, src;
612
613 struct drm_framebuffer fb = {
614 .format = drm_format_info(DRM_FORMAT_XRGB8888),
615 .pitches = { params->pitch, 0, 0 },
616 };
617
618 dst_size = conversion_buf_size(DRM_FORMAT_R8, dst_pitch: result->dst_pitch,
619 clip: &params->clip, plane: 0);
620 KUNIT_ASSERT_GT(test, dst_size, 0);
621
622 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
623 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
624 iosys_map_set_vaddr(map: &dst, vaddr: buf);
625
626 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
627 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
628 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
629
630 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
631 NULL : &result->dst_pitch;
632
633 drm_fb_xrgb8888_to_gray8(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
634
635 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
636}
637
638static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
639{
640 const struct convert_xrgb8888_case *params = test->param_value;
641 const struct convert_to_rgb332_result *result = &params->rgb332_result;
642 size_t dst_size;
643 u8 *buf = NULL;
644 __le32 *xrgb8888 = NULL;
645 struct iosys_map dst, src;
646
647 struct drm_framebuffer fb = {
648 .format = drm_format_info(DRM_FORMAT_XRGB8888),
649 .pitches = { params->pitch, 0, 0 },
650 };
651
652 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, dst_pitch: result->dst_pitch,
653 clip: &params->clip, plane: 0);
654 KUNIT_ASSERT_GT(test, dst_size, 0);
655
656 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
657 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
658 iosys_map_set_vaddr(map: &dst, vaddr: buf);
659
660 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
661 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
662 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
663
664 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
665 NULL : &result->dst_pitch;
666
667 drm_fb_xrgb8888_to_rgb332(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
668 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
669}
670
671static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
672{
673 const struct convert_xrgb8888_case *params = test->param_value;
674 const struct convert_to_rgb565_result *result = &params->rgb565_result;
675 size_t dst_size;
676 u16 *buf = NULL;
677 __le32 *xrgb8888 = NULL;
678 struct iosys_map dst, src;
679
680 struct drm_framebuffer fb = {
681 .format = drm_format_info(DRM_FORMAT_XRGB8888),
682 .pitches = { params->pitch, 0, 0 },
683 };
684
685 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, dst_pitch: result->dst_pitch,
686 clip: &params->clip, plane: 0);
687 KUNIT_ASSERT_GT(test, dst_size, 0);
688
689 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
690 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
691 iosys_map_set_vaddr(map: &dst, vaddr: buf);
692
693 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
694 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
695 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
696
697 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
698 NULL : &result->dst_pitch;
699
700 drm_fb_xrgb8888_to_rgb565(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip, swab: false);
701 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
702 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
703
704 buf = dst.vaddr; /* restore original value of buf */
705 drm_fb_xrgb8888_to_rgb565(dst: &dst, dst_pitch: &result->dst_pitch, src: &src, fb: &fb, clip: &params->clip, swab: true);
706 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
707 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
708
709 buf = dst.vaddr;
710 memset(buf, 0, dst_size);
711
712 int blit_result = 0;
713
714 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_RGB565, src: &src, fb: &fb, rect: &params->clip);
715
716 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
717
718 KUNIT_EXPECT_FALSE(test, blit_result);
719 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
720}
721
722static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
723{
724 const struct convert_xrgb8888_case *params = test->param_value;
725 const struct convert_to_xrgb1555_result *result = &params->xrgb1555_result;
726 size_t dst_size;
727 u16 *buf = NULL;
728 __le32 *xrgb8888 = NULL;
729 struct iosys_map dst, src;
730
731 struct drm_framebuffer fb = {
732 .format = drm_format_info(DRM_FORMAT_XRGB8888),
733 .pitches = { params->pitch, 0, 0 },
734 };
735
736 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, dst_pitch: result->dst_pitch,
737 clip: &params->clip, plane: 0);
738 KUNIT_ASSERT_GT(test, dst_size, 0);
739
740 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
741 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
742 iosys_map_set_vaddr(map: &dst, vaddr: buf);
743
744 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
745 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
746 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
747
748 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
749 NULL : &result->dst_pitch;
750
751 drm_fb_xrgb8888_to_xrgb1555(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
752 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
753 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
754
755 buf = dst.vaddr; /* restore original value of buf */
756 memset(buf, 0, dst_size);
757
758 int blit_result = 0;
759
760 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_XRGB1555, src: &src, fb: &fb, rect: &params->clip);
761
762 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
763
764 KUNIT_EXPECT_FALSE(test, blit_result);
765 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
766}
767
768static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
769{
770 const struct convert_xrgb8888_case *params = test->param_value;
771 const struct convert_to_argb1555_result *result = &params->argb1555_result;
772 size_t dst_size;
773 u16 *buf = NULL;
774 __le32 *xrgb8888 = NULL;
775 struct iosys_map dst, src;
776
777 struct drm_framebuffer fb = {
778 .format = drm_format_info(DRM_FORMAT_XRGB8888),
779 .pitches = { params->pitch, 0, 0 },
780 };
781
782 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, dst_pitch: result->dst_pitch,
783 clip: &params->clip, plane: 0);
784 KUNIT_ASSERT_GT(test, dst_size, 0);
785
786 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
787 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
788 iosys_map_set_vaddr(map: &dst, vaddr: buf);
789
790 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
791 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
792 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
793
794 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
795 NULL : &result->dst_pitch;
796
797 drm_fb_xrgb8888_to_argb1555(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
798 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
799 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
800
801 buf = dst.vaddr; /* restore original value of buf */
802 memset(buf, 0, dst_size);
803
804 int blit_result = 0;
805
806 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_ARGB1555, src: &src, fb: &fb, rect: &params->clip);
807
808 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
809
810 KUNIT_EXPECT_FALSE(test, blit_result);
811 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
812}
813
814static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
815{
816 const struct convert_xrgb8888_case *params = test->param_value;
817 const struct convert_to_rgba5551_result *result = &params->rgba5551_result;
818 size_t dst_size;
819 u16 *buf = NULL;
820 __le32 *xrgb8888 = NULL;
821 struct iosys_map dst, src;
822
823 struct drm_framebuffer fb = {
824 .format = drm_format_info(DRM_FORMAT_XRGB8888),
825 .pitches = { params->pitch, 0, 0 },
826 };
827
828 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, dst_pitch: result->dst_pitch,
829 clip: &params->clip, plane: 0);
830 KUNIT_ASSERT_GT(test, dst_size, 0);
831
832 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
833 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
834 iosys_map_set_vaddr(map: &dst, vaddr: buf);
835
836 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
837 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
838 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
839
840 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
841 NULL : &result->dst_pitch;
842
843 drm_fb_xrgb8888_to_rgba5551(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
844 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
845 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
846
847 buf = dst.vaddr; /* restore original value of buf */
848 memset(buf, 0, dst_size);
849
850 int blit_result = 0;
851
852 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_RGBA5551, src: &src, fb: &fb, rect: &params->clip);
853
854 buf = le16buf_to_cpu(test, buf: (__force const __le16 *)buf, buf_size: dst_size / sizeof(__le16));
855
856 KUNIT_EXPECT_FALSE(test, blit_result);
857 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
858}
859
860static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
861{
862 const struct convert_xrgb8888_case *params = test->param_value;
863 const struct convert_to_rgb888_result *result = &params->rgb888_result;
864 size_t dst_size;
865 u8 *buf = NULL;
866 __le32 *xrgb8888 = NULL;
867 struct iosys_map dst, src;
868
869 struct drm_framebuffer fb = {
870 .format = drm_format_info(DRM_FORMAT_XRGB8888),
871 .pitches = { params->pitch, 0, 0 },
872 };
873
874 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, dst_pitch: result->dst_pitch,
875 clip: &params->clip, plane: 0);
876 KUNIT_ASSERT_GT(test, dst_size, 0);
877
878 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
879 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
880 iosys_map_set_vaddr(map: &dst, vaddr: buf);
881
882 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
883 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
884 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
885
886 /*
887 * RGB888 expected results are already in little-endian
888 * order, so there's no need to convert the test output.
889 */
890 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
891 NULL : &result->dst_pitch;
892
893 drm_fb_xrgb8888_to_rgb888(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
894 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
895
896 buf = dst.vaddr; /* restore original value of buf */
897 memset(buf, 0, dst_size);
898
899 int blit_result = 0;
900
901 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_RGB888, src: &src, fb: &fb, rect: &params->clip);
902
903 KUNIT_EXPECT_FALSE(test, blit_result);
904 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
905}
906
907static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
908{
909 const struct convert_xrgb8888_case *params = test->param_value;
910 const struct convert_to_argb8888_result *result = &params->argb8888_result;
911 size_t dst_size;
912 u32 *buf = NULL;
913 __le32 *xrgb8888 = NULL;
914 struct iosys_map dst, src;
915
916 struct drm_framebuffer fb = {
917 .format = drm_format_info(DRM_FORMAT_XRGB8888),
918 .pitches = { params->pitch, 0, 0 },
919 };
920
921 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
922 dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
923 KUNIT_ASSERT_GT(test, dst_size, 0);
924
925 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
926 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
927 iosys_map_set_vaddr(map: &dst, vaddr: buf);
928
929 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
930 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
931 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
932
933 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
934 NULL : &result->dst_pitch;
935
936 drm_fb_xrgb8888_to_argb8888(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
937 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
938 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
939
940 buf = dst.vaddr; /* restore original value of buf */
941 memset(buf, 0, dst_size);
942
943 int blit_result = 0;
944
945 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_ARGB8888, src: &src, fb: &fb, rect: &params->clip);
946
947 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
948
949 KUNIT_EXPECT_FALSE(test, blit_result);
950 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
951}
952
953static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
954{
955 const struct convert_xrgb8888_case *params = test->param_value;
956 const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
957 size_t dst_size;
958 u32 *buf = NULL;
959 __le32 *xrgb8888 = NULL;
960 struct iosys_map dst, src;
961
962 struct drm_framebuffer fb = {
963 .format = drm_format_info(DRM_FORMAT_XRGB8888),
964 .pitches = { params->pitch, 0, 0 },
965 };
966
967 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
968 dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
969 KUNIT_ASSERT_GT(test, dst_size, 0);
970
971 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
972 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
973 iosys_map_set_vaddr(map: &dst, vaddr: buf);
974
975 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
976 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
977 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
978
979 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
980 NULL : &result->dst_pitch;
981
982 drm_fb_xrgb8888_to_xrgb2101010(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
983 buf = le32buf_to_cpu(test, buf, buf_size: dst_size / sizeof(u32));
984 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
985
986 buf = dst.vaddr; /* restore original value of buf */
987 memset(buf, 0, dst_size);
988
989 int blit_result = 0;
990
991 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_XRGB2101010, src: &src, fb: &fb,
992 rect: &params->clip);
993
994 KUNIT_EXPECT_FALSE(test, blit_result);
995 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
996}
997
998static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
999{
1000 const struct convert_xrgb8888_case *params = test->param_value;
1001 const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
1002 size_t dst_size;
1003 u32 *buf = NULL;
1004 __le32 *xrgb8888 = NULL;
1005 struct iosys_map dst, src;
1006
1007 struct drm_framebuffer fb = {
1008 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1009 .pitches = { params->pitch, 0, 0 },
1010 };
1011
1012 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1013 dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
1014 KUNIT_ASSERT_GT(test, dst_size, 0);
1015
1016 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
1017 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1018 iosys_map_set_vaddr(map: &dst, vaddr: buf);
1019
1020 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
1021 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1022 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
1023
1024 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1025 NULL : &result->dst_pitch;
1026
1027 drm_fb_xrgb8888_to_argb2101010(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
1028 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1029 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1030
1031 buf = dst.vaddr; /* restore original value of buf */
1032 memset(buf, 0, dst_size);
1033
1034 int blit_result = 0;
1035
1036 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_ARGB2101010, src: &src, fb: &fb,
1037 rect: &params->clip);
1038
1039 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1040
1041 KUNIT_EXPECT_FALSE(test, blit_result);
1042 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1043}
1044
1045static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1046{
1047 const struct convert_xrgb8888_case *params = test->param_value;
1048 const struct convert_to_mono_result *result = &params->mono_result;
1049 size_t dst_size;
1050 u8 *buf = NULL;
1051 __le32 *xrgb8888 = NULL;
1052 struct iosys_map dst, src;
1053
1054 struct drm_framebuffer fb = {
1055 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1056 .pitches = { params->pitch, 0, 0 },
1057 };
1058
1059 dst_size = conversion_buf_size(DRM_FORMAT_C1, dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
1060
1061 KUNIT_ASSERT_GT(test, dst_size, 0);
1062
1063 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
1064 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1065 iosys_map_set_vaddr(map: &dst, vaddr: buf);
1066
1067 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
1068 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1069 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
1070
1071 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1072 NULL : &result->dst_pitch;
1073
1074 drm_fb_xrgb8888_to_mono(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip);
1075 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1076}
1077
1078static void drm_test_fb_swab(struct kunit *test)
1079{
1080 const struct convert_xrgb8888_case *params = test->param_value;
1081 const struct fb_swab_result *result = &params->swab_result;
1082 size_t dst_size;
1083 u32 *buf = NULL;
1084 __le32 *xrgb8888 = NULL;
1085 struct iosys_map dst, src;
1086
1087 struct drm_framebuffer fb = {
1088 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1089 .pitches = { params->pitch, 0, 0 },
1090 };
1091
1092 dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
1093
1094 KUNIT_ASSERT_GT(test, dst_size, 0);
1095
1096 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
1097 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1098 iosys_map_set_vaddr(map: &dst, vaddr: buf);
1099
1100 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
1101 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1102 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
1103
1104 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1105 NULL : &result->dst_pitch;
1106
1107 drm_fb_swab(dst: &dst, dst_pitch, src: &src, fb: &fb, clip: &params->clip, cached: false);
1108 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1109 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1110
1111 buf = dst.vaddr; /* restore original value of buf */
1112 memset(buf, 0, dst_size);
1113
1114 int blit_result;
1115
1116 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN,
1117 src: &src, fb: &fb, rect: &params->clip);
1118 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1119
1120 KUNIT_EXPECT_FALSE(test, blit_result);
1121 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1122
1123 buf = dst.vaddr;
1124 memset(buf, 0, dst_size);
1125
1126 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_BGRX8888, src: &src, fb: &fb, rect: &params->clip);
1127 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1128
1129 KUNIT_EXPECT_FALSE(test, blit_result);
1130 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1131
1132 buf = dst.vaddr;
1133 memset(buf, 0, dst_size);
1134
1135 struct drm_format_info mock_format = *fb.format;
1136
1137 mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1138 fb.format = &mock_format;
1139
1140 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_XRGB8888, src: &src, fb: &fb, rect: &params->clip);
1141 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1142
1143 KUNIT_EXPECT_FALSE(test, blit_result);
1144 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1145}
1146
1147static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1148{
1149 const struct convert_xrgb8888_case *params = test->param_value;
1150 const struct convert_to_abgr8888_result *result = &params->abgr8888_result;
1151 size_t dst_size;
1152 u32 *buf = NULL;
1153 __le32 *xrgb8888 = NULL;
1154 struct iosys_map dst, src;
1155
1156 struct drm_framebuffer fb = {
1157 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1158 .pitches = { params->pitch, 0, 0 },
1159 };
1160
1161 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
1162
1163 KUNIT_ASSERT_GT(test, dst_size, 0);
1164
1165 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
1166 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1167 iosys_map_set_vaddr(map: &dst, vaddr: buf);
1168
1169 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
1170 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1171 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
1172
1173 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1174 NULL : &result->dst_pitch;
1175
1176 int blit_result = 0;
1177
1178 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_ABGR8888, src: &src, fb: &fb, rect: &params->clip);
1179
1180 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1181
1182 KUNIT_EXPECT_FALSE(test, blit_result);
1183 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1184}
1185
1186static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1187{
1188 const struct convert_xrgb8888_case *params = test->param_value;
1189 const struct convert_to_xbgr8888_result *result = &params->xbgr8888_result;
1190 size_t dst_size;
1191 u32 *buf = NULL;
1192 __le32 *xrgb8888 = NULL;
1193 struct iosys_map dst, src;
1194
1195 struct drm_framebuffer fb = {
1196 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1197 .pitches = { params->pitch, 0, 0 },
1198 };
1199
1200 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, dst_pitch: result->dst_pitch, clip: &params->clip, plane: 0);
1201
1202 KUNIT_ASSERT_GT(test, dst_size, 0);
1203
1204 buf = kunit_kzalloc(test, size: dst_size, GFP_KERNEL);
1205 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1206 iosys_map_set_vaddr(map: &dst, vaddr: buf);
1207
1208 xrgb8888 = cpubuf_to_le32(test, buf: params->xrgb8888, TEST_BUF_SIZE);
1209 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1210 iosys_map_set_vaddr(map: &src, vaddr: xrgb8888);
1211
1212 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1213 NULL : &result->dst_pitch;
1214
1215 int blit_result = 0;
1216
1217 blit_result = drm_fb_blit(dst: &dst, dst_pitch, DRM_FORMAT_XBGR8888, src: &src, fb: &fb, rect: &params->clip);
1218
1219 buf = le32buf_to_cpu(test, buf: (__force const __le32 *)buf, buf_size: dst_size / sizeof(u32));
1220
1221 KUNIT_EXPECT_FALSE(test, blit_result);
1222 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1223}
1224
1225struct clip_offset_case {
1226 const char *name;
1227 unsigned int pitch;
1228 u32 format;
1229 struct drm_rect clip;
1230 unsigned int expected_offset;
1231};
1232
1233static struct clip_offset_case clip_offset_cases[] = {
1234 {
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
1240 },
1241 {
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,
1247 },
1248 {
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,
1254 },
1255 {
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,
1261 },
1262 {
1263 .name = "horizontal offset (custom pitch)",
1264 .pitch = 20,
1265 .format = DRM_FORMAT_XRGB8888,
1266 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1267 .expected_offset = 4,
1268 },
1269 {
1270 .name = "vertical offset (custom pitch)",
1271 .pitch = 20,
1272 .format = DRM_FORMAT_XRGB8888,
1273 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1274 .expected_offset = 20,
1275 },
1276 {
1277 .name = "horizontal and vertical offset (custom pitch)",
1278 .pitch = 20,
1279 .format = DRM_FORMAT_XRGB8888,
1280 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1281 .expected_offset = 24,
1282 },
1283};
1284
1285static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1286{
1287 strscpy(p: desc, q: t->name, KUNIT_PARAM_DESC_SIZE);
1288}
1289
1290KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1291
1292static void drm_test_fb_clip_offset(struct kunit *test)
1293{
1294 const struct clip_offset_case *params = test->param_value;
1295 const struct drm_format_info *format_info = drm_format_info(format: params->format);
1296
1297 unsigned int offset;
1298 unsigned int pitch = params->pitch;
1299
1300 if (pitch == TEST_USE_DEFAULT_PITCH)
1301 pitch = drm_format_info_min_pitch(info: format_info, plane: 0,
1302 buffer_width: drm_rect_width(r: &params->clip));
1303
1304 /*
1305 * Assure that the pitch is not zero, because this will inevitable cause the
1306 * wrong expected result
1307 */
1308 KUNIT_ASSERT_NE(test, pitch, 0);
1309
1310 offset = drm_fb_clip_offset(pitch, format: format_info, clip: &params->clip);
1311
1312 KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1313}
1314
1315struct fb_build_fourcc_list_case {
1316 const char *name;
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;
1321};
1322
1323static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
1324 {
1325 .name = "no native formats",
1326 .native_fourccs = { },
1327 .native_fourccs_size = 0,
1328 .expected = { DRM_FORMAT_XRGB8888 },
1329 .expected_fourccs_size = 1,
1330 },
1331 {
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,
1337 },
1338 {
1339 .name = "remove duplicates",
1340 .native_fourccs = {
1341 DRM_FORMAT_XRGB8888,
1342 DRM_FORMAT_XRGB8888,
1343 DRM_FORMAT_RGB888,
1344 DRM_FORMAT_RGB888,
1345 DRM_FORMAT_RGB888,
1346 DRM_FORMAT_XRGB8888,
1347 DRM_FORMAT_RGB888,
1348 DRM_FORMAT_RGB565,
1349 DRM_FORMAT_RGB888,
1350 DRM_FORMAT_XRGB8888,
1351 DRM_FORMAT_RGB565,
1352 DRM_FORMAT_RGB565,
1353 DRM_FORMAT_XRGB8888,
1354 },
1355 .native_fourccs_size = 11,
1356 .expected = {
1357 DRM_FORMAT_XRGB8888,
1358 DRM_FORMAT_RGB888,
1359 DRM_FORMAT_RGB565,
1360 },
1361 .expected_fourccs_size = 3,
1362 },
1363 {
1364 .name = "convert alpha formats",
1365 .native_fourccs = {
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,
1378 },
1379 .native_fourccs_size = 12,
1380 .expected = {
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,
1393 },
1394 .expected_fourccs_size = 12,
1395 },
1396 {
1397 .name = "random formats",
1398 .native_fourccs = {
1399 DRM_FORMAT_Y212,
1400 DRM_FORMAT_ARGB1555,
1401 DRM_FORMAT_ABGR16161616F,
1402 DRM_FORMAT_C8,
1403 DRM_FORMAT_BGR888,
1404 DRM_FORMAT_XRGB1555,
1405 DRM_FORMAT_RGBA5551,
1406 DRM_FORMAT_BGR565_A8,
1407 DRM_FORMAT_R10,
1408 DRM_FORMAT_XYUV8888,
1409 },
1410 .native_fourccs_size = 10,
1411 .expected = {
1412 DRM_FORMAT_Y212,
1413 DRM_FORMAT_XRGB1555,
1414 DRM_FORMAT_ABGR16161616F,
1415 DRM_FORMAT_C8,
1416 DRM_FORMAT_BGR888,
1417 DRM_FORMAT_RGBX5551,
1418 DRM_FORMAT_BGR565_A8,
1419 DRM_FORMAT_R10,
1420 DRM_FORMAT_XYUV8888,
1421 DRM_FORMAT_XRGB8888,
1422 },
1423 .expected_fourccs_size = 10,
1424 },
1425};
1426
1427static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
1428{
1429 strscpy(p: desc, q: t->name, KUNIT_PARAM_DESC_SIZE);
1430}
1431
1432KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1433
1434static void drm_test_fb_build_fourcc_list(struct kunit *test)
1435{
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;
1440 struct device *dev;
1441
1442 dev = drm_kunit_helper_alloc_device(test);
1443 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1444
1445 drm = __drm_kunit_helper_alloc_drm_device(test, dev, size: sizeof(*drm), offset: 0, features: DRIVER_MODESET);
1446 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1447
1448 nfourccs_out = drm_fb_build_fourcc_list(dev: drm, native_fourccs: params->native_fourccs,
1449 native_nfourccs: params->native_fourccs_size,
1450 fourccs_out, TEST_BUF_SIZE);
1451
1452 KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
1453 KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
1454}
1455
1456struct fb_memcpy_case {
1457 const char *name;
1458 u32 format;
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];
1464};
1465
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.
1469 *
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.
1472 */
1473
1474static struct fb_memcpy_case fb_memcpy_cases[] = {
1475 {
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 }},
1483 },
1484 {
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 },
1489 .src = {
1490 { 0x01020304 },
1491 { 0xFFFFFF01 },
1492 },
1493 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1494 .expected = {
1495 { 0x01020304 },
1496 { 0x00000001 },
1497 },
1498 },
1499 {
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 },
1504 .src = {
1505 { 0xFFFFFF01 },
1506 { 0xFFFFFF01 },
1507 { 0xFFFFFF01 },
1508 },
1509 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1510 .expected = {
1511 { 0x00000001 },
1512 { 0x00000001 },
1513 { 0x00000001 },
1514 },
1515 },
1516 {
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 },
1521 .src = {
1522 {
1523 0x00000000, 0x00000000,
1524 0x00000000, 0x01020304,
1525 },
1526 },
1527 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1528 .expected = {
1529 { 0x01020304 },
1530 },
1531 },
1532 {
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 },
1537 .src = {
1538 {
1539 0x00000000, 0x00000000,
1540 0x00000000, 0x01020304,
1541 },
1542 { 0x01000000 },
1543 },
1544 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1545 .expected = {
1546 { 0x01020304 },
1547 { 0x00000001 },
1548 },
1549 },
1550 {
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 },
1555 .src = {
1556 { 0x01000000 },
1557 { 0x01000000 },
1558 { 0x01000000 },
1559 },
1560 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1561 .expected = {
1562 { 0x00000001 },
1563 { 0x00000001 },
1564 { 0x00000001 },
1565 },
1566 },
1567 {
1568 .name = "well_known_colors",
1569 .format = DRM_FORMAT_XBGR8888,
1570 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1571 .src_pitches = { 4 * 4 },
1572 .src = {
1573 {
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,
1579 },
1580 },
1581 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1582 .expected = {
1583 {
1584 0x11FFFFFF, 0x22000000,
1585 0x33FF0000, 0x4400FF00,
1586 0x550000FF, 0x66FF00FF,
1587 0x77FFFF00, 0x8800FFFF,
1588 },
1589 },
1590 },
1591 {
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 },
1596 .src = {
1597 {
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,
1603 },
1604 {
1605 0x00000000,
1606 0x00221100,
1607 0x00443300,
1608 0x00665500,
1609 0x00887700,
1610 },
1611 },
1612 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1613 .expected = {
1614 {
1615 0xFFFFFFFF, 0xFF000000,
1616 0xFFFF0000, 0xFF00FF00,
1617 0xFF0000FF, 0xFFFF00FF,
1618 0xFFFFFF00, 0xFF00FFFF,
1619 },
1620 {
1621 0x44332211,
1622 0x88776655,
1623 },
1624 },
1625 },
1626 {
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 },
1631 .src = {
1632 {
1633 0x00000000,
1634 0x0000FF00,
1635 0x00954C00,
1636 0x00691D00,
1637 0x00B2E100,
1638 },
1639 {
1640 0x00000000,
1641 0x00000000,
1642 0x00BEDE00,
1643 0x00436500,
1644 0x00229B00,
1645 },
1646 {
1647 0x00000000,
1648 0x00000000,
1649 0x007E9C00,
1650 0x0083E700,
1651 0x00641A00,
1652 },
1653 },
1654 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1655 .expected = {
1656 {
1657 0x954C00FF,
1658 0xB2E1691D,
1659 },
1660 {
1661 0xBEDE0000,
1662 0x229B4365,
1663 },
1664 {
1665 0x7E9C0000,
1666 0x641A83E7,
1667 },
1668 },
1669 },
1670 {
1671 .name = "destination_pitch",
1672 .format = DRM_FORMAT_XBGR8888,
1673 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1674 .src_pitches = { 3 * 4 },
1675 .src = {
1676 {
1677 0xA10E449C, 0xB1114D05, 0xC1A8F303,
1678 0xD16CF073, 0xA20E449C, 0xB2114D05,
1679 0xC2A80303, 0xD26CF073, 0xA30E449C,
1680 },
1681 },
1682 .dst_pitches = { 5 * 4 },
1683 .expected = {
1684 {
1685 0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1686 0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1687 0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1688 },
1689 },
1690 },
1691 {
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 },
1696 .src = {
1697 {
1698 0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1699 0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1700 0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1701 },
1702 {
1703 0xB2C1B1A1,
1704 0xD2A3D1A2,
1705 0xFFFFFFC2,
1706 },
1707 },
1708 .dst_pitches = { 5 * 4, 5 * 1 },
1709 .expected = {
1710 {
1711 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1712 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1713 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1714 },
1715 {
1716 0x00C1B1A1,
1717 0xD1A2B200,
1718 0xD2A30000,
1719 0xFF0000C2,
1720 },
1721 },
1722 },
1723 {
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 },
1728 .src = {
1729 {
1730 0xBAC1323D,
1731 0xBA34323D,
1732 0xFFFFFF3D,
1733 },
1734 {
1735 0xE1ABEC2A,
1736 0xE1EAEC2A,
1737 0xFFFFFF2A,
1738 },
1739 {
1740 0xBCEBE4D7,
1741 0xBC65E4D7,
1742 0xFFFFFFD7,
1743 },
1744 },
1745 .dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1746 .expected = {
1747 {
1748 0x00C1323D,
1749 0x323DBA00,
1750 0xBA340000,
1751 0xFF00003D,
1752 },
1753 {
1754 0x00ABEC2A,
1755 0xEC2AE100,
1756 0xE1EA0000,
1757 0xFF00002A,
1758 },
1759 {
1760 0x00EBE4D7,
1761 0xE4D7BC00,
1762 0xBC650000,
1763 0xFF0000D7,
1764 },
1765 },
1766 },
1767};
1768
1769static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1770{
1771 snprintf(buf: desc, KUNIT_PARAM_DESC_SIZE, fmt: "%s: %p4cc", t->name, &t->format);
1772}
1773
1774KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1775
1776static void drm_test_fb_memcpy(struct kunit *test)
1777{
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];
1785
1786 struct drm_framebuffer fb = {
1787 .format = drm_format_info(format: params->format),
1788 };
1789
1790 memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1791
1792 for (size_t i = 0; i < fb.format->num_planes; i++) {
1793 dst_size[i] = conversion_buf_size(dst_format: params->format, dst_pitch: params->dst_pitches[i],
1794 clip: &params->clip, plane: i);
1795 KUNIT_ASSERT_GT(test, dst_size[i], 0);
1796
1797 buf[i] = kunit_kzalloc(test, size: dst_size[i], GFP_KERNEL);
1798 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1799 iosys_map_set_vaddr(map: &dst[i], vaddr: buf[i]);
1800
1801 src_cp[i] = cpubuf_to_le32(test, buf: params->src[i], TEST_BUF_SIZE);
1802 iosys_map_set_vaddr(map: &src[i], vaddr: src_cp[i]);
1803 }
1804
1805 const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1806 params->dst_pitches;
1807
1808 drm_fb_memcpy(dst, dst_pitch: dst_pitches, src, fb: &fb, clip: &params->clip);
1809
1810 for (size_t i = 0; i < fb.format->num_planes; i++) {
1811 expected[i] = cpubuf_to_le32(test, buf: 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);
1814
1815 memset(buf[i], 0, dst_size[i]);
1816 }
1817
1818 int blit_result;
1819
1820 blit_result = drm_fb_blit(dst, dst_pitch: dst_pitches, dst_format: params->format, src, fb: &fb, rect: &params->clip);
1821
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, buf: 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);
1827 }
1828}
1829
1830static 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),
1848 {}
1849};
1850
1851static struct kunit_suite drm_format_helper_test_suite = {
1852 .name = "drm_format_helper_test",
1853 .test_cases = drm_format_helper_test_cases,
1854};
1855
1856kunit_test_suite(drm_format_helper_test_suite);
1857
1858MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1859MODULE_LICENSE("GPL");
1860MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
1861

source code of linux/drivers/gpu/drm/tests/drm_format_helper_test.c