1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Test case for drm_damage_helper functions 4 */ 5 6#define pr_fmt(fmt) "drm_damage_helper: " fmt 7 8#include <drm/drm_damage_helper.h> 9 10#include "test-drm_modeset_common.h" 11 12static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2, 13 int y2) 14{ 15 state->src.x1 = x1; 16 state->src.y1 = y1; 17 state->src.x2 = x2; 18 state->src.y2 = y2; 19} 20 21static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2, 22 int y2) 23{ 24 r->x1 = x1; 25 r->y1 = y1; 26 r->x2 = x2; 27 r->y2 = y2; 28} 29 30static void set_damage_blob(struct drm_property_blob *damage_blob, 31 struct drm_mode_rect *r, uint32_t size) 32{ 33 damage_blob->length = size; 34 damage_blob->data = r; 35} 36 37static void set_plane_damage(struct drm_plane_state *state, 38 struct drm_property_blob *damage_blob) 39{ 40 state->fb_damage_clips = damage_blob; 41} 42 43static bool check_damage_clip(struct drm_plane_state *state, struct drm_rect *r, 44 int x1, int y1, int x2, int y2) 45{ 46 /* 47 * Round down x1/y1 and round up x2/y2. This is because damage is not in 48 * 16.16 fixed point so to catch all pixels. 49 */ 50 int src_x1 = state->src.x1 >> 16; 51 int src_y1 = state->src.y1 >> 16; 52 int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF); 53 int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF); 54 55 if (x1 >= x2 || y1 >= y2) { 56 pr_err("Cannot have damage clip with no dimension.\n"); 57 return false; 58 } 59 60 if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) { 61 pr_err("Damage cannot be outside rounded plane src.\n"); 62 return false; 63 } 64 65 if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) { 66 pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r->y2); 67 return false; 68 } 69 70 return true; 71} 72 73int igt_damage_iter_no_damage(void *ignored) 74{ 75 struct drm_atomic_helper_damage_iter iter; 76 struct drm_plane_state old_state; 77 struct drm_rect clip; 78 uint32_t num_hits = 0; 79 80 struct drm_framebuffer fb = { 81 .width = 2048, 82 .height = 2048 83 }; 84 85 struct drm_plane_state state = { 86 .crtc = ZERO_SIZE_PTR, 87 .fb = &fb, 88 .visible = true, 89 }; 90 91 /* Plane src same as fb size. */ 92 set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16); 93 set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16); 94 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 95 drm_atomic_for_each_plane_damage(&iter, &clip) 96 num_hits++; 97 98 FAIL(num_hits != 1, "Should return plane src as damage."); 99 FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048)); 100 101 return 0; 102} 103 104int igt_damage_iter_no_damage_fractional_src(void *ignored) 105{ 106 struct drm_atomic_helper_damage_iter iter; 107 struct drm_plane_state old_state; 108 struct drm_rect clip; 109 uint32_t num_hits = 0; 110 111 struct drm_framebuffer fb = { 112 .width = 2048, 113 .height = 2048 114 }; 115 116 struct drm_plane_state state = { 117 .crtc = ZERO_SIZE_PTR, 118 .fb = &fb, 119 .visible = true, 120 }; 121 122 /* Plane src has fractional part. */ 123 set_plane_src(&old_state, 0x3fffe, 0x3fffe, 124 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 125 set_plane_src(&state, 0x3fffe, 0x3fffe, 126 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 127 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 128 drm_atomic_for_each_plane_damage(&iter, &clip) 129 num_hits++; 130 131 FAIL(num_hits != 1, "Should return rounded off plane src as damage."); 132 FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); 133 134 return 0; 135} 136 137int igt_damage_iter_no_damage_src_moved(void *ignored) 138{ 139 struct drm_atomic_helper_damage_iter iter; 140 struct drm_plane_state old_state; 141 struct drm_rect clip; 142 uint32_t num_hits = 0; 143 144 struct drm_framebuffer fb = { 145 .width = 2048, 146 .height = 2048 147 }; 148 149 struct drm_plane_state state = { 150 .crtc = ZERO_SIZE_PTR, 151 .fb = &fb, 152 .visible = true, 153 }; 154 155 /* Plane src moved since old plane state. */ 156 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 157 set_plane_src(&state, 10 << 16, 10 << 16, 158 (10 + 1024) << 16, (10 + 768) << 16); 159 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 160 drm_atomic_for_each_plane_damage(&iter, &clip) 161 num_hits++; 162 163 FAIL(num_hits != 1, "Should return plane src as damage."); 164 FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); 165 166 return 0; 167} 168 169int igt_damage_iter_no_damage_fractional_src_moved(void *ignored) 170{ 171 struct drm_atomic_helper_damage_iter iter; 172 struct drm_plane_state old_state; 173 struct drm_rect clip; 174 uint32_t num_hits = 0; 175 176 struct drm_framebuffer fb = { 177 .width = 2048, 178 .height = 2048 179 }; 180 181 struct drm_plane_state state = { 182 .crtc = ZERO_SIZE_PTR, 183 .fb = &fb, 184 .visible = true, 185 }; 186 187 /* Plane src has fractional part and it moved since old plane state. */ 188 set_plane_src(&old_state, 0x3fffe, 0x3fffe, 189 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 190 set_plane_src(&state, 0x40002, 0x40002, 191 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 192 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 193 drm_atomic_for_each_plane_damage(&iter, &clip) 194 num_hits++; 195 196 FAIL(num_hits != 1, "Should return plane src as damage."); 197 FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); 198 199 return 0; 200} 201 202int igt_damage_iter_no_damage_not_visible(void *ignored) 203{ 204 struct drm_atomic_helper_damage_iter iter; 205 struct drm_plane_state old_state; 206 struct drm_rect clip; 207 uint32_t num_hits = 0; 208 209 struct drm_framebuffer fb = { 210 .width = 2048, 211 .height = 2048 212 }; 213 214 struct drm_plane_state state = { 215 .crtc = ZERO_SIZE_PTR, 216 .fb = &fb, 217 .visible = false, 218 }; 219 220 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 221 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 222 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 223 drm_atomic_for_each_plane_damage(&iter, &clip) 224 num_hits++; 225 226 FAIL(num_hits != 0, "Should have no damage."); 227 228 return 0; 229} 230 231int igt_damage_iter_no_damage_no_crtc(void *ignored) 232{ 233 struct drm_atomic_helper_damage_iter iter; 234 struct drm_plane_state old_state; 235 struct drm_rect clip; 236 uint32_t num_hits = 0; 237 238 struct drm_framebuffer fb = { 239 .width = 2048, 240 .height = 2048 241 }; 242 243 struct drm_plane_state state = { 244 .crtc = 0, 245 .fb = &fb, 246 }; 247 248 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 249 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 250 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 251 drm_atomic_for_each_plane_damage(&iter, &clip) 252 num_hits++; 253 254 FAIL(num_hits != 0, "Should have no damage."); 255 256 return 0; 257} 258 259int igt_damage_iter_no_damage_no_fb(void *ignored) 260{ 261 struct drm_atomic_helper_damage_iter iter; 262 struct drm_plane_state old_state; 263 struct drm_rect clip; 264 uint32_t num_hits = 0; 265 266 struct drm_plane_state state = { 267 .crtc = ZERO_SIZE_PTR, 268 .fb = 0, 269 }; 270 271 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 272 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 273 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 274 drm_atomic_for_each_plane_damage(&iter, &clip) 275 num_hits++; 276 277 FAIL(num_hits != 0, "Should have no damage."); 278 279 return 0; 280} 281 282int igt_damage_iter_simple_damage(void *ignored) 283{ 284 struct drm_atomic_helper_damage_iter iter; 285 struct drm_plane_state old_state; 286 struct drm_property_blob damage_blob; 287 struct drm_mode_rect damage; 288 struct drm_rect clip; 289 uint32_t num_hits = 0; 290 291 struct drm_framebuffer fb = { 292 .width = 2048, 293 .height = 2048 294 }; 295 296 struct drm_plane_state state = { 297 .crtc = ZERO_SIZE_PTR, 298 .fb = &fb, 299 .visible = true, 300 }; 301 302 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 303 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 304 /* Damage set to plane src */ 305 set_damage_clip(&damage, 0, 0, 1024, 768); 306 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 307 set_plane_damage(&state, &damage_blob); 308 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 309 drm_atomic_for_each_plane_damage(&iter, &clip) 310 num_hits++; 311 312 FAIL(num_hits != 1, "Should return damage when set."); 313 FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768)); 314 315 return 0; 316} 317 318int igt_damage_iter_single_damage(void *ignored) 319{ 320 struct drm_atomic_helper_damage_iter iter; 321 struct drm_plane_state old_state; 322 struct drm_property_blob damage_blob; 323 struct drm_mode_rect damage; 324 struct drm_rect clip; 325 uint32_t num_hits = 0; 326 327 struct drm_framebuffer fb = { 328 .width = 2048, 329 .height = 2048 330 }; 331 332 struct drm_plane_state state = { 333 .crtc = ZERO_SIZE_PTR, 334 .fb = &fb, 335 .visible = true, 336 }; 337 338 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 339 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 340 set_damage_clip(&damage, 256, 192, 768, 576); 341 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 342 set_plane_damage(&state, &damage_blob); 343 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 344 drm_atomic_for_each_plane_damage(&iter, &clip) 345 num_hits++; 346 347 FAIL(num_hits != 1, "Should return damage when set."); 348 FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576)); 349 350 return 0; 351} 352 353int igt_damage_iter_single_damage_intersect_src(void *ignored) 354{ 355 struct drm_atomic_helper_damage_iter iter; 356 struct drm_plane_state old_state; 357 struct drm_property_blob damage_blob; 358 struct drm_mode_rect damage; 359 struct drm_rect clip; 360 uint32_t num_hits = 0; 361 362 struct drm_framebuffer fb = { 363 .width = 2048, 364 .height = 2048 365 }; 366 367 struct drm_plane_state state = { 368 .crtc = ZERO_SIZE_PTR, 369 .fb = &fb, 370 .visible = true, 371 }; 372 373 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 374 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 375 /* Damage intersect with plane src. */ 376 set_damage_clip(&damage, 256, 192, 1360, 768); 377 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 378 set_plane_damage(&state, &damage_blob); 379 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 380 drm_atomic_for_each_plane_damage(&iter, &clip) 381 num_hits++; 382 383 FAIL(num_hits != 1, "Should return damage clipped to src."); 384 FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768)); 385 386 return 0; 387} 388 389int igt_damage_iter_single_damage_outside_src(void *ignored) 390{ 391 struct drm_atomic_helper_damage_iter iter; 392 struct drm_plane_state old_state; 393 struct drm_property_blob damage_blob; 394 struct drm_mode_rect damage; 395 struct drm_rect clip; 396 uint32_t num_hits = 0; 397 398 struct drm_framebuffer fb = { 399 .width = 2048, 400 .height = 2048 401 }; 402 403 struct drm_plane_state state = { 404 .crtc = ZERO_SIZE_PTR, 405 .fb = &fb, 406 .visible = true, 407 }; 408 409 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 410 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 411 /* Damage clip outside plane src */ 412 set_damage_clip(&damage, 1360, 1360, 1380, 1380); 413 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 414 set_plane_damage(&state, &damage_blob); 415 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 416 drm_atomic_for_each_plane_damage(&iter, &clip) 417 num_hits++; 418 419 FAIL(num_hits != 0, "Should have no damage."); 420 421 return 0; 422} 423 424int igt_damage_iter_single_damage_fractional_src(void *ignored) 425{ 426 struct drm_atomic_helper_damage_iter iter; 427 struct drm_plane_state old_state; 428 struct drm_property_blob damage_blob; 429 struct drm_mode_rect damage; 430 struct drm_rect clip; 431 uint32_t num_hits = 0; 432 433 struct drm_framebuffer fb = { 434 .width = 2048, 435 .height = 2048 436 }; 437 438 struct drm_plane_state state = { 439 .crtc = ZERO_SIZE_PTR, 440 .fb = &fb, 441 .visible = true, 442 }; 443 444 /* Plane src has fractional part. */ 445 set_plane_src(&old_state, 0x40002, 0x40002, 446 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 447 set_plane_src(&state, 0x40002, 0x40002, 448 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 449 set_damage_clip(&damage, 10, 10, 256, 330); 450 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 451 set_plane_damage(&state, &damage_blob); 452 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 453 drm_atomic_for_each_plane_damage(&iter, &clip) 454 num_hits++; 455 456 FAIL(num_hits != 1, "Should return damage when set."); 457 FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330)); 458 459 return 0; 460} 461 462int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored) 463{ 464 struct drm_atomic_helper_damage_iter iter; 465 struct drm_plane_state old_state; 466 struct drm_property_blob damage_blob; 467 struct drm_mode_rect damage; 468 struct drm_rect clip; 469 uint32_t num_hits = 0; 470 471 struct drm_framebuffer fb = { 472 .width = 2048, 473 .height = 2048 474 }; 475 476 struct drm_plane_state state = { 477 .crtc = ZERO_SIZE_PTR, 478 .fb = &fb, 479 .visible = true, 480 }; 481 482 /* Plane src has fractional part. */ 483 set_plane_src(&old_state, 0x40002, 0x40002, 484 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 485 set_plane_src(&state, 0x40002, 0x40002, 486 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 487 /* Damage intersect with plane src. */ 488 set_damage_clip(&damage, 10, 1, 1360, 330); 489 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 490 set_plane_damage(&state, &damage_blob); 491 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 492 drm_atomic_for_each_plane_damage(&iter, &clip) 493 num_hits++; 494 495 FAIL(num_hits != 1, "Should return damage clipped to rounded off src."); 496 FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330)); 497 498 return 0; 499} 500 501int igt_damage_iter_single_damage_outside_fractional_src(void *ignored) 502{ 503 struct drm_atomic_helper_damage_iter iter; 504 struct drm_plane_state old_state; 505 struct drm_property_blob damage_blob; 506 struct drm_mode_rect damage; 507 struct drm_rect clip; 508 uint32_t num_hits = 0; 509 510 struct drm_framebuffer fb = { 511 .width = 2048, 512 .height = 2048 513 }; 514 515 struct drm_plane_state state = { 516 .crtc = ZERO_SIZE_PTR, 517 .fb = &fb, 518 .visible = true, 519 }; 520 521 /* Plane src has fractional part. */ 522 set_plane_src(&old_state, 0x40002, 0x40002, 523 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 524 set_plane_src(&state, 0x40002, 0x40002, 525 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 526 /* Damage clip outside plane src */ 527 set_damage_clip(&damage, 1360, 1360, 1380, 1380); 528 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 529 set_plane_damage(&state, &damage_blob); 530 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 531 drm_atomic_for_each_plane_damage(&iter, &clip) 532 num_hits++; 533 534 FAIL(num_hits != 0, "Should have no damage."); 535 536 return 0; 537} 538 539int igt_damage_iter_single_damage_src_moved(void *ignored) 540{ 541 struct drm_atomic_helper_damage_iter iter; 542 struct drm_plane_state old_state; 543 struct drm_property_blob damage_blob; 544 struct drm_mode_rect damage; 545 struct drm_rect clip; 546 uint32_t num_hits = 0; 547 548 struct drm_framebuffer fb = { 549 .width = 2048, 550 .height = 2048 551 }; 552 553 struct drm_plane_state state = { 554 .crtc = ZERO_SIZE_PTR, 555 .fb = &fb, 556 .visible = true, 557 }; 558 559 /* Plane src moved since old plane state. */ 560 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 561 set_plane_src(&state, 10 << 16, 10 << 16, 562 (10 + 1024) << 16, (10 + 768) << 16); 563 set_damage_clip(&damage, 20, 30, 256, 256); 564 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 565 set_plane_damage(&state, &damage_blob); 566 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 567 drm_atomic_for_each_plane_damage(&iter, &clip) 568 num_hits++; 569 570 FAIL(num_hits != 1, "Should return plane src as damage."); 571 FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); 572 573 return 0; 574} 575 576int igt_damage_iter_single_damage_fractional_src_moved(void *ignored) 577{ 578 struct drm_atomic_helper_damage_iter iter; 579 struct drm_plane_state old_state; 580 struct drm_property_blob damage_blob; 581 struct drm_mode_rect damage; 582 struct drm_rect clip; 583 uint32_t num_hits = 0; 584 585 struct drm_framebuffer fb = { 586 .width = 2048, 587 .height = 2048 588 }; 589 590 struct drm_plane_state state = { 591 .crtc = ZERO_SIZE_PTR, 592 .fb = &fb, 593 .visible = true, 594 }; 595 596 /* Plane src with fractional part moved since old plane state. */ 597 set_plane_src(&old_state, 0x3fffe, 0x3fffe, 598 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 599 set_plane_src(&state, 0x40002, 0x40002, 600 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 601 /* Damage intersect with plane src. */ 602 set_damage_clip(&damage, 20, 30, 1360, 256); 603 set_damage_blob(&damage_blob, &damage, sizeof(damage)); 604 set_plane_damage(&state, &damage_blob); 605 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 606 drm_atomic_for_each_plane_damage(&iter, &clip) 607 num_hits++; 608 609 FAIL(num_hits != 1, "Should return rounded off plane src as damage."); 610 FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); 611 612 return 0; 613} 614 615int igt_damage_iter_damage(void *ignored) 616{ 617 struct drm_atomic_helper_damage_iter iter; 618 struct drm_plane_state old_state; 619 struct drm_property_blob damage_blob; 620 struct drm_mode_rect damage[2]; 621 struct drm_rect clip; 622 uint32_t num_hits = 0; 623 624 struct drm_framebuffer fb = { 625 .width = 2048, 626 .height = 2048 627 }; 628 629 struct drm_plane_state state = { 630 .crtc = ZERO_SIZE_PTR, 631 .fb = &fb, 632 .visible = true, 633 }; 634 635 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 636 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 637 /* 2 damage clips. */ 638 set_damage_clip(&damage[0], 20, 30, 200, 180); 639 set_damage_clip(&damage[1], 240, 200, 280, 250); 640 set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); 641 set_plane_damage(&state, &damage_blob); 642 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 643 drm_atomic_for_each_plane_damage(&iter, &clip) { 644 if (num_hits == 0) 645 FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180)); 646 if (num_hits == 1) 647 FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250)); 648 num_hits++; 649 } 650 651 FAIL(num_hits != 2, "Should return damage when set."); 652 653 return 0; 654} 655 656int igt_damage_iter_damage_one_intersect(void *ignored) 657{ 658 struct drm_atomic_helper_damage_iter iter; 659 struct drm_plane_state old_state; 660 struct drm_property_blob damage_blob; 661 struct drm_mode_rect damage[2]; 662 struct drm_rect clip; 663 uint32_t num_hits = 0; 664 665 struct drm_framebuffer fb = { 666 .width = 2048, 667 .height = 2048 668 }; 669 670 struct drm_plane_state state = { 671 .crtc = ZERO_SIZE_PTR, 672 .fb = &fb, 673 .visible = true, 674 }; 675 676 set_plane_src(&old_state, 0x40002, 0x40002, 677 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 678 set_plane_src(&state, 0x40002, 0x40002, 679 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 680 /* 2 damage clips, one intersect plane src. */ 681 set_damage_clip(&damage[0], 20, 30, 200, 180); 682 set_damage_clip(&damage[1], 2, 2, 1360, 1360); 683 set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); 684 set_plane_damage(&state, &damage_blob); 685 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 686 drm_atomic_for_each_plane_damage(&iter, &clip) { 687 if (num_hits == 0) 688 FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180)); 689 if (num_hits == 1) 690 FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); 691 num_hits++; 692 } 693 694 FAIL(num_hits != 2, "Should return damage when set."); 695 696 return 0; 697} 698 699int igt_damage_iter_damage_one_outside(void *ignored) 700{ 701 struct drm_atomic_helper_damage_iter iter; 702 struct drm_plane_state old_state; 703 struct drm_property_blob damage_blob; 704 struct drm_mode_rect damage[2]; 705 struct drm_rect clip; 706 uint32_t num_hits = 0; 707 708 struct drm_framebuffer fb = { 709 .width = 2048, 710 .height = 2048 711 }; 712 713 struct drm_plane_state state = { 714 .crtc = ZERO_SIZE_PTR, 715 .fb = &fb, 716 .visible = true, 717 }; 718 719 set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); 720 set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); 721 /* 2 damage clips, one outside plane src. */ 722 set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); 723 set_damage_clip(&damage[1], 240, 200, 280, 250); 724 set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); 725 set_plane_damage(&state, &damage_blob); 726 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 727 drm_atomic_for_each_plane_damage(&iter, &clip) 728 num_hits++; 729 730 FAIL(num_hits != 1, "Should return damage when set."); 731 FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250)); 732 733 return 0; 734} 735 736int igt_damage_iter_damage_src_moved(void *ignored) 737{ 738 struct drm_atomic_helper_damage_iter iter; 739 struct drm_plane_state old_state; 740 struct drm_property_blob damage_blob; 741 struct drm_mode_rect damage[2]; 742 struct drm_rect clip; 743 uint32_t num_hits = 0; 744 745 struct drm_framebuffer fb = { 746 .width = 2048, 747 .height = 2048 748 }; 749 750 struct drm_plane_state state = { 751 .crtc = ZERO_SIZE_PTR, 752 .fb = &fb, 753 .visible = true, 754 }; 755 756 set_plane_src(&old_state, 0x40002, 0x40002, 757 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 758 set_plane_src(&state, 0x3fffe, 0x3fffe, 759 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 760 /* 2 damage clips, one outside plane src. */ 761 set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); 762 set_damage_clip(&damage[1], 240, 200, 280, 250); 763 set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); 764 set_plane_damage(&state, &damage_blob); 765 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 766 drm_atomic_for_each_plane_damage(&iter, &clip) 767 num_hits++; 768 769 FAIL(num_hits != 1, "Should return round off plane src as damage."); 770 FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); 771 772 return 0; 773} 774 775int igt_damage_iter_damage_not_visible(void *ignored) 776{ 777 struct drm_atomic_helper_damage_iter iter; 778 struct drm_plane_state old_state; 779 struct drm_property_blob damage_blob; 780 struct drm_mode_rect damage[2]; 781 struct drm_rect clip; 782 uint32_t num_hits = 0; 783 784 struct drm_framebuffer fb = { 785 .width = 2048, 786 .height = 2048 787 }; 788 789 struct drm_plane_state state = { 790 .crtc = ZERO_SIZE_PTR, 791 .fb = &fb, 792 .visible = false, 793 }; 794 795 set_plane_src(&old_state, 0x40002, 0x40002, 796 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); 797 set_plane_src(&state, 0x3fffe, 0x3fffe, 798 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); 799 /* 2 damage clips, one outside plane src. */ 800 set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); 801 set_damage_clip(&damage[1], 240, 200, 280, 250); 802 set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); 803 set_plane_damage(&state, &damage_blob); 804 drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); 805 drm_atomic_for_each_plane_damage(&iter, &clip) 806 num_hits++; 807 808 FAIL(num_hits != 0, "Should not return any damage."); 809 810 return 0; 811} 812