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 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch, 440 const struct drm_rect *clip) 441 { 442 const struct drm_format_info *dst_fi = drm_format_info(dst_format); 443 444 if (!dst_fi) 445 return -EINVAL; 446 447 if (!dst_pitch) 448 dst_pitch = drm_format_info_min_pitch(dst_fi, 0, drm_rect_width(clip)); 449 450 return dst_pitch * drm_rect_height(clip); 451 } 452 453 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size) 454 { 455 u16 *dst = NULL; 456 int n; 457 458 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 459 if (!dst) 460 return NULL; 461 462 for (n = 0; n < buf_size; n++) 463 dst[n] = le16_to_cpu(buf[n]); 464 465 return dst; 466 } 467 468 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size) 469 { 470 u32 *dst = NULL; 471 int n; 472 473 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 474 if (!dst) 475 return NULL; 476 477 for (n = 0; n < buf_size; n++) 478 dst[n] = le32_to_cpu((__force __le32)buf[n]); 479 480 return dst; 481 } 482 483 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size) 484 { 485 __le32 *dst = NULL; 486 int n; 487 488 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 489 if (!dst) 490 return NULL; 491 492 for (n = 0; n < buf_size; n++) 493 dst[n] = cpu_to_le32(buf[n]); 494 495 return dst; 496 } 497 498 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t, 499 char *desc) 500 { 501 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 502 } 503 504 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases, 505 convert_xrgb8888_case_desc); 506 507 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test) 508 { 509 const struct convert_xrgb8888_case *params = test->param_value; 510 const struct convert_to_gray8_result *result = ¶ms->gray8_result; 511 size_t dst_size; 512 u8 *buf = NULL; 513 __le32 *xrgb8888 = NULL; 514 struct iosys_map dst, src; 515 516 struct drm_framebuffer fb = { 517 .format = drm_format_info(DRM_FORMAT_XRGB8888), 518 .pitches = { params->pitch, 0, 0 }, 519 }; 520 521 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch, 522 ¶ms->clip); 523 KUNIT_ASSERT_GT(test, dst_size, 0); 524 525 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 526 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 527 iosys_map_set_vaddr(&dst, buf); 528 529 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 530 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 531 iosys_map_set_vaddr(&src, xrgb8888); 532 533 drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 534 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 535 } 536 537 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test) 538 { 539 const struct convert_xrgb8888_case *params = test->param_value; 540 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result; 541 size_t dst_size; 542 u8 *buf = NULL; 543 __le32 *xrgb8888 = NULL; 544 struct iosys_map dst, src; 545 546 struct drm_framebuffer fb = { 547 .format = drm_format_info(DRM_FORMAT_XRGB8888), 548 .pitches = { params->pitch, 0, 0 }, 549 }; 550 551 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch, 552 ¶ms->clip); 553 KUNIT_ASSERT_GT(test, dst_size, 0); 554 555 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 556 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 557 iosys_map_set_vaddr(&dst, buf); 558 559 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 560 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 561 iosys_map_set_vaddr(&src, xrgb8888); 562 563 drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 564 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 565 } 566 567 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test) 568 { 569 const struct convert_xrgb8888_case *params = test->param_value; 570 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result; 571 size_t dst_size; 572 u16 *buf = NULL; 573 __le32 *xrgb8888 = NULL; 574 struct iosys_map dst, src; 575 576 struct drm_framebuffer fb = { 577 .format = drm_format_info(DRM_FORMAT_XRGB8888), 578 .pitches = { params->pitch, 0, 0 }, 579 }; 580 581 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch, 582 ¶ms->clip); 583 KUNIT_ASSERT_GT(test, dst_size, 0); 584 585 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 586 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 587 iosys_map_set_vaddr(&dst, buf); 588 589 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 590 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 591 iosys_map_set_vaddr(&src, xrgb8888); 592 593 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, false); 594 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 595 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 596 597 buf = dst.vaddr; /* restore original value of buf */ 598 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true); 599 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 600 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size); 601 } 602 603 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test) 604 { 605 const struct convert_xrgb8888_case *params = test->param_value; 606 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result; 607 size_t dst_size; 608 u16 *buf = NULL; 609 __le32 *xrgb8888 = NULL; 610 struct iosys_map dst, src; 611 612 struct drm_framebuffer fb = { 613 .format = drm_format_info(DRM_FORMAT_XRGB8888), 614 .pitches = { params->pitch, 0, 0 }, 615 }; 616 617 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch, 618 ¶ms->clip); 619 KUNIT_ASSERT_GT(test, dst_size, 0); 620 621 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 622 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 623 iosys_map_set_vaddr(&dst, buf); 624 625 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 626 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 627 iosys_map_set_vaddr(&src, xrgb8888); 628 629 drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 630 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 631 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 632 } 633 634 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test) 635 { 636 const struct convert_xrgb8888_case *params = test->param_value; 637 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result; 638 size_t dst_size; 639 u16 *buf = NULL; 640 __le32 *xrgb8888 = NULL; 641 struct iosys_map dst, src; 642 643 struct drm_framebuffer fb = { 644 .format = drm_format_info(DRM_FORMAT_XRGB8888), 645 .pitches = { params->pitch, 0, 0 }, 646 }; 647 648 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch, 649 ¶ms->clip); 650 KUNIT_ASSERT_GT(test, dst_size, 0); 651 652 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 653 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 654 iosys_map_set_vaddr(&dst, buf); 655 656 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 657 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 658 iosys_map_set_vaddr(&src, xrgb8888); 659 660 drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 661 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 662 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 663 } 664 665 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test) 666 { 667 const struct convert_xrgb8888_case *params = test->param_value; 668 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result; 669 size_t dst_size; 670 u16 *buf = NULL; 671 __le32 *xrgb8888 = NULL; 672 struct iosys_map dst, src; 673 674 struct drm_framebuffer fb = { 675 .format = drm_format_info(DRM_FORMAT_XRGB8888), 676 .pitches = { params->pitch, 0, 0 }, 677 }; 678 679 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch, 680 ¶ms->clip); 681 KUNIT_ASSERT_GT(test, dst_size, 0); 682 683 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 684 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 685 iosys_map_set_vaddr(&dst, buf); 686 687 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 688 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 689 iosys_map_set_vaddr(&src, xrgb8888); 690 691 drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 692 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 693 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 694 } 695 696 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test) 697 { 698 const struct convert_xrgb8888_case *params = test->param_value; 699 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result; 700 size_t dst_size; 701 u8 *buf = NULL; 702 __le32 *xrgb8888 = NULL; 703 struct iosys_map dst, src; 704 705 struct drm_framebuffer fb = { 706 .format = drm_format_info(DRM_FORMAT_XRGB8888), 707 .pitches = { params->pitch, 0, 0 }, 708 }; 709 710 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch, 711 ¶ms->clip); 712 KUNIT_ASSERT_GT(test, dst_size, 0); 713 714 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 715 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 716 iosys_map_set_vaddr(&dst, buf); 717 718 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 719 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 720 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 drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 727 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 728 } 729 730 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test) 731 { 732 const struct convert_xrgb8888_case *params = test->param_value; 733 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result; 734 size_t dst_size; 735 u32 *buf = NULL; 736 __le32 *xrgb8888 = NULL; 737 struct iosys_map dst, src; 738 739 struct drm_framebuffer fb = { 740 .format = drm_format_info(DRM_FORMAT_XRGB8888), 741 .pitches = { params->pitch, 0, 0 }, 742 }; 743 744 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888, 745 result->dst_pitch, ¶ms->clip); 746 KUNIT_ASSERT_GT(test, dst_size, 0); 747 748 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 749 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 750 iosys_map_set_vaddr(&dst, buf); 751 752 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 753 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 754 iosys_map_set_vaddr(&src, xrgb8888); 755 756 drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 757 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 758 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 759 } 760 761 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) 762 { 763 const struct convert_xrgb8888_case *params = test->param_value; 764 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result; 765 size_t dst_size; 766 u32 *buf = NULL; 767 __le32 *xrgb8888 = NULL; 768 struct iosys_map dst, src; 769 770 struct drm_framebuffer fb = { 771 .format = drm_format_info(DRM_FORMAT_XRGB8888), 772 .pitches = { params->pitch, 0, 0 }, 773 }; 774 775 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010, 776 result->dst_pitch, ¶ms->clip); 777 KUNIT_ASSERT_GT(test, dst_size, 0); 778 779 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 780 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 781 iosys_map_set_vaddr(&dst, buf); 782 783 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 784 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 785 iosys_map_set_vaddr(&src, xrgb8888); 786 787 drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 788 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32)); 789 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 790 } 791 792 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test) 793 { 794 const struct convert_xrgb8888_case *params = test->param_value; 795 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result; 796 size_t dst_size; 797 u32 *buf = NULL; 798 __le32 *xrgb8888 = NULL; 799 struct iosys_map dst, src; 800 801 struct drm_framebuffer fb = { 802 .format = drm_format_info(DRM_FORMAT_XRGB8888), 803 .pitches = { params->pitch, 0, 0 }, 804 }; 805 806 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010, 807 result->dst_pitch, ¶ms->clip); 808 KUNIT_ASSERT_GT(test, dst_size, 0); 809 810 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 811 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 812 iosys_map_set_vaddr(&dst, buf); 813 814 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 815 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 816 iosys_map_set_vaddr(&src, xrgb8888); 817 818 drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 819 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 820 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 821 } 822 823 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test) 824 { 825 const struct convert_xrgb8888_case *params = test->param_value; 826 const struct convert_to_mono_result *result = ¶ms->mono_result; 827 size_t dst_size; 828 u8 *buf = NULL; 829 __le32 *xrgb8888 = NULL; 830 struct iosys_map dst, src; 831 832 struct drm_framebuffer fb = { 833 .format = drm_format_info(DRM_FORMAT_XRGB8888), 834 .pitches = { params->pitch, 0, 0 }, 835 }; 836 837 dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, ¶ms->clip); 838 839 KUNIT_ASSERT_GT(test, dst_size, 0); 840 841 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 842 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 843 iosys_map_set_vaddr(&dst, buf); 844 845 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 846 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 847 iosys_map_set_vaddr(&src, xrgb8888); 848 849 drm_fb_xrgb8888_to_mono(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 850 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 851 } 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>"); 878