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