• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_plane_src(struct drm_plane_state * state,int x1,int y1,int x2,int y2)12 static 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 
set_damage_clip(struct drm_mode_rect * r,int x1,int y1,int x2,int y2)21 static 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 
set_damage_blob(struct drm_property_blob * damage_blob,struct drm_mode_rect * r,uint32_t size)30 static 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 
set_plane_damage(struct drm_plane_state * state,struct drm_property_blob * damage_blob)37 static 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 
check_damage_clip(struct drm_plane_state * state,struct drm_rect * r,int x1,int y1,int x2,int y2)43 static 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 
igt_damage_iter_no_damage(void * ignored)73 int 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 
igt_damage_iter_no_damage_fractional_src(void * ignored)104 int 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 
igt_damage_iter_no_damage_src_moved(void * ignored)137 int 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 
igt_damage_iter_no_damage_fractional_src_moved(void * ignored)169 int 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 
igt_damage_iter_no_damage_not_visible(void * ignored)202 int 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 
igt_damage_iter_no_damage_no_crtc(void * ignored)231 int 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 
igt_damage_iter_no_damage_no_fb(void * ignored)259 int 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 
igt_damage_iter_simple_damage(void * ignored)282 int 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 
igt_damage_iter_single_damage(void * ignored)318 int 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 
igt_damage_iter_single_damage_intersect_src(void * ignored)353 int 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 
igt_damage_iter_single_damage_outside_src(void * ignored)389 int 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 
igt_damage_iter_single_damage_fractional_src(void * ignored)424 int 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 
igt_damage_iter_single_damage_intersect_fractional_src(void * ignored)462 int 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 
igt_damage_iter_single_damage_outside_fractional_src(void * ignored)501 int 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 
igt_damage_iter_single_damage_src_moved(void * ignored)539 int 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 
igt_damage_iter_single_damage_fractional_src_moved(void * ignored)576 int 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 
igt_damage_iter_damage(void * ignored)615 int 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 
igt_damage_iter_damage_one_intersect(void * ignored)656 int 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 
igt_damage_iter_damage_one_outside(void * ignored)699 int 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 
igt_damage_iter_damage_src_moved(void * ignored)736 int 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 
igt_damage_iter_damage_not_visible(void * ignored)775 int 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