blob: cb0ac1eb7b63da08fde2ac107d39f1ba1a0150fd [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;
Tvrtko Ursulind9011062015-04-22 16:46:43 +010034 struct igt_fb fb_modeset;
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +010035 struct igt_fb fb_flip;
Damien Lespiau19743a12014-07-08 12:59:03 +010036 igt_crc_t ref_crc;
Sonika Jindale3611392014-06-18 14:27:27 +053037 igt_pipe_crc_t *pipe_crc;
Sonika Jindale1ce5ea2015-04-22 16:44:05 +053038 igt_rotation_t rotation;
39 int pos_x;
40 int pos_y;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010041 unsigned int w, h;
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
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010048paint_squares(data_t *data, drmModeModeInfo *mode, 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;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +010052 unsigned int w = data->w;
53 unsigned int h = data->h;
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
Tvrtko Ursulin637f0452015-04-27 12:29:11 +010087static void commit_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
88{
89 igt_display_t *display = &data->display;
90 enum igt_commit_style commit = COMMIT_LEGACY;
91 igt_plane_t *primary;
92
93 /*
94 * With igt_display_commit2 and COMMIT_UNIVERSAL, we call just the
95 * setplane without a modeset. So, to be able to call
96 * igt_display_commit and ultimately setcrtc to do the first modeset,
97 * we create an fb covering the crtc and call commit
98 */
99
100 primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
101 igt_plane_set_fb(primary, &data->fb_modeset);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100102 primary->rotation_changed = false;
Tvrtko Ursulin637f0452015-04-27 12:29:11 +0100103 igt_display_commit(display);
104
105 igt_plane_set_fb(plane, &data->fb);
106
107 if (!plane->is_cursor)
108 igt_plane_set_position(plane, data->pos_x, data->pos_y);
109
Lyude80baeb02016-12-07 19:02:04 -0500110 if (plane->is_primary || plane->is_cursor)
Tvrtko Ursulin637f0452015-04-27 12:29:11 +0100111 commit = COMMIT_UNIVERSAL;
Tvrtko Ursulin637f0452015-04-27 12:29:11 +0100112
pvishwak8b8d7aa2016-04-11 11:24:56 +0530113 if (data->display.is_atomic)
114 commit = COMMIT_ATOMIC;
115
Tvrtko Ursulin637f0452015-04-27 12:29:11 +0100116 igt_display_commit2(display, commit);
117}
118
Daniel Vetter57259d72014-11-24 16:08:32 +0100119static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
Damien Lespiau05f90b02014-07-08 18:51:25 +0100120 igt_plane_t *plane)
Sonika Jindale3611392014-06-18 14:27:27 +0530121{
122 drmModeModeInfo *mode;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100123 int fb_id, fb_modeset_id;
124 unsigned int w, h;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100125 uint64_t tiling = data->override_tiling ?
126 data->override_tiling : LOCAL_DRM_FORMAT_MOD_NONE;
127 uint32_t pixel_format = data->override_fmt ?
128 data->override_fmt : DRM_FORMAT_XRGB8888;
Sonika Jindale3611392014-06-18 14:27:27 +0530129
Damien Lespiau8facccf2014-07-08 18:28:53 +0100130 igt_output_set_pipe(output, pipe);
Sonika Jindale3611392014-06-18 14:27:27 +0530131
132 /* create the pipe_crc object for this pipe */
Damien Lespiau2eaa50f2014-07-08 18:56:15 +0100133 igt_pipe_crc_free(data->pipe_crc);
Damien Lespiau8facccf2014-07-08 18:28:53 +0100134 data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Sonika Jindale3611392014-06-18 14:27:27 +0530135
Damien Lespiau19743a12014-07-08 12:59:03 +0100136 mode = igt_output_get_mode(output);
Sonika Jindale3611392014-06-18 14:27:27 +0530137
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530138 w = mode->hdisplay;
139 h = mode->vdisplay;
140
Tvrtko Ursulind9011062015-04-22 16:46:43 +0100141 fb_modeset_id = igt_create_fb(data->gfx_fd,
142 w, h,
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100143 pixel_format,
Tvrtko Ursulind9011062015-04-22 16:46:43 +0100144 tiling,
145 &data->fb_modeset);
146 igt_assert(fb_modeset_id);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530147
148 /*
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530149 * For 90/270, we will use create smaller fb so that the rotated
150 * frame can fit in
151 */
152 if (data->rotation == IGT_ROTATION_90 ||
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100153 data->rotation == IGT_ROTATION_270) {
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100154 tiling = data->override_tiling ?
155 data->override_tiling : LOCAL_I915_FORMAT_MOD_Y_TILED;
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530156 w = h = mode->vdisplay;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100157 } else if (plane->is_cursor) {
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100158 pixel_format = data->override_fmt ?
159 data->override_fmt : DRM_FORMAT_ARGB8888;
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100160 w = h = 128;
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530161 }
162
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100163 data->w = w;
164 data->h = h;
Sonika Jindale3611392014-06-18 14:27:27 +0530165
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100166 fb_id = igt_create_fb(data->gfx_fd,
167 w, h,
168 pixel_format,
169 tiling,
170 &data->fb);
171 igt_assert(fb_id);
Damien Lespiau282f5602014-07-10 17:44:28 +0100172
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100173 if (data->flip_stress) {
174 fb_id = igt_create_fb(data->gfx_fd,
175 w, h,
176 pixel_format,
177 tiling,
178 &data->fb_flip);
179 igt_assert(fb_id);
180 paint_squares(data, mode, IGT_ROTATION_0, &data->fb_flip, 0.92);
181 }
182
Sonika Jindal47246982014-10-23 08:48:50 -0700183 /* Step 1: create a reference CRC for a software-rotated fb */
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100184 paint_squares(data, mode, data->rotation, &data->fb, 1.0);
Tvrtko Ursulin637f0452015-04-27 12:29:11 +0100185 commit_crtc(data, output, plane);
Damien Lespiau19743a12014-07-08 12:59:03 +0100186 igt_pipe_crc_collect_crc(data->pipe_crc, &data->ref_crc);
Sonika Jindale3611392014-06-18 14:27:27 +0530187
Damien Lespiau282f5602014-07-10 17:44:28 +0100188 /*
189 * Step 2: prepare the plane with an non-rotated fb let the hw
190 * rotate it.
191 */
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100192 paint_squares(data, mode, IGT_ROTATION_0, &data->fb, 1.0);
Tvrtko Ursulinb769a7c2015-04-22 16:46:46 +0100193 igt_plane_set_fb(plane, &data->fb);
Sonika Jindale3611392014-06-18 14:27:27 +0530194}
195
Damien Lespiau05f90b02014-07-08 18:51:25 +0100196static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
Sonika Jindale3611392014-06-18 14:27:27 +0530197{
198 igt_display_t *display = &data->display;
Sonika Jindale3611392014-06-18 14:27:27 +0530199
200 igt_pipe_crc_free(data->pipe_crc);
201 data->pipe_crc = NULL;
202
203 igt_remove_fb(data->gfx_fd, &data->fb);
Tvrtko Ursulind9011062015-04-22 16:46:43 +0100204 igt_remove_fb(data->gfx_fd, &data->fb_modeset);
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100205 if (data->fb_flip.fb_id)
206 igt_remove_fb(data->gfx_fd, &data->fb_flip);
Damien Lespiau1a754392014-07-09 14:00:59 +0100207
208 /* XXX: see the note in prepare_crtc() */
209 if (!plane->is_primary) {
210 igt_plane_t *primary;
211
212 primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
213 igt_plane_set_fb(primary, NULL);
214 }
215
Damien Lespiau05f90b02014-07-08 18:51:25 +0100216 igt_plane_set_fb(plane, NULL);
Sonika Jindale3611392014-06-18 14:27:27 +0530217 igt_output_set_pipe(output, PIPE_ANY);
Damien Lespiaueb81a922014-07-08 18:20:51 +0100218
Sonika Jindale3611392014-06-18 14:27:27 +0530219 igt_display_commit(display);
220}
221
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100222static void wait_for_pageflip(int fd)
223{
224 drmEventContext evctx = { .version = DRM_EVENT_CONTEXT_VERSION };
Maarten Lankhorst3c1362f2016-01-05 15:19:13 +0100225 struct timeval timeout = { .tv_sec = 0, .tv_usec = 50000 };
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100226 fd_set fds;
227 int ret;
228
229 /* Wait for pageflip completion, then consume event on fd */
230 FD_ZERO(&fds);
231 FD_SET(fd, &fds);
232 do {
233 ret = select(fd + 1, &fds, NULL, NULL, &timeout);
234 } while (ret < 0 && errno == EINTR);
235 igt_assert_eq(ret, 1);
236 igt_assert(drmHandleEvent(fd, &evctx) == 0);
237}
238
Damien Lespiau05f90b02014-07-08 18:51:25 +0100239static void test_plane_rotation(data_t *data, enum igt_plane plane_type)
Sonika Jindale3611392014-06-18 14:27:27 +0530240{
241 igt_display_t *display = &data->display;
242 igt_output_t *output;
Damien Lespiauaef475b2014-07-08 18:43:44 +0100243 enum pipe pipe;
Sonika Jindale3611392014-06-18 14:27:27 +0530244 int valid_tests = 0;
Thomas Wood1bec6cb2014-08-14 14:06:37 +0100245 igt_crc_t crc_output, crc_unrotated;
Damien Lespiauc4564e02014-07-08 19:24:24 +0100246 enum igt_commit_style commit = COMMIT_LEGACY;
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100247 unsigned int flip_count;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100248 int ret;
Damien Lespiau13e979c2014-07-08 18:13:47 +0100249
Lyude80baeb02016-12-07 19:02:04 -0500250 if (plane_type == IGT_PLANE_PRIMARY || plane_type == IGT_PLANE_CURSOR)
Damien Lespiauc4564e02014-07-08 19:24:24 +0100251 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500252
253 if (plane_type == IGT_PLANE_CURSOR)
254 igt_require(display->has_cursor_plane);
Sonika Jindale3611392014-06-18 14:27:27 +0530255
pvishwak8b8d7aa2016-04-11 11:24:56 +0530256 if (data->display.is_atomic)
257 commit = COMMIT_ATOMIC;
258
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100259 for_each_pipe_with_valid_output(display, pipe, output) {
260 igt_plane_t *plane;
Damien Lespiau05f90b02014-07-08 18:51:25 +0100261
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100262 igt_output_set_pipe(output, pipe);
Damien Lespiau05f90b02014-07-08 18:51:25 +0100263
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100264 plane = igt_output_get_plane(output, plane_type);
265 igt_require(igt_plane_supports_rotation(plane));
Damien Lespiau05f90b02014-07-08 18:51:25 +0100266
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100267 prepare_crtc(data, output, pipe, plane);
Daniel Vetter57259d72014-11-24 16:08:32 +0100268
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100269 igt_display_commit2(display, commit);
Sonika Jindale3611392014-06-18 14:27:27 +0530270
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100271 /* collect unrotated CRC */
272 igt_pipe_crc_collect_crc(data->pipe_crc, &crc_unrotated);
Thomas Wood1bec6cb2014-08-14 14:06:37 +0100273
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100274 igt_plane_set_rotation(plane, data->rotation);
275 ret = igt_display_try_commit2(display, commit);
276 if (data->override_fmt || data->override_tiling) {
277 igt_assert_eq(ret, -EINVAL);
278 } else {
279 igt_assert_eq(ret, 0);
280 igt_pipe_crc_collect_crc(data->pipe_crc,
281 &crc_output);
282 igt_assert_crc_equal(&data->ref_crc,
283 &crc_output);
Sonika Jindale3611392014-06-18 14:27:27 +0530284 }
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100285
286 flip_count = data->flip_stress;
287 while (flip_count--) {
288 ret = drmModePageFlip(data->gfx_fd,
289 output->config.crtc->crtc_id,
290 data->fb_flip.fb_id,
291 DRM_MODE_PAGE_FLIP_EVENT,
292 NULL);
293 igt_assert_eq(ret, 0);
294 wait_for_pageflip(data->gfx_fd);
295 ret = drmModePageFlip(data->gfx_fd,
296 output->config.crtc->crtc_id,
297 data->fb.fb_id,
298 DRM_MODE_PAGE_FLIP_EVENT,
299 NULL);
300 igt_assert_eq(ret, 0);
301 wait_for_pageflip(data->gfx_fd);
302 }
303
304 /*
305 * check the rotation state has been reset when the VT
306 * mode is restored
307 */
308 kmstest_restore_vt_mode();
309 kmstest_set_vt_graphics_mode();
310
311 commit_crtc(data, output, plane);
312
313 igt_pipe_crc_collect_crc(data->pipe_crc, &crc_output);
314 igt_assert_crc_equal(&crc_unrotated, &crc_output);
315
316 valid_tests++;
317 cleanup_crtc(data, output, plane);
Sonika Jindale3611392014-06-18 14:27:27 +0530318 }
319 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
320}
321
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100322static void test_plane_rotation_ytiled_obj(data_t *data,
323 igt_output_t *output,
324 enum igt_plane plane_type)
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700325{
326 igt_display_t *display = &data->display;
327 uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
328 uint32_t format = DRM_FORMAT_XRGB8888;
329 int bpp = igt_drm_format_to_bpp(format);
330 enum igt_commit_style commit = COMMIT_LEGACY;
331 int fd = data->gfx_fd;
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700332 igt_plane_t *plane;
333 drmModeModeInfo *mode;
334 unsigned int stride, size, w, h;
335 uint32_t gem_handle;
336 int ret;
337
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700338 plane = igt_output_get_plane(output, plane_type);
339 igt_require(igt_plane_supports_rotation(plane));
340
Lyude80baeb02016-12-07 19:02:04 -0500341 if (plane_type == IGT_PLANE_PRIMARY || plane_type == IGT_PLANE_CURSOR)
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700342 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500343
344 if (plane_type == IGT_PLANE_CURSOR)
345 igt_require(display->has_cursor_plane);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700346
pvishwak8b8d7aa2016-04-11 11:24:56 +0530347 if (data->display.is_atomic)
348 commit = COMMIT_ATOMIC;
349
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700350 mode = igt_output_get_mode(output);
351 w = mode->hdisplay;
352 h = mode->vdisplay;
353
354 for (stride = 512; stride < (w * bpp / 8); stride *= 2)
355 ;
356 for (size = 1024*1024; size < stride * h; size *= 2)
357 ;
358
359 gem_handle = gem_create(fd, size);
360 ret = __gem_set_tiling(fd, gem_handle, I915_TILING_Y, stride);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100361 igt_assert_eq(ret, 0);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700362
363 do_or_die(__kms_addfb(fd, gem_handle, w, h, stride,
364 format, tiling, LOCAL_DRM_MODE_FB_MODIFIERS,
365 &data->fb.fb_id));
366 data->fb.width = w;
367 data->fb.height = h;
368 data->fb.gem_handle = gem_handle;
369
370 igt_plane_set_fb(plane, NULL);
371 igt_display_commit(display);
372
373 igt_plane_set_rotation(plane, data->rotation);
374 igt_plane_set_fb(plane, &data->fb);
375
376 drmModeObjectSetProperty(fd, plane->drm_plane->plane_id,
377 DRM_MODE_OBJECT_PLANE,
378 plane->rotation_property,
379 plane->rotation);
380 ret = igt_display_try_commit2(display, commit);
381
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100382 igt_output_set_pipe(output, PIPE_NONE);
383
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700384 kmstest_restore_vt_mode();
385 igt_remove_fb(fd, &data->fb);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100386 igt_assert_eq(ret, 0);
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700387}
388
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100389static void test_plane_rotation_exhaust_fences(data_t *data,
390 igt_output_t *output,
391 enum igt_plane plane_type)
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800392{
393 igt_display_t *display = &data->display;
394 uint64_t tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
395 uint32_t format = DRM_FORMAT_XRGB8888;
396 int bpp = igt_drm_format_to_bpp(format);
397 enum igt_commit_style commit = COMMIT_LEGACY;
398 int fd = data->gfx_fd;
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800399 igt_plane_t *plane;
400 drmModeModeInfo *mode;
401 data_t data2[MAX_FENCES+1] = {};
402 unsigned int stride, size, w, h;
403 uint32_t gem_handle;
404 uint64_t total_aperture_size, total_fbs_size;
405 int i, ret;
406
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800407 plane = igt_output_get_plane(output, plane_type);
408 igt_require(igt_plane_supports_rotation(plane));
409
Lyude80baeb02016-12-07 19:02:04 -0500410 if (plane_type == IGT_PLANE_PRIMARY || plane_type == IGT_PLANE_CURSOR)
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800411 commit = COMMIT_UNIVERSAL;
Lyude80baeb02016-12-07 19:02:04 -0500412
413 if (plane_type == IGT_PLANE_CURSOR)
414 igt_require(display->has_cursor_plane);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800415
pvishwak8b8d7aa2016-04-11 11:24:56 +0530416 if (data->display.is_atomic)
417 commit = COMMIT_ATOMIC;
418
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800419 mode = igt_output_get_mode(output);
420 w = mode->hdisplay;
421 h = mode->vdisplay;
422
423 for (stride = 512; stride < (w * bpp / 8); stride *= 2)
424 ;
425 for (size = 1024*1024; size < stride * h; size *= 2)
426 ;
427
428 /*
429 * Make sure there is atleast 90% of the available GTT space left
430 * for creating (MAX_FENCES+1) framebuffers.
431 */
432 total_fbs_size = size * (MAX_FENCES + 1);
Chris Wilson16038902016-02-18 10:35:10 +0000433 total_aperture_size = gem_available_aperture_size(fd);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800434 igt_require(total_fbs_size < total_aperture_size * 0.9);
435
436 igt_plane_set_fb(plane, NULL);
437 igt_display_commit(display);
438
439 for (i = 0; i < MAX_FENCES + 1; i++) {
440 gem_handle = gem_create(fd, size);
441 ret = __gem_set_tiling(fd, gem_handle, I915_TILING_Y, stride);
442 if (ret) {
443 igt_warn("failed to set tiling\n");
444 goto err_alloc;
445 }
446
447 ret = (__kms_addfb(fd, gem_handle, w, h, stride,
448 format, tiling, LOCAL_DRM_MODE_FB_MODIFIERS,
449 &data2[i].fb.fb_id));
450 if (ret) {
451 igt_warn("failed to create framebuffer\n");
452 goto err_alloc;
453 }
454
455 data2[i].fb.width = w;
456 data2[i].fb.height = h;
457 data2[i].fb.gem_handle = gem_handle;
458
459 igt_plane_set_fb(plane, &data2[i].fb);
460 igt_plane_set_rotation(plane, IGT_ROTATION_0);
461
462 ret = igt_display_try_commit2(display, commit);
463 if (ret) {
464 igt_warn("failed to commit unrotated fb\n");
465 goto err_commit;
466 }
467
468 igt_plane_set_rotation(plane, IGT_ROTATION_90);
469
470 drmModeObjectSetProperty(fd, plane->drm_plane->plane_id,
471 DRM_MODE_OBJECT_PLANE,
472 plane->rotation_property,
473 plane->rotation);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100474 igt_display_commit2(display, commit);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800475 if (ret) {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100476 igt_warn("failed to commit hardware rotated fb: %i\n", ret);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800477 goto err_commit;
478 }
479 }
480
481err_alloc:
482 if (ret)
483 gem_close(fd, gem_handle);
484
485 i--;
486err_commit:
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100487 igt_plane_set_fb(plane, NULL);
488 igt_plane_set_rotation(plane, IGT_ROTATION_0);
489
490 if (commit < COMMIT_ATOMIC)
491 igt_display_commit2(display, commit);
492
493 igt_output_set_pipe(output, PIPE_NONE);
494 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
495
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800496 for (; i >= 0; i--)
497 igt_remove_fb(fd, &data2[i].fb);
498
499 kmstest_restore_vt_mode();
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100500 igt_assert_eq(ret, 0);
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800501}
502
Sonika Jindale3611392014-06-18 14:27:27 +0530503igt_main
504{
505 data_t data = {};
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530506 int gen = 0;
Sonika Jindale3611392014-06-18 14:27:27 +0530507
508 igt_skip_on_simulation();
509
510 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000511 data.gfx_fd = drm_open_driver_master(DRIVER_INTEL);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530512 gen = intel_gen(intel_get_drm_devid(data.gfx_fd));
Sonika Jindale3611392014-06-18 14:27:27 +0530513
Daniel Vetter33f08842014-08-12 11:23:09 +0200514 kmstest_set_vt_graphics_mode();
Sonika Jindale3611392014-06-18 14:27:27 +0530515
516 igt_require_pipe_crc();
517
518 igt_display_init(&data.display, data.gfx_fd);
519 }
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530520 igt_subtest_f("primary-rotation-180") {
521 data.rotation = IGT_ROTATION_180;
Damien Lespiau13e979c2014-07-08 18:13:47 +0100522 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530523 }
Sonika Jindale3611392014-06-18 14:27:27 +0530524
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530525 igt_subtest_f("sprite-rotation-180") {
526 data.rotation = IGT_ROTATION_180;
Damien Lespiau13e979c2014-07-08 18:13:47 +0100527 test_plane_rotation(&data, IGT_PLANE_2);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530528 }
Sonika Jindale3611392014-06-18 14:27:27 +0530529
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530530 igt_subtest_f("cursor-rotation-180") {
531 data.rotation = IGT_ROTATION_180;
Sonika Jindal47246982014-10-23 08:48:50 -0700532 test_plane_rotation(&data, IGT_PLANE_CURSOR);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530533 }
534
535 igt_subtest_f("primary-rotation-90") {
536 igt_require(gen >= 9);
537 data.rotation = IGT_ROTATION_90;
538 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
539 }
540
541 igt_subtest_f("primary-rotation-270") {
542 igt_require(gen >= 9);
543 data.rotation = IGT_ROTATION_270;
544 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
545 }
546
547 igt_subtest_f("sprite-rotation-90") {
548 igt_require(gen >= 9);
549 data.rotation = IGT_ROTATION_90;
550 test_plane_rotation(&data, IGT_PLANE_2);
551 }
552
553 igt_subtest_f("sprite-rotation-270") {
554 igt_require(gen >= 9);
555 data.rotation = IGT_ROTATION_270;
556 test_plane_rotation(&data, IGT_PLANE_2);
557 }
558
559 igt_subtest_f("sprite-rotation-90-pos-100-0") {
560 igt_require(gen >= 9);
561 data.rotation = IGT_ROTATION_90;
562 data.pos_x = 100,
563 data.pos_y = 0;
564 test_plane_rotation(&data, IGT_PLANE_2);
565 }
566
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100567 igt_subtest_f("bad-pixel-format") {
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530568 igt_require(gen >= 9);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530569 data.pos_x = 0,
570 data.pos_y = 0;
Tvrtko Ursulindbf64682015-04-22 16:46:48 +0100571 data.rotation = IGT_ROTATION_90;
572 data.override_fmt = DRM_FORMAT_RGB565;
573 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
574 }
575
576 igt_subtest_f("bad-tiling") {
577 igt_require(gen >= 9);
578 data.override_fmt = 0;
579 data.rotation = IGT_ROTATION_90;
580 data.override_tiling = LOCAL_DRM_FORMAT_MOD_NONE;
581 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
Sonika Jindale1ce5ea2015-04-22 16:44:05 +0530582 }
Sonika Jindal47246982014-10-23 08:48:50 -0700583
Tvrtko Ursulin061a38f2015-10-07 12:18:52 +0100584 igt_subtest_f("primary-rotation-90-flip-stress") {
585 igt_require(gen >= 9);
586 data.override_tiling = 0;
587 data.flip_stress = 60;
588 data.rotation = IGT_ROTATION_90;
589 test_plane_rotation(&data, IGT_PLANE_PRIMARY);
590 }
591
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700592 igt_subtest_f("primary-rotation-90-Y-tiled") {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100593 enum pipe pipe;
594 igt_output_t *output;
595 int valid_tests = 0;
596
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700597 igt_require(gen >= 9);
598 data.rotation = IGT_ROTATION_90;
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100599
600 for_each_pipe_with_valid_output(&data.display, pipe, output) {
601 igt_output_set_pipe(output, pipe);
602
603 test_plane_rotation_ytiled_obj(&data, output, IGT_PLANE_PRIMARY);
604
605 valid_tests++;
606 break;
607 }
608
609 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
Vivek Kasireddyfe548fa2015-10-22 18:34:03 -0700610 }
611
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800612 igt_subtest_f("exhaust-fences") {
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100613 enum pipe pipe;
614 igt_output_t *output;
615 int valid_tests = 0;
616
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800617 igt_require(gen >= 9);
Maarten Lankhorsteeffa252017-01-05 14:13:34 +0100618
619 for_each_pipe_with_valid_output(&data.display, pipe, output) {
620 igt_output_set_pipe(output, pipe);
621
622 test_plane_rotation_exhaust_fences(&data, output, IGT_PLANE_PRIMARY);
623
624 valid_tests++;
625 break;
626 }
627
628 igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
Vivek Kasireddy938b9302015-11-04 16:10:15 -0800629 }
630
Sonika Jindale3611392014-06-18 14:27:27 +0530631 igt_fixture {
632 igt_display_fini(&data.display);
633 }
634}