xref: /aosp_15_r20/external/igt-gpu-tools/tests/kms_rotation_crc.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013,2014 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
26*d83cc019SAndroid Build Coastguard Worker #include <math.h>
27*d83cc019SAndroid Build Coastguard Worker 
28*d83cc019SAndroid Build Coastguard Worker #define MAX_FENCES 32
29*d83cc019SAndroid Build Coastguard Worker #define MAXMULTIPLANESAMOUNT 2
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker struct p_struct {
32*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *plane;
33*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb;
34*d83cc019SAndroid Build Coastguard Worker };
35*d83cc019SAndroid Build Coastguard Worker 
36*d83cc019SAndroid Build Coastguard Worker enum p_pointorigo {
37*d83cc019SAndroid Build Coastguard Worker 	p_top = 1 << 0,
38*d83cc019SAndroid Build Coastguard Worker 	p_bottom = 1 << 1,
39*d83cc019SAndroid Build Coastguard Worker 	p_left = 1 << 2,
40*d83cc019SAndroid Build Coastguard Worker 	p_right = 1 << 3
41*d83cc019SAndroid Build Coastguard Worker };
42*d83cc019SAndroid Build Coastguard Worker 
43*d83cc019SAndroid Build Coastguard Worker struct p_point{
44*d83cc019SAndroid Build Coastguard Worker 	enum p_pointorigo origo;
45*d83cc019SAndroid Build Coastguard Worker 	float_t x;
46*d83cc019SAndroid Build Coastguard Worker 	float_t y;
47*d83cc019SAndroid Build Coastguard Worker };
48*d83cc019SAndroid Build Coastguard Worker 
49*d83cc019SAndroid Build Coastguard Worker typedef struct {
50*d83cc019SAndroid Build Coastguard Worker 	int gfx_fd;
51*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display;
52*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb;
53*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb_reference;
54*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb_unrotated;
55*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb_flip;
56*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t ref_crc;
57*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t flip_crc;
58*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_t *pipe_crc;
59*d83cc019SAndroid Build Coastguard Worker 	igt_rotation_t rotation;
60*d83cc019SAndroid Build Coastguard Worker 	int pos_x;
61*d83cc019SAndroid Build Coastguard Worker 	int pos_y;
62*d83cc019SAndroid Build Coastguard Worker 	uint32_t override_fmt;
63*d83cc019SAndroid Build Coastguard Worker 	uint64_t override_tiling;
64*d83cc019SAndroid Build Coastguard Worker 	int devid;
65*d83cc019SAndroid Build Coastguard Worker 
66*d83cc019SAndroid Build Coastguard Worker 	struct p_struct *multiplaneoldview;
67*d83cc019SAndroid Build Coastguard Worker 	struct p_point planepos[MAXMULTIPLANESAMOUNT];
68*d83cc019SAndroid Build Coastguard Worker } data_t;
69*d83cc019SAndroid Build Coastguard Worker 
70*d83cc019SAndroid Build Coastguard Worker typedef struct {
71*d83cc019SAndroid Build Coastguard Worker 	float r;
72*d83cc019SAndroid Build Coastguard Worker 	float g;
73*d83cc019SAndroid Build Coastguard Worker 	float b;
74*d83cc019SAndroid Build Coastguard Worker } rgb_color_t;
75*d83cc019SAndroid Build Coastguard Worker 
set_color(rgb_color_t * color,float r,float g,float b)76*d83cc019SAndroid Build Coastguard Worker static void set_color(rgb_color_t *color, float r, float g, float b)
77*d83cc019SAndroid Build Coastguard Worker {
78*d83cc019SAndroid Build Coastguard Worker 	color->r = r;
79*d83cc019SAndroid Build Coastguard Worker 	color->g = g;
80*d83cc019SAndroid Build Coastguard Worker 	color->b = b;
81*d83cc019SAndroid Build Coastguard Worker }
82*d83cc019SAndroid Build Coastguard Worker 
rotate_colors(rgb_color_t * tl,rgb_color_t * tr,rgb_color_t * br,rgb_color_t * bl,igt_rotation_t rotation)83*d83cc019SAndroid Build Coastguard Worker static void rotate_colors(rgb_color_t *tl, rgb_color_t *tr, rgb_color_t *br,
84*d83cc019SAndroid Build Coastguard Worker 			  rgb_color_t *bl, igt_rotation_t rotation)
85*d83cc019SAndroid Build Coastguard Worker {
86*d83cc019SAndroid Build Coastguard Worker 	rgb_color_t bl_tmp, br_tmp, tl_tmp, tr_tmp;
87*d83cc019SAndroid Build Coastguard Worker 
88*d83cc019SAndroid Build Coastguard Worker 	if (rotation & IGT_REFLECT_X) {
89*d83cc019SAndroid Build Coastguard Worker 		igt_swap(*tl, *tr);
90*d83cc019SAndroid Build Coastguard Worker 		igt_swap(*bl, *br);
91*d83cc019SAndroid Build Coastguard Worker 	}
92*d83cc019SAndroid Build Coastguard Worker 
93*d83cc019SAndroid Build Coastguard Worker 	if (rotation & IGT_ROTATION_90) {
94*d83cc019SAndroid Build Coastguard Worker 		bl_tmp = *bl;
95*d83cc019SAndroid Build Coastguard Worker 		br_tmp = *br;
96*d83cc019SAndroid Build Coastguard Worker 		tl_tmp = *tl;
97*d83cc019SAndroid Build Coastguard Worker 		tr_tmp = *tr;
98*d83cc019SAndroid Build Coastguard Worker 		*tl = tr_tmp;
99*d83cc019SAndroid Build Coastguard Worker 		*bl = tl_tmp;
100*d83cc019SAndroid Build Coastguard Worker 		*tr = br_tmp;
101*d83cc019SAndroid Build Coastguard Worker 		*br = bl_tmp;
102*d83cc019SAndroid Build Coastguard Worker 	} else if (rotation & IGT_ROTATION_180) {
103*d83cc019SAndroid Build Coastguard Worker 		igt_swap(*tl, *br);
104*d83cc019SAndroid Build Coastguard Worker 		igt_swap(*tr, *bl);
105*d83cc019SAndroid Build Coastguard Worker 	} else if (rotation & IGT_ROTATION_270) {
106*d83cc019SAndroid Build Coastguard Worker 		bl_tmp = *bl;
107*d83cc019SAndroid Build Coastguard Worker 		br_tmp = *br;
108*d83cc019SAndroid Build Coastguard Worker 		tl_tmp = *tl;
109*d83cc019SAndroid Build Coastguard Worker 		tr_tmp = *tr;
110*d83cc019SAndroid Build Coastguard Worker 		*tl = bl_tmp;
111*d83cc019SAndroid Build Coastguard Worker 		*bl = br_tmp;
112*d83cc019SAndroid Build Coastguard Worker 		*tr = tl_tmp;
113*d83cc019SAndroid Build Coastguard Worker 		*br = tr_tmp;
114*d83cc019SAndroid Build Coastguard Worker 	}
115*d83cc019SAndroid Build Coastguard Worker }
116*d83cc019SAndroid Build Coastguard Worker 
117*d83cc019SAndroid Build Coastguard Worker #define RGB_COLOR(color) \
118*d83cc019SAndroid Build Coastguard Worker 	color.r, color.g, color.b
119*d83cc019SAndroid Build Coastguard Worker 
120*d83cc019SAndroid Build Coastguard Worker static void
paint_squares(data_t * data,igt_rotation_t rotation,struct igt_fb * fb,float o)121*d83cc019SAndroid Build Coastguard Worker paint_squares(data_t *data, igt_rotation_t rotation,
122*d83cc019SAndroid Build Coastguard Worker 	      struct igt_fb *fb, float o)
123*d83cc019SAndroid Build Coastguard Worker {
124*d83cc019SAndroid Build Coastguard Worker 	cairo_t *cr;
125*d83cc019SAndroid Build Coastguard Worker 	unsigned int w = fb->width;
126*d83cc019SAndroid Build Coastguard Worker 	unsigned int h = fb->height;
127*d83cc019SAndroid Build Coastguard Worker 	rgb_color_t tl, tr, bl, br;
128*d83cc019SAndroid Build Coastguard Worker 
129*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(!(w&1), "rotation image must be even width, now attempted %d\n", w);
130*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(!(h&1), "rotation image must be even height, now attempted %d\n", h);
131*d83cc019SAndroid Build Coastguard Worker 
132*d83cc019SAndroid Build Coastguard Worker 	cr = igt_get_cairo_ctx(data->gfx_fd, fb);
133*d83cc019SAndroid Build Coastguard Worker 
134*d83cc019SAndroid Build Coastguard Worker 	set_color(&tl, o, 0.0f, 0.0f);
135*d83cc019SAndroid Build Coastguard Worker 	set_color(&tr, 0.0f, o, 0.0f);
136*d83cc019SAndroid Build Coastguard Worker 	set_color(&br, o, o, o);
137*d83cc019SAndroid Build Coastguard Worker 	set_color(&bl, 0.0f, 0.0f, o);
138*d83cc019SAndroid Build Coastguard Worker 
139*d83cc019SAndroid Build Coastguard Worker 	rotate_colors(&tl, &tr, &br, &bl, rotation);
140*d83cc019SAndroid Build Coastguard Worker 
141*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, 0, 0, w / 2, h / 2, RGB_COLOR(tl));
142*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, w / 2, 0, w / 2, h / 2, RGB_COLOR(tr));
143*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, 0, h / 2, w / 2, h / 2, RGB_COLOR(bl));
144*d83cc019SAndroid Build Coastguard Worker 	igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, RGB_COLOR(br));
145*d83cc019SAndroid Build Coastguard Worker 
146*d83cc019SAndroid Build Coastguard Worker 	igt_put_cairo_ctx(data->gfx_fd, fb, cr);
147*d83cc019SAndroid Build Coastguard Worker }
148*d83cc019SAndroid Build Coastguard Worker 
remove_fbs(data_t * data)149*d83cc019SAndroid Build Coastguard Worker static void remove_fbs(data_t *data)
150*d83cc019SAndroid Build Coastguard Worker {
151*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb);
152*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb_reference);
153*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb_unrotated);
154*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb_flip);
155*d83cc019SAndroid Build Coastguard Worker }
156*d83cc019SAndroid Build Coastguard Worker 
cleanup_crtc(data_t * data)157*d83cc019SAndroid Build Coastguard Worker static void cleanup_crtc(data_t *data)
158*d83cc019SAndroid Build Coastguard Worker {
159*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
160*d83cc019SAndroid Build Coastguard Worker 
161*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_free(data->pipe_crc);
162*d83cc019SAndroid Build Coastguard Worker 	data->pipe_crc = NULL;
163*d83cc019SAndroid Build Coastguard Worker 
164*d83cc019SAndroid Build Coastguard Worker 	remove_fbs(data);
165*d83cc019SAndroid Build Coastguard Worker 
166*d83cc019SAndroid Build Coastguard Worker 	igt_display_reset(display);
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker 
prepare_crtc(data_t * data,igt_output_t * output,enum pipe pipe,igt_plane_t * plane,bool start_crc)169*d83cc019SAndroid Build Coastguard Worker static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
170*d83cc019SAndroid Build Coastguard Worker 			 igt_plane_t *plane, bool start_crc)
171*d83cc019SAndroid Build Coastguard Worker {
172*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	cleanup_crtc(data);
175*d83cc019SAndroid Build Coastguard Worker 
176*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, pipe);
177*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_rotation(plane, IGT_ROTATION_0);
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	/* create the pipe_crc object for this pipe */
180*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_free(data->pipe_crc);
181*d83cc019SAndroid Build Coastguard Worker 
182*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, COMMIT_ATOMIC);
183*d83cc019SAndroid Build Coastguard Worker 	data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
184*d83cc019SAndroid Build Coastguard Worker 
185*d83cc019SAndroid Build Coastguard Worker 	if (start_crc)
186*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_start(data->pipe_crc);
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker 
189*d83cc019SAndroid Build Coastguard Worker enum rectangle_type {
190*d83cc019SAndroid Build Coastguard Worker 	rectangle,
191*d83cc019SAndroid Build Coastguard Worker 	square,
192*d83cc019SAndroid Build Coastguard Worker 	portrait,
193*d83cc019SAndroid Build Coastguard Worker 	landscape,
194*d83cc019SAndroid Build Coastguard Worker 	num_rectangle_types /* must be last */
195*d83cc019SAndroid Build Coastguard Worker };
196*d83cc019SAndroid Build Coastguard Worker 
prepare_fbs(data_t * data,igt_output_t * output,igt_plane_t * plane,enum rectangle_type rect,uint32_t format)197*d83cc019SAndroid Build Coastguard Worker static void prepare_fbs(data_t *data, igt_output_t *output,
198*d83cc019SAndroid Build Coastguard Worker 			igt_plane_t *plane, enum rectangle_type rect, uint32_t format)
199*d83cc019SAndroid Build Coastguard Worker {
200*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
201*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
202*d83cc019SAndroid Build Coastguard Worker 	unsigned int w, h, ref_w, ref_h, min_w, min_h;
203*d83cc019SAndroid Build Coastguard Worker 	uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
204*d83cc019SAndroid Build Coastguard Worker 	uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
205*d83cc019SAndroid Build Coastguard Worker 	const float flip_opacity = 0.75;
206*d83cc019SAndroid Build Coastguard Worker 
207*d83cc019SAndroid Build Coastguard Worker 	remove_fbs(data);
208*d83cc019SAndroid Build Coastguard Worker 
209*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_rotation(plane, IGT_ROTATION_0);
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
212*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
213*d83cc019SAndroid Build Coastguard Worker 		w = mode->hdisplay;
214*d83cc019SAndroid Build Coastguard Worker 		h = mode->vdisplay;
215*d83cc019SAndroid Build Coastguard Worker 
216*d83cc019SAndroid Build Coastguard Worker 		min_w = 256;
217*d83cc019SAndroid Build Coastguard Worker 		min_h = 256;
218*d83cc019SAndroid Build Coastguard Worker 	} else {
219*d83cc019SAndroid Build Coastguard Worker 		pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 		w = h = 256;
222*d83cc019SAndroid Build Coastguard Worker 		min_w = min_h = 64;
223*d83cc019SAndroid Build Coastguard Worker 	}
224*d83cc019SAndroid Build Coastguard Worker 
225*d83cc019SAndroid Build Coastguard Worker 	switch (rect) {
226*d83cc019SAndroid Build Coastguard Worker 	case rectangle:
227*d83cc019SAndroid Build Coastguard Worker 		break;
228*d83cc019SAndroid Build Coastguard Worker 	case square:
229*d83cc019SAndroid Build Coastguard Worker 		w = h = min(h, w);
230*d83cc019SAndroid Build Coastguard Worker 		break;
231*d83cc019SAndroid Build Coastguard Worker 	case portrait:
232*d83cc019SAndroid Build Coastguard Worker 		w = min_w;
233*d83cc019SAndroid Build Coastguard Worker 		break;
234*d83cc019SAndroid Build Coastguard Worker 	case landscape:
235*d83cc019SAndroid Build Coastguard Worker 		h = min_h;
236*d83cc019SAndroid Build Coastguard Worker 		break;
237*d83cc019SAndroid Build Coastguard Worker 	case num_rectangle_types:
238*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
239*d83cc019SAndroid Build Coastguard Worker 	}
240*d83cc019SAndroid Build Coastguard Worker 
241*d83cc019SAndroid Build Coastguard Worker 	ref_w = w;
242*d83cc019SAndroid Build Coastguard Worker 	ref_h = h;
243*d83cc019SAndroid Build Coastguard Worker 
244*d83cc019SAndroid Build Coastguard Worker 	/*
245*d83cc019SAndroid Build Coastguard Worker 	 * For 90/270, we will use create smaller fb so that the rotated
246*d83cc019SAndroid Build Coastguard Worker 	 * frame can fit in
247*d83cc019SAndroid Build Coastguard Worker 	 */
248*d83cc019SAndroid Build Coastguard Worker 	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270)) {
249*d83cc019SAndroid Build Coastguard Worker 		tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
250*d83cc019SAndroid Build Coastguard Worker 
251*d83cc019SAndroid Build Coastguard Worker 		igt_swap(w, h);
252*d83cc019SAndroid Build Coastguard Worker 	}
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 	/*
255*d83cc019SAndroid Build Coastguard Worker 	 * Create a reference software rotated flip framebuffer.
256*d83cc019SAndroid Build Coastguard Worker 	 */
257*d83cc019SAndroid Build Coastguard Worker 	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling,
258*d83cc019SAndroid Build Coastguard Worker 		      &data->fb_flip);
259*d83cc019SAndroid Build Coastguard Worker 	paint_squares(data, data->rotation, &data->fb_flip,
260*d83cc019SAndroid Build Coastguard Worker 		      flip_opacity);
261*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(plane, &data->fb_flip);
262*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR)
263*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(plane, data->pos_x, data->pos_y);
264*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, COMMIT_ATOMIC);
265*d83cc019SAndroid Build Coastguard Worker 
266*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->flip_crc);
267*d83cc019SAndroid Build Coastguard Worker 
268*d83cc019SAndroid Build Coastguard Worker 	/*
269*d83cc019SAndroid Build Coastguard Worker 	  * Prepare the non-rotated flip fb.
270*d83cc019SAndroid Build Coastguard Worker 	  */
271*d83cc019SAndroid Build Coastguard Worker 	igt_remove_fb(data->gfx_fd, &data->fb_flip);
272*d83cc019SAndroid Build Coastguard Worker 	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling,
273*d83cc019SAndroid Build Coastguard Worker 		      &data->fb_flip);
274*d83cc019SAndroid Build Coastguard Worker 	paint_squares(data, IGT_ROTATION_0, &data->fb_flip,
275*d83cc019SAndroid Build Coastguard Worker 		      flip_opacity);
276*d83cc019SAndroid Build Coastguard Worker 
277*d83cc019SAndroid Build Coastguard Worker 	/*
278*d83cc019SAndroid Build Coastguard Worker 	 * Create a reference CRC for a software-rotated fb.
279*d83cc019SAndroid Build Coastguard Worker 	 */
280*d83cc019SAndroid Build Coastguard Worker 	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
281*d83cc019SAndroid Build Coastguard Worker 		      data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);
282*d83cc019SAndroid Build Coastguard Worker 	paint_squares(data, data->rotation, &data->fb_reference, 1.0);
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(plane, &data->fb_reference);
285*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR)
286*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(plane, data->pos_x, data->pos_y);
287*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, COMMIT_ATOMIC);
288*d83cc019SAndroid Build Coastguard Worker 
289*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &data->ref_crc);
290*d83cc019SAndroid Build Coastguard Worker 
291*d83cc019SAndroid Build Coastguard Worker 	/*
292*d83cc019SAndroid Build Coastguard Worker 	 * Prepare the non-rotated reference fb.
293*d83cc019SAndroid Build Coastguard Worker 	 */
294*d83cc019SAndroid Build Coastguard Worker 	igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format, tiling, &data->fb_unrotated);
295*d83cc019SAndroid Build Coastguard Worker 	paint_squares(data, IGT_ROTATION_0, &data->fb_unrotated, 1.0);
296*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(plane, &data->fb_unrotated);
297*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_rotation(plane, IGT_ROTATION_0);
298*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR)
299*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(plane, data->pos_x, data->pos_y);
300*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, COMMIT_ATOMIC);
301*d83cc019SAndroid Build Coastguard Worker 
302*d83cc019SAndroid Build Coastguard Worker 	/*
303*d83cc019SAndroid Build Coastguard Worker 	 * Prepare the plane with an non-rotated fb let the hw rotate it.
304*d83cc019SAndroid Build Coastguard Worker 	 */
305*d83cc019SAndroid Build Coastguard Worker 	igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
306*d83cc019SAndroid Build Coastguard Worker 	paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
307*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(plane, &data->fb);
308*d83cc019SAndroid Build Coastguard Worker 
309*d83cc019SAndroid Build Coastguard Worker 	if (plane->type != DRM_PLANE_TYPE_CURSOR)
310*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(plane, data->pos_x, data->pos_y);
311*d83cc019SAndroid Build Coastguard Worker }
312*d83cc019SAndroid Build Coastguard Worker 
test_single_case(data_t * data,enum pipe pipe,igt_output_t * output,igt_plane_t * plane,enum rectangle_type rect,uint32_t format,bool test_bad_format)313*d83cc019SAndroid Build Coastguard Worker static void test_single_case(data_t *data, enum pipe pipe,
314*d83cc019SAndroid Build Coastguard Worker 			     igt_output_t *output, igt_plane_t *plane,
315*d83cc019SAndroid Build Coastguard Worker 			     enum rectangle_type rect,
316*d83cc019SAndroid Build Coastguard Worker 			     uint32_t format, bool test_bad_format)
317*d83cc019SAndroid Build Coastguard Worker {
318*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
319*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t crc_output;
320*d83cc019SAndroid Build Coastguard Worker 	int ret;
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Testing case %i on pipe %s, format %s\n", rect, kmstest_pipe_name(pipe), igt_format_str(format));
323*d83cc019SAndroid Build Coastguard Worker 	prepare_fbs(data, output, plane, rect, format);
324*d83cc019SAndroid Build Coastguard Worker 
325*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_rotation(plane, data->rotation);
326*d83cc019SAndroid Build Coastguard Worker 	if (data->rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
327*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_size(plane, data->fb.height, data->fb.width);
328*d83cc019SAndroid Build Coastguard Worker 
329*d83cc019SAndroid Build Coastguard Worker 	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
330*d83cc019SAndroid Build Coastguard Worker 	if (test_bad_format) {
331*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(ret, -EINVAL);
332*d83cc019SAndroid Build Coastguard Worker 		return;
333*d83cc019SAndroid Build Coastguard Worker 	}
334*d83cc019SAndroid Build Coastguard Worker 
335*d83cc019SAndroid Build Coastguard Worker 	/* Verify commit was ok. */
336*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
337*d83cc019SAndroid Build Coastguard Worker 
338*d83cc019SAndroid Build Coastguard Worker 	/* Check CRC */
339*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
340*d83cc019SAndroid Build Coastguard Worker 	igt_assert_crc_equal(&data->ref_crc, &crc_output);
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 	/*
343*d83cc019SAndroid Build Coastguard Worker 	 * If flips are requested flip to a different fb and
344*d83cc019SAndroid Build Coastguard Worker 	 * check CRC against that one as well.
345*d83cc019SAndroid Build Coastguard Worker 	 */
346*d83cc019SAndroid Build Coastguard Worker 	if (data->fb_flip.fb_id) {
347*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(plane, &data->fb_flip);
348*d83cc019SAndroid Build Coastguard Worker 		if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
349*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_size(plane, data->fb.height, data->fb.width);
350*d83cc019SAndroid Build Coastguard Worker 
351*d83cc019SAndroid Build Coastguard Worker 		if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
352*d83cc019SAndroid Build Coastguard Worker 			igt_display_commit_atomic(display, DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, NULL);
353*d83cc019SAndroid Build Coastguard Worker 		} else {
354*d83cc019SAndroid Build Coastguard Worker 			ret = drmModePageFlip(data->gfx_fd,
355*d83cc019SAndroid Build Coastguard Worker 					output->config.crtc->crtc_id,
356*d83cc019SAndroid Build Coastguard Worker 					data->fb_flip.fb_id,
357*d83cc019SAndroid Build Coastguard Worker 					DRM_MODE_PAGE_FLIP_EVENT,
358*d83cc019SAndroid Build Coastguard Worker 					NULL);
359*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(ret, 0);
360*d83cc019SAndroid Build Coastguard Worker 		}
361*d83cc019SAndroid Build Coastguard Worker 		kmstest_wait_for_pageflip(data->gfx_fd);
362*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_get_current(display->drm_fd, data->pipe_crc, &crc_output);
363*d83cc019SAndroid Build Coastguard Worker 		igt_assert_crc_equal(&data->flip_crc,
364*d83cc019SAndroid Build Coastguard Worker 				     &crc_output);
365*d83cc019SAndroid Build Coastguard Worker 	}
366*d83cc019SAndroid Build Coastguard Worker }
367*d83cc019SAndroid Build Coastguard Worker 
test_plane_rotation(data_t * data,int plane_type,bool test_bad_format)368*d83cc019SAndroid Build Coastguard Worker static void test_plane_rotation(data_t *data, int plane_type, bool test_bad_format)
369*d83cc019SAndroid Build Coastguard Worker {
370*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
371*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
372*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
373*d83cc019SAndroid Build Coastguard Worker 
374*d83cc019SAndroid Build Coastguard Worker 	if (plane_type == DRM_PLANE_TYPE_CURSOR)
375*d83cc019SAndroid Build Coastguard Worker 		igt_require(display->has_cursor_plane);
376*d83cc019SAndroid Build Coastguard Worker 
377*d83cc019SAndroid Build Coastguard Worker 	igt_display_require_output(display);
378*d83cc019SAndroid Build Coastguard Worker 
379*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe_with_valid_output(display, pipe, output) {
380*d83cc019SAndroid Build Coastguard Worker 		igt_plane_t *plane;
381*d83cc019SAndroid Build Coastguard Worker 		int i, j;
382*d83cc019SAndroid Build Coastguard Worker 
383*d83cc019SAndroid Build Coastguard Worker 		if (IS_CHERRYVIEW(data->devid) && pipe != PIPE_B)
384*d83cc019SAndroid Build Coastguard Worker 			continue;
385*d83cc019SAndroid Build Coastguard Worker 
386*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
387*d83cc019SAndroid Build Coastguard Worker 
388*d83cc019SAndroid Build Coastguard Worker 		plane = igt_output_get_plane_type(output, plane_type);
389*d83cc019SAndroid Build Coastguard Worker 		igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
390*d83cc019SAndroid Build Coastguard Worker 
391*d83cc019SAndroid Build Coastguard Worker 		prepare_crtc(data, output, pipe, plane, true);
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < num_rectangle_types; i++) {
394*d83cc019SAndroid Build Coastguard Worker 			/* Unsupported on i915 */
395*d83cc019SAndroid Build Coastguard Worker 			if (plane_type == DRM_PLANE_TYPE_CURSOR &&
396*d83cc019SAndroid Build Coastguard Worker 			    i != square)
397*d83cc019SAndroid Build Coastguard Worker 				continue;
398*d83cc019SAndroid Build Coastguard Worker 
399*d83cc019SAndroid Build Coastguard Worker 			/* Only support partial covering primary plane on gen9+ */
400*d83cc019SAndroid Build Coastguard Worker 			if (plane_type == DRM_PLANE_TYPE_PRIMARY &&
401*d83cc019SAndroid Build Coastguard Worker 			    i != rectangle && intel_gen(intel_get_drm_devid(data->gfx_fd)) < 9)
402*d83cc019SAndroid Build Coastguard Worker 				continue;
403*d83cc019SAndroid Build Coastguard Worker 
404*d83cc019SAndroid Build Coastguard Worker 			if (!data->override_fmt) {
405*d83cc019SAndroid Build Coastguard Worker 				for (j = 0; j < plane->drm_plane->count_formats; j++) {
406*d83cc019SAndroid Build Coastguard Worker 					uint32_t format = plane->drm_plane->formats[j];
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 					if (!igt_fb_supported_format(format))
409*d83cc019SAndroid Build Coastguard Worker 						continue;
410*d83cc019SAndroid Build Coastguard Worker 
411*d83cc019SAndroid Build Coastguard Worker 					test_single_case(data, pipe, output, plane, i,
412*d83cc019SAndroid Build Coastguard Worker 							 format, test_bad_format);
413*d83cc019SAndroid Build Coastguard Worker 				}
414*d83cc019SAndroid Build Coastguard Worker 			} else {
415*d83cc019SAndroid Build Coastguard Worker 				test_single_case(data, pipe, output, plane, i,
416*d83cc019SAndroid Build Coastguard Worker 						 data->override_fmt, test_bad_format);
417*d83cc019SAndroid Build Coastguard Worker 			}
418*d83cc019SAndroid Build Coastguard Worker 		}
419*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_stop(data->pipe_crc);
420*d83cc019SAndroid Build Coastguard Worker 	}
421*d83cc019SAndroid Build Coastguard Worker }
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker typedef struct {
424*d83cc019SAndroid Build Coastguard Worker 	int32_t x1, y1;
425*d83cc019SAndroid Build Coastguard Worker 	uint64_t width, height, tiling, planetype, format;
426*d83cc019SAndroid Build Coastguard Worker 	igt_rotation_t rotation_sw, rotation_hw;
427*d83cc019SAndroid Build Coastguard Worker } planeinfos;
428*d83cc019SAndroid Build Coastguard Worker 
get_multiplane_crc(data_t * data,igt_output_t * output,igt_crc_t * crc_output,planeinfos * planeinfo,int numplanes)429*d83cc019SAndroid Build Coastguard Worker static bool get_multiplane_crc(data_t *data, igt_output_t *output,
430*d83cc019SAndroid Build Coastguard Worker 			       igt_crc_t *crc_output, planeinfos *planeinfo,
431*d83cc019SAndroid Build Coastguard Worker 			       int numplanes)
432*d83cc019SAndroid Build Coastguard Worker {
433*d83cc019SAndroid Build Coastguard Worker 	uint32_t w, h;
434*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
435*d83cc019SAndroid Build Coastguard Worker 	struct p_struct *planes, *oldplanes;
436*d83cc019SAndroid Build Coastguard Worker 	int c, ret;
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 	oldplanes = data->multiplaneoldview;
439*d83cc019SAndroid Build Coastguard Worker 	planes = calloc(sizeof(*planes), numplanes);
440*d83cc019SAndroid Build Coastguard Worker 
441*d83cc019SAndroid Build Coastguard Worker 	for (c = 0; c < numplanes; c++) {
442*d83cc019SAndroid Build Coastguard Worker 		planes[c].plane = igt_output_get_plane_type(output,
443*d83cc019SAndroid Build Coastguard Worker 							    planeinfo[c].planetype);
444*d83cc019SAndroid Build Coastguard Worker 
445*d83cc019SAndroid Build Coastguard Worker 		/*
446*d83cc019SAndroid Build Coastguard Worker 		 * make plane and fb width and height always divisible by 4
447*d83cc019SAndroid Build Coastguard Worker 		 * due to NV12 support and Intel hw workarounds.
448*d83cc019SAndroid Build Coastguard Worker 		 */
449*d83cc019SAndroid Build Coastguard Worker 		w = planeinfo[c].width & ~3;
450*d83cc019SAndroid Build Coastguard Worker 		h = planeinfo[c].height & ~3;
451*d83cc019SAndroid Build Coastguard Worker 
452*d83cc019SAndroid Build Coastguard Worker 		if (planeinfo[c].rotation_sw & (IGT_ROTATION_90 | IGT_ROTATION_270))
453*d83cc019SAndroid Build Coastguard Worker 			igt_swap(w, h);
454*d83cc019SAndroid Build Coastguard Worker 
455*d83cc019SAndroid Build Coastguard Worker 		if (!igt_plane_has_format_mod(planes[c].plane,
456*d83cc019SAndroid Build Coastguard Worker 					      planeinfo[c].format,
457*d83cc019SAndroid Build Coastguard Worker 					      planeinfo[c].tiling))
458*d83cc019SAndroid Build Coastguard Worker 			return false;
459*d83cc019SAndroid Build Coastguard Worker 
460*d83cc019SAndroid Build Coastguard Worker 		igt_create_fb(data->gfx_fd, w, h, planeinfo[c].format,
461*d83cc019SAndroid Build Coastguard Worker 			      planeinfo[c].tiling, &planes[c].fb);
462*d83cc019SAndroid Build Coastguard Worker 
463*d83cc019SAndroid Build Coastguard Worker 		paint_squares(data, planeinfo[c].rotation_sw, &planes[c].fb, 1.0f);
464*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(planes[c].plane, &planes[c].fb);
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 		if (planeinfo[c].rotation_hw & (IGT_ROTATION_90 | IGT_ROTATION_270))
467*d83cc019SAndroid Build Coastguard Worker 			igt_plane_set_size(planes[c].plane, h, w);
468*d83cc019SAndroid Build Coastguard Worker 
469*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_position(planes[c].plane, planeinfo[c].x1, planeinfo[c].y1);
470*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_rotation(planes[c].plane, planeinfo[c].rotation_hw);
471*d83cc019SAndroid Build Coastguard Worker 	}
472*d83cc019SAndroid Build Coastguard Worker 
473*d83cc019SAndroid Build Coastguard Worker 	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
474*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(ret, 0);
475*d83cc019SAndroid Build Coastguard Worker 
476*d83cc019SAndroid Build Coastguard Worker 	igt_pipe_crc_get_current(data->gfx_fd, data->pipe_crc, crc_output);
477*d83cc019SAndroid Build Coastguard Worker 
478*d83cc019SAndroid Build Coastguard Worker 	for (c = 0; c < numplanes && oldplanes; c++)
479*d83cc019SAndroid Build Coastguard Worker 		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
480*d83cc019SAndroid Build Coastguard Worker 
481*d83cc019SAndroid Build Coastguard Worker 	free(oldplanes);
482*d83cc019SAndroid Build Coastguard Worker 	data->multiplaneoldview = (void*)planes;
483*d83cc019SAndroid Build Coastguard Worker 	return true;
484*d83cc019SAndroid Build Coastguard Worker }
485*d83cc019SAndroid Build Coastguard Worker 
pointlocation(data_t * data,planeinfos * p,drmModeModeInfo * mode,int c)486*d83cc019SAndroid Build Coastguard Worker static void pointlocation(data_t *data, planeinfos *p, drmModeModeInfo *mode,
487*d83cc019SAndroid Build Coastguard Worker 			  int c)
488*d83cc019SAndroid Build Coastguard Worker {
489*d83cc019SAndroid Build Coastguard Worker 	if (data->planepos[c].origo & p_right) {
490*d83cc019SAndroid Build Coastguard Worker 		p[c].x1 = (int32_t)(data->planepos[c].x * mode->hdisplay
491*d83cc019SAndroid Build Coastguard Worker 				+ mode->hdisplay);
492*d83cc019SAndroid Build Coastguard Worker 		p[c].x1 &= ~3;
493*d83cc019SAndroid Build Coastguard Worker 		/*
494*d83cc019SAndroid Build Coastguard Worker 		 * At this point is handled surface on right side. If display
495*d83cc019SAndroid Build Coastguard Worker 		 * mode is not divisible by 4 but with 2 point location is
496*d83cc019SAndroid Build Coastguard Worker 		 * fixed to match requirements. Because of YUV planes here is
497*d83cc019SAndroid Build Coastguard Worker 		 * intentionally ignored bit 1.
498*d83cc019SAndroid Build Coastguard Worker 		 */
499*d83cc019SAndroid Build Coastguard Worker 		p[c].x1 -= mode->hdisplay & 2;
500*d83cc019SAndroid Build Coastguard Worker 	} else {
501*d83cc019SAndroid Build Coastguard Worker 		p[c].x1 = (int32_t)(data->planepos[c].x * mode->hdisplay);
502*d83cc019SAndroid Build Coastguard Worker 		p[c].x1 &= ~3;
503*d83cc019SAndroid Build Coastguard Worker 	}
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 	if (data->planepos[c].origo & p_bottom) {
506*d83cc019SAndroid Build Coastguard Worker 		p[c].y1 = (int32_t)(data->planepos[c].y * mode->vdisplay
507*d83cc019SAndroid Build Coastguard Worker 				+ mode->vdisplay);
508*d83cc019SAndroid Build Coastguard Worker 		p[c].y1 &= ~3;
509*d83cc019SAndroid Build Coastguard Worker 		p[c].y1 -= mode->vdisplay & 2;
510*d83cc019SAndroid Build Coastguard Worker 	} else {
511*d83cc019SAndroid Build Coastguard Worker 		p[c].y1 = (int32_t)(data->planepos[c].y * mode->vdisplay);
512*d83cc019SAndroid Build Coastguard Worker 		p[c].y1 &= ~3;
513*d83cc019SAndroid Build Coastguard Worker 	}
514*d83cc019SAndroid Build Coastguard Worker }
515*d83cc019SAndroid Build Coastguard Worker 
516*d83cc019SAndroid Build Coastguard Worker /*
517*d83cc019SAndroid Build Coastguard Worker  * Here is pipe parameter which is now used only for first pipe.
518*d83cc019SAndroid Build Coastguard Worker  * It is left here if this test ever was wanted to be run on
519*d83cc019SAndroid Build Coastguard Worker  * different pipes.
520*d83cc019SAndroid Build Coastguard Worker  */
test_multi_plane_rotation(data_t * data,enum pipe pipe)521*d83cc019SAndroid Build Coastguard Worker static void test_multi_plane_rotation(data_t *data, enum pipe pipe)
522*d83cc019SAndroid Build Coastguard Worker {
523*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
524*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
525*d83cc019SAndroid Build Coastguard Worker 	igt_crc_t retcrc_sw, retcrc_hw;
526*d83cc019SAndroid Build Coastguard Worker 	planeinfos p[2];
527*d83cc019SAndroid Build Coastguard Worker 	int c;
528*d83cc019SAndroid Build Coastguard Worker 	struct p_struct *oldplanes;
529*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
530*d83cc019SAndroid Build Coastguard Worker 
531*d83cc019SAndroid Build Coastguard Worker 	static const struct {
532*d83cc019SAndroid Build Coastguard Worker 		igt_rotation_t rotation;
533*d83cc019SAndroid Build Coastguard Worker 		float_t width;
534*d83cc019SAndroid Build Coastguard Worker 		float_t height;
535*d83cc019SAndroid Build Coastguard Worker 		uint64_t tiling;
536*d83cc019SAndroid Build Coastguard Worker 	} planeconfigs[] = {
537*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_0, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
538*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
539*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
540*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_0, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
541*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
542*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_90, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
543*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_180, .2f, .4f, LOCAL_DRM_FORMAT_MOD_NONE },
544*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_X_TILED },
545*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
546*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_180, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
547*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Y_TILED },
548*d83cc019SAndroid Build Coastguard Worker 	{IGT_ROTATION_270, .2f, .4f, LOCAL_I915_FORMAT_MOD_Yf_TILED },
549*d83cc019SAndroid Build Coastguard Worker 	};
550*d83cc019SAndroid Build Coastguard Worker 
551*d83cc019SAndroid Build Coastguard Worker 	/*
552*d83cc019SAndroid Build Coastguard Worker 	* These are those modes which are tested. For testing feel interesting
553*d83cc019SAndroid Build Coastguard Worker 	* case with tiling are 2 bpp, 4 bpp and NV12.
554*d83cc019SAndroid Build Coastguard Worker 	*/
555*d83cc019SAndroid Build Coastguard Worker 	static const uint32_t formatlist[] = {DRM_FORMAT_RGB565,
556*d83cc019SAndroid Build Coastguard Worker 		DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
557*d83cc019SAndroid Build Coastguard Worker 
558*d83cc019SAndroid Build Coastguard Worker 	for_each_valid_output_on_pipe(display, pipe, output) {
559*d83cc019SAndroid Build Coastguard Worker 		int i, j, k, l;
560*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, pipe);
561*d83cc019SAndroid Build Coastguard Worker 		mode = igt_output_get_mode(output);
562*d83cc019SAndroid Build Coastguard Worker 		igt_display_require_output(display);
563*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(display, COMMIT_ATOMIC);
564*d83cc019SAndroid Build Coastguard Worker 
565*d83cc019SAndroid Build Coastguard Worker 		data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe,
566*d83cc019SAndroid Build Coastguard Worker 						  INTEL_PIPE_CRC_SOURCE_AUTO);
567*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_start(data->pipe_crc);
568*d83cc019SAndroid Build Coastguard Worker 
569*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < ARRAY_SIZE(planeconfigs); i++) {
570*d83cc019SAndroid Build Coastguard Worker 			p[0].planetype = DRM_PLANE_TYPE_PRIMARY;
571*d83cc019SAndroid Build Coastguard Worker 			p[0].width = (uint64_t)(planeconfigs[i].width * mode->hdisplay);
572*d83cc019SAndroid Build Coastguard Worker 			p[0].height = (uint64_t)(planeconfigs[i].height * mode->vdisplay);
573*d83cc019SAndroid Build Coastguard Worker 			p[0].tiling = planeconfigs[i].tiling;
574*d83cc019SAndroid Build Coastguard Worker 			pointlocation(data, (planeinfos *)&p, mode, 0);
575*d83cc019SAndroid Build Coastguard Worker 
576*d83cc019SAndroid Build Coastguard Worker 			for (k = 0; k < ARRAY_SIZE(formatlist); k++) {
577*d83cc019SAndroid Build Coastguard Worker 				p[0].format = formatlist[k];
578*d83cc019SAndroid Build Coastguard Worker 
579*d83cc019SAndroid Build Coastguard Worker 				for (j = 0; j < ARRAY_SIZE(planeconfigs); j++) {
580*d83cc019SAndroid Build Coastguard Worker 					p[1].planetype = DRM_PLANE_TYPE_OVERLAY;
581*d83cc019SAndroid Build Coastguard Worker 					p[1].width = (uint64_t)(planeconfigs[j].width * mode->hdisplay);
582*d83cc019SAndroid Build Coastguard Worker 					p[1].height = (uint64_t)(planeconfigs[j].height * mode->vdisplay);
583*d83cc019SAndroid Build Coastguard Worker 					p[1].tiling = planeconfigs[j].tiling;
584*d83cc019SAndroid Build Coastguard Worker 					pointlocation(data, (planeinfos *)&p,
585*d83cc019SAndroid Build Coastguard Worker 						      mode, 1);
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker 					for (l = 0; l < ARRAY_SIZE(formatlist); l++) {
588*d83cc019SAndroid Build Coastguard Worker 						p[1].format = formatlist[l];
589*d83cc019SAndroid Build Coastguard Worker 
590*d83cc019SAndroid Build Coastguard Worker 						/*
591*d83cc019SAndroid Build Coastguard Worker 						 * RGB565 90/270 degrees rotation is supported
592*d83cc019SAndroid Build Coastguard Worker 						 * from gen11 onwards.
593*d83cc019SAndroid Build Coastguard Worker 						 */
594*d83cc019SAndroid Build Coastguard Worker 						if (p[0].format == DRM_FORMAT_RGB565 &&
595*d83cc019SAndroid Build Coastguard Worker 						     (planeconfigs[i].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
596*d83cc019SAndroid Build Coastguard Worker 						     && intel_gen(data->devid) < 11)
597*d83cc019SAndroid Build Coastguard Worker 							continue;
598*d83cc019SAndroid Build Coastguard Worker 
599*d83cc019SAndroid Build Coastguard Worker 						if (p[1].format == DRM_FORMAT_RGB565 &&
600*d83cc019SAndroid Build Coastguard Worker 						     (planeconfigs[j].rotation & (IGT_ROTATION_90 | IGT_ROTATION_270))
601*d83cc019SAndroid Build Coastguard Worker 						     && intel_gen(data->devid) < 11)
602*d83cc019SAndroid Build Coastguard Worker 							continue;
603*d83cc019SAndroid Build Coastguard Worker 
604*d83cc019SAndroid Build Coastguard Worker 						p[0].rotation_sw = planeconfigs[i].rotation;
605*d83cc019SAndroid Build Coastguard Worker 						p[0].rotation_hw = IGT_ROTATION_0;
606*d83cc019SAndroid Build Coastguard Worker 						p[1].rotation_sw = planeconfigs[j].rotation;
607*d83cc019SAndroid Build Coastguard Worker 						p[1].rotation_hw = IGT_ROTATION_0;
608*d83cc019SAndroid Build Coastguard Worker 						if (!get_multiplane_crc(data, output, &retcrc_sw,
609*d83cc019SAndroid Build Coastguard Worker 								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
610*d83cc019SAndroid Build Coastguard Worker 							continue;
611*d83cc019SAndroid Build Coastguard Worker 
612*d83cc019SAndroid Build Coastguard Worker 						igt_swap(p[0].rotation_sw, p[0].rotation_hw);
613*d83cc019SAndroid Build Coastguard Worker 						igt_swap(p[1].rotation_sw, p[1].rotation_hw);
614*d83cc019SAndroid Build Coastguard Worker 						if (!get_multiplane_crc(data, output, &retcrc_hw,
615*d83cc019SAndroid Build Coastguard Worker 								   (planeinfos *)&p, MAXMULTIPLANESAMOUNT))
616*d83cc019SAndroid Build Coastguard Worker 							continue;
617*d83cc019SAndroid Build Coastguard Worker 
618*d83cc019SAndroid Build Coastguard Worker 						igt_assert_crc_equal(&retcrc_sw, &retcrc_hw);
619*d83cc019SAndroid Build Coastguard Worker 					}
620*d83cc019SAndroid Build Coastguard Worker 				}
621*d83cc019SAndroid Build Coastguard Worker 			}
622*d83cc019SAndroid Build Coastguard Worker 		}
623*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_stop(data->pipe_crc);
624*d83cc019SAndroid Build Coastguard Worker 		igt_pipe_crc_free(data->pipe_crc);
625*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, PIPE_ANY);
626*d83cc019SAndroid Build Coastguard Worker 	}
627*d83cc019SAndroid Build Coastguard Worker 
628*d83cc019SAndroid Build Coastguard Worker 	/*
629*d83cc019SAndroid Build Coastguard Worker 	* Old fbs are deleted only after new ones are set on planes.
630*d83cc019SAndroid Build Coastguard Worker 	* This is done to speed up the test
631*d83cc019SAndroid Build Coastguard Worker 	*/
632*d83cc019SAndroid Build Coastguard Worker 	oldplanes = data->multiplaneoldview;
633*d83cc019SAndroid Build Coastguard Worker 	for (c = 0; c < MAXMULTIPLANESAMOUNT && oldplanes; c++)
634*d83cc019SAndroid Build Coastguard Worker 		igt_remove_fb(data->gfx_fd, &oldplanes[c].fb);
635*d83cc019SAndroid Build Coastguard Worker 
636*d83cc019SAndroid Build Coastguard Worker 	free(oldplanes);
637*d83cc019SAndroid Build Coastguard Worker 	data->multiplaneoldview = NULL;
638*d83cc019SAndroid Build Coastguard Worker 	data->pipe_crc = NULL;
639*d83cc019SAndroid Build Coastguard Worker }
640*d83cc019SAndroid Build Coastguard Worker 
test_plane_rotation_exhaust_fences(data_t * data,enum pipe pipe,igt_output_t * output,igt_plane_t * plane)641*d83cc019SAndroid Build Coastguard Worker static void test_plane_rotation_exhaust_fences(data_t *data,
642*d83cc019SAndroid Build Coastguard Worker 					       enum pipe pipe,
643*d83cc019SAndroid Build Coastguard Worker 					       igt_output_t *output,
644*d83cc019SAndroid Build Coastguard Worker 					       igt_plane_t *plane)
645*d83cc019SAndroid Build Coastguard Worker {
646*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data->display;
647*d83cc019SAndroid Build Coastguard Worker 	uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
648*d83cc019SAndroid Build Coastguard Worker 	uint32_t format = DRM_FORMAT_XRGB8888;
649*d83cc019SAndroid Build Coastguard Worker 	int fd = data->gfx_fd;
650*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo *mode;
651*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb fb[MAX_FENCES+1] = {};
652*d83cc019SAndroid Build Coastguard Worker 	uint64_t size;
653*d83cc019SAndroid Build Coastguard Worker 	unsigned int stride, w, h;
654*d83cc019SAndroid Build Coastguard Worker 	uint64_t total_aperture_size, total_fbs_size;
655*d83cc019SAndroid Build Coastguard Worker 	int i;
656*d83cc019SAndroid Build Coastguard Worker 
657*d83cc019SAndroid Build Coastguard Worker 	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
658*d83cc019SAndroid Build Coastguard Worker 
659*d83cc019SAndroid Build Coastguard Worker 	prepare_crtc(data, output, pipe, plane, false);
660*d83cc019SAndroid Build Coastguard Worker 
661*d83cc019SAndroid Build Coastguard Worker 	mode = igt_output_get_mode(output);
662*d83cc019SAndroid Build Coastguard Worker 	w = mode->hdisplay;
663*d83cc019SAndroid Build Coastguard Worker 	h = mode->vdisplay;
664*d83cc019SAndroid Build Coastguard Worker 
665*d83cc019SAndroid Build Coastguard Worker 	igt_calc_fb_size(fd, w, h, format, tiling, &size, &stride);
666*d83cc019SAndroid Build Coastguard Worker 
667*d83cc019SAndroid Build Coastguard Worker 	/*
668*d83cc019SAndroid Build Coastguard Worker 	 * Make sure there is atleast 90% of the available GTT space left
669*d83cc019SAndroid Build Coastguard Worker 	 * for creating (MAX_FENCES+1) framebuffers.
670*d83cc019SAndroid Build Coastguard Worker 	 */
671*d83cc019SAndroid Build Coastguard Worker 	total_fbs_size = size * (MAX_FENCES + 1);
672*d83cc019SAndroid Build Coastguard Worker 	total_aperture_size = gem_available_aperture_size(fd);
673*d83cc019SAndroid Build Coastguard Worker 	igt_require(total_fbs_size < total_aperture_size * 0.9);
674*d83cc019SAndroid Build Coastguard Worker 
675*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_FENCES + 1; i++) {
676*d83cc019SAndroid Build Coastguard Worker 		igt_create_fb(fd, w, h, format, tiling, &fb[i]);
677*d83cc019SAndroid Build Coastguard Worker 
678*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(plane, &fb[i]);
679*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_rotation(plane, IGT_ROTATION_0);
680*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(display, COMMIT_ATOMIC);
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_rotation(plane, IGT_ROTATION_90);
683*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_size(plane, h, w);
684*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(display, COMMIT_ATOMIC);
685*d83cc019SAndroid Build Coastguard Worker 	}
686*d83cc019SAndroid Build Coastguard Worker 
687*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_FENCES + 1; i++)
688*d83cc019SAndroid Build Coastguard Worker 		igt_remove_fb(fd, &fb[i]);
689*d83cc019SAndroid Build Coastguard Worker }
690*d83cc019SAndroid Build Coastguard Worker 
plane_test_str(unsigned plane)691*d83cc019SAndroid Build Coastguard Worker static const char *plane_test_str(unsigned plane)
692*d83cc019SAndroid Build Coastguard Worker {
693*d83cc019SAndroid Build Coastguard Worker 	switch (plane) {
694*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_PRIMARY:
695*d83cc019SAndroid Build Coastguard Worker 		return "primary";
696*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_OVERLAY:
697*d83cc019SAndroid Build Coastguard Worker 		return "sprite";
698*d83cc019SAndroid Build Coastguard Worker 	case DRM_PLANE_TYPE_CURSOR:
699*d83cc019SAndroid Build Coastguard Worker 		return "cursor";
700*d83cc019SAndroid Build Coastguard Worker 	default:
701*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
702*d83cc019SAndroid Build Coastguard Worker 	}
703*d83cc019SAndroid Build Coastguard Worker }
704*d83cc019SAndroid Build Coastguard Worker 
rot_test_str(igt_rotation_t rot)705*d83cc019SAndroid Build Coastguard Worker static const char *rot_test_str(igt_rotation_t rot)
706*d83cc019SAndroid Build Coastguard Worker {
707*d83cc019SAndroid Build Coastguard Worker 	switch (rot) {
708*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_0:
709*d83cc019SAndroid Build Coastguard Worker 		return "0";
710*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_90:
711*d83cc019SAndroid Build Coastguard Worker 		return "90";
712*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_180:
713*d83cc019SAndroid Build Coastguard Worker 		return "180";
714*d83cc019SAndroid Build Coastguard Worker 	case IGT_ROTATION_270:
715*d83cc019SAndroid Build Coastguard Worker 		return "270";
716*d83cc019SAndroid Build Coastguard Worker 	default:
717*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
718*d83cc019SAndroid Build Coastguard Worker 	}
719*d83cc019SAndroid Build Coastguard Worker }
720*d83cc019SAndroid Build Coastguard Worker 
tiling_test_str(uint64_t tiling)721*d83cc019SAndroid Build Coastguard Worker static const char *tiling_test_str(uint64_t tiling)
722*d83cc019SAndroid Build Coastguard Worker {
723*d83cc019SAndroid Build Coastguard Worker 	switch (tiling) {
724*d83cc019SAndroid Build Coastguard Worker 	case LOCAL_I915_FORMAT_MOD_X_TILED:
725*d83cc019SAndroid Build Coastguard Worker 		return "x-tiled";
726*d83cc019SAndroid Build Coastguard Worker 	case LOCAL_I915_FORMAT_MOD_Y_TILED:
727*d83cc019SAndroid Build Coastguard Worker 		return "y-tiled";
728*d83cc019SAndroid Build Coastguard Worker 	case LOCAL_I915_FORMAT_MOD_Yf_TILED:
729*d83cc019SAndroid Build Coastguard Worker 		return "yf-tiled";
730*d83cc019SAndroid Build Coastguard Worker 	default:
731*d83cc019SAndroid Build Coastguard Worker 		igt_assert(0);
732*d83cc019SAndroid Build Coastguard Worker 	}
733*d83cc019SAndroid Build Coastguard Worker }
734*d83cc019SAndroid Build Coastguard Worker 
735*d83cc019SAndroid Build Coastguard Worker igt_main
736*d83cc019SAndroid Build Coastguard Worker {
737*d83cc019SAndroid Build Coastguard Worker 	struct rot_subtest {
738*d83cc019SAndroid Build Coastguard Worker 		unsigned plane;
739*d83cc019SAndroid Build Coastguard Worker 		igt_rotation_t rot;
740*d83cc019SAndroid Build Coastguard Worker 	} *subtest, subtests[] = {
741*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_90 },
742*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_180 },
743*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_PRIMARY, IGT_ROTATION_270 },
744*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_90 },
745*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_180 },
746*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_OVERLAY, IGT_ROTATION_270 },
747*d83cc019SAndroid Build Coastguard Worker 		{ DRM_PLANE_TYPE_CURSOR, IGT_ROTATION_180 },
748*d83cc019SAndroid Build Coastguard Worker 		{ 0, 0}
749*d83cc019SAndroid Build Coastguard Worker 	};
750*d83cc019SAndroid Build Coastguard Worker 
751*d83cc019SAndroid Build Coastguard Worker 	struct reflect_x {
752*d83cc019SAndroid Build Coastguard Worker 		uint64_t tiling;
753*d83cc019SAndroid Build Coastguard Worker 		igt_rotation_t rot;
754*d83cc019SAndroid Build Coastguard Worker 	} *reflect_x, reflect_x_subtests[] = {
755*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_0 },
756*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_X_TILED, IGT_ROTATION_180 },
757*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_0 },
758*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_90 },
759*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_180 },
760*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Y_TILED, IGT_ROTATION_270 },
761*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_0 },
762*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_90 },
763*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_180 },
764*d83cc019SAndroid Build Coastguard Worker 		{ LOCAL_I915_FORMAT_MOD_Yf_TILED, IGT_ROTATION_270 },
765*d83cc019SAndroid Build Coastguard Worker 		{ 0, 0 }
766*d83cc019SAndroid Build Coastguard Worker 	};
767*d83cc019SAndroid Build Coastguard Worker 
768*d83cc019SAndroid Build Coastguard Worker 	data_t data = {};
769*d83cc019SAndroid Build Coastguard Worker 	int gen = 0;
770*d83cc019SAndroid Build Coastguard Worker 
771*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
772*d83cc019SAndroid Build Coastguard Worker 
773*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
774*d83cc019SAndroid Build Coastguard Worker 		data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
775*d83cc019SAndroid Build Coastguard Worker 		data.devid = intel_get_drm_devid(data.gfx_fd);
776*d83cc019SAndroid Build Coastguard Worker 		gen = intel_gen(data.devid);
777*d83cc019SAndroid Build Coastguard Worker 
778*d83cc019SAndroid Build Coastguard Worker 		kmstest_set_vt_graphics_mode();
779*d83cc019SAndroid Build Coastguard Worker 
780*d83cc019SAndroid Build Coastguard Worker 		igt_require_pipe_crc(data.gfx_fd);
781*d83cc019SAndroid Build Coastguard Worker 
782*d83cc019SAndroid Build Coastguard Worker 		igt_display_require(&data.display, data.gfx_fd);
783*d83cc019SAndroid Build Coastguard Worker 	}
784*d83cc019SAndroid Build Coastguard Worker 
785*d83cc019SAndroid Build Coastguard Worker 	for (subtest = subtests; subtest->rot; subtest++) {
786*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("%s-rotation-%s",
787*d83cc019SAndroid Build Coastguard Worker 			      plane_test_str(subtest->plane),
788*d83cc019SAndroid Build Coastguard Worker 			      rot_test_str(subtest->rot)) {
789*d83cc019SAndroid Build Coastguard Worker 			igt_require(!(subtest->rot &
790*d83cc019SAndroid Build Coastguard Worker 				    (IGT_ROTATION_90 | IGT_ROTATION_270)) ||
791*d83cc019SAndroid Build Coastguard Worker 				    gen >= 9);
792*d83cc019SAndroid Build Coastguard Worker 			data.rotation = subtest->rot;
793*d83cc019SAndroid Build Coastguard Worker 			test_plane_rotation(&data, subtest->plane, false);
794*d83cc019SAndroid Build Coastguard Worker 		}
795*d83cc019SAndroid Build Coastguard Worker 	}
796*d83cc019SAndroid Build Coastguard Worker 
797*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("sprite-rotation-90-pos-100-0") {
798*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
799*d83cc019SAndroid Build Coastguard Worker 		data.rotation = IGT_ROTATION_90;
800*d83cc019SAndroid Build Coastguard Worker 		data.pos_x = 100,
801*d83cc019SAndroid Build Coastguard Worker 		data.pos_y = 0;
802*d83cc019SAndroid Build Coastguard Worker 		test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY, false);
803*d83cc019SAndroid Build Coastguard Worker 	}
804*d83cc019SAndroid Build Coastguard Worker 	data.pos_x = 0,
805*d83cc019SAndroid Build Coastguard Worker 	data.pos_y = 0;
806*d83cc019SAndroid Build Coastguard Worker 
807*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("bad-pixel-format") {
808*d83cc019SAndroid Build Coastguard Worker 		 /* gen11 enables RGB565 rotation for 90/270 degrees.
809*d83cc019SAndroid Build Coastguard Worker 		  * so apart from this, any other gen11+ pixel format
810*d83cc019SAndroid Build Coastguard Worker 		  * can be used which doesn't support 90/270 degree
811*d83cc019SAndroid Build Coastguard Worker 		  * rotation */
812*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
813*d83cc019SAndroid Build Coastguard Worker 		data.rotation = IGT_ROTATION_90;
814*d83cc019SAndroid Build Coastguard Worker 		data.override_fmt = gen < 11 ? DRM_FORMAT_RGB565 : DRM_FORMAT_Y212;
815*d83cc019SAndroid Build Coastguard Worker 		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
816*d83cc019SAndroid Build Coastguard Worker 	}
817*d83cc019SAndroid Build Coastguard Worker 	data.override_fmt = 0;
818*d83cc019SAndroid Build Coastguard Worker 
819*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("bad-tiling") {
820*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
821*d83cc019SAndroid Build Coastguard Worker 		data.rotation = IGT_ROTATION_90;
822*d83cc019SAndroid Build Coastguard Worker 		data.override_tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
823*d83cc019SAndroid Build Coastguard Worker 		test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, true);
824*d83cc019SAndroid Build Coastguard Worker 	}
825*d83cc019SAndroid Build Coastguard Worker 	data.override_tiling = 0;
826*d83cc019SAndroid Build Coastguard Worker 
827*d83cc019SAndroid Build Coastguard Worker 	for (reflect_x = reflect_x_subtests; reflect_x->tiling; reflect_x++) {
828*d83cc019SAndroid Build Coastguard Worker 		igt_subtest_f("primary-%s-reflect-x-%s",
829*d83cc019SAndroid Build Coastguard Worker 			      tiling_test_str(reflect_x->tiling),
830*d83cc019SAndroid Build Coastguard Worker 			      rot_test_str(reflect_x->rot)) {
831*d83cc019SAndroid Build Coastguard Worker 			igt_require(gen >= 10 ||
832*d83cc019SAndroid Build Coastguard Worker 				    (IS_CHERRYVIEW(data.devid) && reflect_x->rot == IGT_ROTATION_0
833*d83cc019SAndroid Build Coastguard Worker 				     && reflect_x->tiling == LOCAL_I915_FORMAT_MOD_X_TILED));
834*d83cc019SAndroid Build Coastguard Worker 			data.rotation = (IGT_REFLECT_X | reflect_x->rot);
835*d83cc019SAndroid Build Coastguard Worker 			data.override_tiling = reflect_x->tiling;
836*d83cc019SAndroid Build Coastguard Worker 			test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY, false);
837*d83cc019SAndroid Build Coastguard Worker 		}
838*d83cc019SAndroid Build Coastguard Worker 	}
839*d83cc019SAndroid Build Coastguard Worker 
840*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("multiplane-rotation") {
841*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
842*d83cc019SAndroid Build Coastguard Worker 		cleanup_crtc(&data);
843*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].origo = p_top | p_left;
844*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].x = .2f;
845*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].y = .1f;
846*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].origo = p_top | p_right;
847*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].x = -.4f;
848*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].y = .1f;
849*d83cc019SAndroid Build Coastguard Worker 		test_multi_plane_rotation(&data, 0);
850*d83cc019SAndroid Build Coastguard Worker 	}
851*d83cc019SAndroid Build Coastguard Worker 
852*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("multiplane-rotation-cropping-top") {
853*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
854*d83cc019SAndroid Build Coastguard Worker 		cleanup_crtc(&data);
855*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].origo = p_top | p_left;
856*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].x = -.05f;
857*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].y = -.15f;
858*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].origo = p_top | p_right;
859*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].x = -.15f;
860*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].y = -.15f;
861*d83cc019SAndroid Build Coastguard Worker 		test_multi_plane_rotation(&data, 0);
862*d83cc019SAndroid Build Coastguard Worker 	}
863*d83cc019SAndroid Build Coastguard Worker 
864*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("multiplane-rotation-cropping-bottom") {
865*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
866*d83cc019SAndroid Build Coastguard Worker 		cleanup_crtc(&data);
867*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].origo = p_bottom | p_left;
868*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].x = -.05f;
869*d83cc019SAndroid Build Coastguard Worker 		data.planepos[0].y = -.20f;
870*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].origo = p_bottom | p_right;
871*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].x = -.15f;
872*d83cc019SAndroid Build Coastguard Worker 		data.planepos[1].y = -.20f;
873*d83cc019SAndroid Build Coastguard Worker 		test_multi_plane_rotation(&data, 0);
874*d83cc019SAndroid Build Coastguard Worker 	}
875*d83cc019SAndroid Build Coastguard Worker 
876*d83cc019SAndroid Build Coastguard Worker 	/*
877*d83cc019SAndroid Build Coastguard Worker 	 * exhaust-fences should be last test, if it fails we may OOM in
878*d83cc019SAndroid Build Coastguard Worker 	 * the following subtests otherwise.
879*d83cc019SAndroid Build Coastguard Worker 	 */
880*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_f("exhaust-fences") {
881*d83cc019SAndroid Build Coastguard Worker 		enum pipe pipe;
882*d83cc019SAndroid Build Coastguard Worker 		igt_output_t *output;
883*d83cc019SAndroid Build Coastguard Worker 
884*d83cc019SAndroid Build Coastguard Worker 		igt_require(gen >= 9);
885*d83cc019SAndroid Build Coastguard Worker 		igt_display_require_output(&data.display);
886*d83cc019SAndroid Build Coastguard Worker 
887*d83cc019SAndroid Build Coastguard Worker 		for_each_pipe_with_valid_output(&data.display, pipe, output) {
888*d83cc019SAndroid Build Coastguard Worker 			igt_plane_t *primary = &data.display.pipes[pipe].planes[0];
889*d83cc019SAndroid Build Coastguard Worker 
890*d83cc019SAndroid Build Coastguard Worker 			test_plane_rotation_exhaust_fences(&data, pipe, output, primary);
891*d83cc019SAndroid Build Coastguard Worker 			break;
892*d83cc019SAndroid Build Coastguard Worker 		}
893*d83cc019SAndroid Build Coastguard Worker 	}
894*d83cc019SAndroid Build Coastguard Worker 
895*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
896*d83cc019SAndroid Build Coastguard Worker 		igt_display_fini(&data.display);
897*d83cc019SAndroid Build Coastguard Worker 	}
898*d83cc019SAndroid Build Coastguard Worker }
899