linux/drivers/gpu/drm/selftests/test-drm_damage_helper.c
<<
>>
Prefs
   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