GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / gpu / drm / selftests / test-drm_damage_helper.c
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 #include <drm/drm_plane.h>
10 #include <drm/drm_drv.h>
11
12 #include "test-drm_modeset_common.h"
13
14 struct drm_driver mock_driver;
15 static struct drm_device mock_device;
16 static struct drm_object_properties mock_obj_props;
17 static struct drm_plane mock_plane;
18 static struct drm_property mock_prop;
19
20 static void mock_setup(struct drm_plane_state *state)
21 {
22         static bool setup_done = false;
23
24         state->plane = &mock_plane;
25
26         if (setup_done)
27                 return;
28
29         /* just enough so that drm_plane_enable_fb_damage_clips() works */
30         mock_device.driver = &mock_driver;
31         mock_device.mode_config.prop_fb_damage_clips = &mock_prop;
32         mock_plane.dev = &mock_device;
33         mock_obj_props.count = 0;
34         mock_plane.base.properties = &mock_obj_props;
35         mock_prop.base.id = 1; /* 0 is an invalid id */
36         mock_prop.dev = &mock_device;
37
38         drm_plane_enable_fb_damage_clips(&mock_plane);
39 }
40
41 static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
42                           int y2)
43 {
44         state->src.x1 = x1;
45         state->src.y1 = y1;
46         state->src.x2 = x2;
47         state->src.y2 = y2;
48 }
49
50 static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2,
51                             int y2)
52 {
53         r->x1 = x1;
54         r->y1 = y1;
55         r->x2 = x2;
56         r->y2 = y2;
57 }
58
59 static void set_damage_blob(struct drm_property_blob *damage_blob,
60                             struct drm_mode_rect *r, uint32_t size)
61 {
62         damage_blob->length = size;
63         damage_blob->data = r;
64 }
65
66 static void set_plane_damage(struct drm_plane_state *state,
67                              struct drm_property_blob *damage_blob)
68 {
69         state->fb_damage_clips = damage_blob;
70 }
71
72 static bool check_damage_clip(struct drm_plane_state *state, struct drm_rect *r,
73                               int x1, int y1, int x2, int y2)
74 {
75         /*
76          * Round down x1/y1 and round up x2/y2. This is because damage is not in
77          * 16.16 fixed point so to catch all pixels.
78          */
79         int src_x1 = state->src.x1 >> 16;
80         int src_y1 = state->src.y1 >> 16;
81         int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF);
82         int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF);
83
84         if (x1 >= x2 || y1 >= y2) {
85                 pr_err("Cannot have damage clip with no dimension.\n");
86                 return false;
87         }
88
89         if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) {
90                 pr_err("Damage cannot be outside rounded plane src.\n");
91                 return false;
92         }
93
94         if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) {
95                 pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r->y2);
96                 return false;
97         }
98
99         return true;
100 }
101
102 const struct drm_framebuffer fb = {
103         .width = 2048,
104         .height = 2048
105 };
106
107 /* common mocked structs many tests need */
108 #define MOCK_VARIABLES() \
109         struct drm_plane_state old_state; \
110         struct drm_plane_state state = { \
111                 .crtc = ZERO_SIZE_PTR, \
112                 .fb = (struct drm_framebuffer *) &fb, \
113                 .visible = true, \
114         }; \
115         mock_setup(&old_state); \
116         mock_setup(&state);
117
118 int igt_damage_iter_no_damage(void *ignored)
119 {
120         struct drm_atomic_helper_damage_iter iter;
121         struct drm_rect clip;
122         uint32_t num_hits = 0;
123
124         MOCK_VARIABLES();
125
126         /* Plane src same as fb size. */
127         set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16);
128         set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16);
129         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
130         drm_atomic_for_each_plane_damage(&iter, &clip)
131                 num_hits++;
132
133         FAIL(num_hits != 1, "Should return plane src as damage.");
134         FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048));
135
136         return 0;
137 }
138
139 int igt_damage_iter_no_damage_fractional_src(void *ignored)
140 {
141         struct drm_atomic_helper_damage_iter iter;
142         struct drm_rect clip;
143         uint32_t num_hits = 0;
144
145         MOCK_VARIABLES();
146
147         /* Plane src has fractional part. */
148         set_plane_src(&old_state, 0x3fffe, 0x3fffe,
149                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
150         set_plane_src(&state, 0x3fffe, 0x3fffe,
151                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
152         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
153         drm_atomic_for_each_plane_damage(&iter, &clip)
154                 num_hits++;
155
156         FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
157         FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
158
159         return 0;
160 }
161
162 int igt_damage_iter_no_damage_src_moved(void *ignored)
163 {
164         struct drm_atomic_helper_damage_iter iter;
165         struct drm_rect clip;
166         uint32_t num_hits = 0;
167
168         MOCK_VARIABLES();
169
170         /* Plane src moved since old plane state. */
171         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
172         set_plane_src(&state, 10 << 16, 10 << 16,
173                       (10 + 1024) << 16, (10 + 768) << 16);
174         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
175         drm_atomic_for_each_plane_damage(&iter, &clip)
176                 num_hits++;
177
178         FAIL(num_hits != 1, "Should return plane src as damage.");
179         FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
180
181         return 0;
182 }
183
184 int igt_damage_iter_no_damage_fractional_src_moved(void *ignored)
185 {
186         struct drm_atomic_helper_damage_iter iter;
187         struct drm_rect clip;
188         uint32_t num_hits = 0;
189
190         MOCK_VARIABLES();
191
192         /* Plane src has fractional part and it moved since old plane state. */
193         set_plane_src(&old_state, 0x3fffe, 0x3fffe,
194                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
195         set_plane_src(&state, 0x40002, 0x40002,
196                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
197         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
198         drm_atomic_for_each_plane_damage(&iter, &clip)
199                 num_hits++;
200
201         FAIL(num_hits != 1, "Should return plane src as damage.");
202         FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
203
204         return 0;
205 }
206
207 int igt_damage_iter_no_damage_not_visible(void *ignored)
208 {
209         struct drm_atomic_helper_damage_iter iter;
210         struct drm_rect clip;
211         uint32_t num_hits = 0;
212
213         MOCK_VARIABLES();
214
215         state.visible = false;
216
217         mock_setup(&old_state);
218
219         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
220         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
221         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
222         drm_atomic_for_each_plane_damage(&iter, &clip)
223                 num_hits++;
224
225         FAIL(num_hits != 0, "Should have no damage.");
226
227         return 0;
228 }
229
230 int igt_damage_iter_no_damage_no_crtc(void *ignored)
231 {
232         struct drm_atomic_helper_damage_iter iter;
233         struct drm_rect clip;
234         uint32_t num_hits = 0;
235
236         MOCK_VARIABLES();
237
238         state.crtc = NULL;
239
240         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
241         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
242         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
243         drm_atomic_for_each_plane_damage(&iter, &clip)
244                 num_hits++;
245
246         FAIL(num_hits != 0, "Should have no damage.");
247
248         return 0;
249 }
250
251 int igt_damage_iter_no_damage_no_fb(void *ignored)
252 {
253         struct drm_atomic_helper_damage_iter iter;
254         struct drm_plane_state old_state;
255         struct drm_rect clip;
256         uint32_t num_hits = 0;
257
258         struct drm_plane_state state = {
259                 .crtc = ZERO_SIZE_PTR,
260                 .fb = 0,
261         };
262
263         mock_setup(&old_state);
264
265         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
266         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
267         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
268         drm_atomic_for_each_plane_damage(&iter, &clip)
269                 num_hits++;
270
271         FAIL(num_hits != 0, "Should have no damage.");
272
273         return 0;
274 }
275
276 int igt_damage_iter_simple_damage(void *ignored)
277 {
278         struct drm_atomic_helper_damage_iter iter;
279         struct drm_property_blob damage_blob;
280         struct drm_mode_rect damage;
281         struct drm_rect clip;
282         uint32_t num_hits = 0;
283
284         MOCK_VARIABLES();
285
286         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
287         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
288         /* Damage set to plane src */
289         set_damage_clip(&damage, 0, 0, 1024, 768);
290         set_damage_blob(&damage_blob, &damage, sizeof(damage));
291         set_plane_damage(&state, &damage_blob);
292         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
293         drm_atomic_for_each_plane_damage(&iter, &clip)
294                 num_hits++;
295
296         FAIL(num_hits != 1, "Should return damage when set.");
297         FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768));
298
299         return 0;
300 }
301
302 int igt_damage_iter_single_damage(void *ignored)
303 {
304         struct drm_atomic_helper_damage_iter iter;
305         struct drm_property_blob damage_blob;
306         struct drm_mode_rect damage;
307         struct drm_rect clip;
308         uint32_t num_hits = 0;
309
310         MOCK_VARIABLES();
311
312         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
313         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
314         set_damage_clip(&damage, 256, 192, 768, 576);
315         set_damage_blob(&damage_blob, &damage, sizeof(damage));
316         set_plane_damage(&state, &damage_blob);
317         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
318         drm_atomic_for_each_plane_damage(&iter, &clip)
319                 num_hits++;
320
321         FAIL(num_hits != 1, "Should return damage when set.");
322         FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576));
323
324         return 0;
325 }
326
327 int igt_damage_iter_single_damage_intersect_src(void *ignored)
328 {
329         struct drm_atomic_helper_damage_iter iter;
330         struct drm_property_blob damage_blob;
331         struct drm_mode_rect damage;
332         struct drm_rect clip;
333         uint32_t num_hits = 0;
334
335         MOCK_VARIABLES();
336
337         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
338         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
339         /* Damage intersect with plane src. */
340         set_damage_clip(&damage, 256, 192, 1360, 768);
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 clipped to src.");
348         FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768));
349
350         return 0;
351 }
352
353 int igt_damage_iter_single_damage_outside_src(void *ignored)
354 {
355         struct drm_atomic_helper_damage_iter iter;
356         struct drm_property_blob damage_blob;
357         struct drm_mode_rect damage;
358         struct drm_rect clip;
359         uint32_t num_hits = 0;
360
361         MOCK_VARIABLES();
362
363         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
364         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
365         /* Damage clip outside plane src */
366         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
367         set_damage_blob(&damage_blob, &damage, sizeof(damage));
368         set_plane_damage(&state, &damage_blob);
369         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
370         drm_atomic_for_each_plane_damage(&iter, &clip)
371                 num_hits++;
372
373         FAIL(num_hits != 0, "Should have no damage.");
374
375         return 0;
376 }
377
378 int igt_damage_iter_single_damage_fractional_src(void *ignored)
379 {
380         struct drm_atomic_helper_damage_iter iter;
381         struct drm_property_blob damage_blob;
382         struct drm_mode_rect damage;
383         struct drm_rect clip;
384         uint32_t num_hits = 0;
385
386         MOCK_VARIABLES();
387
388         /* Plane src has fractional part. */
389         set_plane_src(&old_state, 0x40002, 0x40002,
390                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
391         set_plane_src(&state, 0x40002, 0x40002,
392                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
393         set_damage_clip(&damage, 10, 10, 256, 330);
394         set_damage_blob(&damage_blob, &damage, sizeof(damage));
395         set_plane_damage(&state, &damage_blob);
396         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
397         drm_atomic_for_each_plane_damage(&iter, &clip)
398                 num_hits++;
399
400         FAIL(num_hits != 1, "Should return damage when set.");
401         FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330));
402
403         return 0;
404 }
405
406 int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored)
407 {
408         struct drm_atomic_helper_damage_iter iter;
409         struct drm_property_blob damage_blob;
410         struct drm_mode_rect damage;
411         struct drm_rect clip;
412         uint32_t num_hits = 0;
413
414         MOCK_VARIABLES();
415
416         /* Plane src has fractional part. */
417         set_plane_src(&old_state, 0x40002, 0x40002,
418                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
419         set_plane_src(&state, 0x40002, 0x40002,
420                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
421         /* Damage intersect with plane src. */
422         set_damage_clip(&damage, 10, 1, 1360, 330);
423         set_damage_blob(&damage_blob, &damage, sizeof(damage));
424         set_plane_damage(&state, &damage_blob);
425         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
426         drm_atomic_for_each_plane_damage(&iter, &clip)
427                 num_hits++;
428
429         FAIL(num_hits != 1, "Should return damage clipped to rounded off src.");
430         FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330));
431
432         return 0;
433 }
434
435 int igt_damage_iter_single_damage_outside_fractional_src(void *ignored)
436 {
437         struct drm_atomic_helper_damage_iter iter;
438         struct drm_property_blob damage_blob;
439         struct drm_mode_rect damage;
440         struct drm_rect clip;
441         uint32_t num_hits = 0;
442
443         MOCK_VARIABLES();
444
445         /* Plane src has fractional part. */
446         set_plane_src(&old_state, 0x40002, 0x40002,
447                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
448         set_plane_src(&state, 0x40002, 0x40002,
449                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
450         /* Damage clip outside plane src */
451         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
452         set_damage_blob(&damage_blob, &damage, sizeof(damage));
453         set_plane_damage(&state, &damage_blob);
454         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
455         drm_atomic_for_each_plane_damage(&iter, &clip)
456                 num_hits++;
457
458         FAIL(num_hits != 0, "Should have no damage.");
459
460         return 0;
461 }
462
463 int igt_damage_iter_single_damage_src_moved(void *ignored)
464 {
465         struct drm_atomic_helper_damage_iter iter;
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         MOCK_VARIABLES();
472
473         /* Plane src moved since old plane state. */
474         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
475         set_plane_src(&state, 10 << 16, 10 << 16,
476                       (10 + 1024) << 16, (10 + 768) << 16);
477         set_damage_clip(&damage, 20, 30, 256, 256);
478         set_damage_blob(&damage_blob, &damage, sizeof(damage));
479         set_plane_damage(&state, &damage_blob);
480         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
481         drm_atomic_for_each_plane_damage(&iter, &clip)
482                 num_hits++;
483
484         FAIL(num_hits != 1, "Should return plane src as damage.");
485         FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
486
487         return 0;
488 }
489
490 int igt_damage_iter_single_damage_fractional_src_moved(void *ignored)
491 {
492         struct drm_atomic_helper_damage_iter iter;
493         struct drm_property_blob damage_blob;
494         struct drm_mode_rect damage;
495         struct drm_rect clip;
496         uint32_t num_hits = 0;
497
498         MOCK_VARIABLES();
499
500         /* Plane src with fractional part moved since old plane state. */
501         set_plane_src(&old_state, 0x3fffe, 0x3fffe,
502                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
503         set_plane_src(&state, 0x40002, 0x40002,
504                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
505         /* Damage intersect with plane src. */
506         set_damage_clip(&damage, 20, 30, 1360, 256);
507         set_damage_blob(&damage_blob, &damage, sizeof(damage));
508         set_plane_damage(&state, &damage_blob);
509         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
510         drm_atomic_for_each_plane_damage(&iter, &clip)
511                 num_hits++;
512
513         FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
514         FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
515
516         return 0;
517 }
518
519 int igt_damage_iter_damage(void *ignored)
520 {
521         struct drm_atomic_helper_damage_iter iter;
522         struct drm_property_blob damage_blob;
523         struct drm_mode_rect damage[2];
524         struct drm_rect clip;
525         uint32_t num_hits = 0;
526
527         MOCK_VARIABLES();
528
529         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
530         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
531         /* 2 damage clips. */
532         set_damage_clip(&damage[0], 20, 30, 200, 180);
533         set_damage_clip(&damage[1], 240, 200, 280, 250);
534         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
535         set_plane_damage(&state, &damage_blob);
536         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
537         drm_atomic_for_each_plane_damage(&iter, &clip) {
538                 if (num_hits == 0)
539                         FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
540                 if (num_hits == 1)
541                         FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
542                 num_hits++;
543         }
544
545         FAIL(num_hits != 2, "Should return damage when set.");
546
547         return 0;
548 }
549
550 int igt_damage_iter_damage_one_intersect(void *ignored)
551 {
552         struct drm_atomic_helper_damage_iter iter;
553         struct drm_property_blob damage_blob;
554         struct drm_mode_rect damage[2];
555         struct drm_rect clip;
556         uint32_t num_hits = 0;
557
558         MOCK_VARIABLES();
559
560         set_plane_src(&old_state, 0x40002, 0x40002,
561                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
562         set_plane_src(&state, 0x40002, 0x40002,
563                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
564         /* 2 damage clips, one intersect plane src. */
565         set_damage_clip(&damage[0], 20, 30, 200, 180);
566         set_damage_clip(&damage[1], 2, 2, 1360, 1360);
567         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
568         set_plane_damage(&state, &damage_blob);
569         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
570         drm_atomic_for_each_plane_damage(&iter, &clip) {
571                 if (num_hits == 0)
572                         FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
573                 if (num_hits == 1)
574                         FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
575                 num_hits++;
576         }
577
578         FAIL(num_hits != 2, "Should return damage when set.");
579
580         return 0;
581 }
582
583 int igt_damage_iter_damage_one_outside(void *ignored)
584 {
585         struct drm_atomic_helper_damage_iter iter;
586         struct drm_property_blob damage_blob;
587         struct drm_mode_rect damage[2];
588         struct drm_rect clip;
589         uint32_t num_hits = 0;
590
591         MOCK_VARIABLES();
592
593         set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
594         set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
595         /* 2 damage clips, one outside plane src. */
596         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
597         set_damage_clip(&damage[1], 240, 200, 280, 250);
598         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
599         set_plane_damage(&state, &damage_blob);
600         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
601         drm_atomic_for_each_plane_damage(&iter, &clip)
602                 num_hits++;
603
604         FAIL(num_hits != 1, "Should return damage when set.");
605         FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
606
607         return 0;
608 }
609
610 int igt_damage_iter_damage_src_moved(void *ignored)
611 {
612         struct drm_atomic_helper_damage_iter iter;
613         struct drm_property_blob damage_blob;
614         struct drm_mode_rect damage[2];
615         struct drm_rect clip;
616         uint32_t num_hits = 0;
617
618         MOCK_VARIABLES();
619
620         set_plane_src(&old_state, 0x40002, 0x40002,
621                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
622         set_plane_src(&state, 0x3fffe, 0x3fffe,
623                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
624         /* 2 damage clips, one outside plane src. */
625         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
626         set_damage_clip(&damage[1], 240, 200, 280, 250);
627         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
628         set_plane_damage(&state, &damage_blob);
629         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
630         drm_atomic_for_each_plane_damage(&iter, &clip)
631                 num_hits++;
632
633         FAIL(num_hits != 1, "Should return round off plane src as damage.");
634         FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
635
636         return 0;
637 }
638
639 int igt_damage_iter_damage_not_visible(void *ignored)
640 {
641         struct drm_atomic_helper_damage_iter iter;
642         struct drm_property_blob damage_blob;
643         struct drm_mode_rect damage[2];
644         struct drm_rect clip;
645         uint32_t num_hits = 0;
646
647         MOCK_VARIABLES();
648
649         state.visible = false;
650
651         set_plane_src(&old_state, 0x40002, 0x40002,
652                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
653         set_plane_src(&state, 0x3fffe, 0x3fffe,
654                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
655         /* 2 damage clips, one outside plane src. */
656         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
657         set_damage_clip(&damage[1], 240, 200, 280, 250);
658         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
659         set_plane_damage(&state, &damage_blob);
660         drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
661         drm_atomic_for_each_plane_damage(&iter, &clip)
662                 num_hits++;
663
664         FAIL(num_hits != 0, "Should not return any damage.");
665
666         return 0;
667 }