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