Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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}