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_file.h>
7 : #include <drm/drm_format_helper.h>
8 : #include <drm/drm_fourcc.h>
9 : #include <drm/drm_framebuffer.h>
10 : #include <drm/drm_gem_framebuffer_helper.h>
11 : #include <drm/drm_mode.h>
12 : #include <drm/drm_print.h>
13 : #include <drm/drm_rect.h>
14 :
15 : #include "../drm_crtc_internal.h"
16 :
17 : #define TEST_BUF_SIZE 50
18 :
19 : struct convert_to_gray8_result {
20 : unsigned int dst_pitch;
21 : const u8 expected[TEST_BUF_SIZE];
22 : };
23 :
24 : struct convert_to_rgb332_result {
25 : unsigned int dst_pitch;
26 : const u8 expected[TEST_BUF_SIZE];
27 : };
28 :
29 : struct convert_to_rgb565_result {
30 : unsigned int dst_pitch;
31 : const u16 expected[TEST_BUF_SIZE];
32 : const u16 expected_swab[TEST_BUF_SIZE];
33 : };
34 :
35 : struct convert_to_xrgb1555_result {
36 : unsigned int dst_pitch;
37 : const u16 expected[TEST_BUF_SIZE];
38 : };
39 :
40 : struct convert_to_argb1555_result {
41 : unsigned int dst_pitch;
42 : const u16 expected[TEST_BUF_SIZE];
43 : };
44 :
45 : struct convert_to_rgba5551_result {
46 : unsigned int dst_pitch;
47 : const u16 expected[TEST_BUF_SIZE];
48 : };
49 :
50 : struct convert_to_rgb888_result {
51 : unsigned int dst_pitch;
52 : const u8 expected[TEST_BUF_SIZE];
53 : };
54 :
55 : struct convert_to_argb8888_result {
56 : unsigned int dst_pitch;
57 : const u32 expected[TEST_BUF_SIZE];
58 : };
59 :
60 : struct convert_to_xrgb2101010_result {
61 : unsigned int dst_pitch;
62 : const u32 expected[TEST_BUF_SIZE];
63 : };
64 :
65 : struct convert_to_argb2101010_result {
66 : unsigned int dst_pitch;
67 : const u32 expected[TEST_BUF_SIZE];
68 : };
69 :
70 : struct convert_to_mono_result {
71 : unsigned int dst_pitch;
72 : const u8 expected[TEST_BUF_SIZE];
73 : };
74 :
75 : struct convert_xrgb8888_case {
76 : const char *name;
77 : unsigned int pitch;
78 : struct drm_rect clip;
79 : const u32 xrgb8888[TEST_BUF_SIZE];
80 : struct convert_to_gray8_result gray8_result;
81 : struct convert_to_rgb332_result rgb332_result;
82 : struct convert_to_rgb565_result rgb565_result;
83 : struct convert_to_xrgb1555_result xrgb1555_result;
84 : struct convert_to_argb1555_result argb1555_result;
85 : struct convert_to_rgba5551_result rgba5551_result;
86 : struct convert_to_rgb888_result rgb888_result;
87 : struct convert_to_argb8888_result argb8888_result;
88 : struct convert_to_xrgb2101010_result xrgb2101010_result;
89 : struct convert_to_argb2101010_result argb2101010_result;
90 : struct convert_to_mono_result mono_result;
91 : };
92 :
93 : static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
94 : {
95 : .name = "single_pixel_source_buffer",
96 : .pitch = 1 * 4,
97 : .clip = DRM_RECT_INIT(0, 0, 1, 1),
98 : .xrgb8888 = { 0x01FF0000 },
99 : .gray8_result = {
100 : .dst_pitch = 0,
101 : .expected = { 0x4C },
102 : },
103 : .rgb332_result = {
104 : .dst_pitch = 0,
105 : .expected = { 0xE0 },
106 : },
107 : .rgb565_result = {
108 : .dst_pitch = 0,
109 : .expected = { 0xF800 },
110 : .expected_swab = { 0x00F8 },
111 : },
112 : .xrgb1555_result = {
113 : .dst_pitch = 0,
114 : .expected = { 0x7C00 },
115 : },
116 : .argb1555_result = {
117 : .dst_pitch = 0,
118 : .expected = { 0xFC00 },
119 : },
120 : .rgba5551_result = {
121 : .dst_pitch = 0,
122 : .expected = { 0xF801 },
123 : },
124 : .rgb888_result = {
125 : .dst_pitch = 0,
126 : .expected = { 0x00, 0x00, 0xFF },
127 : },
128 : .argb8888_result = {
129 : .dst_pitch = 0,
130 : .expected = { 0xFFFF0000 },
131 : },
132 : .xrgb2101010_result = {
133 : .dst_pitch = 0,
134 : .expected = { 0x3FF00000 },
135 : },
136 : .argb2101010_result = {
137 : .dst_pitch = 0,
138 : .expected = { 0xFFF00000 },
139 : },
140 : .mono_result = {
141 : .dst_pitch = 0,
142 : .expected = { 0b0 },
143 : },
144 : },
145 : {
146 : .name = "single_pixel_clip_rectangle",
147 : .pitch = 2 * 4,
148 : .clip = DRM_RECT_INIT(1, 1, 1, 1),
149 : .xrgb8888 = {
150 : 0x00000000, 0x00000000,
151 : 0x00000000, 0x10FF0000,
152 : },
153 : .gray8_result = {
154 : .dst_pitch = 0,
155 : .expected = { 0x4C },
156 : },
157 : .rgb332_result = {
158 : .dst_pitch = 0,
159 : .expected = { 0xE0 },
160 : },
161 : .rgb565_result = {
162 : .dst_pitch = 0,
163 : .expected = { 0xF800 },
164 : .expected_swab = { 0x00F8 },
165 : },
166 : .xrgb1555_result = {
167 : .dst_pitch = 0,
168 : .expected = { 0x7C00 },
169 : },
170 : .argb1555_result = {
171 : .dst_pitch = 0,
172 : .expected = { 0xFC00 },
173 : },
174 : .rgba5551_result = {
175 : .dst_pitch = 0,
176 : .expected = { 0xF801 },
177 : },
178 : .rgb888_result = {
179 : .dst_pitch = 0,
180 : .expected = { 0x00, 0x00, 0xFF },
181 : },
182 : .argb8888_result = {
183 : .dst_pitch = 0,
184 : .expected = { 0xFFFF0000 },
185 : },
186 : .xrgb2101010_result = {
187 : .dst_pitch = 0,
188 : .expected = { 0x3FF00000 },
189 : },
190 : .argb2101010_result = {
191 : .dst_pitch = 0,
192 : .expected = { 0xFFF00000 },
193 : },
194 : .mono_result = {
195 : .dst_pitch = 0,
196 : .expected = { 0b0 },
197 : },
198 : },
199 : {
200 : /* Well known colors: White, black, red, green, blue, magenta,
201 : * yellow and cyan. Different values for the X in XRGB8888 to
202 : * make sure it is ignored. Partial clip area.
203 : */
204 : .name = "well_known_colors",
205 : .pitch = 4 * 4,
206 : .clip = DRM_RECT_INIT(1, 1, 2, 4),
207 : .xrgb8888 = {
208 : 0x00000000, 0x00000000, 0x00000000, 0x00000000,
209 : 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
210 : 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
211 : 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
212 : 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
213 : },
214 : .gray8_result = {
215 : .dst_pitch = 0,
216 : .expected = {
217 : 0xFF, 0x00,
218 : 0x4C, 0x99,
219 : 0x19, 0x66,
220 : 0xE5, 0xB2,
221 : },
222 : },
223 : .rgb332_result = {
224 : .dst_pitch = 0,
225 : .expected = {
226 : 0xFF, 0x00,
227 : 0xE0, 0x1C,
228 : 0x03, 0xE3,
229 : 0xFC, 0x1F,
230 : },
231 : },
232 : .rgb565_result = {
233 : .dst_pitch = 0,
234 : .expected = {
235 : 0xFFFF, 0x0000,
236 : 0xF800, 0x07E0,
237 : 0x001F, 0xF81F,
238 : 0xFFE0, 0x07FF,
239 : },
240 : .expected_swab = {
241 : 0xFFFF, 0x0000,
242 : 0x00F8, 0xE007,
243 : 0x1F00, 0x1FF8,
244 : 0xE0FF, 0xFF07,
245 : },
246 : },
247 : .xrgb1555_result = {
248 : .dst_pitch = 0,
249 : .expected = {
250 : 0x7FFF, 0x0000,
251 : 0x7C00, 0x03E0,
252 : 0x001F, 0x7C1F,
253 : 0x7FE0, 0x03FF,
254 : },
255 : },
256 : .argb1555_result = {
257 : .dst_pitch = 0,
258 : .expected = {
259 : 0xFFFF, 0x8000,
260 : 0xFC00, 0x83E0,
261 : 0x801F, 0xFC1F,
262 : 0xFFE0, 0x83FF,
263 : },
264 : },
265 : .rgba5551_result = {
266 : .dst_pitch = 0,
267 : .expected = {
268 : 0xFFFF, 0x0001,
269 : 0xF801, 0x07C1,
270 : 0x003F, 0xF83F,
271 : 0xFFC1, 0x07FF,
272 : },
273 : },
274 : .rgb888_result = {
275 : .dst_pitch = 0,
276 : .expected = {
277 : 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
278 : 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
279 : 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
280 : 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
281 : },
282 : },
283 : .argb8888_result = {
284 : .dst_pitch = 0,
285 : .expected = {
286 : 0xFFFFFFFF, 0xFF000000,
287 : 0xFFFF0000, 0xFF00FF00,
288 : 0xFF0000FF, 0xFFFF00FF,
289 : 0xFFFFFF00, 0xFF00FFFF,
290 : },
291 : },
292 : .xrgb2101010_result = {
293 : .dst_pitch = 0,
294 : .expected = {
295 : 0x3FFFFFFF, 0x00000000,
296 : 0x3FF00000, 0x000FFC00,
297 : 0x000003FF, 0x3FF003FF,
298 : 0x3FFFFC00, 0x000FFFFF,
299 : },
300 : },
301 : .argb2101010_result = {
302 : .dst_pitch = 0,
303 : .expected = {
304 : 0xFFFFFFFF, 0xC0000000,
305 : 0xFFF00000, 0xC00FFC00,
306 : 0xC00003FF, 0xFFF003FF,
307 : 0xFFFFFC00, 0xC00FFFFF,
308 : },
309 : },
310 : .mono_result = {
311 : .dst_pitch = 0,
312 : .expected = {
313 : 0b01,
314 : 0b10,
315 : 0b00,
316 : 0b11,
317 : },
318 : },
319 : },
320 : {
321 : /* Randomly picked colors. Full buffer within the clip area. */
322 : .name = "destination_pitch",
323 : .pitch = 3 * 4,
324 : .clip = DRM_RECT_INIT(0, 0, 3, 3),
325 : .xrgb8888 = {
326 : 0xA10E449C, 0xB1114D05, 0xC1A8F303,
327 : 0xD16CF073, 0xA20E449C, 0xB2114D05,
328 : 0xC2A80303, 0xD26CF073, 0xA30E449C,
329 : },
330 : .gray8_result = {
331 : .dst_pitch = 5,
332 : .expected = {
333 : 0x3C, 0x33, 0xC4, 0x00, 0x00,
334 : 0xBB, 0x3C, 0x33, 0x00, 0x00,
335 : 0x34, 0xBB, 0x3C, 0x00, 0x00,
336 : },
337 : },
338 : .rgb332_result = {
339 : .dst_pitch = 5,
340 : .expected = {
341 : 0x0A, 0x08, 0xBC, 0x00, 0x00,
342 : 0x7D, 0x0A, 0x08, 0x00, 0x00,
343 : 0xA0, 0x7D, 0x0A, 0x00, 0x00,
344 : },
345 : },
346 : .rgb565_result = {
347 : .dst_pitch = 10,
348 : .expected = {
349 : 0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
350 : 0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
351 : 0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
352 : },
353 : .expected_swab = {
354 : 0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
355 : 0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
356 : 0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
357 : },
358 : },
359 : .xrgb1555_result = {
360 : .dst_pitch = 10,
361 : .expected = {
362 : 0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
363 : 0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
364 : 0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
365 : },
366 : },
367 : .argb1555_result = {
368 : .dst_pitch = 10,
369 : .expected = {
370 : 0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
371 : 0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
372 : 0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
373 : },
374 : },
375 : .rgba5551_result = {
376 : .dst_pitch = 10,
377 : .expected = {
378 : 0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
379 : 0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
380 : 0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
381 : },
382 : },
383 : .rgb888_result = {
384 : .dst_pitch = 15,
385 : .expected = {
386 : 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0xF3, 0xA8,
387 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 : 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
389 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 : 0x03, 0x03, 0xA8, 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E,
391 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 : },
393 : },
394 : .argb8888_result = {
395 : .dst_pitch = 20,
396 : .expected = {
397 : 0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
398 : 0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
399 : 0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
400 : },
401 : },
402 : .xrgb2101010_result = {
403 : .dst_pitch = 20,
404 : .expected = {
405 : 0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
406 : 0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
407 : 0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
408 : },
409 : },
410 : .argb2101010_result = {
411 : .dst_pitch = 20,
412 : .expected = {
413 : 0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
414 : 0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
415 : 0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
416 : },
417 : },
418 : .mono_result = {
419 : .dst_pitch = 2,
420 : .expected = {
421 : 0b100, 0b000,
422 : 0b001, 0b000,
423 : 0b010, 0b000,
424 : },
425 : },
426 : },
427 : };
428 :
429 : /*
430 : * conversion_buf_size - Return the destination buffer size required to convert
431 : * between formats.
432 : * @dst_format: destination buffer pixel format (DRM_FORMAT_*)
433 : * @dst_pitch: Number of bytes between two consecutive scanlines within dst
434 : * @clip: Clip rectangle area to convert
435 : *
436 : * Returns:
437 : * The size of the destination buffer or negative value on error.
438 : */
439 44 : static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
440 : const struct drm_rect *clip)
441 : {
442 44 : const struct drm_format_info *dst_fi = drm_format_info(dst_format);
443 :
444 44 : if (!dst_fi)
445 : return -EINVAL;
446 :
447 44 : if (!dst_pitch)
448 66 : dst_pitch = drm_format_info_min_pitch(dst_fi, 0, drm_rect_width(clip));
449 :
450 88 : return dst_pitch * drm_rect_height(clip);
451 : }
452 :
453 20 : static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
454 : {
455 20 : u16 *dst = NULL;
456 : int n;
457 :
458 40 : dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
459 20 : if (!dst)
460 : return NULL;
461 :
462 125 : for (n = 0; n < buf_size; n++)
463 125 : dst[n] = le16_to_cpu(buf[n]);
464 :
465 : return dst;
466 : }
467 :
468 12 : static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
469 : {
470 12 : u32 *dst = NULL;
471 : int n;
472 :
473 24 : dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
474 12 : if (!dst)
475 : return NULL;
476 :
477 75 : for (n = 0; n < buf_size; n++)
478 75 : dst[n] = le32_to_cpu((__force __le32)buf[n]);
479 :
480 : return dst;
481 : }
482 :
483 44 : static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
484 : {
485 44 : __le32 *dst = NULL;
486 : int n;
487 :
488 88 : dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
489 44 : if (!dst)
490 : return NULL;
491 :
492 2200 : for (n = 0; n < buf_size; n++)
493 2200 : dst[n] = cpu_to_le32(buf[n]);
494 :
495 : return dst;
496 : }
497 :
498 44 : static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
499 : char *desc)
500 : {
501 44 : strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
502 44 : }
503 :
504 55 : KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
505 : convert_xrgb8888_case_desc);
506 :
507 4 : static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
508 : {
509 4 : const struct convert_xrgb8888_case *params = test->param_value;
510 4 : const struct convert_to_gray8_result *result = ¶ms->gray8_result;
511 : size_t dst_size;
512 4 : u8 *buf = NULL;
513 4 : __le32 *xrgb8888 = NULL;
514 : struct iosys_map dst, src;
515 :
516 12 : struct drm_framebuffer fb = {
517 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
518 4 : .pitches = { params->pitch, 0, 0 },
519 : };
520 :
521 4 : dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
522 : ¶ms->clip);
523 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
524 :
525 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
526 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
527 4 : iosys_map_set_vaddr(&dst, buf);
528 :
529 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
530 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
531 4 : iosys_map_set_vaddr(&src, xrgb8888);
532 :
533 4 : drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
534 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
535 4 : }
536 :
537 4 : static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
538 : {
539 4 : const struct convert_xrgb8888_case *params = test->param_value;
540 4 : const struct convert_to_rgb332_result *result = ¶ms->rgb332_result;
541 : size_t dst_size;
542 4 : u8 *buf = NULL;
543 4 : __le32 *xrgb8888 = NULL;
544 : struct iosys_map dst, src;
545 :
546 12 : struct drm_framebuffer fb = {
547 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
548 4 : .pitches = { params->pitch, 0, 0 },
549 : };
550 :
551 4 : dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
552 : ¶ms->clip);
553 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
554 :
555 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
556 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
557 4 : iosys_map_set_vaddr(&dst, buf);
558 :
559 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
560 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
561 4 : iosys_map_set_vaddr(&src, xrgb8888);
562 :
563 4 : drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
564 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
565 4 : }
566 :
567 4 : static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
568 : {
569 4 : const struct convert_xrgb8888_case *params = test->param_value;
570 4 : const struct convert_to_rgb565_result *result = ¶ms->rgb565_result;
571 : size_t dst_size;
572 4 : u16 *buf = NULL;
573 4 : __le32 *xrgb8888 = NULL;
574 : struct iosys_map dst, src;
575 :
576 12 : struct drm_framebuffer fb = {
577 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
578 4 : .pitches = { params->pitch, 0, 0 },
579 : };
580 :
581 4 : dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
582 : ¶ms->clip);
583 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
584 :
585 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
586 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
587 4 : iosys_map_set_vaddr(&dst, buf);
588 :
589 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
590 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
591 4 : iosys_map_set_vaddr(&src, xrgb8888);
592 :
593 4 : drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, false);
594 4 : buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
595 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
596 :
597 4 : buf = dst.vaddr; /* restore original value of buf */
598 4 : drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true);
599 4 : buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
600 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
601 4 : }
602 :
603 4 : static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
604 : {
605 4 : const struct convert_xrgb8888_case *params = test->param_value;
606 4 : const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result;
607 : size_t dst_size;
608 4 : u16 *buf = NULL;
609 4 : __le32 *xrgb8888 = NULL;
610 : struct iosys_map dst, src;
611 :
612 12 : struct drm_framebuffer fb = {
613 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
614 4 : .pitches = { params->pitch, 0, 0 },
615 : };
616 :
617 4 : dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
618 : ¶ms->clip);
619 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
620 :
621 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
622 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
623 4 : iosys_map_set_vaddr(&dst, buf);
624 :
625 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
626 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
627 4 : iosys_map_set_vaddr(&src, xrgb8888);
628 :
629 4 : drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
630 4 : buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
631 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
632 4 : }
633 :
634 4 : static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
635 : {
636 4 : const struct convert_xrgb8888_case *params = test->param_value;
637 4 : const struct convert_to_argb1555_result *result = ¶ms->argb1555_result;
638 : size_t dst_size;
639 4 : u16 *buf = NULL;
640 4 : __le32 *xrgb8888 = NULL;
641 : struct iosys_map dst, src;
642 :
643 12 : struct drm_framebuffer fb = {
644 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
645 4 : .pitches = { params->pitch, 0, 0 },
646 : };
647 :
648 4 : dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
649 : ¶ms->clip);
650 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
651 :
652 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
653 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
654 4 : iosys_map_set_vaddr(&dst, buf);
655 :
656 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
657 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
658 4 : iosys_map_set_vaddr(&src, xrgb8888);
659 :
660 4 : drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
661 4 : buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
662 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
663 4 : }
664 :
665 4 : static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
666 : {
667 4 : const struct convert_xrgb8888_case *params = test->param_value;
668 4 : const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result;
669 : size_t dst_size;
670 4 : u16 *buf = NULL;
671 4 : __le32 *xrgb8888 = NULL;
672 : struct iosys_map dst, src;
673 :
674 12 : struct drm_framebuffer fb = {
675 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
676 4 : .pitches = { params->pitch, 0, 0 },
677 : };
678 :
679 4 : dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
680 : ¶ms->clip);
681 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
682 :
683 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
684 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
685 4 : iosys_map_set_vaddr(&dst, buf);
686 :
687 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
688 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
689 4 : iosys_map_set_vaddr(&src, xrgb8888);
690 :
691 4 : drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
692 4 : buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
693 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
694 4 : }
695 :
696 4 : static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
697 : {
698 4 : const struct convert_xrgb8888_case *params = test->param_value;
699 4 : const struct convert_to_rgb888_result *result = ¶ms->rgb888_result;
700 : size_t dst_size;
701 4 : u8 *buf = NULL;
702 4 : __le32 *xrgb8888 = NULL;
703 : struct iosys_map dst, src;
704 :
705 12 : struct drm_framebuffer fb = {
706 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
707 4 : .pitches = { params->pitch, 0, 0 },
708 : };
709 :
710 4 : dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
711 : ¶ms->clip);
712 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
713 :
714 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
715 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
716 4 : iosys_map_set_vaddr(&dst, buf);
717 :
718 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
719 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
720 4 : iosys_map_set_vaddr(&src, xrgb8888);
721 :
722 : /*
723 : * RGB888 expected results are already in little-endian
724 : * order, so there's no need to convert the test output.
725 : */
726 4 : drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
727 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
728 4 : }
729 :
730 4 : static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
731 : {
732 4 : const struct convert_xrgb8888_case *params = test->param_value;
733 4 : const struct convert_to_argb8888_result *result = ¶ms->argb8888_result;
734 : size_t dst_size;
735 4 : u32 *buf = NULL;
736 4 : __le32 *xrgb8888 = NULL;
737 : struct iosys_map dst, src;
738 :
739 12 : struct drm_framebuffer fb = {
740 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
741 4 : .pitches = { params->pitch, 0, 0 },
742 : };
743 :
744 4 : dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
745 : result->dst_pitch, ¶ms->clip);
746 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
747 :
748 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
749 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
750 4 : iosys_map_set_vaddr(&dst, buf);
751 :
752 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
753 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
754 4 : iosys_map_set_vaddr(&src, xrgb8888);
755 :
756 4 : drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
757 4 : buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
758 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
759 4 : }
760 :
761 4 : static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
762 : {
763 4 : const struct convert_xrgb8888_case *params = test->param_value;
764 4 : const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result;
765 : size_t dst_size;
766 4 : u32 *buf = NULL;
767 4 : __le32 *xrgb8888 = NULL;
768 : struct iosys_map dst, src;
769 :
770 12 : struct drm_framebuffer fb = {
771 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
772 4 : .pitches = { params->pitch, 0, 0 },
773 : };
774 :
775 4 : dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
776 : result->dst_pitch, ¶ms->clip);
777 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
778 :
779 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
780 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
781 4 : iosys_map_set_vaddr(&dst, buf);
782 :
783 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
784 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
785 4 : iosys_map_set_vaddr(&src, xrgb8888);
786 :
787 4 : drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
788 4 : buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
789 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
790 4 : }
791 :
792 4 : static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
793 : {
794 4 : const struct convert_xrgb8888_case *params = test->param_value;
795 4 : const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result;
796 : size_t dst_size;
797 4 : u32 *buf = NULL;
798 4 : __le32 *xrgb8888 = NULL;
799 : struct iosys_map dst, src;
800 :
801 12 : struct drm_framebuffer fb = {
802 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
803 4 : .pitches = { params->pitch, 0, 0 },
804 : };
805 :
806 4 : dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
807 : result->dst_pitch, ¶ms->clip);
808 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
809 :
810 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
811 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
812 4 : iosys_map_set_vaddr(&dst, buf);
813 :
814 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
815 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
816 4 : iosys_map_set_vaddr(&src, xrgb8888);
817 :
818 4 : drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
819 4 : buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
820 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
821 4 : }
822 :
823 4 : static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
824 : {
825 4 : const struct convert_xrgb8888_case *params = test->param_value;
826 4 : const struct convert_to_mono_result *result = ¶ms->mono_result;
827 : size_t dst_size;
828 4 : u8 *buf = NULL;
829 4 : __le32 *xrgb8888 = NULL;
830 : struct iosys_map dst, src;
831 :
832 12 : struct drm_framebuffer fb = {
833 4 : .format = drm_format_info(DRM_FORMAT_XRGB8888),
834 4 : .pitches = { params->pitch, 0, 0 },
835 : };
836 :
837 4 : dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip);
838 :
839 4 : KUNIT_ASSERT_GT(test, dst_size, 0);
840 :
841 4 : buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
842 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
843 4 : iosys_map_set_vaddr(&dst, buf);
844 :
845 4 : xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
846 8 : KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
847 4 : iosys_map_set_vaddr(&src, xrgb8888);
848 :
849 4 : drm_fb_xrgb8888_to_mono(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip);
850 4 : KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
851 4 : }
852 :
853 : static struct kunit_case drm_format_helper_test_cases[] = {
854 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
855 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
856 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
857 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
858 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
859 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
860 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
861 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
862 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
863 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
864 : KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
865 : {}
866 : };
867 :
868 : static struct kunit_suite drm_format_helper_test_suite = {
869 : .name = "drm_format_helper_test",
870 : .test_cases = drm_format_helper_test_cases,
871 : };
872 :
873 : kunit_test_suite(drm_format_helper_test_suite);
874 :
875 : MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
876 : MODULE_LICENSE("GPL");
877 : MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
|