blob: 32c6a66276d272dc9a71f72225615905c9e31cc8 [file] [log] [blame]
Sonika Jindale3611392014-06-18 14:27:27 +05301/*
Damien Lespiau9cf7e8d2014-07-08 12:08:20 +01002 * Copyright © 2013,2014 Intel Corporation
Sonika Jindale3611392014-06-18 14:27:27 +05303 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
Thomas Wood804e11f2015-08-17 17:57:43 +010025#include "igt.h"
Damien Lespiau92b29b12014-07-08 12:49:03 +010026#include <math.h>
Sonika Jindale3611392014-06-18 14:27:27 +053027
Vivek Kasireddy938b9302015-11-04 16:10:15 -080028#define MAX_FENCES 32
Sonika Jindale3611392014-06-18 14:27:27 +053029
Sonika Jindale3611392014-06-18 14:27:27 +053030typedef struct {
31 int gfx_fd;
32 igt_display_t display;
Sonika Jindale3611392014-06-18 14:27:27 +053033 struct igt_fb fb;
Maarten Lankhorstca239862017-06-06 12:16:43 +020034 struct igt_fb fb_reference;
Tvrtko Ursulind9011062015-04-22 16:46:43 +010035 struct igt_fb fb_modeset;
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010036 struct igt_fb fb_flip;
Damien Lespiau19743a12014-07-08 12:59:03 +010037 igt_crc_t ref_crc;
Sonika Jindale3611392014-06-18 14:27:27 +053038 igt_pipe_crc_t *pipe_crc;
Sonika Jindale1ce5ea2015-04-22 16:44:05 +053039 igt_rotation_t rotation;
40 int pos_x;
41 int pos_y;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +010042 uint32_t override_fmt;
43 uint64_t override_tiling;
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010044 unsigned int flip_stress;
Sonika Jindale3611392014-06-18 14:27:27 +053045} data_t;
46
Damien Lespiau92b29b12014-07-08 12:49:03 +010047static void
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +020048paint_squares(data_t *data, igt_rotation_t rotation,
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010049 struct igt_fb *fb, float o)
Damien Lespiau92b29b12014-07-08 12:49:03 +010050{
51 cairo_t *cr;
Maarten Lankhorstca239862017-06-06 12:16:43 +020052 unsigned int w = fb->width;
53 unsigned int h = fb->height;
Damien Lespiau92b29b12014-07-08 12:49:03 +010054
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010055 cr = igt_get_cairo_ctx(data->gfx_fd, fb);
Damien Lespiau92b29b12014-07-08 12:49:03 +010056
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010057 if (rotation == IGT_ROTATION_180) {
58 cairo_translate(cr, w, h);
59 cairo_rotate(cr, M_PI);
Damien Lespiau92b29b12014-07-08 12:49:03 +010060 }
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010061
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010062 if (rotation == IGT_ROTATION_90) {
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010063 /* Paint 4 squares with width == height in Green, White,
64 Blue, Red Clockwise order to look like 270 degree rotated*/
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010065 igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, o, 0.0);
66 igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, o, o);
67 igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, 0.0, 0.0);
68 igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, o);
Tvrtko Ursulinf2a58962015-05-22 11:00:45 +010069 } else if (rotation == IGT_ROTATION_270) {
70 /* Paint 4 squares with width == height in Blue, Red,
71 Green, White Clockwise order to look like 90 degree rotated*/
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010072 igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, o);
73 igt_paint_color(cr, w / 2, 0, w / 2, h / 2, o, 0.0, 0.0);
74 igt_paint_color(cr, 0, h / 2, w / 2, h / 2, o, o, o);
75 igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, o, 0.0);
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010076 } else {
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010077 /* Paint with 4 squares of Red, Green, White, Blue Clockwise */
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010078 igt_paint_color(cr, 0, 0, w / 2, h / 2, o, 0.0, 0.0);
79 igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 0.0, o, 0.0);
80 igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 0.0, 0.0, o);
81 igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, o, o, o);
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010082 }
83
Damien Lespiau92b29b12014-07-08 12:49:03 +010084 cairo_destroy(cr);
85}
86
Daniel Vetter57259d72014-11-24 16:08:32 +010087static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
Maarten Lankhorstca239862017-06-06 12:16:43 +020088 igt_plane_t *plane, enum igt_commit_style commit)
Sonika Jindale3611392014-06-18 14:27:27 +053089{
90 drmModeModeInfo *mode;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010091 unsigned int w, h;
Maarten Lankhorstca239862017-06-06 12:16:43 +020092 uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
93 uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
94 igt_display_t *display = &data->display;
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +020095 igt_plane_t *primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Sonika Jindale3611392014-06-18 14:27:27 +053096
Damien Lespiau8facccf2014-07-08 18:28:53 +010097 igt_output_set_pipe(output, pipe);
Maarten Lankhorst44023a22017-01-31 13:31:57 +010098 igt_plane_set_rotation(plane, IGT_ROTATION_0);
Sonika Jindale3611392014-06-18 14:27:27 +053099
100 /* create the pipe_crc object for this pipe */
Damien Lespiau2eaa50f2014-07-08 18:56:15 +0100101 igt_pipe_crc_free(data->pipe_crc);
Chris Wilson83884e92017-03-21 17:16:03 +0000102 data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Sonika Jindale3611392014-06-18 14:27:27 +0530103
Damien Lespiau19743a12014-07-08 12:59:03 +0100104 mode = igt_output_get_mode(output);
Sonika Jindale3611392014-06-18 14:27:27 +0530105
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530106 w = mode->hdisplay;
107 h = mode->vdisplay;
108
Maarten Lankhorstca239862017-06-06 12:16:43 +0200109 igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb_modeset);
110
111 /*
112 * With igt_display_commit2 and COMMIT_UNIVERSAL, we call just the
113 * setplane without a modeset. So, to be able to call
114 * igt_display_commit and ultimately setcrtc to do the first modeset,
115 * we create an fb covering the crtc and call commit
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +0200116 *
117 * It's also a good idea to set a primary fb on the primary plane
118 * regardless, to force a underrun when watermarks are allocated
119 * incorrectly for other planes.
Maarten Lankhorstca239862017-06-06 12:16:43 +0200120 */
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +0200121 igt_plane_set_fb(primary, &data->fb_modeset);
Maarten Lankhorstca239862017-06-06 12:16:43 +0200122
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +0200123 if (commit < COMMIT_ATOMIC) {
Maarten Lankhorstca239862017-06-06 12:16:43 +0200124 primary->rotation_changed = false;
125 igt_display_commit(display);
126
127 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
128 primary->rotation_changed = true;
129 }
130
131 igt_plane_set_fb(plane, NULL);
132
133 igt_display_commit2(display, commit);
134}
135
136static void remove_fbs(data_t *data)
137{
138 if (!data->fb.fb_id)
139 return;
140
141 igt_remove_fb(data->gfx_fd, &data->fb);
142 igt_remove_fb(data->gfx_fd, &data->fb_reference);
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200143
Maarten Lankhorstca239862017-06-06 12:16:43 +0200144 if (data->fb_flip.fb_id)
145 igt_remove_fb(data->gfx_fd, &data->fb_flip);
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200146
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +0200147 data->fb_flip.fb_id = data->fb.fb_id = 0;
Maarten Lankhorstca239862017-06-06 12:16:43 +0200148}
149
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200150enum rectangle_type {
151 square,
152 portrait,
153 landscape,
154 num_rectangle_types /* must be last */
155};
156
Maarten Lankhorstca239862017-06-06 12:16:43 +0200157static void prepare_fbs(data_t *data, igt_output_t *output,
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200158 igt_plane_t *plane, enum rectangle_type rect)
Maarten Lankhorstca239862017-06-06 12:16:43 +0200159{
160 drmModeModeInfo *mode;
161 igt_display_t *display = &data->display;
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200162 unsigned int w, h, ref_w, ref_h, min_w, min_h;
Maarten Lankhorstca239862017-06-06 12:16:43 +0200163 uint64_t tiling = data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE;
164 uint32_t pixel_format = data->override_fmt ?: DRM_FORMAT_XRGB8888;
165
166 if (data->fb.fb_id) {
167 igt_plane_set_fb(plane, NULL);
168 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_UNIVERSAL);
169
170 remove_fbs(data);
171 }
172
173 igt_plane_set_rotation(plane, IGT_ROTATION_0);
174
175 mode = igt_output_get_mode(output);
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200176 if (plane->type != DRM_PLANE_TYPE_CURSOR) {
177 w = mode->hdisplay;
178 h = mode->vdisplay;
179
180 min_w = 256;
181 min_h = 256;
182 } else {
183 pixel_format = data->override_fmt ?: DRM_FORMAT_ARGB8888;
184
185 w = h = 256;
186 min_w = min_h = 64;
187 }
188
189 switch (rect) {
190 case square:
191 w = h = min(h, w);
192 break;
193 case portrait:
194 w = min_w;
195 break;
196 case landscape:
197 h = min_h;
198 break;
199 case num_rectangle_types:
200 igt_assert(0);
201 }
202
203 ref_w = w;
204 ref_h = h;
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530205
206 /*
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530207 * For 90/270, we will use create smaller fb so that the rotated
208 * frame can fit in
209 */
210 if (data->rotation == IGT_ROTATION_90 ||
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100211 data->rotation == IGT_ROTATION_270) {
Maarten Lankhorstca239862017-06-06 12:16:43 +0200212 tiling = data->override_tiling ?: LOCAL_I915_FORMAT_MOD_Y_TILED;
213
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200214 igt_swap(w, h);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530215 }
216
Maarten Lankhorstca239862017-06-06 12:16:43 +0200217 igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb);
Damien Lespiau282f5602014-07-10 17:44:28 +0100218
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100219 if (data->flip_stress) {
Maarten Lankhorstca239862017-06-06 12:16:43 +0200220 igt_create_fb(data->gfx_fd, w, h, pixel_format, tiling, &data->fb_flip);
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200221 paint_squares(data, IGT_ROTATION_0, &data->fb_flip, 0.92);
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100222 }
223
Sonika Jindal47246982014-10-23 08:48:50 -0700224 /* Step 1: create a reference CRC for a software-rotated fb */
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200225 igt_create_fb(data->gfx_fd, ref_w, ref_h, pixel_format,
226 data->override_tiling ?: LOCAL_DRM_FORMAT_MOD_NONE, &data->fb_reference);
227 paint_squares(data, data->rotation, &data->fb_reference, 1.0);
Maarten Lankhorstca239862017-06-06 12:16:43 +0200228
229 igt_plane_set_fb(plane, &data->fb_reference);
230 if (plane->type != DRM_PLANE_TYPE_CURSOR)
231 igt_plane_set_position(plane, data->pos_x, data->pos_y);
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200232 igt_plane_set_rotation(plane, IGT_ROTATION_0);
Maarten Lankhorstca239862017-06-06 12:16:43 +0200233 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_UNIVERSAL);
234
Damien Lespiau19743a12014-07-08 12:59:03 +0100235 igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
Sonika Jindale3611392014-06-18 14:27:27 +0530236
Damien Lespiau282f5602014-07-10 17:44:28 +0100237 /*
238 * Step 2: prepare the plane with an non-rotated fb let the hw
239 * rotate it.
240 */
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200241 paint_squares(data, IGT_ROTATION_0, &data->fb, 1.0);
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100242 igt_plane_set_fb(plane, &data->fb);
Maarten Lankhorstca239862017-06-06 12:16:43 +0200243
244 if (plane->type != DRM_PLANE_TYPE_CURSOR)
245 igt_plane_set_position(plane, data->pos_x, data->pos_y);
Sonika Jindale3611392014-06-18 14:27:27 +0530246}
247
Damien Lespiau05f90b02014-07-08 18:51:25 +0100248static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
Sonika Jindale3611392014-06-18 14:27:27 +0530249{
250 igt_display_t *display = &data->display;
Sonika Jindale3611392014-06-18 14:27:27 +0530251
252 igt_pipe_crc_free(data->pipe_crc);
253 data->pipe_crc = NULL;
254
Maarten Lankhorstca239862017-06-06 12:16:43 +0200255 remove_fbs(data);
Damien Lespiau1a754392014-07-09 14:00:59 +0100256
Maarten Lankhorst9d809cd2017-06-06 17:12:20 +0200257 igt_remove_fb(data->gfx_fd, &data->fb_modeset);
258
Damien Lespiau1a754392014-07-09 14:00:59 +0100259 /* XXX: see the note in prepare_crtc() */
Robert Foss3e04c512017-01-10 20:18:41 -0500260 if (plane->type != DRM_PLANE_TYPE_PRIMARY) {
Damien Lespiau1a754392014-07-09 14:00:59 +0100261 igt_plane_t *primary;
262
Robert Foss3e04c512017-01-10 20:18:41 -0500263 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Damien Lespiau1a754392014-07-09 14:00:59 +0100264 igt_plane_set_fb(primary, NULL);
265 }
266
Damien Lespiau05f90b02014-07-08 18:51:25 +0100267 igt_plane_set_fb(plane, NULL);
Maarten Lankhorst44023a22017-01-31 13:31:57 +0100268 igt_plane_set_rotation(plane, IGT_ROTATION_0);
269
270 igt_display_commit2(display, COMMIT_UNIVERSAL);
271
Sonika Jindale3611392014-06-18 14:27:27 +0530272 igt_output_set_pipe(output, PIPE_ANY);
Damien Lespiaueb81a922014-07-08 18:20:51 +0100273
Sonika Jindale3611392014-06-18 14:27:27 +0530274 igt_display_commit(display);
275}
276
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100277static void wait_for_pageflip(int fd)
278{
Daniel Stoned7db79d2017-04-07 14:15:26 +0100279 drmEventContext evctx = { .version = 2 };
Maarten Lankhorst3c1362f2016-01-05 15:19:13 +0100280 struct timeval timeout = { .tv_sec = 0, .tv_usec = 50000 };
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100281 fd_set fds;
282 int ret;
283
284 /* Wait for pageflip completion, then consume event on fd */
285 FD_ZERO(&fds);
286 FD_SET(fd, &fds);
287 do {
288 ret = select(fd + 1, &fds, NULL, NULL, &timeout);
289 } while (ret < 0 && errno == EINTR);
290 igt_assert_eq(ret, 1);
291 igt_assert(drmHandleEvent(fd, &evctx) == 0);
292}
293
Robert Foss3e04c512017-01-10 20:18:41 -0500294static void test_plane_rotation(data_t *data, int plane_type)
Sonika Jindale3611392014-06-18 14:27:27 +0530295{
296 igt_display_t *display = &data->display;
297 igt_output_t *output;
Damien Lespiauaef475b2014-07-08 18:43:44 +0100298 enum pipe pipe;
Sonika Jindale3611392014-06-18 14:27:27 +0530299 int valid_tests = 0;
Thomas Wood1bec6cb2014-08-14 14:06:37 +0100300 igt_crc_t crc_output, crc_unrotated;
Damien Lespiauc4564e02014-07-08 19:24:24 +0100301 enum igt_commit_style commit = COMMIT_LEGACY;
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100302 unsigned int flip_count;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100303 int ret;
Damien Lespiau13e979c2014-07-08 18:13:47 +0100304
Robert Foss3e04c512017-01-10 20:18:41 -0500305 if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
Damien Lespiauc4564e02014-07-08 19:24:24 +0100306 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500307
Robert Foss3e04c512017-01-10 20:18:41 -0500308 if (plane_type == DRM_PLANE_TYPE_CURSOR)
Lyude80baeb02016-12-07 19:02:04 -0500309 igt_require(display->has_cursor_plane);
Sonika Jindale3611392014-06-18 14:27:27 +0530310
pvishwak8b8d7aa2016-04-11 11:24:56 +0530311 if (data->display.is_atomic)
312 commit = COMMIT_ATOMIC;
313
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100314 for_each_pipe_with_valid_output(display, pipe, output) {
315 igt_plane_t *plane;
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200316 int i;
Damien Lespiau05f90b02014-07-08 18:51:25 +0100317
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100318 igt_output_set_pipe(output, pipe);
Damien Lespiau05f90b02014-07-08 18:51:25 +0100319
Robert Foss3e04c512017-01-10 20:18:41 -0500320 plane = igt_output_get_plane_type(output, plane_type);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100321 igt_require(igt_plane_supports_rotation(plane));
Damien Lespiau05f90b02014-07-08 18:51:25 +0100322
Maarten Lankhorstca239862017-06-06 12:16:43 +0200323 prepare_crtc(data, output, pipe, plane, commit);
324
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200325 for (i = 0; i < num_rectangle_types; i++) {
326 /* Unsupported on i915 */
327 if (plane_type == DRM_PLANE_TYPE_CURSOR &&
328 i != square)
329 continue;
Daniel Vetter57259d72014-11-24 16:08:32 +0100330
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200331 igt_debug("Testing case %i on pipe %s\n", i, kmstest_pipe_name(pipe));
332 prepare_fbs(data, output, plane, i);
Sonika Jindale3611392014-06-18 14:27:27 +0530333
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200334 igt_display_commit2(display, commit);
Thomas Wood1bec6cb2014-08-14 14:06:37 +0100335
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200336 /* collect unrotated CRC */
337 igt_pipe_crc_collect_crc(data->pipe_crc, &crc_unrotated);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100338
Maarten Lankhorsta7fe05b2017-06-06 16:41:12 +0200339 igt_plane_set_rotation(plane, data->rotation);
340 if (data->rotation == IGT_ROTATION_90 || data->rotation == IGT_ROTATION_270)
341 igt_plane_set_size(plane, data->fb.height, data->fb.width);
342
343 ret = igt_display_try_commit2(display, commit);
344 if (data->override_fmt || data->override_tiling) {
345 igt_assert_eq(ret, -EINVAL);
346 } else {
347 igt_assert_eq(ret, 0);
348 igt_pipe_crc_collect_crc(data->pipe_crc,
349 &crc_output);
350 igt_assert_crc_equal(&data->ref_crc,
351 &crc_output);
352 }
353
354 flip_count = data->flip_stress;
355 while (flip_count--) {
356 ret = drmModePageFlip(data->gfx_fd,
357 output->config.crtc->crtc_id,
358 data->fb_flip.fb_id,
359 DRM_MODE_PAGE_FLIP_EVENT,
360 NULL);
361 igt_assert_eq(ret, 0);
362 wait_for_pageflip(data->gfx_fd);
363 ret = drmModePageFlip(data->gfx_fd,
364 output->config.crtc->crtc_id,
365 data->fb.fb_id,
366 DRM_MODE_PAGE_FLIP_EVENT,
367 NULL);
368 igt_assert_eq(ret, 0);
369 wait_for_pageflip(data->gfx_fd);
370 }
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100371 }
372
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100373 valid_tests++;
374 cleanup_crtc(data, output, plane);
Sonika Jindale3611392014-06-18 14:27:27 +0530375 }
376 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
377}
378
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100379static void test_plane_rotation_ytiled_obj(data_t *data,
380 igt_output_t *output,
Robert Foss3e04c512017-01-10 20:18:41 -0500381 int plane_type)
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700382{
383 igt_display_t *display = &data->display;
384 uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
385 uint32_t format = DRM_FORMAT_XRGB8888;
386 int bpp = igt_drm_format_to_bpp(format);
387 enum igt_commit_style commit = COMMIT_LEGACY;
388 int fd = data->gfx_fd;
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700389 igt_plane_t *plane;
390 drmModeModeInfo *mode;
391 unsigned int stride, size, w, h;
392 uint32_t gem_handle;
393 int ret;
394
Robert Foss3e04c512017-01-10 20:18:41 -0500395 plane = igt_output_get_plane_type(output, plane_type);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700396 igt_require(igt_plane_supports_rotation(plane));
397
Robert Foss3e04c512017-01-10 20:18:41 -0500398 if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700399 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500400
Robert Foss3e04c512017-01-10 20:18:41 -0500401 if (plane_type == DRM_PLANE_TYPE_CURSOR)
Lyude80baeb02016-12-07 19:02:04 -0500402 igt_require(display->has_cursor_plane);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700403
pvishwak8b8d7aa2016-04-11 11:24:56 +0530404 if (data->display.is_atomic)
405 commit = COMMIT_ATOMIC;
406
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700407 mode = igt_output_get_mode(output);
408 w = mode->hdisplay;
409 h = mode->vdisplay;
410
411 for (stride = 512; stride < (w * bpp / 8); stride *= 2)
412 ;
413 for (size = 1024*1024; size < stride * h; size *= 2)
414 ;
415
416 gem_handle = gem_create(fd, size);
417 ret = __gem_set_tiling(fd, gem_handle, I915_TILING_Y, stride);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100418 igt_assert_eq(ret, 0);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700419
420 do_or_die(__kms_addfb(fd, gem_handle, w, h, stride,
421 format, tiling, LOCAL_DRM_MODE_FB_MODIFIERS,
422 &data->fb.fb_id));
423 data->fb.width = w;
424 data->fb.height = h;
425 data->fb.gem_handle = gem_handle;
426
427 igt_plane_set_fb(plane, NULL);
428 igt_display_commit(display);
429
430 igt_plane_set_rotation(plane, data->rotation);
431 igt_plane_set_fb(plane, &data->fb);
Maarten Lankhorst44023a22017-01-31 13:31:57 +0100432 igt_plane_set_size(plane, h, w);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700433
Maarten Lankhorst44023a22017-01-31 13:31:57 +0100434 if (commit < COMMIT_ATOMIC)
435 drmModeObjectSetProperty(fd, plane->drm_plane->plane_id,
436 DRM_MODE_OBJECT_PLANE,
437 plane->rotation_property,
438 plane->rotation);
439
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700440 ret = igt_display_try_commit2(display, commit);
441
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100442 igt_output_set_pipe(output, PIPE_NONE);
443
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700444 kmstest_restore_vt_mode();
445 igt_remove_fb(fd, &data->fb);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100446 igt_assert_eq(ret, 0);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700447}
448
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100449static void test_plane_rotation_exhaust_fences(data_t *data,
450 igt_output_t *output,
Robert Foss3e04c512017-01-10 20:18:41 -0500451 int plane_type)
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800452{
453 igt_display_t *display = &data->display;
454 uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
455 uint32_t format = DRM_FORMAT_XRGB8888;
456 int bpp = igt_drm_format_to_bpp(format);
457 enum igt_commit_style commit = COMMIT_LEGACY;
458 int fd = data->gfx_fd;
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800459 igt_plane_t *plane;
460 drmModeModeInfo *mode;
461 data_t data2[MAX_FENCES+1] = {};
462 unsigned int stride, size, w, h;
463 uint32_t gem_handle;
464 uint64_t total_aperture_size, total_fbs_size;
465 int i, ret;
466
Robert Foss3e04c512017-01-10 20:18:41 -0500467 plane = igt_output_get_plane_type(output, plane_type);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800468 igt_require(igt_plane_supports_rotation(plane));
469
Robert Foss3e04c512017-01-10 20:18:41 -0500470 if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800471 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500472
Robert Foss3e04c512017-01-10 20:18:41 -0500473 if (plane_type == DRM_PLANE_TYPE_CURSOR)
Lyude80baeb02016-12-07 19:02:04 -0500474 igt_require(display->has_cursor_plane);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800475
pvishwak8b8d7aa2016-04-11 11:24:56 +0530476 if (data->display.is_atomic)
477 commit = COMMIT_ATOMIC;
478
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800479 mode = igt_output_get_mode(output);
480 w = mode->hdisplay;
481 h = mode->vdisplay;
482
483 for (stride = 512; stride < (w * bpp / 8); stride *= 2)
484 ;
485 for (size = 1024*1024; size < stride * h; size *= 2)
486 ;
487
488 /*
489 * Make sure there is atleast 90% of the available GTT space left
490 * for creating (MAX_FENCES+1) framebuffers.
491 */
492 total_fbs_size = size * (MAX_FENCES + 1);
Chris Wilson16038902016-02-18 10:35:10 +0000493 total_aperture_size = gem_available_aperture_size(fd);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800494 igt_require(total_fbs_size < total_aperture_size * 0.9);
495
496 igt_plane_set_fb(plane, NULL);
497 igt_display_commit(display);
498
499 for (i = 0; i < MAX_FENCES + 1; i++) {
500 gem_handle = gem_create(fd, size);
501 ret = __gem_set_tiling(fd, gem_handle, I915_TILING_Y, stride);
502 if (ret) {
503 igt_warn("failed to set tiling\n");
504 goto err_alloc;
505 }
506
507 ret = (__kms_addfb(fd, gem_handle, w, h, stride,
508 format, tiling, LOCAL_DRM_MODE_FB_MODIFIERS,
509 &data2[i].fb.fb_id));
510 if (ret) {
511 igt_warn("failed to create framebuffer\n");
512 goto err_alloc;
513 }
514
515 data2[i].fb.width = w;
516 data2[i].fb.height = h;
517 data2[i].fb.gem_handle = gem_handle;
518
519 igt_plane_set_fb(plane, &data2[i].fb);
520 igt_plane_set_rotation(plane, IGT_ROTATION_0);
521
522 ret = igt_display_try_commit2(display, commit);
523 if (ret) {
524 igt_warn("failed to commit unrotated fb\n");
525 goto err_commit;
526 }
527
528 igt_plane_set_rotation(plane, IGT_ROTATION_90);
Maarten Lankhorst44023a22017-01-31 13:31:57 +0100529 igt_plane_set_size(plane, h, w);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800530
531 drmModeObjectSetProperty(fd, plane->drm_plane->plane_id,
532 DRM_MODE_OBJECT_PLANE,
533 plane->rotation_property,
534 plane->rotation);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100535 igt_display_commit2(display, commit);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800536 if (ret) {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100537 igt_warn("failed to commit hardware rotated fb: %i\n", ret);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800538 goto err_commit;
539 }
540 }
541
542err_alloc:
543 if (ret)
544 gem_close(fd, gem_handle);
545
546 i--;
547err_commit:
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100548 igt_plane_set_fb(plane, NULL);
549 igt_plane_set_rotation(plane, IGT_ROTATION_0);
550
551 if (commit < COMMIT_ATOMIC)
552 igt_display_commit2(display, commit);
553
554 igt_output_set_pipe(output, PIPE_NONE);
555 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
556
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800557 for (; i >= 0; i--)
558 igt_remove_fb(fd, &data2[i].fb);
559
560 kmstest_restore_vt_mode();
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100561 igt_assert_eq(ret, 0);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800562}
563
Sonika Jindale3611392014-06-18 14:27:27 +0530564igt_main
565{
566 data_t data = {};
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530567 int gen = 0;
Sonika Jindale3611392014-06-18 14:27:27 +0530568
569 igt_skip_on_simulation();
570
571 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000572 data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530573 gen = intel_gen(intel_get_drm_devid(data.gfx_fd));
Sonika Jindale3611392014-06-18 14:27:27 +0530574
Daniel Vetter33f08842014-08-12 11:23:09 +0200575 kmstest_set_vt_graphics_mode();
Sonika Jindale3611392014-06-18 14:27:27 +0530576
Chris Wilson83884e92017-03-21 17:16:03 +0000577 igt_require_pipe_crc(data.gfx_fd);
Sonika Jindale3611392014-06-18 14:27:27 +0530578
579 igt_display_init(&data.display, data.gfx_fd);
580 }
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530581 igt_subtest_f("primary-rotation-180") {
582 data.rotation = IGT_ROTATION_180;
Robert Foss3e04c512017-01-10 20:18:41 -0500583 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530584 }
Sonika Jindale3611392014-06-18 14:27:27 +0530585
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530586 igt_subtest_f("sprite-rotation-180") {
587 data.rotation = IGT_ROTATION_180;
Robert Foss3e04c512017-01-10 20:18:41 -0500588 test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530589 }
Sonika Jindale3611392014-06-18 14:27:27 +0530590
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530591 igt_subtest_f("cursor-rotation-180") {
592 data.rotation = IGT_ROTATION_180;
Robert Foss3e04c512017-01-10 20:18:41 -0500593 test_plane_rotation(&data, DRM_PLANE_TYPE_CURSOR);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530594 }
595
596 igt_subtest_f("primary-rotation-90") {
597 igt_require(gen >= 9);
598 data.rotation = IGT_ROTATION_90;
Robert Foss3e04c512017-01-10 20:18:41 -0500599 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530600 }
601
602 igt_subtest_f("primary-rotation-270") {
603 igt_require(gen >= 9);
604 data.rotation = IGT_ROTATION_270;
Robert Foss3e04c512017-01-10 20:18:41 -0500605 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530606 }
607
608 igt_subtest_f("sprite-rotation-90") {
609 igt_require(gen >= 9);
610 data.rotation = IGT_ROTATION_90;
Robert Foss3e04c512017-01-10 20:18:41 -0500611 test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530612 }
613
614 igt_subtest_f("sprite-rotation-270") {
615 igt_require(gen >= 9);
616 data.rotation = IGT_ROTATION_270;
Robert Foss3e04c512017-01-10 20:18:41 -0500617 test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530618 }
619
620 igt_subtest_f("sprite-rotation-90-pos-100-0") {
621 igt_require(gen >= 9);
622 data.rotation = IGT_ROTATION_90;
623 data.pos_x = 100,
624 data.pos_y = 0;
Robert Foss3e04c512017-01-10 20:18:41 -0500625 test_plane_rotation(&data, DRM_PLANE_TYPE_OVERLAY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530626 }
627
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100628 igt_subtest_f("bad-pixel-format") {
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530629 igt_require(gen >= 9);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530630 data.pos_x = 0,
631 data.pos_y = 0;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100632 data.rotation = IGT_ROTATION_90;
633 data.override_fmt = DRM_FORMAT_RGB565;
Robert Foss3e04c512017-01-10 20:18:41 -0500634 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100635 }
636
637 igt_subtest_f("bad-tiling") {
638 igt_require(gen >= 9);
639 data.override_fmt = 0;
640 data.rotation = IGT_ROTATION_90;
641 data.override_tiling = LOCAL_DRM_FORMAT_MOD_NONE;
Robert Foss3e04c512017-01-10 20:18:41 -0500642 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530643 }
Sonika Jindal47246982014-10-23 08:48:50 -0700644
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100645 igt_subtest_f("primary-rotation-90-flip-stress") {
646 igt_require(gen >= 9);
647 data.override_tiling = 0;
648 data.flip_stress = 60;
649 data.rotation = IGT_ROTATION_90;
Robert Foss3e04c512017-01-10 20:18:41 -0500650 test_plane_rotation(&data, DRM_PLANE_TYPE_PRIMARY);
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100651 }
652
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700653 igt_subtest_f("primary-rotation-90-Y-tiled") {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100654 enum pipe pipe;
655 igt_output_t *output;
656 int valid_tests = 0;
657
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700658 igt_require(gen >= 9);
659 data.rotation = IGT_ROTATION_90;
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100660
661 for_each_pipe_with_valid_output(&data.display, pipe, output) {
662 igt_output_set_pipe(output, pipe);
663
Robert Foss3e04c512017-01-10 20:18:41 -0500664 test_plane_rotation_ytiled_obj(&data, output, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100665
666 valid_tests++;
667 break;
668 }
669
670 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700671 }
672
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800673 igt_subtest_f("exhaust-fences") {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100674 enum pipe pipe;
675 igt_output_t *output;
676 int valid_tests = 0;
677
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800678 igt_require(gen >= 9);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100679
680 for_each_pipe_with_valid_output(&data.display, pipe, output) {
681 igt_output_set_pipe(output, pipe);
682
Robert Foss3e04c512017-01-10 20:18:41 -0500683 test_plane_rotation_exhaust_fences(&data, output, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100684
685 valid_tests++;
686 break;
687 }
688
689 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800690 }
691
Sonika Jindale3611392014-06-18 14:27:27 +0530692 igt_fixture {
693 igt_display_fini(&data.display);
694 }
695}