1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test cases for the drm_rect functions 4 * 5 * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net> 6 */ 7 8 #include <kunit/test.h> 9 10 #include <drm/drm_rect.h> 11 #include <drm/drm_mode.h> 12 13 #include <linux/string_helpers.h> 14 #include <linux/errno.h> 15 16 static void drm_rect_compare(struct kunit *test, const struct drm_rect *r, 17 const struct drm_rect *expected) 18 { 19 KUNIT_EXPECT_EQ(test, r->x1, expected->x1); 20 KUNIT_EXPECT_EQ(test, r->y1, expected->y1); 21 KUNIT_EXPECT_EQ(test, drm_rect_width(r), drm_rect_width(expected)); 22 KUNIT_EXPECT_EQ(test, drm_rect_height(r), drm_rect_height(expected)); 23 } 24 25 static void drm_test_rect_clip_scaled_div_by_zero(struct kunit *test) 26 { 27 struct drm_rect src, dst, clip; 28 bool visible; 29 30 /* 31 * Make sure we don't divide by zero when dst 32 * width/height is zero and dst and clip do not intersect. 33 */ 34 drm_rect_init(&src, 0, 0, 0, 0); 35 drm_rect_init(&dst, 0, 0, 0, 0); 36 drm_rect_init(&clip, 1, 1, 1, 1); 37 visible = drm_rect_clip_scaled(&src, &dst, &clip); 38 39 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); 40 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 41 42 drm_rect_init(&src, 0, 0, 0, 0); 43 drm_rect_init(&dst, 3, 3, 0, 0); 44 drm_rect_init(&clip, 1, 1, 1, 1); 45 visible = drm_rect_clip_scaled(&src, &dst, &clip); 46 47 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); 48 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 49 } 50 51 static void drm_test_rect_clip_scaled_not_clipped(struct kunit *test) 52 { 53 struct drm_rect src, dst, clip; 54 bool visible; 55 56 /* 1:1 scaling */ 57 drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 58 drm_rect_init(&dst, 0, 0, 1, 1); 59 drm_rect_init(&clip, 0, 0, 1, 1); 60 61 visible = drm_rect_clip_scaled(&src, &dst, &clip); 62 63 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 64 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 65 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 66 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 67 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 68 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 69 70 /* 2:1 scaling */ 71 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 72 drm_rect_init(&dst, 0, 0, 1, 1); 73 drm_rect_init(&clip, 0, 0, 1, 1); 74 75 visible = drm_rect_clip_scaled(&src, &dst, &clip); 76 77 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || 78 src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); 79 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 80 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 81 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 82 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 83 84 /* 1:2 scaling */ 85 drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 86 drm_rect_init(&dst, 0, 0, 2, 2); 87 drm_rect_init(&clip, 0, 0, 2, 2); 88 89 visible = drm_rect_clip_scaled(&src, &dst, &clip); 90 91 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 92 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 93 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || 94 dst.y1 != 0 || dst.y2 != 2, "Destination badly clipped\n"); 95 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 96 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 97 } 98 99 static void drm_test_rect_clip_scaled_clipped(struct kunit *test) 100 { 101 struct drm_rect src, dst, clip; 102 bool visible; 103 104 /* 1:1 scaling top/left clip */ 105 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 106 drm_rect_init(&dst, 0, 0, 2, 2); 107 drm_rect_init(&clip, 0, 0, 1, 1); 108 109 visible = drm_rect_clip_scaled(&src, &dst, &clip); 110 111 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 112 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 113 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 114 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 115 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 116 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 117 118 /* 1:1 scaling bottom/right clip */ 119 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 120 drm_rect_init(&dst, 0, 0, 2, 2); 121 drm_rect_init(&clip, 1, 1, 1, 1); 122 123 visible = drm_rect_clip_scaled(&src, &dst, &clip); 124 125 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || 126 src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); 127 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || 128 dst.y2 != 2, "Destination badly clipped\n"); 129 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 130 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 131 132 /* 2:1 scaling top/left clip */ 133 drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 134 drm_rect_init(&dst, 0, 0, 2, 2); 135 drm_rect_init(&clip, 0, 0, 1, 1); 136 137 visible = drm_rect_clip_scaled(&src, &dst, &clip); 138 139 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || 140 src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); 141 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || 142 dst.y2 != 1, "Destination badly clipped\n"); 143 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 144 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 145 146 /* 2:1 scaling bottom/right clip */ 147 drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 148 drm_rect_init(&dst, 0, 0, 2, 2); 149 drm_rect_init(&clip, 1, 1, 1, 1); 150 151 visible = drm_rect_clip_scaled(&src, &dst, &clip); 152 153 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 2 << 16 || src.x2 != 4 << 16 || 154 src.y1 != 2 << 16 || src.y2 != 4 << 16, "Source badly clipped\n"); 155 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || 156 dst.y2 != 2, "Destination badly clipped\n"); 157 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 158 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 159 160 /* 1:2 scaling top/left clip */ 161 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 162 drm_rect_init(&dst, 0, 0, 4, 4); 163 drm_rect_init(&clip, 0, 0, 2, 2); 164 165 visible = drm_rect_clip_scaled(&src, &dst, &clip); 166 167 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 168 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 169 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || dst.y1 != 0 || 170 dst.y2 != 2, "Destination badly clipped\n"); 171 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 172 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 173 174 /* 1:2 scaling bottom/right clip */ 175 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 176 drm_rect_init(&dst, 0, 0, 4, 4); 177 drm_rect_init(&clip, 2, 2, 2, 2); 178 179 visible = drm_rect_clip_scaled(&src, &dst, &clip); 180 181 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || 182 src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); 183 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 2 || dst.x2 != 4 || dst.y1 != 2 || 184 dst.y2 != 4, "Destination badly clipped\n"); 185 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 186 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 187 } 188 189 static void drm_test_rect_clip_scaled_signed_vs_unsigned(struct kunit *test) 190 { 191 struct drm_rect src, dst, clip; 192 bool visible; 193 194 /* 195 * 'clip.x2 - dst.x1 >= dst width' could result a negative 196 * src rectangle width which is no longer expected by the 197 * code as it's using unsigned types. This could lead to 198 * the clipped source rectangle appering visible when it 199 * should have been fully clipped. Make sure both rectangles 200 * end up invisible. 201 */ 202 drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX); 203 drm_rect_init(&dst, 0, 0, 2, 2); 204 drm_rect_init(&clip, 3, 3, 1, 1); 205 206 visible = drm_rect_clip_scaled(&src, &dst, &clip); 207 208 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination should not be visible\n"); 209 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 210 } 211 212 struct drm_rect_intersect_case { 213 const char *description; 214 struct drm_rect r1, r2; 215 bool should_be_visible; 216 struct drm_rect expected_intersection; 217 }; 218 219 static const struct drm_rect_intersect_case drm_rect_intersect_cases[] = { 220 { 221 .description = "top-left x bottom-right", 222 .r1 = DRM_RECT_INIT(1, 1, 2, 2), 223 .r2 = DRM_RECT_INIT(0, 0, 2, 2), 224 .should_be_visible = true, 225 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1), 226 }, 227 { 228 .description = "top-right x bottom-left", 229 .r1 = DRM_RECT_INIT(0, 0, 2, 2), 230 .r2 = DRM_RECT_INIT(1, -1, 2, 2), 231 .should_be_visible = true, 232 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1), 233 }, 234 { 235 .description = "bottom-left x top-right", 236 .r1 = DRM_RECT_INIT(1, -1, 2, 2), 237 .r2 = DRM_RECT_INIT(0, 0, 2, 2), 238 .should_be_visible = true, 239 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1), 240 }, 241 { 242 .description = "bottom-right x top-left", 243 .r1 = DRM_RECT_INIT(0, 0, 2, 2), 244 .r2 = DRM_RECT_INIT(1, 1, 2, 2), 245 .should_be_visible = true, 246 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1), 247 }, 248 { 249 .description = "right x left", 250 .r1 = DRM_RECT_INIT(0, 0, 2, 1), 251 .r2 = DRM_RECT_INIT(1, 0, 3, 1), 252 .should_be_visible = true, 253 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1), 254 }, 255 { 256 .description = "left x right", 257 .r1 = DRM_RECT_INIT(1, 0, 3, 1), 258 .r2 = DRM_RECT_INIT(0, 0, 2, 1), 259 .should_be_visible = true, 260 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1), 261 }, 262 { 263 .description = "up x bottom", 264 .r1 = DRM_RECT_INIT(0, 0, 1, 2), 265 .r2 = DRM_RECT_INIT(0, -1, 1, 3), 266 .should_be_visible = true, 267 .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2), 268 }, 269 { 270 .description = "bottom x up", 271 .r1 = DRM_RECT_INIT(0, -1, 1, 3), 272 .r2 = DRM_RECT_INIT(0, 0, 1, 2), 273 .should_be_visible = true, 274 .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2), 275 }, 276 { 277 .description = "touching corner", 278 .r1 = DRM_RECT_INIT(0, 0, 1, 1), 279 .r2 = DRM_RECT_INIT(1, 1, 2, 2), 280 .should_be_visible = false, 281 .expected_intersection = DRM_RECT_INIT(1, 1, 0, 0), 282 }, 283 { 284 .description = "touching side", 285 .r1 = DRM_RECT_INIT(0, 0, 1, 1), 286 .r2 = DRM_RECT_INIT(1, 0, 1, 1), 287 .should_be_visible = false, 288 .expected_intersection = DRM_RECT_INIT(1, 0, 0, 1), 289 }, 290 { 291 .description = "equal rects", 292 .r1 = DRM_RECT_INIT(0, 0, 2, 2), 293 .r2 = DRM_RECT_INIT(0, 0, 2, 2), 294 .should_be_visible = true, 295 .expected_intersection = DRM_RECT_INIT(0, 0, 2, 2), 296 }, 297 { 298 .description = "inside another", 299 .r1 = DRM_RECT_INIT(0, 0, 2, 2), 300 .r2 = DRM_RECT_INIT(1, 1, 1, 1), 301 .should_be_visible = true, 302 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1), 303 }, 304 { 305 .description = "far away", 306 .r1 = DRM_RECT_INIT(0, 0, 1, 1), 307 .r2 = DRM_RECT_INIT(3, 6, 1, 1), 308 .should_be_visible = false, 309 .expected_intersection = DRM_RECT_INIT(3, 6, -2, -5), 310 }, 311 { 312 .description = "points intersecting", 313 .r1 = DRM_RECT_INIT(5, 10, 0, 0), 314 .r2 = DRM_RECT_INIT(5, 10, 0, 0), 315 .should_be_visible = false, 316 .expected_intersection = DRM_RECT_INIT(5, 10, 0, 0), 317 }, 318 { 319 .description = "points not intersecting", 320 .r1 = DRM_RECT_INIT(0, 0, 0, 0), 321 .r2 = DRM_RECT_INIT(5, 10, 0, 0), 322 .should_be_visible = false, 323 .expected_intersection = DRM_RECT_INIT(5, 10, -5, -10), 324 }, 325 }; 326 327 static void drm_rect_intersect_case_desc(const struct drm_rect_intersect_case *t, char *desc) 328 { 329 snprintf(desc, KUNIT_PARAM_DESC_SIZE, 330 "%s: " DRM_RECT_FMT " x " DRM_RECT_FMT, 331 t->description, DRM_RECT_ARG(&t->r1), DRM_RECT_ARG(&t->r2)); 332 } 333 334 KUNIT_ARRAY_PARAM(drm_rect_intersect, drm_rect_intersect_cases, drm_rect_intersect_case_desc); 335 336 static void drm_test_rect_intersect(struct kunit *test) 337 { 338 const struct drm_rect_intersect_case *params = test->param_value; 339 struct drm_rect r1_aux = params->r1; 340 bool visible; 341 342 visible = drm_rect_intersect(&r1_aux, ¶ms->r2); 343 344 KUNIT_EXPECT_EQ(test, visible, params->should_be_visible); 345 drm_rect_compare(test, &r1_aux, ¶ms->expected_intersection); 346 } 347 348 struct drm_rect_scale_case { 349 const char *name; 350 struct drm_rect src, dst; 351 int min_range, max_range; 352 int expected_scaling_factor; 353 }; 354 355 static const struct drm_rect_scale_case drm_rect_scale_cases[] = { 356 { 357 .name = "normal use", 358 .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16), 359 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16), 360 .min_range = 0, .max_range = INT_MAX, 361 .expected_scaling_factor = 2, 362 }, 363 { 364 .name = "out of max range", 365 .src = DRM_RECT_INIT(0, 0, 10 << 16, 10 << 16), 366 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16), 367 .min_range = 3, .max_range = 5, 368 .expected_scaling_factor = -ERANGE, 369 }, 370 { 371 .name = "out of min range", 372 .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16), 373 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16), 374 .min_range = 3, .max_range = 5, 375 .expected_scaling_factor = -ERANGE, 376 }, 377 { 378 .name = "zero dst", 379 .src = DRM_RECT_INIT(0, 0, 2 << 16, 2 << 16), 380 .dst = DRM_RECT_INIT(0, 0, 0 << 16, 0 << 16), 381 .min_range = 0, .max_range = INT_MAX, 382 .expected_scaling_factor = 0, 383 }, 384 { 385 .name = "negative src", 386 .src = DRM_RECT_INIT(0, 0, -(1 << 16), -(1 << 16)), 387 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16), 388 .min_range = 0, .max_range = INT_MAX, 389 .expected_scaling_factor = -EINVAL, 390 }, 391 { 392 .name = "negative dst", 393 .src = DRM_RECT_INIT(0, 0, 1 << 16, 1 << 16), 394 .dst = DRM_RECT_INIT(0, 0, -(1 << 16), -(1 << 16)), 395 .min_range = 0, .max_range = INT_MAX, 396 .expected_scaling_factor = -EINVAL, 397 }, 398 }; 399 400 static void drm_rect_scale_case_desc(const struct drm_rect_scale_case *t, char *desc) 401 { 402 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 403 } 404 405 KUNIT_ARRAY_PARAM(drm_rect_scale, drm_rect_scale_cases, drm_rect_scale_case_desc); 406 407 static void drm_test_rect_calc_hscale(struct kunit *test) 408 { 409 const struct drm_rect_scale_case *params = test->param_value; 410 int scaling_factor; 411 412 scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst, 413 params->min_range, params->max_range); 414 415 KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor); 416 } 417 418 static void drm_test_rect_calc_vscale(struct kunit *test) 419 { 420 const struct drm_rect_scale_case *params = test->param_value; 421 int scaling_factor; 422 423 scaling_factor = drm_rect_calc_vscale(¶ms->src, ¶ms->dst, 424 params->min_range, params->max_range); 425 426 KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor); 427 } 428 429 struct drm_rect_rotate_case { 430 const char *name; 431 unsigned int rotation; 432 struct drm_rect rect; 433 int width, height; 434 struct drm_rect expected; 435 }; 436 437 static const struct drm_rect_rotate_case drm_rect_rotate_cases[] = { 438 { 439 .name = "reflect-x", 440 .rotation = DRM_MODE_REFLECT_X, 441 .rect = DRM_RECT_INIT(0, 0, 5, 5), 442 .width = 5, .height = 10, 443 .expected = DRM_RECT_INIT(0, 0, 5, 5), 444 }, 445 { 446 .name = "reflect-y", 447 .rotation = DRM_MODE_REFLECT_Y, 448 .rect = DRM_RECT_INIT(2, 0, 5, 5), 449 .width = 5, .height = 10, 450 .expected = DRM_RECT_INIT(2, 5, 5, 5), 451 }, 452 { 453 .name = "rotate-0", 454 .rotation = DRM_MODE_ROTATE_0, 455 .rect = DRM_RECT_INIT(0, 2, 5, 5), 456 .width = 5, .height = 10, 457 .expected = DRM_RECT_INIT(0, 2, 5, 5), 458 }, 459 { 460 .name = "rotate-90", 461 .rotation = DRM_MODE_ROTATE_90, 462 .rect = DRM_RECT_INIT(0, 0, 5, 10), 463 .width = 5, .height = 10, 464 .expected = DRM_RECT_INIT(0, 0, 10, 5), 465 }, 466 { 467 .name = "rotate-180", 468 .rotation = DRM_MODE_ROTATE_180, 469 .rect = DRM_RECT_INIT(11, 3, 5, 10), 470 .width = 5, .height = 10, 471 .expected = DRM_RECT_INIT(-11, -3, 5, 10), 472 }, 473 { 474 .name = "rotate-270", 475 .rotation = DRM_MODE_ROTATE_270, 476 .rect = DRM_RECT_INIT(6, 3, 5, 10), 477 .width = 5, .height = 10, 478 .expected = DRM_RECT_INIT(-3, 6, 10, 5), 479 }, 480 }; 481 482 static void drm_rect_rotate_case_desc(const struct drm_rect_rotate_case *t, char *desc) 483 { 484 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 485 } 486 487 KUNIT_ARRAY_PARAM(drm_rect_rotate, drm_rect_rotate_cases, drm_rect_rotate_case_desc); 488 489 static void drm_test_rect_rotate(struct kunit *test) 490 { 491 const struct drm_rect_rotate_case *params = test->param_value; 492 struct drm_rect r = params->rect; 493 494 drm_rect_rotate(&r, params->width, params->height, params->rotation); 495 496 drm_rect_compare(test, &r, ¶ms->expected); 497 } 498 499 static void drm_test_rect_rotate_inv(struct kunit *test) 500 { 501 const struct drm_rect_rotate_case *params = test->param_value; 502 struct drm_rect r = params->expected; 503 504 drm_rect_rotate_inv(&r, params->width, params->height, params->rotation); 505 506 drm_rect_compare(test, &r, ¶ms->rect); 507 } 508 509 static struct kunit_case drm_rect_tests[] = { 510 KUNIT_CASE(drm_test_rect_clip_scaled_div_by_zero), 511 KUNIT_CASE(drm_test_rect_clip_scaled_not_clipped), 512 KUNIT_CASE(drm_test_rect_clip_scaled_clipped), 513 KUNIT_CASE(drm_test_rect_clip_scaled_signed_vs_unsigned), 514 KUNIT_CASE_PARAM(drm_test_rect_intersect, drm_rect_intersect_gen_params), 515 KUNIT_CASE_PARAM(drm_test_rect_calc_hscale, drm_rect_scale_gen_params), 516 KUNIT_CASE_PARAM(drm_test_rect_calc_vscale, drm_rect_scale_gen_params), 517 KUNIT_CASE_PARAM(drm_test_rect_rotate, drm_rect_rotate_gen_params), 518 KUNIT_CASE_PARAM(drm_test_rect_rotate_inv, drm_rect_rotate_gen_params), 519 { } 520 }; 521 522 static struct kunit_suite drm_rect_test_suite = { 523 .name = "drm_rect", 524 .test_cases = drm_rect_tests, 525 }; 526 527 kunit_test_suite(drm_rect_test_suite); 528 529 MODULE_LICENSE("GPL"); 530