blob: 82ceebcb0809a3a04fea244b687bc3dcd700ed86 [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 Wilson4b57f852018-06-25 13:27:36 +0100535 spin = igt_spin_batch_new(display->drm_fd,
536 .dependency = fb_info.gem_handle);
Chris Wilson237cb892016-09-13 11:37:41 +0100537
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200538 /* Start with a synchronous query to align with the vblank */
539 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
540
541 switch (order) {
542 case FLIP_BEFORE_CURSOR:
543 switch (mode) {
544 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200545 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200546 break;
547 case flip_test_atomic_transitions:
548 case flip_test_atomic_transitions_varying_size:
549 transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
550 break;
551 }
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200552
553 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
554 miss = delta != 0;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200555
556 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Chris Wilson237cb892016-09-13 11:37:41 +0100557 break;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200558
559 case FLIP_AFTER_CURSOR:
560 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200561
562 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
563 miss = delta != 0;
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200564
565 switch (mode) {
566 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200567 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200568 break;
569 case flip_test_atomic_transitions:
570 case flip_test_atomic_transitions_varying_size:
571 transition_nonblocking(display, pipe, &fb_info, &argb_fb, 0);
572 break;
573 }
Chris Wilson237cb892016-09-13 11:37:41 +0100574 }
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200575
576 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
577
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100578 if (spin) {
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200579 struct pollfd pfd = { display->drm_fd, POLLIN };
580 igt_assert(poll(&pfd, 1, 0) == 0);
Chris Wilson7f97a4a2017-09-14 14:18:07 +0100581 igt_spin_batch_free(display->drm_fd, spin);
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200582 }
583
Maarten Lankhorst012ad452017-05-09 17:28:49 +0200584 if (miss)
585 { /* compare nothing, already failed */ }
586 else if (!cursor_slowpath(mode))
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200587 miss = delta != 0;
588 else
589 miss = delta != 0 && delta != 1;
590
591 miss1 += miss;
592
593 igt_set_timeout(1, "Stuck page flip");
594 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
595 igt_reset_timeout();
596
597 if (miss1)
598 continue;
599
600 delta = get_vblank(display->drm_fd, pipe, 0) - vblank_start;
601
602 if (!mode_requires_extra_vblank(mode))
603 miss2 += delta != 1;
604 else
605 miss2 += delta != 1 && delta != 2;
Chris Wilson237cb892016-09-13 11:37:41 +0100606 }
607
Maarten Lankhorst0d67d8e2017-05-09 11:58:55 +0200608 igt_fail_on_f(miss1 > 2 || miss1 + miss2 > 5, "Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
609 if (miss1 || miss2)
610 igt_info("Failed to evade %i vblanks and missed %i page flips\n", miss1, miss2);
Chris Wilson237cb892016-09-13 11:37:41 +0100611
Chris Wilson237cb892016-09-13 11:37:41 +0100612 igt_remove_fb(display->drm_fd, &fb_info);
613 igt_remove_fb(display->drm_fd, &cursor_fb);
614
615 if (argb_fb.gem_handle)
616 igt_remove_fb(display->drm_fd, &argb_fb);
617 if (cursor_fb2.gem_handle)
618 igt_remove_fb(display->drm_fd, &cursor_fb2);
619}
620
Maarten Lankhorstad718612016-12-27 13:50:31 +0100621static int
622get_cursor_updates_per_vblank(igt_display_t *display, enum pipe pipe,
623 struct drm_mode_cursor *arg)
624{
625 int target;
626
627 for (target = 65536; target; target /= 2) {
628 unsigned vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
629
630 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
631
632 for (int n = 0; n < target; n++)
633 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, arg);
634 if (get_vblank(display->drm_fd, pipe, 0) == vblank_start)
635 break;
636 }
637
638 /*
639 * Divide by 4, to handle variations in amount of vblanks
640 * caused by cpufreq throttling.
641 */
642 target /= 4;
643 igt_require(target > 1);
644
645 igt_debug("Using a target of %d cursor updates per quarter-vblank\n", target);
646
647 return target;
648}
649
Chris Wilson237cb892016-09-13 11:37:41 +0100650static void flip_vs_cursor(igt_display_t *display, enum flip_test mode, int nloops)
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200651{
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200652 struct drm_mode_cursor arg[2];
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100653 struct drm_event_vblank vbl;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200654 struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
Chris Wilson162d4562016-06-22 15:41:23 +0100655 unsigned vblank_start;
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100656 int target, cpu;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200657 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100658 volatile unsigned long *shared;
659 cpu_set_t mask, oldmask;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200660
661 if (mode >= flip_test_atomic)
662 igt_require(display->is_atomic);
Chris Wilson162d4562016-06-22 15:41:23 +0100663
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200664 igt_require(set_fb_on_crtc(display, pipe, &fb_info));
Chris Wilson162d4562016-06-22 15:41:23 +0100665
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200666 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 +0200667 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200668 populate_cursor_args(display, pipe, arg, &cursor_fb);
669
670 prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +0100671
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200672 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
Chris Wilson162d4562016-06-22 15:41:23 +0100673
Maarten Lankhorstad718612016-12-27 13:50:31 +0100674 if (nloops)
675 target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
676 else
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100677 target = 1;
Chris Wilson162d4562016-06-22 15:41:23 +0100678
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200679 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
680 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200681 for (int n = 0; n < target; n++)
682 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200683 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Chris Wilson162d4562016-06-22 15:41:23 +0100684
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100685 /*
686 * There are variations caused by using cpu frequency changing. To
687 * eliminate those we force this test to run on the same cpu as an
688 * idle thread that does a busy loop of sched_yield(); The effect is
689 * that we don't throttle the cpu to a lower frequency, and the
690 * variations caused by cpu speed changing are eliminated.
691 */
692 if (target > 1) {
693 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
694 igt_assert(shared != MAP_FAILED);
695
696 cpu = sched_getcpu();
697 igt_assert(cpu >= 0);
698
699 CPU_ZERO(&mask);
700 CPU_SET(cpu, &mask);
701 sched_getaffinity(0, sizeof(oldmask), &oldmask);
702 sched_setaffinity(0, sizeof(mask), &mask);
703
704 shared[0] = 0;
705
706 igt_fork(child, 1) {
707 struct sched_param parm = { .sched_priority = 0 };
708
709 igt_assert(sched_setscheduler(0, SCHED_IDLE, &parm) == 0);
710
711 while (!shared[0])
712 sched_yield();
713 }
714 }
715
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100716 do {
717 /* Bind the cursor first to warm up */
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200718 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
Chris Wilson162d4562016-06-22 15:41:23 +0100719
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100720 /* Start with a synchronous query to align with the vblank */
721 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200722 switch (mode) {
723 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200724 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200725 break;
726 case flip_test_atomic_transitions:
727 case flip_test_atomic_transitions_varying_size:
728 transition_nonblocking(display, pipe, &fb_info, &argb_fb, (nloops & 2) /2);
729 break;
730 }
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100731
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100732 /* The nonblocking flip should not have delayed us */
Maarten Lankhorst29516cd2016-07-18 11:47:06 +0200733 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100734 for (int n = 0; n < target; n++)
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200735 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[nloops & 1]);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100736
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100737 /* Nor should it have delayed the following cursor update */
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100738 if (!cursor_slowpath(mode))
739 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
740 else
741 igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100742
743 igt_set_timeout(1, "Stuck page flip");
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200744 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
Maarten Lankhorstda0b6ab2017-01-23 16:37:01 +0100745
746 if (!mode_requires_extra_vblank(mode))
747 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
748 else
749 igt_assert_lte(get_vblank(display->drm_fd, pipe, 0), vblank_start + 2);
750
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100751 igt_reset_timeout();
Chris Wilson3a3c0fa2016-08-24 14:55:25 +0100752 } while (nloops--);
Chris Wilson162d4562016-06-22 15:41:23 +0100753
Maarten Lankhorste5e8b7c2017-01-03 11:31:04 +0100754 if (target > 1) {
755 shared[0] = 1;
756 igt_waitchildren();
757 munmap((void *)shared, 4096);
758 sched_setaffinity(0, sizeof(oldmask), &oldmask);
759 }
760
Maarten Lankhorst6b985872016-07-13 14:59:02 +0200761 igt_remove_fb(display->drm_fd, &fb_info);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +0200762 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +0200763
764 if (argb_fb.gem_handle)
765 igt_remove_fb(display->drm_fd, &argb_fb);
766 if (cursor_fb2.gem_handle)
767 igt_remove_fb(display->drm_fd, &cursor_fb2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +0100768}
769
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100770static void nonblocking_modeset_vs_cursor(igt_display_t *display, int loops)
771{
772 struct igt_fb fb_info, cursor_fb;
773 igt_output_t *output;
774 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100775 struct drm_mode_cursor arg[2];
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100776 igt_plane_t *cursor = NULL, *plane;
777
778 igt_require(display->is_atomic);
779 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
780 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
781 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100782 populate_cursor_args(display, pipe, arg, &cursor_fb);
783 arg[0].flags |= DRM_MODE_CURSOR_BO;
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100784
785 for_each_plane_on_pipe(display, pipe, plane) {
Robert Fossa7864792017-01-10 19:21:26 -0500786 if (plane->type != DRM_PLANE_TYPE_CURSOR)
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100787 continue;
788
789 cursor = plane;
790 break;
791 }
792
793 igt_skip_on(!cursor);
794
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100795 /*
Maarten Lankhorstcb437352017-12-07 10:11:47 +0100796 * Start disabled. No way around it, since the first atomic
797 * commit may be unreliable with amount of events sent.
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100798 */
799 igt_output_set_pipe(output, PIPE_NONE);
800 igt_display_commit2(display, COMMIT_ATOMIC);
801
802 while (loops--) {
803 unsigned flags;
804 struct pollfd pfd = { display->drm_fd, POLLIN };
805 struct drm_event_vblank vbl;
806
807 flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
808 flags |= DRM_MODE_ATOMIC_NONBLOCK;
809 flags |= DRM_MODE_PAGE_FLIP_EVENT;
810
811 /*
812 * Test that a cursor update after a nonblocking modeset
813 * works as intended. It should block until the modeset completes.
814 */
815
816 igt_output_set_pipe(output, pipe);
817 igt_plane_set_fb(cursor, NULL);
818 igt_display_commit_atomic(display, flags, NULL);
819
820 igt_assert_eq(0, poll(&pfd, 1, 0));
821 igt_assert_eq(0, pfd.revents);
822
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100823 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100824
825 igt_assert_eq(1, poll(&pfd, 1, 0));
826 igt_assert_eq(POLLIN, pfd.revents);
827
828 igt_set_timeout(1, "Stuck page flip");
829 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
830 igt_reset_timeout();
831
832 igt_output_set_pipe(output, PIPE_NONE);
833 igt_display_commit_atomic(display, flags, NULL);
834
835 igt_assert_eq(0, poll(&pfd, 1, 0));
836 igt_assert_eq(0, pfd.revents);
837
838 /* Same for cursor on disabled crtc. */
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +0100839 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100840
841 igt_assert_eq(1, poll(&pfd, 1, 0));
842 igt_assert_eq(POLLIN, pfd.revents);
843
844 igt_set_timeout(1, "Stuck page flip");
845 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
846 igt_reset_timeout();
847 }
848
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100849 igt_remove_fb(display->drm_fd, &fb_info);
850 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst59cdcf12016-11-02 13:38:48 +0100851}
852
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100853static void two_screens_flip_vs_cursor(igt_display_t *display, int nloops, bool modeset, bool atomic)
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200854{
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200855 struct drm_mode_cursor arg1[2], arg2[2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200856 struct igt_fb fb_info, fb2_info, cursor_fb;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200857 enum pipe pipe = find_connected_pipe(display, false);
858 enum pipe pipe2 = find_connected_pipe(display, true);
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100859 igt_output_t *output, *output2;
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200860 bool vblank_matches, enabled = false;
861 volatile unsigned long *shared;
862 unsigned flags = 0, vblank_start;
863 struct drm_event_vblank vbl;
864 int ret;
865
866 if (modeset) {
867 uint64_t val;
868
869 igt_fail_on(!atomic);
870 igt_require(drmGetCap(display->drm_fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &val) == 0);
871 }
872
873 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
874 igt_assert(shared != MAP_FAILED);
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200875
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100876 igt_fail_on(modeset && !atomic);
877
878 if (atomic)
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200879 igt_require(display->is_atomic);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200880
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100881 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200882 igt_require((output2 = set_fb_on_crtc(display, pipe2, &fb2_info)));
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200883
884 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
885 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200886 populate_cursor_args(display, pipe, arg1, &cursor_fb);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200887
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200888 arg1[1].x = arg1[1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200889
890 set_cursor_on_pipe(display, pipe2, &cursor_fb);
891 populate_cursor_args(display, pipe2, arg2, &cursor_fb);
892
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100893 arg2[1].x = arg2[1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200894
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200895
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200896 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
897
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200898 igt_fork(child, 2) {
899 struct drm_mode_cursor *arg = child ? arg2 : arg1;
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200900
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200901 while (!shared[0])
902 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR,
903 &arg[!shared[1]]);
904 }
905
906 if (modeset) {
907 igt_plane_t *plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
908
909 flags = DRM_MODE_ATOMIC_ALLOW_MODESET |
910 DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
911
912 /* Disable pipe2 */
913 igt_output_set_pipe(output2, PIPE_NONE);
914 igt_display_commit_atomic(display, flags, NULL);
915 enabled = false;
916
917 /*
918 * Try a page flip on crtc 1, if we succeed pump page flips and
919 * modesets interleaved, else do a single atomic commit with both.
920 */
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200921 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200922 igt_plane_set_fb(plane, &fb_info);
923 ret = igt_display_try_commit_atomic(display, flags, (void*)(ptrdiff_t)vblank_start);
924 igt_assert(!ret || ret == -EBUSY);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200925
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200926 if (ret == -EBUSY) {
927 /* Force completion on both pipes, and generate event. */
928 igt_display_commit_atomic(display, flags, NULL);
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100929
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200930 while (nloops--) {
931 shared[1] = nloops & 1;
932
933 igt_set_timeout(35, "Stuck modeset");
934 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
935 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
936 igt_reset_timeout();
937
938 if (!nloops)
939 break;
940
941 /* Commit page flip and modeset simultaneously. */
942 igt_plane_set_fb(plane, &fb_info);
943 igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
944 enabled = !enabled;
945
946 igt_set_timeout(5, "Scheduling modeset\n");
947 do {
948 ret = igt_display_try_commit_atomic(display, flags, NULL);
949 } while (ret == -EBUSY);
950 igt_assert(!ret);
951 igt_reset_timeout();
952 }
953
954 goto done;
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100955 }
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200956 } else {
957 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
958 flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200959
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200960 vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
961 flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
962 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200963
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200964 vblank_matches = false;
965 while (nloops) {
966 shared[1] = nloops & 1;
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100967
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200968 if (!modeset || nloops > 1)
Maarten Lankhorst5b8a1ba2017-01-18 10:41:37 +0100969 igt_set_timeout(1, "Stuck page flip");
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200970 else
971 igt_set_timeout(35, "Stuck modeset");
972 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
973 igt_reset_timeout();
974
975 vblank_start = vbl.user_data;
976 if (!modeset)
977 igt_assert_eq(vbl.sequence, vblank_start + 1);
978
979 if (vblank_start && vbl.sequence == vblank_start + 1)
980 vblank_matches = true;
981
982 /* Do not requeue on the last 2 events. */
983 if (nloops <= 2) {
984 nloops--;
985 continue;
Maarten Lankhorstdba96672016-08-01 14:44:17 +0200986 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +0200987
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +0200988 if (vbl.crtc_id == display->pipes[pipe].crtc_id) {
989 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
990 flip_nonblocking(display, pipe, atomic, &fb_info, (void*)(ptrdiff_t)vblank_start);
991 } else {
992 igt_assert(vbl.crtc_id == display->pipes[pipe2].crtc_id);
993
994 nloops--;
995
996 if (!modeset) {
997 vblank_start = get_vblank(display->drm_fd, pipe2, DRM_VBLANK_NEXTONMISS);
998 flip_nonblocking(display, pipe2, atomic, &fb2_info, (void*)(ptrdiff_t)vblank_start);
999 } else {
1000 igt_output_set_pipe(output2, enabled ? PIPE_NONE : pipe2);
1001
1002 igt_set_timeout(1, "Scheduling modeset\n");
1003 do {
1004 ret = igt_display_try_commit_atomic(display, flags, NULL);
1005 } while (ret == -EBUSY);
1006 igt_assert(!ret);
1007 igt_reset_timeout();
1008
1009 enabled = !enabled;
1010 }
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001011 }
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001012 }
1013
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001014 igt_assert_f(vblank_matches, "During modeset at least 1 page flip needs to match!\n");
1015
1016done:
1017 shared[0] = 1;
1018 igt_waitchildren();
1019
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001020 igt_remove_fb(display->drm_fd, &fb_info);
1021 igt_remove_fb(display->drm_fd, &fb2_info);
1022 igt_remove_fb(display->drm_fd, &cursor_fb);
1023}
1024
Chris Wilson237cb892016-09-13 11:37:41 +01001025static void cursor_vs_flip(igt_display_t *display, enum flip_test mode, int nloops)
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001026{
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001027 struct drm_mode_cursor arg[2];
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001028 struct drm_event_vblank vbl;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001029 struct igt_fb fb_info, cursor_fb, cursor_fb2, argb_fb;
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001030 unsigned vblank_start, vblank_last;
1031 volatile unsigned long *shared;
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001032 long target;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001033 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001034 igt_output_t *output;
1035 uint32_t vrefresh;
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001036
1037 if (mode >= flip_test_atomic)
1038 igt_require(display->is_atomic);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001039
1040 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1041 igt_assert(shared != MAP_FAILED);
1042
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001043 igt_require((output = set_fb_on_crtc(display, pipe, &fb_info)));
1044 vrefresh = igt_output_get_mode(output)->vrefresh;
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001045
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001046 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 +02001047 set_cursor_on_pipe(display, pipe, &cursor_fb);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001048 populate_cursor_args(display, pipe, arg, &cursor_fb);
1049
1050 prepare_flip_test(display, mode, pipe, pipe, arg, &fb_info, &argb_fb, &cursor_fb2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001051
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001052 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001053
Maarten Lankhorstad718612016-12-27 13:50:31 +01001054 target = get_cursor_updates_per_vblank(display, pipe, &arg[0]);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001055
1056 for (int i = 0; i < nloops; i++) {
1057 shared[0] = 0;
1058 igt_fork(child, 1) {
1059 unsigned long count = 0;
1060 while (!shared[0]) {
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001061 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i & 1]);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001062 count++;
1063 }
1064 igt_debug("child: %lu cursor updates\n", count);
1065 shared[0] = count;
1066 }
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001067
1068 switch (mode) {
1069 default:
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001070 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001071 break;
1072 case flip_test_atomic_transitions:
1073 case flip_test_atomic_transitions_varying_size:
1074 transition_nonblocking(display, pipe, &fb_info, &argb_fb, (i & 2) >> 1);
1075 break;
1076 }
1077
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001078 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001079 vblank_start = vblank_last = vbl.sequence;
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001080 for (int n = 0; n < vrefresh / 2; n++) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001081 flip_nonblocking(display, pipe, mode >= flip_test_atomic, &fb_info, NULL);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001082
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001083 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001084 if (vbl.sequence != vblank_last + 1) {
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001085 igt_info("page flip %d was delayed, missed %d frames\n",
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001086 n, vbl.sequence - vblank_last - 1);
1087 }
1088 vblank_last = vbl.sequence;
1089 }
Maarten Lankhorstaaf46cb2016-08-10 13:13:19 +02001090
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001091 if (!cursor_slowpath(mode))
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001092 igt_assert_lte(vbl.sequence, vblank_start + 5 * vrefresh / 8);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001093
1094 shared[0] = 1;
1095 igt_waitchildren();
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001096 igt_assert_f(shared[0] > vrefresh*target / 2,
1097 "completed %lu cursor updated in a period of %u flips, "
1098 "we expect to complete approximately %lu updates, "
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001099 "with the threshold set at %lu\n",
Maarten Lankhorstbc000862016-12-22 10:54:37 +01001100 shared[0], vrefresh / 2,
1101 vrefresh*target, vrefresh*target / 2);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001102 }
1103
Maarten Lankhorst6b985872016-07-13 14:59:02 +02001104 igt_remove_fb(display->drm_fd, &fb_info);
Maarten Lankhorstcf84a942016-07-18 11:04:27 +02001105 igt_remove_fb(display->drm_fd, &cursor_fb);
Chris Wilson88c1f7c2016-06-23 22:53:23 +01001106 munmap((void *)shared, 4096);
Maarten Lankhorst69aa8a42016-07-19 13:07:32 +02001107 if (argb_fb.gem_handle)
1108 igt_remove_fb(display->drm_fd, &argb_fb);
1109 if (cursor_fb2.gem_handle)
1110 igt_remove_fb(display->drm_fd, &cursor_fb2);
Chris Wilson162d4562016-06-22 15:41:23 +01001111}
1112
Maarten Lankhorst39660182017-01-17 17:07:52 +01001113static void two_screens_cursor_vs_flip(igt_display_t *display, int nloops, bool atomic)
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001114{
Maarten Lankhorst39660182017-01-17 17:07:52 +01001115 struct drm_mode_cursor arg[2][2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001116 struct drm_event_vblank vbl;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001117 struct igt_fb fb_info[2], cursor_fb;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001118 volatile unsigned long *shared;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001119 int target[2];
1120 enum pipe pipe[2] = {
1121 find_connected_pipe(display, false),
1122 find_connected_pipe(display, true)
1123 };
1124 igt_output_t *outputs[2];
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001125
1126 shared = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
1127 igt_assert(shared != MAP_FAILED);
1128
Maarten Lankhorst39660182017-01-17 17:07:52 +01001129 if (atomic)
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001130 igt_require(display->is_atomic);
1131
Maarten Lankhorst39660182017-01-17 17:07:52 +01001132 igt_require((outputs[0] = set_fb_on_crtc(display, pipe[0], &fb_info[0])));
1133 igt_require((outputs[1] = set_fb_on_crtc(display, pipe[1], &fb_info[1])));
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001134
1135 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 +02001136
Maarten Lankhorst39660182017-01-17 17:07:52 +01001137 set_cursor_on_pipe(display, pipe[0], &cursor_fb);
1138 populate_cursor_args(display, pipe[0], arg[0], &cursor_fb);
1139 arg[0][1].x = arg[0][1].y = 192;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001140
Maarten Lankhorst39660182017-01-17 17:07:52 +01001141 set_cursor_on_pipe(display, pipe[1], &cursor_fb);
1142 populate_cursor_args(display, pipe[1], arg[1], &cursor_fb);
1143 arg[1][1].x = arg[1][1].y = 192;
Maarten Lankhorstdba96672016-08-01 14:44:17 +02001144
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001145 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1146
Maarten Lankhorst39660182017-01-17 17:07:52 +01001147 target[0] = get_cursor_updates_per_vblank(display, pipe[0], &arg[0][0]);
1148 target[1] = get_cursor_updates_per_vblank(display, pipe[1], &arg[1][0]);
Maarten Lankhorstad718612016-12-27 13:50:31 +01001149
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001150 for (int i = 0; i < nloops; i++) {
Maarten Lankhorst39660182017-01-17 17:07:52 +01001151 unsigned long vrefresh[2];
1152 unsigned vblank_start[2], vblank_last[2];
1153 int done[2] = {};
1154
1155 vrefresh[0] = igt_output_get_mode(outputs[0])->vrefresh;
1156 vrefresh[1] = igt_output_get_mode(outputs[1])->vrefresh;
1157
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001158 shared[0] = 0;
Maarten Lankhorst39660182017-01-17 17:07:52 +01001159 shared[1] = 0;
1160 igt_fork(child, 2) {
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001161 unsigned long count = 0;
1162
Maarten Lankhorst39660182017-01-17 17:07:52 +01001163 while (!shared[child]) {
1164 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[child][(i >> child) & 1]);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001165 count++;
1166 }
Maarten Lankhorst39660182017-01-17 17:07:52 +01001167 igt_debug("child %i: %lu cursor updates\n", child, count);
1168 shared[child] = count;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001169 }
1170
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001171 flip_nonblocking(display, pipe[0], atomic, &fb_info[0], (void *)0UL);
1172 flip_nonblocking(display, pipe[1], atomic, &fb_info[1], (void *)1UL);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001173
Maarten Lankhorst39660182017-01-17 17:07:52 +01001174 for (int n = 0; n < vrefresh[0] / 2 + vrefresh[1] / 2; n++) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001175 unsigned long child;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001176
1177 igt_assert_eq(read(display->drm_fd, &vbl, sizeof(vbl)), sizeof(vbl));
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001178 child = vbl.user_data;
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001179
Maarten Lankhorst39660182017-01-17 17:07:52 +01001180 if (!done[child]++)
1181 vblank_start[child] = vbl.sequence;
1182 else if (vbl.sequence != vblank_last[child] + 1)
1183 igt_info("page flip %d was delayed, missed %d frames\n",
1184 done[child], vbl.sequence - vblank_last[child] - 1);
1185
1186 vblank_last[child] = vbl.sequence;
1187
1188 if (done[child] < vrefresh[child] / 2) {
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001189 flip_nonblocking(display, pipe[child], atomic, &fb_info[child], (void *)child);
Maarten Lankhorst39660182017-01-17 17:07:52 +01001190 } else {
1191 igt_assert_lte(vbl.sequence, vblank_start[child] + 5 * vrefresh[child] / 8);
1192
1193 shared[child] = 1;
1194 }
1195 }
1196
1197 igt_assert_eq(done[0], vrefresh[0] / 2);
1198 igt_assert_eq(done[1], vrefresh[1] / 2);
1199
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001200 igt_waitchildren();
Maarten Lankhorst39660182017-01-17 17:07:52 +01001201 for (int child = 0; child < 2; child++)
1202 igt_assert_f(shared[child] > vrefresh[child]*target[child] / 2,
1203 "completed %lu cursor updated in a period of %lu flips, "
1204 "we expect to complete approximately %lu updates, "
1205 "with the threshold set at %lu\n",
1206 shared[child], vrefresh[child] / 2,
1207 vrefresh[child]*target[child], vrefresh[child]*target[child] / 2);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001208 }
1209
Maarten Lankhorst39660182017-01-17 17:07:52 +01001210 igt_remove_fb(display->drm_fd, &fb_info[0]);
1211 igt_remove_fb(display->drm_fd, &fb_info[1]);
Maarten Lankhorst9654d512016-07-25 10:53:54 +02001212 igt_remove_fb(display->drm_fd, &cursor_fb);
1213 munmap((void *)shared, 4096);
1214}
1215
Maarten Lankhorst7baf4ee2016-12-21 18:26:54 +01001216static void flip_vs_cursor_crc(igt_display_t *display, bool atomic)
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001217{
1218 struct drm_mode_cursor arg[2];
1219 struct drm_event_vblank vbl;
1220 struct igt_fb fb_info, cursor_fb;
1221 unsigned vblank_start;
1222 enum pipe pipe = find_connected_pipe(display, false);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001223 igt_crc_t crcs[3];
1224
1225 if (atomic)
1226 igt_require(display->is_atomic);
1227
1228 igt_require(set_fb_on_crtc(display, pipe, &fb_info));
1229
1230 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1231 populate_cursor_args(display, pipe, arg, &cursor_fb);
1232
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001233 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1234
Chris Wilson83884e92017-03-21 17:16:03 +00001235 pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001236
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001237 set_cursor_on_pipe(display, pipe, &cursor_fb);
1238 igt_display_commit2(display, COMMIT_UNIVERSAL);
1239
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001240 /* Collect reference crcs, crcs[0] last. */
1241 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1242 igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001243
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001244 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001245 igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1246
1247 /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1248 for (int i = 1; i >= 0; i--) {
1249 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1250
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001251 flip_nonblocking(display, pipe, atomic, &fb_info, NULL);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001252 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1253
1254 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1255
1256 igt_set_timeout(1, "Stuck page flip");
1257 igt_ignore_warn(read(display->drm_fd, &vbl, sizeof(vbl)));
1258 igt_reset_timeout();
1259
1260 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start + 1);
1261
1262 igt_pipe_crc_collect_crc(pipe_crc, &crcs[2]);
1263
1264 igt_assert_crc_equal(&crcs[i], &crcs[2]);
1265 }
1266
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001267 igt_remove_fb(display->drm_fd, &fb_info);
1268 igt_remove_fb(display->drm_fd, &cursor_fb);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001269}
1270
1271static void flip_vs_cursor_busy_crc(igt_display_t *display, bool atomic)
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001272{
1273 struct drm_mode_cursor arg[2];
1274 struct drm_event_vblank vbl;
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001275 struct igt_fb fb_info[2], cursor_fb;
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001276 unsigned vblank_start;
1277 enum pipe pipe = find_connected_pipe(display, false);
Robert Fossa7864792017-01-10 19:21:26 -05001278 igt_pipe_t *pipe_connected = &display->pipes[pipe];
1279 igt_plane_t *plane_primary = igt_pipe_get_plane_type(pipe_connected, DRM_PLANE_TYPE_PRIMARY);
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001280 igt_crc_t crcs[2], test_crc;
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001281
1282 if (atomic)
1283 igt_require(display->is_atomic);
1284
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001285 igt_require(set_fb_on_crtc(display, pipe, &fb_info[0]));
1286 igt_create_color_pattern_fb(display->drm_fd, fb_info[0].width, fb_info[0].height,
1287 DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED, .1, .1, .1, &fb_info[1]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001288
1289 igt_create_color_fb(display->drm_fd, 64, 64, DRM_FORMAT_ARGB8888, 0, 1., 1., 1., &cursor_fb);
1290 populate_cursor_args(display, pipe, arg, &cursor_fb);
1291
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001292 igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
1293
Maarten Lankhorst7d48c022018-02-02 13:34:25 +01001294 pipe_crc = igt_pipe_crc_new(display->drm_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001295
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001296 set_cursor_on_pipe(display, pipe, &cursor_fb);
1297 igt_display_commit2(display, COMMIT_UNIVERSAL);
1298
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001299 /* Collect reference crcs, crc[0] last for the loop. */
1300 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[1]);
1301 igt_pipe_crc_collect_crc(pipe_crc, &crcs[1]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001302
Maarten Lankhorst4f086662016-12-08 10:56:13 +01001303 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[0]);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001304 igt_pipe_crc_collect_crc(pipe_crc, &crcs[0]);
1305
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001306 /*
1307 * Set fb 1 on primary at least once before flipping to force
1308 * setting the correct cache level, else we get a stall in the
1309 * page flip handler.
1310 */
Robert Fossa7864792017-01-10 19:21:26 -05001311 igt_plane_set_fb(plane_primary, &fb_info[1]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001312 igt_display_commit2(display, COMMIT_UNIVERSAL);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001313
Robert Fossa7864792017-01-10 19:21:26 -05001314 igt_plane_set_fb(plane_primary, &fb_info[0]);
Maarten Lankhorst954923c2016-10-06 12:52:53 +02001315 igt_display_commit2(display, COMMIT_UNIVERSAL);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001316
Maarten Lankhorst1043c092017-09-19 13:31:13 +02001317 /*
1318 * We must enable CRC collecting here since this may force
1319 * a modeset, and this loop is timing sensitive.
1320 */
1321 igt_pipe_crc_start(pipe_crc);
1322
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001323 /* Disable cursor, and immediately queue a flip. Check if resulting crc is correct. */
1324 for (int i = 1; i >= 0; i--) {
Chris Wilson7f97a4a2017-09-14 14:18:07 +01001325 igt_spin_t *spin;
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001326
Chris Wilson4b57f852018-06-25 13:27:36 +01001327 spin = igt_spin_batch_new(display->drm_fd,
1328 .dependency = fb_info[1].gem_handle);
Maarten Lankhorst4ef3fe92016-10-05 15:51:00 +02001329
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001330 vblank_start = get_vblank(display->drm_fd, pipe, DRM_VBLANK_NEXTONMISS);
1331
Maarten Lankhorstd86d53b2017-10-18 12:38:20 +02001332 flip_nonblocking(display, pipe, atomic, &fb_info[1], NULL);
Maarten Lankhorst4fb21782016-09-07 17:00:39 +02001333 do_ioctl(display->drm_fd, DRM_IOCTL_MODE_CURSOR, &arg[i]);
1334
1335 igt_assert_eq(get_vblank(display->drm_fd, pipe, 0), vblank_start);
1336
Maarten Lankhorst5d1c8292018-07-24 15:59:26 +02001337 igt_pipe_crc_get_current(display->drm_fd, 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}