xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/selftests/test-drm_rect.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Test cases for the drm_rect functions
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #define pr_fmt(fmt) "drm_rect: " fmt
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/limits.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <drm/drm_rect.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include "test-drm_modeset_common.h"
13*4882a593Smuzhiyun 
igt_drm_rect_clip_scaled_div_by_zero(void * ignored)14*4882a593Smuzhiyun int igt_drm_rect_clip_scaled_div_by_zero(void *ignored)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun 	struct drm_rect src, dst, clip;
17*4882a593Smuzhiyun 	bool visible;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 	/*
20*4882a593Smuzhiyun 	 * Make sure we don't divide by zero when dst
21*4882a593Smuzhiyun 	 * width/height is zero and dst and clip do not intersect.
22*4882a593Smuzhiyun 	 */
23*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 0, 0);
24*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 0, 0);
25*4882a593Smuzhiyun 	drm_rect_init(&clip, 1, 1, 1, 1);
26*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
27*4882a593Smuzhiyun 	FAIL(visible, "Destination not be visible\n");
28*4882a593Smuzhiyun 	FAIL(drm_rect_visible(&src), "Source should not be visible\n");
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 0, 0);
31*4882a593Smuzhiyun 	drm_rect_init(&dst, 3, 3, 0, 0);
32*4882a593Smuzhiyun 	drm_rect_init(&clip, 1, 1, 1, 1);
33*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
34*4882a593Smuzhiyun 	FAIL(visible, "Destination not be visible\n");
35*4882a593Smuzhiyun 	FAIL(drm_rect_visible(&src), "Source should not be visible\n");
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
igt_drm_rect_clip_scaled_not_clipped(void * ignored)40*4882a593Smuzhiyun int igt_drm_rect_clip_scaled_not_clipped(void *ignored)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	struct drm_rect src, dst, clip;
43*4882a593Smuzhiyun 	bool visible;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	/* 1:1 scaling */
46*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16);
47*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 1, 1);
48*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 1, 1);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 1 << 16 ||
53*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 1 << 16,
54*4882a593Smuzhiyun 	     "Source badly clipped\n");
55*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 1 ||
56*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 1,
57*4882a593Smuzhiyun 	     "Destination badly clipped\n");
58*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
59*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	/* 2:1 scaling */
62*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
63*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 1, 1);
64*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 1, 1);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 2 << 16 ||
69*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 2 << 16,
70*4882a593Smuzhiyun 	     "Source badly clipped\n");
71*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 1 ||
72*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 1,
73*4882a593Smuzhiyun 	     "Destination badly clipped\n");
74*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
75*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	/* 1:2 scaling */
78*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16);
79*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
80*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 2, 2);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 1 << 16 ||
85*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 1 << 16,
86*4882a593Smuzhiyun 	     "Source badly clipped\n");
87*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 2 ||
88*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 2,
89*4882a593Smuzhiyun 	     "Destination badly clipped\n");
90*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
91*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	return 0;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
igt_drm_rect_clip_scaled_clipped(void * ignored)96*4882a593Smuzhiyun int igt_drm_rect_clip_scaled_clipped(void *ignored)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	struct drm_rect src, dst, clip;
99*4882a593Smuzhiyun 	bool visible;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	/* 1:1 scaling top/left clip */
102*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
103*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
104*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 1, 1);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 1 << 16 ||
109*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 1 << 16,
110*4882a593Smuzhiyun 	     "Source badly clipped\n");
111*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 1 ||
112*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 1,
113*4882a593Smuzhiyun 	     "Destination badly clipped\n");
114*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
115*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	/* 1:1 scaling bottom/right clip */
118*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
119*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
120*4882a593Smuzhiyun 	drm_rect_init(&clip, 1, 1, 1, 1);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 ||
125*4882a593Smuzhiyun 	     src.y1 != 1 << 16 || src.y2 != 2 << 16,
126*4882a593Smuzhiyun 	     "Source badly clipped\n");
127*4882a593Smuzhiyun 	FAIL(dst.x1 != 1 || dst.x2 != 2 ||
128*4882a593Smuzhiyun 	     dst.y1 != 1 || dst.y2 != 2,
129*4882a593Smuzhiyun 	     "Destination badly clipped\n");
130*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
131*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	/* 2:1 scaling top/left clip */
134*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16);
135*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
136*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 1, 1);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 2 << 16 ||
141*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 2 << 16,
142*4882a593Smuzhiyun 	     "Source badly clipped\n");
143*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 1 ||
144*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 1,
145*4882a593Smuzhiyun 	     "Destination badly clipped\n");
146*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
147*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	/* 2:1 scaling bottom/right clip */
150*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16);
151*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
152*4882a593Smuzhiyun 	drm_rect_init(&clip, 1, 1, 1, 1);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	FAIL(src.x1 != 2 << 16 || src.x2 != 4 << 16 ||
157*4882a593Smuzhiyun 	     src.y1 != 2 << 16 || src.y2 != 4 << 16,
158*4882a593Smuzhiyun 	     "Source badly clipped\n");
159*4882a593Smuzhiyun 	FAIL(dst.x1 != 1 || dst.x2 != 2 ||
160*4882a593Smuzhiyun 	     dst.y1 != 1 || dst.y2 != 2,
161*4882a593Smuzhiyun 	     "Destination badly clipped\n");
162*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
163*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* 1:2 scaling top/left clip */
166*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
167*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 4, 4);
168*4882a593Smuzhiyun 	drm_rect_init(&clip, 0, 0, 2, 2);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	FAIL(src.x1 != 0 || src.x2 != 1 << 16 ||
173*4882a593Smuzhiyun 	     src.y1 != 0 || src.y2 != 1 << 16,
174*4882a593Smuzhiyun 	     "Source badly clipped\n");
175*4882a593Smuzhiyun 	FAIL(dst.x1 != 0 || dst.x2 != 2 ||
176*4882a593Smuzhiyun 	     dst.y1 != 0 || dst.y2 != 2,
177*4882a593Smuzhiyun 	     "Destination badly clipped\n");
178*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
179*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	/* 1:2 scaling bottom/right clip */
182*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
183*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 4, 4);
184*4882a593Smuzhiyun 	drm_rect_init(&clip, 2, 2, 2, 2);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 ||
189*4882a593Smuzhiyun 	     src.y1 != 1 << 16 || src.y2 != 2 << 16,
190*4882a593Smuzhiyun 	     "Source badly clipped\n");
191*4882a593Smuzhiyun 	FAIL(dst.x1 != 2 || dst.x2 != 4 ||
192*4882a593Smuzhiyun 	     dst.y1 != 2 || dst.y2 != 4,
193*4882a593Smuzhiyun 	     "Destination badly clipped\n");
194*4882a593Smuzhiyun 	FAIL(!visible, "Destination should be visible\n");
195*4882a593Smuzhiyun 	FAIL(!drm_rect_visible(&src), "Source should be visible\n");
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	return 0;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
igt_drm_rect_clip_scaled_signed_vs_unsigned(void * ignored)200*4882a593Smuzhiyun int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	struct drm_rect src, dst, clip;
203*4882a593Smuzhiyun 	bool visible;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	/*
206*4882a593Smuzhiyun 	 * 'clip.x2 - dst.x1 >= dst width' could result a negative
207*4882a593Smuzhiyun 	 * src rectangle width which is no longer expected by the
208*4882a593Smuzhiyun 	 * code as it's using unsigned types. This could lead to
209*4882a593Smuzhiyun 	 * the clipped source rectangle appering visible when it
210*4882a593Smuzhiyun 	 * should have been fully clipped. Make sure both rectangles
211*4882a593Smuzhiyun 	 * end up invisible.
212*4882a593Smuzhiyun 	 */
213*4882a593Smuzhiyun 	drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX);
214*4882a593Smuzhiyun 	drm_rect_init(&dst, 0, 0, 2, 2);
215*4882a593Smuzhiyun 	drm_rect_init(&clip, 3, 3, 1, 1);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	visible = drm_rect_clip_scaled(&src, &dst, &clip);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	FAIL(visible, "Destination should not be visible\n");
220*4882a593Smuzhiyun 	FAIL(drm_rect_visible(&src), "Source should not be visible\n");
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	return 0;
223*4882a593Smuzhiyun }
224