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

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