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