blob: d0a28b3c442ceb61dde3d8a037e9ae626554ce6f [file] [log] [blame]
Chris Wilson9579e542016-05-23 21:56:01 +01001/*
2 * Copyright © 2013 Intel Corporation
3 *
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
Chris Wilson9579e542016-05-23 21:56:01 +010025#include <sched.h>
Chris Wilsond2adbdf2016-10-04 13:50:50 +010026#include <sys/poll.h>
Chris Wilson9579e542016-05-23 21:56:01 +010027
28#include "igt.h"
Chris Wilson376b8132016-07-03 09:42:38 +010029#include "igt_rand.h"
Chris Wilsonc74e0712016-05-24 16:24:15 +010030#include "igt_stats.h"
Chris Wilson9579e542016-05-23 21:56:01 +010031
Tomeu Vizoso047c9992016-06-07 10:18:34 +020032#if defined(__x86_64__) || defined(__i386__)
33#define cpu_relax() __builtin_ia32_pause()
34#else
35#define cpu_relax() asm volatile("": : :"memory")
36#endif
37
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +020038#ifndef DRM_CAP_CURSOR_WIDTH
39#define DRM_CAP_CURSOR_WIDTH 0x8
40#endif
41
42#ifndef DRM_CAP_CURSOR_HEIGHT
43#define DRM_CAP_CURSOR_HEIGHT 0x9
44#endif
45
Chris Wilson9579e542016-05-23 21:56:01 +010046IGT_TEST_DESCRIPTION("Stress legacy cursor ioctl");
47
Maarten Lankhorstcb437352017-12-07 10:11:47 +010048igt_pipe_crc_t *pipe_crc;
49
Maarten Lankhorst6b985872016-07-13 14:59:02 +020050static void stress(igt_display_t *display,
Gustavo Padovanc2270592017-08-02 19:54:17 -030051 enum pipe pipe, int num_children, unsigned mode,
Chris Wilsoncce2ff02016-05-25 08:34:25 +010052 int timeout)
Chris Wilson9579e542016-05-23 21:56:01 +010053{
Chris Wilson9579e542016-05-23 21:56:01 +010054 struct drm_mode_cursor arg;
Chris Wilsonc74e0712016-05-24 16:24:15 +010055 uint64_t *results;
Chris Wilsonf5d370c2016-06-04 21:25:17 +010056 bool torture;
Chris Wilson9579e542016-05-23 21:56:01 +010057 int n;
Leo (Sunpeng) Lidf682172017-06-09 17:13:04 -040058 unsigned crtc_id[IGT_MAX_PIPES], num_crtcs;
Chris Wilson9579e542016-05-23 21:56:01 +010059
Chris Wilsonf5d370c2016-06-04 21:25:17 +010060 torture = false;
61 if (num_children < 0) {
62 torture = true;
63 num_children = -num_children;
64 }
65
Chris Wilsonc74e0712016-05-24 16:24:15 +010066 results = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
67 igt_assert(results != MAP_FAILED);
68
Chris Wilson9579e542016-05-23 21:56:01 +010069 memset(&arg, 0, sizeof(arg));
70 arg.flags = DRM_MODE_CURSOR_BO;
71 arg.crtc_id = 0;
72 arg.width = 64;
73 arg.height = 64;
Maarten Lankhorst6b985872016-07-13 14:59:02 +020074 arg.handle = kmstest_dumb_create(display->drm_fd, 64, 64, 32, NULL, NULL);
Chris Wilson9579e542016-05-23 21:56:01 +010075
Maarten Lankhorst6b985872016-07-13 14:59:02 +020076 if (pipe < 0) {
77 num_crtcs = display->n_pipes;
78 for_each_pipe(display, n) {
79 arg.crtc_id = crtc_id[n] = display->pipes[n].crtc_id;
Maarten Lankhorstcf84a942016-07-18 11:04:27 +020080 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
Maarten Lankhorst6b985872016-07-13 14:59:02 +020081 }
82 } else {
83 num_crtcs = 1;
84 arg.crtc_id = crtc_id[0] = display->pipes[pipe].crtc_id;
Maarten Lankhorstcf84a942016-07-18 11:04:27 +020085 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
Chris Wilsoncce2ff02016-05-25 08:34:25 +010086 }
Chris Wilson9579e542016-05-23 21:56:01 +010087
88 arg.flags = mode;
Chris Wilsondab6b6b2016-05-24 16:14:32 +010089 igt_fork(child, num_children) {
Chris Wilson9579e542016-05-23 21:56:01 +010090 struct sched_param rt = {.sched_priority = 99 };
91 cpu_set_t allowed;
92 unsigned long count = 0;
93
94 sched_setscheduler(getpid(), SCHED_RR, &rt);
95
96 CPU_ZERO(&allowed);
97 CPU_SET(child, &allowed);
98 sched_setaffinity(getpid(), sizeof(cpu_set_t), &allowed);
99
Chris Wilson376b8132016-07-03 09:42:38 +0100100 hars_petruska_f54_1_random_perturb(child);
Chris Wilson9579e542016-05-23 21:56:01 +0100101 igt_until_timeout(timeout) {
Chris Wilson376b8132016-07-03 09:42:38 +0100102 arg.crtc_id = crtc_id[hars_petruska_f54_1_random_unsafe() % num_crtcs];
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200103 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg);
Chris Wilson9579e542016-05-23 21:56:01 +0100104 count++;
105 }
106
Chris Wilsonc74e0712016-05-24 16:24:15 +0100107 igt_debug("[%d] count=%lu\n", child, count);
108 results[child] = count;
Chris Wilson9579e542016-05-23 21:56:01 +0100109 }
Chris Wilsonf5d370c2016-06-04 21:25:17 +0100110 if (torture) {
111 igt_fork(child, num_children) {
112 struct sched_param rt = {.sched_priority = 1 };
113 cpu_set_t allowed;
114 unsigned long long count = 0;
115
116 sched_setscheduler(getpid(), SCHED_RR, &rt);
117
118 CPU_ZERO(&allowed);
119 CPU_SET(child, &allowed);
120 sched_setaffinity(getpid(), sizeof(cpu_set_t), &allowed);
121 igt_until_timeout(timeout) {
122 count++;
Tomeu Vizoso047c9992016-06-07 10:18:34 +0200123 cpu_relax();
Chris Wilsonf5d370c2016-06-04 21:25:17 +0100124 }
125 igt_debug("[hog:%d] count=%llu\n", child, count);
126 }
127 }
Chris Wilson9579e542016-05-23 21:56:01 +0100128 igt_waitchildren();
129
Chris Wilsonc74e0712016-05-24 16:24:15 +0100130 if (num_children > 1) {
131 igt_stats_t stats;
132
133 igt_stats_init_with_size(&stats, num_children);
134 results[num_children] = 0;
135 for (int child = 0; child < num_children; child++) {
136 igt_stats_push(&stats, results[child]);
137 results[num_children] += results[child];
138 }
139 igt_info("Total updates %llu (median of %d processes is %.2f)\n",
140 (long long)results[num_children],
141 num_children,
142 igt_stats_get_median(&stats));
143 igt_stats_fini(&stats);
144 } else {
145 igt_info("Total updates %llu\n", (long long)results[0]);
146 }
147
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200148 gem_close(display->drm_fd, arg.handle);
Chris Wilsonc74e0712016-05-24 16:24:15 +0100149 munmap(results, 4096);
Chris Wilson9579e542016-05-23 21:56:01 +0100150}
151
Gustavo Padovanc2270592017-08-02 19:54:17 -0300152static igt_output_t *set_fb_on_crtc(igt_display_t *display, enum pipe pipe, struct igt_fb *fb_info)
Chris Wilson162d4562016-06-22 15:41:23 +0100153{
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200154 igt_output_t *output;
Chris Wilson162d4562016-06-22 15:41:23 +0100155
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200156 for_each_valid_output_on_pipe(display, pipe, output) {
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200157 drmModeModeInfoPtr mode;
158 igt_plane_t *primary;
Chris Wilson162d4562016-06-22 15:41:23 +0100159
Maarten Lankhorst76c7a712017-09-27 12:25:37 +0200160 if (output->pending_pipe != PIPE_NONE)
Chris Wilson162d4562016-06-22 15:41:23 +0100161 continue;
162
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200163 igt_output_set_pipe(output, pipe);
164 mode = igt_output_get_mode(output);
165
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200166 igt_create_pattern_fb(display->drm_fd,
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200167 mode->hdisplay, mode->vdisplay,
168 DRM_FORMAT_XRGB8888, I915_TILING_NONE, fb_info);
169
Robert Fossa7864792017-01-10 19:21:26 -0500170 primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200171 igt_plane_set_fb(primary, fb_info);
172
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200173 return output;
Chris Wilson162d4562016-06-22 15:41:23 +0100174 }
175
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200176 return NULL;
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200177}
178
179static void set_cursor_on_pipe(igt_display_t *display, enum pipe pipe, struct igt_fb *fb)
180{
181 igt_plane_t *plane, *cursor = NULL;
182
183 for_each_plane_on_pipe(display, pipe, plane) {
Robert Fossa7864792017-01-10 19:21:26 -0500184 if (plane->type != DRM_PLANE_TYPE_CURSOR)
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200185 continue;
186
187 cursor = plane;
188 break;
189 }
190
191 igt_require(cursor);
192 igt_plane_set_fb(cursor, fb);
193}
194
195static void populate_cursor_args(igt_display_t *display, enum pipe pipe,
196 struct drm_mode_cursor *arg, struct igt_fb *fb)
197{
198 arg->crtc_id = display->pipes[pipe].crtc_id;
199 arg->flags = DRM_MODE_CURSOR_MOVE;
200 arg->x = 128;
201 arg->y = 128;
202 arg->width = fb->width;
203 arg->height = fb->height;
204 arg->handle = fb->gem_handle;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200205 arg[1] = *arg;
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200206}
207
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200208static enum pipe find_connected_pipe(igt_display_t *display, bool second)
209{
210 enum pipe pipe, first = PIPE_NONE;
211 igt_output_t *output;
212 igt_output_t *first_output = NULL;
213 bool found = false;
214
Maarten Lankhorstcb437352017-12-07 10:11:47 +0100215 if (!second) {
216 igt_pipe_crc_free(pipe_crc);
217 pipe_crc = NULL;
218
219 /* Clear display, events will be eaten by commit.. */
220 igt_display_reset(display);
221 }
222
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200223 for_each_pipe_with_valid_output(display, pipe, output) {
224 if (first == pipe || output == first_output)
225 continue;
226
227 if (second) {
228 first = pipe;
229 first_output = output;
230 second = false;
231 continue;
232 }
233
234 found = true;
235 break;
236 }
237
238 if (first_output)
239 igt_require_f(found, "No second valid output found\n");
240 else
Chris Wilson1105d9f2016-08-23 18:03:51 +0100241 igt_require_f(found, "No valid outputs found\n");
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200242
243 return pipe;
244}
245
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200246static void flip_nonblocking(igt_display_t *display, enum pipe pipe_id, bool atomic, struct igt_fb *fb, void *data)
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200247{
Robert Fossa7864792017-01-10 19:21:26 -0500248 igt_pipe_t *pipe = &display->pipes[pipe_id];
249 igt_plane_t *primary = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200250 int ret;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200251
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200252 igt_set_timeout(1, "Scheduling page flip\n");
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200253 if (!atomic) {
254 /* Schedule a nonblocking flip for the next vblank */
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200255 do {
256 ret = drmModePageFlip(display->drm_fd, pipe->crtc_id, fb->fb_id,
257 DRM_MODE_PAGE_FLIP_EVENT, data);
258 } while (ret == -EBUSY);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200259 } else {
260 igt_plane_set_fb(primary, fb);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200261 do {
262 ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, data);
263 } while (ret == -EBUSY);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200264 }
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200265 igt_assert(!ret);
266 igt_reset_timeout();
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200267}
268
269enum flip_test {
270 flip_test_legacy = 0,
271 flip_test_varying_size,
272 flip_test_toggle_visibility,
273 flip_test_atomic,
274 flip_test_atomic_transitions,
275 flip_test_atomic_transitions_varying_size,
276 flip_test_last = flip_test_atomic_transitions_varying_size
277};
278
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100279static bool cursor_slowpath(enum flip_test mode)
280{
281 /* cursor moving doesn't take slowpath, everything else does. */
282 if (mode == flip_test_legacy || mode == flip_test_atomic)
283 return false;
284
285 return true;
286}
287
Maarten Lankhorstda0b6ab2017-01-23 16:37:01 +0100288/*
289 * On platforms with two-stage watermark programming
290 * changing sprite visibility may require a extra vblank wait.
291 *
292 * Handle this here.
293 */
294static bool mode_requires_extra_vblank(enum flip_test mode)
295{
296 if (mode == flip_test_atomic_transitions ||
297 mode == flip_test_atomic_transitions_varying_size)
298 return true;
299
300 return false;
301}
302
Robert Fossa7864792017-01-10 19:21:26 -0500303static void transition_nonblocking(igt_display_t *display, enum pipe pipe_id,
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200304 struct igt_fb *prim_fb, struct igt_fb *argb_fb,
305 bool hide_sprite)
306{
Robert Fossa7864792017-01-10 19:21:26 -0500307 igt_pipe_t *pipe = &display->pipes[pipe_id];
308 igt_plane_t *primary = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_PRIMARY);
309 igt_plane_t *sprite = igt_pipe_get_plane_type(pipe, DRM_PLANE_TYPE_OVERLAY);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200310
311 if (hide_sprite) {
312 igt_plane_set_fb(primary, prim_fb);
313 igt_plane_set_fb(sprite, NULL);
314 } else {
Maarten Lankhorsta36e6272017-01-16 13:35:39 +0100315 int ret;
316
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200317 igt_plane_set_fb(primary, NULL);
318 igt_plane_set_fb(sprite, argb_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200319
Maarten Lankhorsta36e6272017-01-16 13:35:39 +0100320 ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
321 if (!ret)
322 return;
323
324 igt_assert(ret == -EINVAL);
325
326 igt_plane_set_fb(sprite, prim_fb);
327 }
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200328 igt_display_commit_atomic(display, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, display);
329}
330
331static void prepare_flip_test(igt_display_t *display,
332 enum flip_test mode,
333 enum pipe flip_pipe,
334 enum pipe cursor_pipe,
335 struct drm_mode_cursor *arg,
336 const struct igt_fb *prim_fb,
337 struct igt_fb *argb_fb,
338 struct igt_fb *cursor_fb2)
339{
340 argb_fb->gem_handle = 0;
341 cursor_fb2->gem_handle = 0;
342
343 if (mode == flip_test_varying_size ||
344 mode == flip_test_atomic_transitions_varying_size) {
345 uint64_t width, height;
346
347 do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_WIDTH, &width));
348 do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_HEIGHT, &height));
349
350 igt_skip_on(width <= 64 && height <= 64);
351 igt_create_color_fb(display->drm_fd, width, height,
352 DRM_FORMAT_ARGB8888, 0, 1., 0., .7, cursor_fb2);
353
354 arg[0].flags = arg[1].flags = DRM_MODE_CURSOR_BO;
355 arg[1].handle = cursor_fb2->gem_handle;
356 arg[1].width = width;
357 arg[1].height = height;
358 }
359
360 if (mode == flip_test_legacy ||
361 mode == flip_test_atomic) {
362 arg[1].x = 192;
363 arg[1].y = 192;
364 }
365
366 if (mode == flip_test_toggle_visibility) {
367 arg[0].flags = arg[1].flags = DRM_MODE_CURSOR_BO;
368 arg[1].handle = 0;
369 arg[1].width = arg[1].height = 0;
370 }
371
372 if (mode == flip_test_atomic_transitions ||
373 mode == flip_test_atomic_transitions_varying_size) {
374 igt_require(display->pipes[flip_pipe].n_planes > 1 &&
Robert Fossa7864792017-01-10 19:21:26 -0500375 display->pipes[flip_pipe].planes[1].type != DRM_PLANE_TYPE_CURSOR);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200376
377 igt_create_color_pattern_fb(display->drm_fd, prim_fb->width, prim_fb->height,
378 DRM_FORMAT_ARGB8888, 0, .1, .1, .1, argb_fb);
379 }
380}
381
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200382static void flip(igt_display_t *display,
Chris Wilson162d4562016-06-22 15:41:23 +0100383 int cursor_pipe, int flip_pipe,
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200384 int timeout, enum flip_test mode)
Chris Wilson162d4562016-06-22 15:41:23 +0100385{
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200386 struct drm_mode_cursor arg[2];
Chris Wilson162d4562016-06-22 15:41:23 +0100387 uint64_t *results;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200388 struct igt_fb fb_info, fb_info2, argb_fb, cursor_fb, cursor_fb2;
Chris Wilson162d4562016-06-22 15:41:23 +0100389
390 results = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
391 igt_assert(results != MAP_FAILED);
392
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200393 flip_pipe = find_connected_pipe(display, !!flip_pipe);
394 cursor_pipe = find_connected_pipe(display, !!cursor_pipe);
395
396 igt_info("Using pipe %s for page flip, pipe %s for cursor\n",
397 kmstest_pipe_name(flip_pipe), kmstest_pipe_name(cursor_pipe));
398
399 if (mode >= flip_test_atomic)
400 igt_require(display->is_atomic);
401
402 igt_require(set_fb_on_crtc(display, flip_pipe, &fb_info));
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200403 if (flip_pipe != cursor_pipe)
404 igt_require(set_fb_on_crtc(display, cursor_pipe, &fb_info2));
Chris Wilson162d4562016-06-22 15:41:23 +0100405
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200406 igt_create_color_fb(display->drm_fd, fb_info.width, fb_info.height, DRM_FORMAT_ARGB8888, 0, .5, .5, .5, &cursor_fb);
407
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200408 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
409 set_cursor_on_pipe(display, cursor_pipe, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200410 populate_cursor_args(display, cursor_pipe, arg, &cursor_fb);
411
412 prepare_flip_test(display, mode, flip_pipe, cursor_pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +0100413
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200414 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
Chris Wilson162d4562016-06-22 15:41:23 +0100415
Chris Wilson162d4562016-06-22 15:41:23 +0100416 igt_fork(child, 1) {
417 unsigned long count = 0;
418
419 igt_until_timeout(timeout) {
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200420 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[(count & 64)/64]);
Chris Wilson162d4562016-06-22 15:41:23 +0100421 count++;
422 }
423
424 igt_debug("cursor count=%lu\n", count);
425 results[0] = count;
426 }
427 igt_fork(child, 1) {
428 unsigned long count = 0;
Chris Wilson162d4562016-06-22 15:41:23 +0100429
430 igt_until_timeout(timeout) {
431 char buf[128];
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200432
433 switch (mode) {
434 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200435 flip_nonblocking(display, flip_pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200436 break;
437 case flip_test_atomic_transitions:
438 case flip_test_atomic_transitions_varying_size:
439 transition_nonblocking(display, flip_pipe, &fb_info, &argb_fb, count & 1);
440 break;
441 }
442
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200443 while (read(display->drm_fd, buf, sizeof(buf)) < 0 &&
Chris Wilsond86d6eb2016-06-23 21:07:36 +0100444 (errno == EINTR || errno == EAGAIN))
445 ;
Chris Wilson162d4562016-06-22 15:41:23 +0100446 count++;
447 }
448
449 igt_debug("flip count=%lu\n", count);
450 results[1] = count;
451 }
452 igt_waitchildren();
453
Chris Wilson162d4562016-06-22 15:41:23 +0100454 munmap(results, 4096);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200455
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200456 igt_remove_fb(display->drm_fd, &fb_info);
457 if (flip_pipe != cursor_pipe)
458 igt_remove_fb(display->drm_fd, &fb_info2);
459 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200460 if (argb_fb.gem_handle)
461 igt_remove_fb(display->drm_fd, &argb_fb);
462 if (cursor_fb2.gem_handle)
463 igt_remove_fb(display->drm_fd, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +0100464}
465
Gustavo Padovanc2270592017-08-02 19:54:17 -0300466static inline uint32_t pipe_select(enum pipe pipe)
Chris Wilson162d4562016-06-22 15:41:23 +0100467{
468 if (pipe > 1)
469 return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT;
470 else if (pipe > 0)
471 return DRM_VBLANK_SECONDARY;
472 else
473 return 0;
474}
475
Gustavo Padovanc2270592017-08-02 19:54:17 -0300476static unsigned get_vblank(int fd, enum pipe pipe, unsigned flags)
Chris Wilson162d4562016-06-22 15:41:23 +0100477{
478 union drm_wait_vblank vbl;
479
480 memset(&vbl, 0, sizeof(vbl));
481 vbl.request.type = DRM_VBLANK_RELATIVE | pipe_select(pipe) | flags;
482 if (drmIoctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl))
483 return 0;
484
485 return vbl.reply.sequence;
486}
487
Chris Wilson237cb892016-09-13 11:37:41 +0100488enum basic_flip_cursor {
489 FLIP_BEFORE_CURSOR,
490 FLIP_AFTER_CURSOR
491};
492
Chris Wilsond2adbdf2016-10-04 13:50:50 +0100493#define BASIC_BUSY 0x1
494
Chris Wilson237cb892016-09-13 11:37:41 +0100495static void basic_flip_cursor(igt_display_t *display,
496 enum flip_test mode,
Chris Wilsond2adbdf2016-10-04 13:50:50 +0100497 enum basic_flip_cursor order,
498 unsigned flags)
Chris Wilson237cb892016-09-13 11:37:41 +0100499{
500 struct drm_mode_cursor arg[2];
501 struct drm_event_vblank vbl;
502 struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
503 unsigned vblank_start;
504 enum pipe pipe = find_connected_pipe(display, false);
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100505 igt_spin_t *spin;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200506 int i, miss1 = 0, miss2 = 0, delta;
Chris Wilson237cb892016-09-13 11:37:41 +0100507
508 if (mode >= flip_test_atomic)
509 igt_require(display->is_atomic);
510
511 igt_require(set_fb_on_crtc(display, pipe, &fb_info));
512
513 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
514 set_cursor_on_pipe(display, pipe, &cursor_fb);
515 populate_cursor_args(display, pipe, arg, &cursor_fb);
516
517 prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
518
519 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
520
521 /* Quick sanity check that we can update a cursor in a single vblank */
522 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
523 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
524 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
525 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
526
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200527 for (i = 0; i < 25; i++) {
528 bool miss;
Chris Wilson237cb892016-09-13 11:37:41 +0100529
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200530 /* Bind the cursor first to warm up */
Chris Wilson237cb892016-09-13 11:37:41 +0100531 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Chris Wilson237cb892016-09-13 11:37:41 +0100532
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100533 spin = NULL;
Chris Wilsona6634242017-06-07 11:32:50 +0100534 if (flags & BASIC_BUSY)
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100535 spin = igt_spin_batch_new(display->drm_fd, 0, 0, fb_info.gem_handle);
Chris Wilson237cb892016-09-13 11:37:41 +0100536
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200537 /* Start with a synchronous query to align with the vblank */
538 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
539
540 switch (order) {
541 case FLIP_BEFORE_CURSOR:
542 switch (mode) {
543 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200544 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200545 break;
546 case flip_test_atomic_transitions:
547 case flip_test_atomic_transitions_varying_size:
548 transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
549 break;
550 }
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200551
552 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
553 miss = delta != 0;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200554
555 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Chris Wilson237cb892016-09-13 11:37:41 +0100556 break;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200557
558 case FLIP_AFTER_CURSOR:
559 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200560
561 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
562 miss = delta != 0;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200563
564 switch (mode) {
565 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200566 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200567 break;
568 case flip_test_atomic_transitions:
569 case flip_test_atomic_transitions_varying_size:
570 transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
571 break;
572 }
Chris Wilson237cb892016-09-13 11:37:41 +0100573 }
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200574
575 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
576
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100577 if (spin) {
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200578 struct pollfd pfd = { display->drm_fd, POLLIN };
579 igt_assert(poll(&pfd, 1, 0) == 0);
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100580 igt_spin_batch_free(display->drm_fd, spin);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200581 }
582
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200583 if (miss)
584 { /* compare nothing, already failed */ }
585 else if (!cursor_slowpath(mode))
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200586 miss = delta != 0;
587 else
588 miss = delta != 0 && delta != 1;
589
590 miss1 += miss;
591
592 igt_set_timeout(1, "Stuck page flip");
593 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
594 igt_reset_timeout();
595
596 if (miss1)
597 continue;
598
599 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
600
601 if (!mode_requires_extra_vblank(mode))
602 miss2 += delta != 1;
603 else
604 miss2 += delta != 1 && delta != 2;
Chris Wilson237cb892016-09-13 11:37:41 +0100605 }
606
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200607 igt_fail_on_f(miss1 > 2 || miss1 + miss2 > 5, "Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
608 if (miss1 || miss2)
609 igt_info("Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
Chris Wilson237cb892016-09-13 11:37:41 +0100610
Chris Wilson237cb892016-09-13 11:37:41 +0100611 igt_remove_fb(display->drm_fd, &fb_info);
612 igt_remove_fb(display->drm_fd, &cursor_fb);
613
614 if (argb_fb.gem_handle)
615 igt_remove_fb(display->drm_fd, &argb_fb);
616 if (cursor_fb2.gem_handle)
617 igt_remove_fb(display->drm_fd, &cursor_fb2);
618}
619
Maarten Lankhorstad718612016-12-27 13:50:31 +0100620static int
621get_cursor_updates_per_vblank(igt_display_t *display, enum pipe pipe,
622 struct drm_mode_cursor *arg)
623{
624 int target;
625
626 for (target = 65536; target; target /= 2) {
627 unsigned vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
628
629 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
630
631 for (int n = 0; n < target; n++)
632 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, arg);
633 if (get_vblank(display->drm_fd, pipe, 0) == vblank_start)
634 break;
635 }
636
637 /*
638 * Divide by 4, to handle variations in amount of vblanks
639 * caused by cpufreq throttling.
640 */
641 target /= 4;
642 igt_require(target > 1);
643
644 igt_debug("Using a target of %d cursor updates per quarter-vblank\n", target);
645
646 return target;
647}
648
Chris Wilson237cb892016-09-13 11:37:41 +0100649static void flip_vs_cursor(igt_display_t *display, enum flip_test mode, int nloops)
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200650{
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200651 struct drm_mode_cursor arg[2];
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100652 struct drm_event_vblank vbl;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200653 struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
Chris Wilson162d4562016-06-22 15:41:23 +0100654 unsigned vblank_start;
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100655 int target, cpu;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200656 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100657 volatile unsigned long *shared;
658 cpu_set_t mask, oldmask;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200659
660 if (mode >= flip_test_atomic)
661 igt_require(display->is_atomic);
Chris Wilson162d4562016-06-22 15:41:23 +0100662
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200663 igt_require(set_fb_on_crtc(display, pipe, &fb_info));
Chris Wilson162d4562016-06-22 15:41:23 +0100664
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200665 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200666 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200667 populate_cursor_args(display, pipe, arg, &cursor_fb);
668
669 prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +0100670
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200671 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
Chris Wilson162d4562016-06-22 15:41:23 +0100672
Maarten Lankhorstad718612016-12-27 13:50:31 +0100673 if (nloops)
674 target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
675 else
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100676 target = 1;
Chris Wilson162d4562016-06-22 15:41:23 +0100677
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200678 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
679 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200680 for (int n = 0; n < target; n++)
681 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200682 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Chris Wilson162d4562016-06-22 15:41:23 +0100683
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100684 /*
685 * There are variations caused by using cpu frequency changing. To
686 * eliminate those we force this test to run on the same cpu as an
687 * idle thread that does a busy loop of sched_yield(); The effect is
688 * that we don't throttle the cpu to a lower frequency, and the
689 * variations caused by cpu speed changing are eliminated.
690 */
691 if (target > 1) {
692 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
693 igt_assert(shared != MAP_FAILED);
694
695 cpu = sched_getcpu();
696 igt_assert(cpu >= 0);
697
698 CPU_ZERO(&mask);
699 CPU_SET(cpu, &mask);
700 sched_getaffinity(0, sizeof(oldmask), &oldmask);
701 sched_setaffinity(0, sizeof(mask), &mask);
702
703 shared[0] = 0;
704
705 igt_fork(child, 1) {
706 struct sched_param parm = { .sched_priority = 0 };
707
708 igt_assert(sched_setscheduler(0, SCHED_IDLE, &parm) == 0);
709
710 while (!shared[0])
711 sched_yield();
712 }
713 }
714
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100715 do {
716 /* Bind the cursor first to warm up */
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200717 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
Chris Wilson162d4562016-06-22 15:41:23 +0100718
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100719 /* Start with a synchronous query to align with the vblank */
720 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200721 switch (mode) {
722 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200723 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200724 break;
725 case flip_test_atomic_transitions:
726 case flip_test_atomic_transitions_varying_size:
727 transition_nonblocking(display, pipe, &fb_info, &argb_fb, (nloops & 2) /2);
728 break;
729 }
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100730
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100731 /* The nonblocking flip should not have delayed us */
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200732 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100733 for (int n = 0; n < target; n++)
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200734 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100735
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100736 /* Nor should it have delayed the following cursor update */
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100737 if (!cursor_slowpath(mode))
738 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
739 else
740 igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100741
742 igt_set_timeout(1, "Stuck page flip");
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200743 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
Maarten Lankhorstda0b6ab2017-01-23 16:37:01 +0100744
745 if (!mode_requires_extra_vblank(mode))
746 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
747 else
748 igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 2);
749
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100750 igt_reset_timeout();
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100751 } while (nloops--);
Chris Wilson162d4562016-06-22 15:41:23 +0100752
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100753 if (target > 1) {
754 shared[0] = 1;
755 igt_waitchildren();
756 munmap((void *)shared, 4096);
757 sched_setaffinity(0, sizeof(oldmask), &oldmask);
758 }
759
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200760 igt_remove_fb(display->drm_fd, &fb_info);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200761 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200762
763 if (argb_fb.gem_handle)
764 igt_remove_fb(display->drm_fd, &argb_fb);
765 if (cursor_fb2.gem_handle)
766 igt_remove_fb(display->drm_fd, &cursor_fb2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100767}
768
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100769static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
770{
771 struct igt_fb fb_info, cursor_fb;
772 igt_output_t *output;
773 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100774 struct drm_mode_cursor arg[2];
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100775 igt_plane_t *cursor = NULL, *plane;
776
777 igt_require(display->is_atomic);
778 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
779 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
780 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100781 populate_cursor_args(display, pipe, arg, &cursor_fb);
782 arg[0].flags |= DRM_MODE_CURSOR_BO;
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100783
784 for_each_plane_on_pipe(display, pipe, plane) {
Robert Fossa7864792017-01-10 19:21:26 -0500785 if (plane->type != DRM_PLANE_TYPE_CURSOR)
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100786 continue;
787
788 cursor = plane;
789 break;
790 }
791
792 igt_skip_on(!cursor);
793
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100794 /*
Maarten Lankhorstcb437352017-12-07 10:11:47 +0100795 * Start disabled. No way around it, since the first atomic
796 * commit may be unreliable with amount of events sent.
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100797 */
798 igt_output_set_pipe(output, PIPE_NONE);
799 igt_display_commit2(display, COMMIT_ATOMIC);
800
801 while (loops--) {
802 unsigned flags;
803 struct pollfd pfd = { display->drm_fd, POLLIN };
804 struct drm_event_vblank vbl;
805
806 flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
807 flags |= DRM_MODE_ATOMIC_NONBLOCK;
808 flags |= DRM_MODE_PAGE_FLIP_EVENT;
809
810 /*
811 * Test that a cursor update after a nonblocking modeset
812 * works as intended. It should block until the modeset completes.
813 */
814
815 igt_output_set_pipe(output, pipe);
816 igt_plane_set_fb(cursor, NULL);
817 igt_display_commit_atomic(display, flags, NULL);
818
819 igt_assert_eq(0, poll(&pfd, 1, 0));
820 igt_assert_eq(0, pfd.revents);
821
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100822 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100823
824 igt_assert_eq(1, poll(&pfd, 1, 0));
825 igt_assert_eq(POLLIN, pfd.revents);
826
827 igt_set_timeout(1, "Stuck page flip");
828 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
829 igt_reset_timeout();
830
831 igt_output_set_pipe(output, PIPE_NONE);
832 igt_display_commit_atomic(display, flags, NULL);
833
834 igt_assert_eq(0, poll(&pfd, 1, 0));
835 igt_assert_eq(0, pfd.revents);
836
837 /* Same for cursor on disabled crtc. */
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100838 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100839
840 igt_assert_eq(1, poll(&pfd, 1, 0));
841 igt_assert_eq(POLLIN, pfd.revents);
842
843 igt_set_timeout(1, "Stuck page flip");
844 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
845 igt_reset_timeout();
846 }
847
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100848 igt_remove_fb(display->drm_fd, &fb_info);
849 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100850}
851
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100852static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool modeset, bool atomic)
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200853{
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200854 struct drm_mode_cursor arg1[2], arg2[2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200855 struct igt_fb fb_info, fb2_info, cursor_fb;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200856 enum pipe pipe = find_connected_pipe(display, false);
857 enum pipe pipe2 = find_connected_pipe(display, true);
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100858 igt_output_t *output, *output2;
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200859 bool vblank_matches, enabled = false;
860 volatile unsigned long *shared;
861 unsigned flags = 0, vblank_start;
862 struct drm_event_vblank vbl;
863 int ret;
864
865 if (modeset) {
866 uint64_t val;
867
868 igt_fail_on(!atomic);
869 igt_require(drmGetCap(display->drm_fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &val) == 0);
870 }
871
872 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
873 igt_assert(shared != MAP_FAILED);
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200874
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100875 igt_fail_on(modeset && !atomic);
876
877 if (atomic)
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200878 igt_require(display->is_atomic);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200879
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100880 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200881 igt_require((output2 = set_fb_on_crtc(display, pipe2, &fb2_info)));
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200882
883 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
884 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200885 populate_cursor_args(display, pipe, arg1, &cursor_fb);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200886
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200887 arg1[1].x = arg1[1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200888
889 set_cursor_on_pipe(display, pipe2, &cursor_fb);
890 populate_cursor_args(display, pipe2, arg2, &cursor_fb);
891
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100892 arg2[1].x = arg2[1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200893
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200894
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200895 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
896
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200897 igt_fork(child, 2) {
898 struct drm_mode_cursor *arg = child ? arg2 : arg1;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200899
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200900 while (!shared[0])
901 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR,
902 &arg[!shared[1]]);
903 }
904
905 if (modeset) {
906 igt_plane_t *plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
907
908 flags = DRM_MODE_ATOMIC_ALLOW_MODESET |
909 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
910
911 /* Disable pipe2 */
912 igt_output_set_pipe(output2, PIPE_NONE);
913 igt_display_commit_atomic(display, flags, NULL);
914 enabled = false;
915
916 /*
917 * Try a page flip on crtc 1, if we succeed pump page flips and
918 * modesets interleaved, else do a single atomic commit with both.
919 */
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200920 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200921 igt_plane_set_fb(plane, &fb_info);
922 ret = igt_display_try_commit_atomic(display, flags, (void*)(ptrdiff_t)vblank_start);
923 igt_assert(!ret || ret == -EBUSY);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200924
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200925 if (ret == -EBUSY) {
926 /* Force completion on both pipes, and generate event. */
927 igt_display_commit_atomic(display, flags, NULL);
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100928
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200929 while (nloops--) {
930 shared[1] = nloops & 1;
931
932 igt_set_timeout(35, "Stuck modeset");
933 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
934 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
935 igt_reset_timeout();
936
937 if (!nloops)
938 break;
939
940 /* Commit page flip and modeset simultaneously. */
941 igt_plane_set_fb(plane, &fb_info);
942 igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
943 enabled = !enabled;
944
945 igt_set_timeout(5, "Scheduling modeset\n");
946 do {
947 ret = igt_display_try_commit_atomic(display, flags, NULL);
948 } while (ret == -EBUSY);
949 igt_assert(!ret);
950 igt_reset_timeout();
951 }
952
953 goto done;
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100954 }
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200955 } else {
956 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
957 flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200958
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200959 vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
960 flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
961 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200962
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200963 vblank_matches = false;
964 while (nloops) {
965 shared[1] = nloops & 1;
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100966
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200967 if (!modeset || nloops > 1)
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100968 igt_set_timeout(1, "Stuck page flip");
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200969 else
970 igt_set_timeout(35, "Stuck modeset");
971 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
972 igt_reset_timeout();
973
974 vblank_start = vbl.user_data;
975 if (!modeset)
976 igt_assert_eq(vbl.sequence, vblank_start + 1);
977
978 if (vblank_start && vbl.sequence == vblank_start + 1)
979 vblank_matches = true;
980
981 /* Do not requeue on the last 2 events. */
982 if (nloops <= 2) {
983 nloops--;
984 continue;
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200985 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200986
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200987 if (vbl.crtc_id == display->pipes[pipe].crtc_id) {
988 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
989 flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
990 } else {
991 igt_assert(vbl.crtc_id == display->pipes[pipe2].crtc_id);
992
993 nloops--;
994
995 if (!modeset) {
996 vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
997 flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
998 } else {
999 igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
1000
1001 igt_set_timeout(1, "Scheduling modeset\n");
1002 do {
1003 ret = igt_display_try_commit_atomic(display, flags, NULL);
1004 } while (ret == -EBUSY);
1005 igt_assert(!ret);
1006 igt_reset_timeout();
1007
1008 enabled = !enabled;
1009 }
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001010 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001011 }
1012
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001013 igt_assert_f(vblank_matches, "During modeset at least 1 page flip needs to match!\n");
1014
1015done:
1016 shared[0] = 1;
1017 igt_waitchildren();
1018
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001019 igt_remove_fb(display->drm_fd, &fb_info);
1020 igt_remove_fb(display->drm_fd, &fb2_info);
1021 igt_remove_fb(display->drm_fd, &cursor_fb);
1022}
1023
Chris Wilson237cb892016-09-13 11:37:41 +01001024static void cursor_vs_flip(igt_display_t *display, enum flip_test mode, int nloops)
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001025{
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001026 struct drm_mode_cursor arg[2];
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001027 struct drm_event_vblank vbl;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001028 struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001029 unsigned vblank_start, vblank_last;
1030 volatile unsigned long *shared;
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001031 long target;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001032 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001033 igt_output_t *output;
1034 uint32_t vrefresh;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001035
1036 if (mode >= flip_test_atomic)
1037 igt_require(display->is_atomic);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001038
1039 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1040 igt_assert(shared != MAP_FAILED);
1041
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001042 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
1043 vrefresh = igt_output_get_mode(output)->vrefresh;
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001044
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001045 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
Maarten Lankhorst29516cd2016-07-18 11:47:06 +02001046 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001047 populate_cursor_args(display, pipe, arg, &cursor_fb);
1048
1049 prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001050
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001051 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001052
Maarten Lankhorstad718612016-12-27 13:50:31 +01001053 target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001054
1055 for (int i = 0; i < nloops; i++) {
1056 shared[0] = 0;
1057 igt_fork(child, 1) {
1058 unsigned long count = 0;
1059 while (!shared[0]) {
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001060 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i & 1]);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001061 count++;
1062 }
1063 igt_debug("child: %lu cursor updates\n", count);
1064 shared[0] = count;
1065 }
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001066
1067 switch (mode) {
1068 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001069 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001070 break;
1071 case flip_test_atomic_transitions:
1072 case flip_test_atomic_transitions_varying_size:
1073 transition_nonblocking(display, pipe, &fb_info, &argb_fb, (i & 2) >> 1);
1074 break;
1075 }
1076
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001077 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001078 vblank_start = vblank_last = vbl.sequence;
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001079 for (int n = 0; n < vrefresh / 2; n++) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001080 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001081
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001082 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001083 if (vbl.sequence != vblank_last + 1) {
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001084 igt_info("page flip %d was delayed, missed %d frames\n",
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001085 n, vbl.sequence - vblank_last - 1);
1086 }
1087 vblank_last = vbl.sequence;
1088 }
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001089
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001090 if (!cursor_slowpath(mode))
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001091 igt_assert_lte(vbl.sequence, vblank_start + 5 * vrefresh / 8);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001092
1093 shared[0] = 1;
1094 igt_waitchildren();
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001095 igt_assert_f(shared[0] > vrefresh*target / 2,
1096 "completed %lu cursor updated in a period of %u flips, "
1097 "we expect to complete approximately %lu updates, "
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001098 "with the threshold set at %lu\n",
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001099 shared[0], vrefresh / 2,
1100 vrefresh*target, vrefresh*target / 2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001101 }
1102
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001103 igt_remove_fb(display->drm_fd, &fb_info);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001104 igt_remove_fb(display->drm_fd, &cursor_fb);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001105 munmap((void *)shared, 4096);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001106 if (argb_fb.gem_handle)
1107 igt_remove_fb(display->drm_fd, &argb_fb);
1108 if (cursor_fb2.gem_handle)
1109 igt_remove_fb(display->drm_fd, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +01001110}
1111
Maarten Lankhorst39660182017-01-17 17:07:52 +01001112static void two_screens_cursor_vs_flip(igt_display_t *display, int nloops, bool atomic)
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001113{
Maarten Lankhorst39660182017-01-17 17:07:52 +01001114 struct drm_mode_cursor arg[2][2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001115 struct drm_event_vblank vbl;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001116 struct igt_fb fb_info[2], cursor_fb;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001117 volatile unsigned long *shared;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001118 int target[2];
1119 enum pipe pipe[2] = {
1120 find_connected_pipe(display, false),
1121 find_connected_pipe(display, true)
1122 };
1123 igt_output_t *outputs[2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001124
1125 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1126 igt_assert(shared != MAP_FAILED);
1127
Maarten Lankhorst39660182017-01-17 17:07:52 +01001128 if (atomic)
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001129 igt_require(display->is_atomic);
1130
Maarten Lankhorst39660182017-01-17 17:07:52 +01001131 igt_require((outputs[0] = set_fb_on_crtc(display, pipe[0], &fb_info[0])));
1132 igt_require((outputs[1] = set_fb_on_crtc(display, pipe[1], &fb_info[1])));
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001133
1134 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001135
Maarten Lankhorst39660182017-01-17 17:07:52 +01001136 set_cursor_on_pipe(display, pipe[0], &cursor_fb);
1137 populate_cursor_args(display, pipe[0], arg[0], &cursor_fb);
1138 arg[0][1].x = arg[0][1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001139
Maarten Lankhorst39660182017-01-17 17:07:52 +01001140 set_cursor_on_pipe(display, pipe[1], &cursor_fb);
1141 populate_cursor_args(display, pipe[1], arg[1], &cursor_fb);
1142 arg[1][1].x = arg[1][1].y = 192;
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001143
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001144 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1145
Maarten Lankhorst39660182017-01-17 17:07:52 +01001146 target[0] = get_cursor_updates_per_vblank(display, pipe[0], &arg[0][0]);
1147 target[1] = get_cursor_updates_per_vblank(display, pipe[1], &arg[1][0]);
Maarten Lankhorstad718612016-12-27 13:50:31 +01001148
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001149 for (int i = 0; i < nloops; i++) {
Maarten Lankhorst39660182017-01-17 17:07:52 +01001150 unsigned long vrefresh[2];
1151 unsigned vblank_start[2], vblank_last[2];
1152 int done[2] = {};
1153
1154 vrefresh[0] = igt_output_get_mode(outputs[0])->vrefresh;
1155 vrefresh[1] = igt_output_get_mode(outputs[1])->vrefresh;
1156
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001157 shared[0] = 0;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001158 shared[1] = 0;
1159 igt_fork(child, 2) {
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001160 unsigned long count = 0;
1161
Maarten Lankhorst39660182017-01-17 17:07:52 +01001162 while (!shared[child]) {
1163 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[child][(i >> child) & 1]);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001164 count++;
1165 }
Maarten Lankhorst39660182017-01-17 17:07:52 +01001166 igt_debug("child %i: %lu cursor updates\n", child, count);
1167 shared[child] = count;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001168 }
1169
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001170 flip_nonblocking(display, pipe[0], atomic, &fb_info[0], (void *)0UL);
1171 flip_nonblocking(display, pipe[1], atomic, &fb_info[1], (void *)1UL);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001172
Maarten Lankhorst39660182017-01-17 17:07:52 +01001173 for (int n = 0; n < vrefresh[0] / 2 + vrefresh[1] / 2; n++) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001174 unsigned long child;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001175
1176 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001177 child = vbl.user_data;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001178
Maarten Lankhorst39660182017-01-17 17:07:52 +01001179 if (!done[child]++)
1180 vblank_start[child] = vbl.sequence;
1181 else if (vbl.sequence != vblank_last[child] + 1)
1182 igt_info("page flip %d was delayed, missed %d frames\n",
1183 done[child], vbl.sequence - vblank_last[child] - 1);
1184
1185 vblank_last[child] = vbl.sequence;
1186
1187 if (done[child] < vrefresh[child] / 2) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001188 flip_nonblocking(display, pipe[child], atomic, &fb_info[child], (void *)child);
Maarten Lankhorst39660182017-01-17 17:07:52 +01001189 } else {
1190 igt_assert_lte(vbl.sequence, vblank_start[child] + 5 * vrefresh[child] / 8);
1191
1192 shared[child] = 1;
1193 }
1194 }
1195
1196 igt_assert_eq(done[0], vrefresh[0] / 2);
1197 igt_assert_eq(done[1], vrefresh[1] / 2);
1198
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001199 igt_waitchildren();
Maarten Lankhorst39660182017-01-17 17:07:52 +01001200 for (int child = 0; child < 2; child++)
1201 igt_assert_f(shared[child] > vrefresh[child]*target[child] / 2,
1202 "completed %lu cursor updated in a period of %lu flips, "
1203 "we expect to complete approximately %lu updates, "
1204 "with the threshold set at %lu\n",
1205 shared[child], vrefresh[child] / 2,
1206 vrefresh[child]*target[child], vrefresh[child]*target[child] / 2);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001207 }
1208
Maarten Lankhorst39660182017-01-17 17:07:52 +01001209 igt_remove_fb(display->drm_fd, &fb_info[0]);
1210 igt_remove_fb(display->drm_fd, &fb_info[1]);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001211 igt_remove_fb(display->drm_fd, &cursor_fb);
1212 munmap((void *)shared, 4096);
1213}
1214
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001215static void flip_vs_cursor_crc(igt_display_t *display, bool atomic)
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001216{
1217 struct drm_mode_cursor arg[2];
1218 struct drm_event_vblank vbl;
1219 struct igt_fb fb_info, cursor_fb;
1220 unsigned vblank_start;
1221 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001222 igt_crc_t crcs[3];
1223
1224 if (atomic)
1225 igt_require(display->is_atomic);
1226
1227 igt_require(set_fb_on_crtc(display, pipe, &fb_info));
1228
1229 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1230 populate_cursor_args(display, pipe, arg, &cursor_fb);
1231
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001232 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1233
Chris Wilson83884e92017-03-21 17:16:03 +00001234 pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001235
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001236 set_cursor_on_pipe(display, pipe, &cursor_fb);
1237 igt_display_commit2(display, COMMIT_UNIVERSAL);
1238
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001239 /* Collect reference crcs, crcs[0] last. */
1240 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1241 igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001242
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001243 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001244 igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1245
1246 /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1247 for (int i = 1; i >= 0; i--) {
1248 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1249
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001250 flip_nonblocking(display, pipe, atomic, &fb_info, NULL);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001251 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1252
1253 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1254
1255 igt_set_timeout(1, "Stuck page flip");
1256 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
1257 igt_reset_timeout();
1258
1259 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
1260
1261 igt_pipe_crc_collect_crc(pipe_crc, &crcs[2]);
1262
1263 igt_assert_crc_equal(&crcs[i], &crcs[2]);
1264 }
1265
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001266 igt_remove_fb(display->drm_fd, &fb_info);
1267 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001268}
1269
1270static void flip_vs_cursor_busy_crc(igt_display_t *display, bool atomic)
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001271{
1272 struct drm_mode_cursor arg[2];
1273 struct drm_event_vblank vbl;
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001274 struct igt_fb fb_info[2], cursor_fb;
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001275 unsigned vblank_start;
1276 enum pipe pipe = find_connected_pipe(display, false);
Robert Fossa7864792017-01-10 19:21:26 -05001277 igt_pipe_t *pipe_connected = &display->pipes[pipe];
1278 igt_plane_t *plane_primary = igt_pipe_get_plane_type(pipe_connected, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001279 igt_crc_t crcs[2], test_crc;
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001280
1281 if (atomic)
1282 igt_require(display->is_atomic);
1283
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001284 igt_require(set_fb_on_crtc(display, pipe, &fb_info[0]));
1285 igt_create_color_pattern_fb(display->drm_fd, fb_info[0].width, fb_info[0].height,
1286 DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED, .1, .1, .1, &fb_info[1]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001287
1288 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1289 populate_cursor_args(display, pipe, arg, &cursor_fb);
1290
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001291 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1292
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001293 pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001294
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001295 set_cursor_on_pipe(display, pipe, &cursor_fb);
1296 igt_display_commit2(display, COMMIT_UNIVERSAL);
1297
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001298 /* Collect reference crcs, crc[0] last for the loop. */
1299 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1300 igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001301
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001302 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001303 igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1304
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001305 /*
1306 * Set fb 1 on primary at least once before flipping to force
1307 * setting the correct cache level, else we get a stall in the
1308 * page flip handler.
1309 */
Robert Fossa7864792017-01-10 19:21:26 -05001310 igt_plane_set_fb(plane_primary, &fb_info[1]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001311 igt_display_commit2(display, COMMIT_UNIVERSAL);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001312
Robert Fossa7864792017-01-10 19:21:26 -05001313 igt_plane_set_fb(plane_primary, &fb_info[0]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001314 igt_display_commit2(display, COMMIT_UNIVERSAL);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001315
Maarten Lankhorst1043c092017-09-19 13:31:13 +02001316 /*
1317 * We must enable CRC collecting here since this may force
1318 * a modeset, and this loop is timing sensitive.
1319 */
1320 igt_pipe_crc_start(pipe_crc);
1321
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001322 /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1323 for (int i = 1; i >= 0; i--) {
Chris Wilson7f97a4a2017-09-14 14:18:07 +01001324 igt_spin_t *spin;
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001325
Chris Wilson7f97a4a2017-09-14 14:18:07 +01001326 spin = igt_spin_batch_new(display->drm_fd, 0, 0,
1327 fb_info[1].gem_handle);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001328
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001329 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1330
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001331 flip_nonblocking(display, pipe, atomic, &fb_info[1], NULL);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001332 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1333
1334 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1335
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001336 igt_pipe_crc_drain(pipe_crc);
1337 igt_pipe_crc_get_single(pipe_crc, &test_crc);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001338
Chris Wilson7f97a4a2017-09-14 14:18:07 +01001339 igt_spin_batch_free(display->drm_fd, spin);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001340
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001341 igt_set_timeout(1, "Stuck page flip");
1342 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
1343 igt_reset_timeout();
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001344
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001345 igt_assert_lte(vblank_start + 1, get_vblank(display->drm_fd, pipe, 0));
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001346
Robert Fossa7864792017-01-10 19:21:26 -05001347 igt_plane_set_fb(plane_primary, &fb_info[0]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001348 igt_display_commit2(display, COMMIT_UNIVERSAL);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001349
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001350 igt_assert_crc_equal(&crcs[i], &test_crc);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001351 }
1352
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001353 igt_remove_fb(display->drm_fd, &fb_info[1]);
1354 igt_remove_fb(display->drm_fd, &fb_info[0]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001355 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001356}
1357
Chris Wilson9579e542016-05-23 21:56:01 +01001358igt_main
1359{
Chris Wilsondab6b6b2016-05-24 16:14:32 +01001360 const int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001361 igt_display_t display = { .drm_fd = -1 };
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001362 int i;
Chris Wilson9579e542016-05-23 21:56:01 +01001363
Chris Wilson9579e542016-05-23 21:56:01 +01001364 igt_fixture {
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001365 display.drm_fd = drm_open_driver_master(DRIVER_ANY);
Chris Wilson9579e542016-05-23 21:56:01 +01001366 kmstest_set_vt_graphics_mode();
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001367
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001368 igt_display_init(&display, display.drm_fd);
1369 igt_require(display.n_pipes > 0);
Chris Wilson9579e542016-05-23 21:56:01 +01001370 }
1371
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001372 igt_subtest_group {
Daniel Vetter229d7d22017-08-14 11:32:05 +02001373 enum pipe n;
1374 for_each_pipe_static(n) {
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001375 errno = 0;
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001376
Chris Wilson04b8f0e2016-05-25 14:53:34 +01001377 igt_fixture {
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001378 igt_skip_on(n >= display.n_pipes);
Chris Wilson04b8f0e2016-05-25 14:53:34 +01001379 }
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001380
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001381 igt_subtest_f("pipe-%s-single-bo", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001382 stress(&display, n, 1, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001383 igt_subtest_f("pipe-%s-single-move", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001384 stress(&display, n, 1, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001385
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001386 igt_subtest_f("pipe-%s-forked-bo", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001387 stress(&display, n, ncpus, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001388 igt_subtest_f("pipe-%s-forked-move", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001389 stress(&display, n, ncpus, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilsonf5d370c2016-06-04 21:25:17 +01001390
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001391 igt_subtest_f("pipe-%s-torture-bo", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001392 stress(&display, n, -ncpus, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001393 igt_subtest_f("pipe-%s-torture-move", kmstest_pipe_name(n))
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001394 stress(&display, n, -ncpus, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001395 }
1396 }
1397
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001398 igt_subtest("all-pipes-single-bo")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001399 stress(&display, -1, 1, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001400 igt_subtest("all-pipes-single-move")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001401 stress(&display, -1, 1, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilsoncce2ff02016-05-25 08:34:25 +01001402
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001403 igt_subtest("all-pipes-forked-bo")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001404 stress(&display, -1, ncpus, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001405 igt_subtest("all-pipes-forked-move")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001406 stress(&display, -1, ncpus, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilson9579e542016-05-23 21:56:01 +01001407
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001408 igt_subtest("all-pipes-torture-bo")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001409 stress(&display, -1, -ncpus, DRM_MODE_CURSOR_BO, 20);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001410 igt_subtest("all-pipes-torture-move")
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001411 stress(&display, -1, -ncpus, DRM_MODE_CURSOR_MOVE, 20);
Chris Wilsonf5d370c2016-06-04 21:25:17 +01001412
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +01001413 igt_subtest("nonblocking-modeset-vs-cursor-atomic")
1414 nonblocking_modeset_vs_cursor(&display, 1);
1415
1416 igt_subtest("long-nonblocking-modeset-vs-cursor-atomic")
1417 nonblocking_modeset_vs_cursor(&display, 16);
1418
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001419 igt_subtest("2x-flip-vs-cursor-legacy")
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +01001420 two_screens_flip_vs_cursor(&display, 8, false, false);
1421
1422 igt_subtest("2x-flip-vs-cursor-atomic")
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001423 two_screens_flip_vs_cursor(&display, 8, false, true);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001424
1425 igt_subtest("2x-cursor-vs-flip-legacy")
Maarten Lankhorst39660182017-01-17 17:07:52 +01001426 two_screens_cursor_vs_flip(&display, 8, false);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001427
1428 igt_subtest("2x-long-flip-vs-cursor-legacy")
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +01001429 two_screens_flip_vs_cursor(&display, 150, false, false);
1430
1431 igt_subtest("2x-long-flip-vs-cursor-atomic")
1432 two_screens_flip_vs_cursor(&display, 150, false, true);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001433
1434 igt_subtest("2x-long-cursor-vs-flip-legacy")
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001435 two_screens_cursor_vs_flip(&display, 50, false);
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001436
1437 igt_subtest("2x-nonblocking-modeset-vs-cursor-atomic")
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001438 two_screens_flip_vs_cursor(&display, 4, true, true);
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001439
Maarten Lankhorst39660182017-01-17 17:07:52 +01001440 igt_subtest("2x-cursor-vs-flip-atomic")
1441 two_screens_cursor_vs_flip(&display, 8, true);
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001442
1443 igt_subtest("2x-long-nonblocking-modeset-vs-cursor-atomic")
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001444 two_screens_flip_vs_cursor(&display, 15, true, true);
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001445
Maarten Lankhorst39660182017-01-17 17:07:52 +01001446 igt_subtest("2x-long-cursor-vs-flip-atomic")
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001447 two_screens_cursor_vs_flip(&display, 50, true);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001448
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001449 igt_subtest("flip-vs-cursor-crc-legacy")
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001450 flip_vs_cursor_crc(&display, false);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001451
1452 igt_subtest("flip-vs-cursor-crc-atomic")
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001453 flip_vs_cursor_crc(&display, true);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001454
1455 igt_subtest("flip-vs-cursor-busy-crc-legacy")
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001456 flip_vs_cursor_busy_crc(&display, false);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001457
1458 igt_subtest("flip-vs-cursor-busy-crc-atomic")
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001459 flip_vs_cursor_busy_crc(&display, true);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001460
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001461 for (i = 0; i <= flip_test_last; i++) {
1462 const char *modes[flip_test_last+1] = {
1463 "legacy",
1464 "varying-size",
1465 "toggle",
1466 "atomic",
1467 "atomic-transitions",
1468 "atomic-transitions-varying-size"
1469 };
1470 const char *prefix = "short-";
Chris Wilson162d4562016-06-22 15:41:23 +01001471
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001472 switch (i) {
1473 case flip_test_legacy:
1474 case flip_test_varying_size:
1475 case flip_test_atomic:
1476 prefix = "basic-";
1477 break;
1478 default: break;
1479 }
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001480
Chris Wilson237cb892016-09-13 11:37:41 +01001481 igt_subtest_f("%sflip-before-cursor-%s", prefix, modes[i])
Chris Wilsond2adbdf2016-10-04 13:50:50 +01001482 basic_flip_cursor(&display, i, FLIP_BEFORE_CURSOR, 0);
1483
Chris Wilson83cab8a2017-04-27 09:22:54 +01001484 if (!cursor_slowpath(i)) {
1485 igt_subtest_f("%sbusy-flip-before-cursor-%s", prefix, modes[i]) {
1486 igt_require_gem(display.drm_fd);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001487 basic_flip_cursor(&display, i, FLIP_BEFORE_CURSOR,
1488 BASIC_BUSY);
Chris Wilson83cab8a2017-04-27 09:22:54 +01001489 }
1490 }
Chris Wilson237cb892016-09-13 11:37:41 +01001491
1492 igt_subtest_f("%sflip-after-cursor-%s", prefix, modes[i])
Chris Wilsond2adbdf2016-10-04 13:50:50 +01001493 basic_flip_cursor(&display, i, FLIP_AFTER_CURSOR, 0);
Chris Wilson237cb892016-09-13 11:37:41 +01001494
1495 igt_subtest_f("flip-vs-cursor-%s", modes[i])
1496 flip_vs_cursor(&display, i, 150);
1497 igt_subtest_f("cursor-vs-flip-%s", modes[i])
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001498 cursor_vs_flip(&display, i, 50);
Maarten Lankhorst1b8d8bc2016-07-12 11:55:26 +02001499
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001500 igt_subtest_f("cursorA-vs-flipA-%s", modes[i])
1501 flip(&display, 0, 0, 10, i);
1502
1503 igt_subtest_f("cursorA-vs-flipB-%s", modes[i])
1504 flip(&display, 0, 1, 10, i);
1505
1506 igt_subtest_f("cursorB-vs-flipA-%s", modes[i])
1507 flip(&display, 1, 0, 10, i);
1508
1509 igt_subtest_f("cursorB-vs-flipB-%s", modes[i])
1510 flip(&display, 1, 1, 10, i);
Chris Wilson162d4562016-06-22 15:41:23 +01001511 }
1512
Chris Wilson9579e542016-05-23 21:56:01 +01001513 igt_fixture {
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001514 igt_display_fini(&display);
Chris Wilson9579e542016-05-23 21:56:01 +01001515 }
1516}