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 int blit_result = 0;
752
753 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, ¶ms->clip,
754 &fmtcnv_state);
755
756 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
757
758 KUNIT_EXPECT_FALSE(test, blit_result);
759 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
760 }
761
drm_test_fb_xrgb8888_to_xrgb1555(struct kunit * test)762 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
763 {
764 const struct convert_xrgb8888_case *params = test->param_value;
765 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result;
766 size_t dst_size;
767 u16 *buf = NULL;
768 __le32 *xrgb8888 = NULL;
769 struct iosys_map dst, src;
770
771 struct drm_framebuffer fb = {
772 .format = drm_format_info(DRM_FORMAT_XRGB8888),
773 .pitches = { params->pitch, 0, 0 },
774 };
775
776 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
777 ¶ms->clip, 0);
778 KUNIT_ASSERT_GT(test, dst_size, 0);
779
780 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
781 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
782 iosys_map_set_vaddr(&dst, buf);
783
784 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
785 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
786 iosys_map_set_vaddr(&src, xrgb8888);
787
788 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
789 NULL : &result->dst_pitch;
790
791 drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
792 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
793 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
794
795 buf = dst.vaddr; /* restore original value of buf */
796 memset(buf, 0, dst_size);
797
798 int blit_result = 0;
799
800 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, ¶ms->clip,
801 &fmtcnv_state);
802
803 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
804
805 KUNIT_EXPECT_FALSE(test, blit_result);
806 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
807 }
808
drm_test_fb_xrgb8888_to_argb1555(struct kunit * test)809 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
810 {
811 const struct convert_xrgb8888_case *params = test->param_value;
812 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result;
813 size_t dst_size;
814 u16 *buf = NULL;
815 __le32 *xrgb8888 = NULL;
816 struct iosys_map dst, src;
817
818 struct drm_framebuffer fb = {
819 .format = drm_format_info(DRM_FORMAT_XRGB8888),
820 .pitches = { params->pitch, 0, 0 },
821 };
822
823 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
824 ¶ms->clip, 0);
825 KUNIT_ASSERT_GT(test, dst_size, 0);
826
827 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
828 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
829 iosys_map_set_vaddr(&dst, buf);
830
831 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
832 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
833 iosys_map_set_vaddr(&src, xrgb8888);
834
835 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
836 NULL : &result->dst_pitch;
837
838 drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
839 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
840 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
841
842 buf = dst.vaddr; /* restore original value of buf */
843 memset(buf, 0, dst_size);
844
845 int blit_result = 0;
846
847 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, ¶ms->clip,
848 &fmtcnv_state);
849
850 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
851
852 KUNIT_EXPECT_FALSE(test, blit_result);
853 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
854 }
855
drm_test_fb_xrgb8888_to_rgba5551(struct kunit * test)856 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
857 {
858 const struct convert_xrgb8888_case *params = test->param_value;
859 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result;
860 size_t dst_size;
861 u16 *buf = NULL;
862 __le32 *xrgb8888 = NULL;
863 struct iosys_map dst, src;
864
865 struct drm_framebuffer fb = {
866 .format = drm_format_info(DRM_FORMAT_XRGB8888),
867 .pitches = { params->pitch, 0, 0 },
868 };
869
870 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
871 ¶ms->clip, 0);
872 KUNIT_ASSERT_GT(test, dst_size, 0);
873
874 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
875 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
876 iosys_map_set_vaddr(&dst, buf);
877
878 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
879 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
880 iosys_map_set_vaddr(&src, xrgb8888);
881
882 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
883 NULL : &result->dst_pitch;
884
885 drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
886 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
887 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
888
889 buf = dst.vaddr; /* restore original value of buf */
890 memset(buf, 0, dst_size);
891
892 int blit_result = 0;
893
894 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, ¶ms->clip,
895 &fmtcnv_state);
896
897 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
898
899 KUNIT_EXPECT_FALSE(test, blit_result);
900 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
901 }
902
drm_test_fb_xrgb8888_to_rgb888(struct kunit * test)903 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
904 {
905 const struct convert_xrgb8888_case *params = test->param_value;
906 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result;
907 size_t dst_size;
908 u8 *buf = NULL;
909 __le32 *xrgb8888 = NULL;
910 struct iosys_map dst, src;
911
912 struct drm_framebuffer fb = {
913 .format = drm_format_info(DRM_FORMAT_XRGB8888),
914 .pitches = { params->pitch, 0, 0 },
915 };
916
917 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
918 ¶ms->clip, 0);
919 KUNIT_ASSERT_GT(test, dst_size, 0);
920
921 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
922 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
923 iosys_map_set_vaddr(&dst, buf);
924
925 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
926 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
927 iosys_map_set_vaddr(&src, xrgb8888);
928
929 /*
930 * RGB888 expected results are already in little-endian
931 * order, so there's no need to convert the test output.
932 */
933 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
934 NULL : &result->dst_pitch;
935
936 drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
937 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
938
939 buf = dst.vaddr; /* restore original value of buf */
940 memset(buf, 0, dst_size);
941
942 int blit_result = 0;
943
944 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, ¶ms->clip,
945 &fmtcnv_state);
946
947 KUNIT_EXPECT_FALSE(test, blit_result);
948 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
949 }
950
drm_test_fb_xrgb8888_to_bgr888(struct kunit * test)951 static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test)
952 {
953 const struct convert_xrgb8888_case *params = test->param_value;
954 const struct convert_to_bgr888_result *result = ¶ms->bgr888_result;
955 size_t dst_size;
956 u8 *buf = NULL;
957 __le32 *xrgb8888 = NULL;
958 struct iosys_map dst, src;
959
960 struct drm_framebuffer fb = {
961 .format = drm_format_info(DRM_FORMAT_XRGB8888),
962 .pitches = { params->pitch, 0, 0 },
963 };
964
965 dst_size = conversion_buf_size(DRM_FORMAT_BGR888, result->dst_pitch,
966 ¶ms->clip, 0);
967 KUNIT_ASSERT_GT(test, dst_size, 0);
968
969 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
970 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
971 iosys_map_set_vaddr(&dst, buf);
972
973 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
974 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
975 iosys_map_set_vaddr(&src, xrgb8888);
976
977 /*
978 * BGR888 expected results are already in little-endian
979 * order, so there's no need to convert the test output.
980 */
981 drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip,
982 &fmtcnv_state);
983 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
984
985 buf = dst.vaddr; /* restore original value of buf */
986 memset(buf, 0, dst_size);
987
988 int blit_result = 0;
989
990 blit_result = drm_fb_blit(&dst, &result->dst_pitch, DRM_FORMAT_BGR888, &src, &fb, ¶ms->clip,
991 &fmtcnv_state);
992
993 KUNIT_EXPECT_FALSE(test, blit_result);
994 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
995 }
996
drm_test_fb_xrgb8888_to_argb8888(struct kunit * test)997 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
998 {
999 const struct convert_xrgb8888_case *params = test->param_value;
1000 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result;
1001 size_t dst_size;
1002 u32 *buf = NULL;
1003 __le32 *xrgb8888 = NULL;
1004 struct iosys_map dst, src;
1005
1006 struct drm_framebuffer fb = {
1007 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1008 .pitches = { params->pitch, 0, 0 },
1009 };
1010
1011 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
1012 result->dst_pitch, ¶ms->clip, 0);
1013 KUNIT_ASSERT_GT(test, dst_size, 0);
1014
1015 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1016 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1017 iosys_map_set_vaddr(&dst, buf);
1018
1019 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1020 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1021 iosys_map_set_vaddr(&src, xrgb8888);
1022
1023 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1024 NULL : &result->dst_pitch;
1025
1026 drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1027 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1028 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1029
1030 buf = dst.vaddr; /* restore original value of buf */
1031 memset(buf, 0, dst_size);
1032
1033 int blit_result = 0;
1034
1035 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, ¶ms->clip,
1036 &fmtcnv_state);
1037
1038 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1039
1040 KUNIT_EXPECT_FALSE(test, blit_result);
1041 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1042 }
1043
drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit * test)1044 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
1045 {
1046 const struct convert_xrgb8888_case *params = test->param_value;
1047 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result;
1048 size_t dst_size;
1049 u32 *buf = NULL;
1050 __le32 *xrgb8888 = NULL;
1051 struct iosys_map dst, src;
1052
1053 struct drm_framebuffer fb = {
1054 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1055 .pitches = { params->pitch, 0, 0 },
1056 };
1057
1058 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
1059 result->dst_pitch, ¶ms->clip, 0);
1060 KUNIT_ASSERT_GT(test, dst_size, 0);
1061
1062 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1063 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1064 iosys_map_set_vaddr(&dst, buf);
1065
1066 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1067 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1068 iosys_map_set_vaddr(&src, xrgb8888);
1069
1070 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1071 NULL : &result->dst_pitch;
1072
1073 drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1074 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
1075 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1076
1077 buf = dst.vaddr; /* restore original value of buf */
1078 memset(buf, 0, dst_size);
1079
1080 int blit_result = 0;
1081
1082 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb,
1083 ¶ms->clip, &fmtcnv_state);
1084
1085 KUNIT_EXPECT_FALSE(test, blit_result);
1086 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1087 }
1088
drm_test_fb_xrgb8888_to_argb2101010(struct kunit * test)1089 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1090 {
1091 const struct convert_xrgb8888_case *params = test->param_value;
1092 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_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_ARGB2101010,
1104 result->dst_pitch, ¶ms->clip, 0);
1105 KUNIT_ASSERT_GT(test, dst_size, 0);
1106
1107 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1108 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1109 iosys_map_set_vaddr(&dst, buf);
1110
1111 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1112 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1113 iosys_map_set_vaddr(&src, xrgb8888);
1114
1115 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1116 NULL : &result->dst_pitch;
1117
1118 drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1119 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1120 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1121
1122 buf = dst.vaddr; /* restore original value of buf */
1123 memset(buf, 0, dst_size);
1124
1125 int blit_result = 0;
1126
1127 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb,
1128 ¶ms->clip, &fmtcnv_state);
1129
1130 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1131
1132 KUNIT_EXPECT_FALSE(test, blit_result);
1133 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1134 }
1135
drm_test_fb_xrgb8888_to_mono(struct kunit * test)1136 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1137 {
1138 const struct convert_xrgb8888_case *params = test->param_value;
1139 const struct convert_to_mono_result *result = ¶ms->mono_result;
1140 size_t dst_size;
1141 u8 *buf = NULL;
1142 __le32 *xrgb8888 = NULL;
1143 struct iosys_map dst, src;
1144
1145 struct drm_framebuffer fb = {
1146 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1147 .pitches = { params->pitch, 0, 0 },
1148 };
1149
1150 dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip, 0);
1151
1152 KUNIT_ASSERT_GT(test, dst_size, 0);
1153
1154 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1155 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1156 iosys_map_set_vaddr(&dst, buf);
1157
1158 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1159 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1160 iosys_map_set_vaddr(&src, xrgb8888);
1161
1162 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1163 NULL : &result->dst_pitch;
1164
1165 drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state);
1166 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1167 }
1168
drm_test_fb_swab(struct kunit * test)1169 static void drm_test_fb_swab(struct kunit *test)
1170 {
1171 const struct convert_xrgb8888_case *params = test->param_value;
1172 const struct fb_swab_result *result = ¶ms->swab_result;
1173 size_t dst_size;
1174 u32 *buf = NULL;
1175 __le32 *xrgb8888 = NULL;
1176 struct iosys_map dst, src;
1177
1178 struct drm_framebuffer fb = {
1179 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1180 .pitches = { params->pitch, 0, 0 },
1181 };
1182
1183 dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, ¶ms->clip, 0);
1184
1185 KUNIT_ASSERT_GT(test, dst_size, 0);
1186
1187 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1188 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1189 iosys_map_set_vaddr(&dst, buf);
1190
1191 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1192 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1193 iosys_map_set_vaddr(&src, xrgb8888);
1194
1195 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1196 NULL : &result->dst_pitch;
1197
1198 drm_fb_swab(&dst, dst_pitch, &src, &fb, ¶ms->clip, false, &fmtcnv_state);
1199 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1200 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1201
1202 buf = dst.vaddr; /* restore original value of buf */
1203 memset(buf, 0, dst_size);
1204
1205 int blit_result;
1206
1207 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN,
1208 &src, &fb, ¶ms->clip, &fmtcnv_state);
1209 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1210
1211 KUNIT_EXPECT_FALSE(test, blit_result);
1212 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1213
1214 buf = dst.vaddr;
1215 memset(buf, 0, dst_size);
1216
1217 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, ¶ms->clip,
1218 &fmtcnv_state);
1219 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1220
1221 KUNIT_EXPECT_FALSE(test, blit_result);
1222 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1223
1224 buf = dst.vaddr;
1225 memset(buf, 0, dst_size);
1226
1227 struct drm_format_info mock_format = *fb.format;
1228
1229 mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1230 fb.format = &mock_format;
1231
1232 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, ¶ms->clip,
1233 &fmtcnv_state);
1234 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1235
1236 KUNIT_EXPECT_FALSE(test, blit_result);
1237 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1238 }
1239
drm_test_fb_xrgb8888_to_abgr8888(struct kunit * test)1240 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1241 {
1242 const struct convert_xrgb8888_case *params = test->param_value;
1243 const struct convert_to_abgr8888_result *result = ¶ms->abgr8888_result;
1244 size_t dst_size;
1245 u32 *buf = NULL;
1246 __le32 *xrgb8888 = NULL;
1247 struct iosys_map dst, src;
1248
1249 struct drm_framebuffer fb = {
1250 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1251 .pitches = { params->pitch, 0, 0 },
1252 };
1253
1254 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1255
1256 KUNIT_ASSERT_GT(test, dst_size, 0);
1257
1258 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1259 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1260 iosys_map_set_vaddr(&dst, buf);
1261
1262 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1263 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1264 iosys_map_set_vaddr(&src, xrgb8888);
1265
1266 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1267 NULL : &result->dst_pitch;
1268
1269 int blit_result = 0;
1270
1271 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, ¶ms->clip,
1272 &fmtcnv_state);
1273
1274 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1275
1276 KUNIT_EXPECT_FALSE(test, blit_result);
1277 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1278 }
1279
drm_test_fb_xrgb8888_to_xbgr8888(struct kunit * test)1280 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1281 {
1282 const struct convert_xrgb8888_case *params = test->param_value;
1283 const struct convert_to_xbgr8888_result *result = ¶ms->xbgr8888_result;
1284 size_t dst_size;
1285 u32 *buf = NULL;
1286 __le32 *xrgb8888 = NULL;
1287 struct iosys_map dst, src;
1288
1289 struct drm_framebuffer fb = {
1290 .format = drm_format_info(DRM_FORMAT_XRGB8888),
1291 .pitches = { params->pitch, 0, 0 },
1292 };
1293
1294 dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, ¶ms->clip, 0);
1295
1296 KUNIT_ASSERT_GT(test, dst_size, 0);
1297
1298 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1299 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1300 iosys_map_set_vaddr(&dst, buf);
1301
1302 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1303 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1304 iosys_map_set_vaddr(&src, xrgb8888);
1305
1306 const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1307 NULL : &result->dst_pitch;
1308
1309 int blit_result = 0;
1310
1311 blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, ¶ms->clip,
1312 &fmtcnv_state);
1313
1314 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1315
1316 KUNIT_EXPECT_FALSE(test, blit_result);
1317 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1318 }
1319
1320 struct clip_offset_case {
1321 const char *name;
1322 unsigned int pitch;
1323 u32 format;
1324 struct drm_rect clip;
1325 unsigned int expected_offset;
1326 };
1327
1328 static struct clip_offset_case clip_offset_cases[] = {
1329 {
1330 .name = "pass through",
1331 .pitch = TEST_USE_DEFAULT_PITCH,
1332 .format = DRM_FORMAT_XRGB8888,
1333 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1334 .expected_offset = 0
1335 },
1336 {
1337 .name = "horizontal offset",
1338 .pitch = TEST_USE_DEFAULT_PITCH,
1339 .format = DRM_FORMAT_XRGB8888,
1340 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1341 .expected_offset = 4,
1342 },
1343 {
1344 .name = "vertical offset",
1345 .pitch = TEST_USE_DEFAULT_PITCH,
1346 .format = DRM_FORMAT_XRGB8888,
1347 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1348 .expected_offset = 12,
1349 },
1350 {
1351 .name = "horizontal and vertical offset",
1352 .pitch = TEST_USE_DEFAULT_PITCH,
1353 .format = DRM_FORMAT_XRGB8888,
1354 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1355 .expected_offset = 16,
1356 },
1357 {
1358 .name = "horizontal offset (custom pitch)",
1359 .pitch = 20,
1360 .format = DRM_FORMAT_XRGB8888,
1361 .clip = DRM_RECT_INIT(1, 0, 3, 3),
1362 .expected_offset = 4,
1363 },
1364 {
1365 .name = "vertical offset (custom pitch)",
1366 .pitch = 20,
1367 .format = DRM_FORMAT_XRGB8888,
1368 .clip = DRM_RECT_INIT(0, 1, 3, 3),
1369 .expected_offset = 20,
1370 },
1371 {
1372 .name = "horizontal and vertical offset (custom pitch)",
1373 .pitch = 20,
1374 .format = DRM_FORMAT_XRGB8888,
1375 .clip = DRM_RECT_INIT(1, 1, 3, 3),
1376 .expected_offset = 24,
1377 },
1378 };
1379
clip_offset_case_desc(struct clip_offset_case * t,char * desc)1380 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1381 {
1382 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1383 }
1384
1385 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1386
drm_test_fb_clip_offset(struct kunit * test)1387 static void drm_test_fb_clip_offset(struct kunit *test)
1388 {
1389 const struct clip_offset_case *params = test->param_value;
1390 const struct drm_format_info *format_info = drm_format_info(params->format);
1391
1392 unsigned int offset;
1393 unsigned int pitch = params->pitch;
1394
1395 if (pitch == TEST_USE_DEFAULT_PITCH)
1396 pitch = drm_format_info_min_pitch(format_info, 0,
1397 drm_rect_width(¶ms->clip));
1398
1399 /*
1400 * Assure that the pitch is not zero, because this will inevitable cause the
1401 * wrong expected result
1402 */
1403 KUNIT_ASSERT_NE(test, pitch, 0);
1404
1405 offset = drm_fb_clip_offset(pitch, format_info, ¶ms->clip);
1406
1407 KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1408 }
1409
1410 struct fb_build_fourcc_list_case {
1411 const char *name;
1412 u32 native_fourccs[TEST_BUF_SIZE];
1413 size_t native_fourccs_size;
1414 u32 expected[TEST_BUF_SIZE];
1415 size_t expected_fourccs_size;
1416 };
1417
1418 static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
1419 {
1420 .name = "no native formats",
1421 .native_fourccs = { },
1422 .native_fourccs_size = 0,
1423 .expected = { DRM_FORMAT_XRGB8888 },
1424 .expected_fourccs_size = 1,
1425 },
1426 {
1427 .name = "XRGB8888 as native format",
1428 .native_fourccs = { DRM_FORMAT_XRGB8888 },
1429 .native_fourccs_size = 1,
1430 .expected = { DRM_FORMAT_XRGB8888 },
1431 .expected_fourccs_size = 1,
1432 },
1433 {
1434 .name = "remove duplicates",
1435 .native_fourccs = {
1436 DRM_FORMAT_XRGB8888,
1437 DRM_FORMAT_XRGB8888,
1438 DRM_FORMAT_RGB888,
1439 DRM_FORMAT_RGB888,
1440 DRM_FORMAT_RGB888,
1441 DRM_FORMAT_XRGB8888,
1442 DRM_FORMAT_RGB888,
1443 DRM_FORMAT_RGB565,
1444 DRM_FORMAT_RGB888,
1445 DRM_FORMAT_XRGB8888,
1446 DRM_FORMAT_RGB565,
1447 DRM_FORMAT_RGB565,
1448 DRM_FORMAT_XRGB8888,
1449 },
1450 .native_fourccs_size = 11,
1451 .expected = {
1452 DRM_FORMAT_XRGB8888,
1453 DRM_FORMAT_RGB888,
1454 DRM_FORMAT_RGB565,
1455 },
1456 .expected_fourccs_size = 3,
1457 },
1458 {
1459 .name = "convert alpha formats",
1460 .native_fourccs = {
1461 DRM_FORMAT_ARGB1555,
1462 DRM_FORMAT_ABGR1555,
1463 DRM_FORMAT_RGBA5551,
1464 DRM_FORMAT_BGRA5551,
1465 DRM_FORMAT_ARGB8888,
1466 DRM_FORMAT_ABGR8888,
1467 DRM_FORMAT_RGBA8888,
1468 DRM_FORMAT_BGRA8888,
1469 DRM_FORMAT_ARGB2101010,
1470 DRM_FORMAT_ABGR2101010,
1471 DRM_FORMAT_RGBA1010102,
1472 DRM_FORMAT_BGRA1010102,
1473 },
1474 .native_fourccs_size = 12,
1475 .expected = {
1476 DRM_FORMAT_XRGB1555,
1477 DRM_FORMAT_XBGR1555,
1478 DRM_FORMAT_RGBX5551,
1479 DRM_FORMAT_BGRX5551,
1480 DRM_FORMAT_XRGB8888,
1481 DRM_FORMAT_XBGR8888,
1482 DRM_FORMAT_RGBX8888,
1483 DRM_FORMAT_BGRX8888,
1484 DRM_FORMAT_XRGB2101010,
1485 DRM_FORMAT_XBGR2101010,
1486 DRM_FORMAT_RGBX1010102,
1487 DRM_FORMAT_BGRX1010102,
1488 },
1489 .expected_fourccs_size = 12,
1490 },
1491 {
1492 .name = "random formats",
1493 .native_fourccs = {
1494 DRM_FORMAT_Y212,
1495 DRM_FORMAT_ARGB1555,
1496 DRM_FORMAT_ABGR16161616F,
1497 DRM_FORMAT_C8,
1498 DRM_FORMAT_BGR888,
1499 DRM_FORMAT_XRGB1555,
1500 DRM_FORMAT_RGBA5551,
1501 DRM_FORMAT_BGR565_A8,
1502 DRM_FORMAT_R10,
1503 DRM_FORMAT_XYUV8888,
1504 },
1505 .native_fourccs_size = 10,
1506 .expected = {
1507 DRM_FORMAT_Y212,
1508 DRM_FORMAT_XRGB1555,
1509 DRM_FORMAT_ABGR16161616F,
1510 DRM_FORMAT_C8,
1511 DRM_FORMAT_BGR888,
1512 DRM_FORMAT_RGBX5551,
1513 DRM_FORMAT_BGR565_A8,
1514 DRM_FORMAT_R10,
1515 DRM_FORMAT_XYUV8888,
1516 DRM_FORMAT_XRGB8888,
1517 },
1518 .expected_fourccs_size = 10,
1519 },
1520 };
1521
fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case * t,char * desc)1522 static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
1523 {
1524 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1525 }
1526
1527 KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1528
drm_test_fb_build_fourcc_list(struct kunit * test)1529 static void drm_test_fb_build_fourcc_list(struct kunit *test)
1530 {
1531 const struct fb_build_fourcc_list_case *params = test->param_value;
1532 u32 fourccs_out[TEST_BUF_SIZE] = {0};
1533 size_t nfourccs_out;
1534 struct drm_device *drm;
1535 struct device *dev;
1536
1537 dev = drm_kunit_helper_alloc_device(test);
1538 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1539
1540 drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
1541 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1542
1543 nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs,
1544 params->native_fourccs_size,
1545 fourccs_out, TEST_BUF_SIZE);
1546
1547 KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
1548 KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
1549 }
1550
1551 struct fb_memcpy_case {
1552 const char *name;
1553 u32 format;
1554 struct drm_rect clip;
1555 unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1556 const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1557 unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1558 const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1559 };
1560
1561 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1562 * have a cpp != 4 the values are stored together on the same u32 number in a
1563 * way so the order in memory is correct in a little-endian machine.
1564 *
1565 * Because of that, on some occasions, parts of a u32 will not be part of the
1566 * test, to make this explicit the 0xFF byte is used on those parts.
1567 */
1568
1569 static struct fb_memcpy_case fb_memcpy_cases[] = {
1570 {
1571 .name = "single_pixel_source_buffer",
1572 .format = DRM_FORMAT_XRGB8888,
1573 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1574 .src_pitches = { 1 * 4 },
1575 .src = {{ 0x01020304 }},
1576 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1577 .expected = {{ 0x01020304 }},
1578 },
1579 {
1580 .name = "single_pixel_source_buffer",
1581 .format = DRM_FORMAT_XRGB8888_A8,
1582 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1583 .src_pitches = { 1 * 4, 1 },
1584 .src = {
1585 { 0x01020304 },
1586 { 0xFFFFFF01 },
1587 },
1588 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1589 .expected = {
1590 { 0x01020304 },
1591 { 0x00000001 },
1592 },
1593 },
1594 {
1595 .name = "single_pixel_source_buffer",
1596 .format = DRM_FORMAT_YUV444,
1597 .clip = DRM_RECT_INIT(0, 0, 1, 1),
1598 .src_pitches = { 1, 1, 1 },
1599 .src = {
1600 { 0xFFFFFF01 },
1601 { 0xFFFFFF01 },
1602 { 0xFFFFFF01 },
1603 },
1604 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1605 .expected = {
1606 { 0x00000001 },
1607 { 0x00000001 },
1608 { 0x00000001 },
1609 },
1610 },
1611 {
1612 .name = "single_pixel_clip_rectangle",
1613 .format = DRM_FORMAT_XBGR8888,
1614 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1615 .src_pitches = { 2 * 4 },
1616 .src = {
1617 {
1618 0x00000000, 0x00000000,
1619 0x00000000, 0x01020304,
1620 },
1621 },
1622 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1623 .expected = {
1624 { 0x01020304 },
1625 },
1626 },
1627 {
1628 .name = "single_pixel_clip_rectangle",
1629 .format = DRM_FORMAT_XRGB8888_A8,
1630 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1631 .src_pitches = { 2 * 4, 2 * 1 },
1632 .src = {
1633 {
1634 0x00000000, 0x00000000,
1635 0x00000000, 0x01020304,
1636 },
1637 { 0x01000000 },
1638 },
1639 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1640 .expected = {
1641 { 0x01020304 },
1642 { 0x00000001 },
1643 },
1644 },
1645 {
1646 .name = "single_pixel_clip_rectangle",
1647 .format = DRM_FORMAT_YUV444,
1648 .clip = DRM_RECT_INIT(1, 1, 1, 1),
1649 .src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1650 .src = {
1651 { 0x01000000 },
1652 { 0x01000000 },
1653 { 0x01000000 },
1654 },
1655 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1656 .expected = {
1657 { 0x00000001 },
1658 { 0x00000001 },
1659 { 0x00000001 },
1660 },
1661 },
1662 {
1663 .name = "well_known_colors",
1664 .format = DRM_FORMAT_XBGR8888,
1665 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1666 .src_pitches = { 4 * 4 },
1667 .src = {
1668 {
1669 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1670 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1671 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1672 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1673 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1674 },
1675 },
1676 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1677 .expected = {
1678 {
1679 0x11FFFFFF, 0x22000000,
1680 0x33FF0000, 0x4400FF00,
1681 0x550000FF, 0x66FF00FF,
1682 0x77FFFF00, 0x8800FFFF,
1683 },
1684 },
1685 },
1686 {
1687 .name = "well_known_colors",
1688 .format = DRM_FORMAT_XRGB8888_A8,
1689 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1690 .src_pitches = { 4 * 4, 4 * 1 },
1691 .src = {
1692 {
1693 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1694 0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1695 0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1696 0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1697 0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1698 },
1699 {
1700 0x00000000,
1701 0x00221100,
1702 0x00443300,
1703 0x00665500,
1704 0x00887700,
1705 },
1706 },
1707 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1708 .expected = {
1709 {
1710 0xFFFFFFFF, 0xFF000000,
1711 0xFFFF0000, 0xFF00FF00,
1712 0xFF0000FF, 0xFFFF00FF,
1713 0xFFFFFF00, 0xFF00FFFF,
1714 },
1715 {
1716 0x44332211,
1717 0x88776655,
1718 },
1719 },
1720 },
1721 {
1722 .name = "well_known_colors",
1723 .format = DRM_FORMAT_YUV444,
1724 .clip = DRM_RECT_INIT(1, 1, 2, 4),
1725 .src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1726 .src = {
1727 {
1728 0x00000000,
1729 0x0000FF00,
1730 0x00954C00,
1731 0x00691D00,
1732 0x00B2E100,
1733 },
1734 {
1735 0x00000000,
1736 0x00000000,
1737 0x00BEDE00,
1738 0x00436500,
1739 0x00229B00,
1740 },
1741 {
1742 0x00000000,
1743 0x00000000,
1744 0x007E9C00,
1745 0x0083E700,
1746 0x00641A00,
1747 },
1748 },
1749 .dst_pitches = { TEST_USE_DEFAULT_PITCH },
1750 .expected = {
1751 {
1752 0x954C00FF,
1753 0xB2E1691D,
1754 },
1755 {
1756 0xBEDE0000,
1757 0x229B4365,
1758 },
1759 {
1760 0x7E9C0000,
1761 0x641A83E7,
1762 },
1763 },
1764 },
1765 {
1766 .name = "destination_pitch",
1767 .format = DRM_FORMAT_XBGR8888,
1768 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1769 .src_pitches = { 3 * 4 },
1770 .src = {
1771 {
1772 0xA10E449C, 0xB1114D05, 0xC1A8F303,
1773 0xD16CF073, 0xA20E449C, 0xB2114D05,
1774 0xC2A80303, 0xD26CF073, 0xA30E449C,
1775 },
1776 },
1777 .dst_pitches = { 5 * 4 },
1778 .expected = {
1779 {
1780 0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1781 0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1782 0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1783 },
1784 },
1785 },
1786 {
1787 .name = "destination_pitch",
1788 .format = DRM_FORMAT_XRGB8888_A8,
1789 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1790 .src_pitches = { 3 * 4, 3 * 1 },
1791 .src = {
1792 {
1793 0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1794 0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1795 0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1796 },
1797 {
1798 0xB2C1B1A1,
1799 0xD2A3D1A2,
1800 0xFFFFFFC2,
1801 },
1802 },
1803 .dst_pitches = { 5 * 4, 5 * 1 },
1804 .expected = {
1805 {
1806 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1807 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1808 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1809 },
1810 {
1811 0x00C1B1A1,
1812 0xD1A2B200,
1813 0xD2A30000,
1814 0xFF0000C2,
1815 },
1816 },
1817 },
1818 {
1819 .name = "destination_pitch",
1820 .format = DRM_FORMAT_YUV444,
1821 .clip = DRM_RECT_INIT(0, 0, 3, 3),
1822 .src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1823 .src = {
1824 {
1825 0xBAC1323D,
1826 0xBA34323D,
1827 0xFFFFFF3D,
1828 },
1829 {
1830 0xE1ABEC2A,
1831 0xE1EAEC2A,
1832 0xFFFFFF2A,
1833 },
1834 {
1835 0xBCEBE4D7,
1836 0xBC65E4D7,
1837 0xFFFFFFD7,
1838 },
1839 },
1840 .dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1841 .expected = {
1842 {
1843 0x00C1323D,
1844 0x323DBA00,
1845 0xBA340000,
1846 0xFF00003D,
1847 },
1848 {
1849 0x00ABEC2A,
1850 0xEC2AE100,
1851 0xE1EA0000,
1852 0xFF00002A,
1853 },
1854 {
1855 0x00EBE4D7,
1856 0xE4D7BC00,
1857 0xBC650000,
1858 0xFF0000D7,
1859 },
1860 },
1861 },
1862 };
1863
fb_memcpy_case_desc(struct fb_memcpy_case * t,char * desc)1864 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1865 {
1866 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1867 }
1868
1869 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1870
drm_test_fb_memcpy(struct kunit * test)1871 static void drm_test_fb_memcpy(struct kunit *test)
1872 {
1873 const struct fb_memcpy_case *params = test->param_value;
1874 size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1875 u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1876 __le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1877 __le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1878 struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1879 struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1880
1881 struct drm_framebuffer fb = {
1882 .format = drm_format_info(params->format),
1883 };
1884
1885 memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1886
1887 for (size_t i = 0; i < fb.format->num_planes; i++) {
1888 dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1889 ¶ms->clip, i);
1890 KUNIT_ASSERT_GT(test, dst_size[i], 0);
1891
1892 buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1893 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1894 iosys_map_set_vaddr(&dst[i], buf[i]);
1895
1896 src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1897 iosys_map_set_vaddr(&src[i], src_cp[i]);
1898 }
1899
1900 const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1901 params->dst_pitches;
1902
1903 drm_fb_memcpy(dst, dst_pitches, src, &fb, ¶ms->clip);
1904
1905 for (size_t i = 0; i < fb.format->num_planes; i++) {
1906 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1907 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1908 "Failed expectation on plane %zu", i);
1909
1910 memset(buf[i], 0, dst_size[i]);
1911 }
1912
1913 int blit_result;
1914
1915 blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, ¶ms->clip,
1916 &fmtcnv_state);
1917
1918 KUNIT_EXPECT_FALSE(test, blit_result);
1919 for (size_t i = 0; i < fb.format->num_planes; i++) {
1920 expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1921 KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1922 "Failed expectation on plane %zu", i);
1923 }
1924 }
1925
1926 static struct kunit_case drm_format_helper_test_cases[] = {
1927 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1928 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1929 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1930 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1931 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1932 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1933 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1934 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params),
1935 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1936 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1937 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1938 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1939 KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1940 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1941 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1942 KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1943 KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),
1944 KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1945 {}
1946 };
1947
1948 static struct kunit_suite drm_format_helper_test_suite = {
1949 .name = "drm_format_helper_test",
1950 .test_cases = drm_format_helper_test_cases,
1951 };
1952
1953 kunit_test_suite(drm_format_helper_test_suite);
1954
1955 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1956 MODULE_LICENSE("GPL");
1957 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
1958