2 * Copyright 2012 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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 THE
18 * 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
35 #include <sys/ioctl.h>
39 #include "testdisplay.h"
40 #include "intel_bufmgr.h"
41 #include "intel_batchbuffer.h"
42 #include "intel_gpu_tools.h"
44 #define TEST_DPMS (1 << 0)
45 #define TEST_WITH_DUMMY_LOAD (1 << 1)
46 #define TEST_PAN (1 << 2)
47 #define TEST_MODESET (1 << 3)
48 #define TEST_CHECK_TS (1 << 4)
49 #define TEST_EBUSY (1 << 5)
50 #define TEST_EINVAL (1 << 6)
51 #define TEST_FLIP (1 << 7)
52 #define TEST_VBLANK (1 << 8)
53 #define TEST_VBLANK_BLOCK (1 << 9)
54 #define TEST_VBLANK_ABSOLUTE (1 << 10)
56 #define EVENT_FLIP (1 << 0)
57 #define EVENT_VBLANK (1 << 1)
59 drmModeRes *resources;
61 static drm_intel_bufmgr *bufmgr;
62 struct intel_batchbuffer *batch;
77 * Event data for the last event that has already passed our check.
78 * Updated using the below current_* vars in update_state().
80 struct timeval last_ts; /* kernel reported timestamp */
81 struct timeval last_received_ts; /* the moment we received it */
82 unsigned int last_seq; /* kernel reported seq. num */
85 * Event data for for the current event that we just received and
86 * going to check for validity. Set in event_handler().
88 struct timeval current_ts; /* kernel reported timestamp */
89 struct timeval current_received_ts; /* the moment we received it */
90 unsigned int current_seq; /* kernel reported seq. num */
92 int count; /* # of events of this type */
94 /* Step between the current and next 'target' sequence number. */
99 const char *test_name;
102 drmModeModeInfo mode;
103 drmModeEncoder *encoder;
104 drmModeConnector *connector;
108 unsigned int current_fb_id;
109 unsigned int fb_width;
110 unsigned int fb_height;
111 unsigned int fb_ids[2];
112 struct kmstest_fb fb_info[2];
114 struct event_state flip_state;
115 struct event_state vblank_state;
116 unsigned int pending_events;
119 static void emit_dummy_load(struct test_output *o)
122 drm_intel_bo *dummy_bo, *target_bo, *tmp_bo;
123 struct kmstest_fb *fb_info = &o->fb_info[o->current_fb_id];
124 unsigned pitch = fb_info->stride;
126 limit = intel_gen(devid) < 6 ? 500 : 5000;
128 dummy_bo = drm_intel_bo_alloc(bufmgr, "dummy_bo", fb_info->size, 4096);
130 target_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "imported", fb_info->gem_handle);
133 for (i = 0; i < limit; i++) {
135 OUT_BATCH(XY_SRC_COPY_BLT_CMD |
136 XY_SRC_COPY_BLT_WRITE_ALPHA |
137 XY_SRC_COPY_BLT_WRITE_RGB);
138 OUT_BATCH((3 << 24) | /* 32 bits */
139 (0xcc << 16) | /* copy ROP */
141 OUT_BATCH(0 << 16 | 0);
142 OUT_BATCH((o->mode.vdisplay) << 16 | (o->mode.hdisplay));
143 OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
144 OUT_BATCH(0 << 16 | 0);
146 OUT_RELOC_FENCED(target_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
149 if (IS_GEN6(devid) || IS_GEN7(devid)) {
151 OUT_BATCH(XY_SETUP_CLIP_BLT_CMD);
158 dummy_bo = target_bo;
161 intel_batchbuffer_flush(batch);
163 drm_intel_bo_unreference(dummy_bo);
164 drm_intel_bo_unreference(target_bo);
167 static int set_dpms(struct test_output *o, int mode)
171 for (i = 0; i < o->connector->count_props; i++) {
172 struct drm_mode_get_property prop;
174 prop.prop_id = o->connector->props[i];
175 prop.count_values = 0;
176 prop.count_enum_blobs = 0;
177 if (drmIoctl(drm_fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
180 if (strcmp(prop.name, "DPMS"))
187 fprintf(stderr, "DPMS property not found on %d\n", o->id);
192 return drmModeConnectorSetProperty(drm_fd, o->id, dpms, mode);
195 static void set_flag(unsigned int *v, unsigned int flag)
197 assert(!(*v & flag));
201 static void clear_flag(unsigned int *v, unsigned int flag)
207 static int do_page_flip(struct test_output *o, int fb_id)
211 ret = drmModePageFlip(drm_fd, o->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT,
214 set_flag(&o->pending_events, EVENT_FLIP);
219 struct vblank_reply {
220 unsigned int sequence;
224 static int do_wait_for_vblank(struct test_output *o, int crtc_idx,
225 int target_seq, struct vblank_reply *reply)
229 unsigned crtc_idx_mask;
230 bool event = !(o->flags & TEST_VBLANK_BLOCK);
232 memset(&wait_vbl, 0, sizeof(wait_vbl));
234 crtc_idx_mask = crtc_idx << DRM_VBLANK_HIGH_CRTC_SHIFT;
235 assert(!(crtc_idx_mask & ~DRM_VBLANK_HIGH_CRTC_MASK));
237 wait_vbl.request.type = crtc_idx_mask;
238 if (o->flags & TEST_VBLANK_ABSOLUTE)
239 wait_vbl.request.type |= DRM_VBLANK_ABSOLUTE;
241 wait_vbl.request.type |= DRM_VBLANK_RELATIVE;
243 wait_vbl.request.type |= DRM_VBLANK_EVENT;
244 wait_vbl.request.signal = (unsigned long)o;
246 wait_vbl.request.sequence = target_seq;
248 ret = drmWaitVBlank(drm_fd, &wait_vbl);
251 reply->ts.tv_sec = wait_vbl.reply.tval_sec;
252 reply->ts.tv_usec = wait_vbl.reply.tval_usec;
253 reply->sequence = wait_vbl.reply.sequence;
256 assert(!(o->pending_events & EVENT_VBLANK));
257 o->pending_events |= EVENT_VBLANK;
266 analog_tv_connector(struct test_output *o)
268 uint32_t connector_type = o->connector->connector_type;
270 return connector_type == DRM_MODE_CONNECTOR_TV ||
271 connector_type == DRM_MODE_CONNECTOR_9PinDIN ||
272 connector_type == DRM_MODE_CONNECTOR_SVIDEO ||
273 connector_type == DRM_MODE_CONNECTOR_Composite;
276 static void event_handler(struct event_state *es, unsigned int frame,
277 unsigned int sec, unsigned int usec)
279 gettimeofday(&es->current_received_ts, NULL);
280 es->current_ts.tv_sec = sec;
281 es->current_ts.tv_usec = usec;
282 es->current_seq = frame;
285 static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
286 unsigned int usec, void *data)
288 struct test_output *o = data;
290 clear_flag(&o->pending_events, EVENT_FLIP);
291 event_handler(&o->flip_state, frame, sec, usec);
294 static void vblank_handler(int fd, unsigned int frame, unsigned int sec,
295 unsigned int usec, void *data)
297 struct test_output *o = data;
299 clear_flag(&o->pending_events, EVENT_VBLANK);
300 event_handler(&o->vblank_state, frame, sec, usec);
303 static void check_state(struct test_output *o, struct event_state *es)
306 double usec_interflip;
308 timersub(&es->current_ts, &es->current_received_ts, &diff);
309 if (diff.tv_sec > 0 || (diff.tv_sec == 0 && diff.tv_usec > 2000)) {
310 fprintf(stderr, "%s ts delayed for too long: %is, %iusec\n",
311 es->name, (int)diff.tv_sec, (int)diff.tv_usec);
315 if (!timercmp(&es->last_received_ts, &es->current_ts, <)) {
316 fprintf(stderr, "%s ts before the %s was issued!\n",
319 timersub(&es->current_ts, &es->last_received_ts, &diff);
320 fprintf(stderr, "timerdiff %is, %ius\n",
321 (int) diff.tv_sec, (int) diff.tv_usec);
328 /* This bounding matches the one in DRM_IOCTL_WAIT_VBLANK. */
329 if (es->current_seq - (es->last_seq + es->seq_step) > 1UL << 23) {
330 fprintf(stderr, "unexpected %s seq %u, should be >= %u\n",
331 es->name, es->current_seq, es->last_seq + es->seq_step);
335 if ((o->flags & TEST_CHECK_TS) && (!analog_tv_connector(o))) {
336 timersub(&es->current_ts, &es->last_ts, &diff);
337 usec_interflip = (double)es->seq_step /
338 ((double)o->mode.vrefresh) * 1000.0 * 1000.0;
339 if (fabs((((double) diff.tv_usec) - usec_interflip) /
340 usec_interflip) > 0.005) {
341 fprintf(stderr, "inter-%s ts jitter: %is, %ius\n",
343 (int) diff.tv_sec, (int) diff.tv_usec);
344 /* atm this is way too easy to hit, thanks to the hpd
345 * poll helper :( hence make it non-fatal for now */
349 if (es->current_seq != es->last_seq + es->seq_step) {
350 fprintf(stderr, "unexpected %s seq %u, expected %u\n",
351 es->name, es->current_seq,
352 es->last_seq + es->seq_step);
353 /* no exit, due to the same reason as above */
358 static void check_all_state(struct test_output *o,
359 unsigned int completed_events)
361 if (completed_events & EVENT_FLIP)
362 check_state(o, &o->flip_state);
363 if (completed_events & EVENT_VBLANK)
364 check_state(o, &o->vblank_state);
367 /* Return mask of completed events. */
368 static unsigned int run_test_step(struct test_output *o)
370 unsigned int new_fb_id;
371 /* for funny reasons page_flip returns -EBUSY on disabled crtcs ... */
372 int expected_einval = o->flags & TEST_MODESET ? -EBUSY : -EINVAL;
373 unsigned int completed_events = 0;
376 struct vblank_reply vbl_reply;
377 unsigned int target_seq;
379 target_seq = o->vblank_state.seq_step;
380 if (o->flags & TEST_VBLANK_ABSOLUTE)
381 target_seq += o->vblank_state.last_seq;
383 do_flip = (o->flags & TEST_FLIP) && !(o->pending_events & EVENT_FLIP);
384 do_vblank = (o->flags & TEST_VBLANK) &&
385 !(o->pending_events & EVENT_VBLANK);
387 if (o->flags & TEST_WITH_DUMMY_LOAD)
391 o->current_fb_id = !o->current_fb_id;
392 new_fb_id = o->fb_ids[o->current_fb_id];
394 if (do_flip && (o->flags & TEST_EINVAL) && o->flip_state.count > 0)
395 assert(do_page_flip(o, new_fb_id) == expected_einval);
397 if (do_vblank && (o->flags & TEST_EINVAL) && o->vblank_state.count > 0)
398 assert(do_wait_for_vblank(o, o->pipe, target_seq, &vbl_reply)
401 if (o->flags & TEST_MODESET) {
402 if (drmModeSetCrtc(drm_fd, o->crtc,
403 o->fb_ids[o->current_fb_id],
405 &o->id, 1, &o->mode)) {
406 fprintf(stderr, "failed to restore output mode: %s\n",
412 if (o->flags & TEST_DPMS)
413 do_or_die(set_dpms(o, DRM_MODE_DPMS_ON));
415 printf("."); fflush(stdout);
418 do_or_die(do_page_flip(o, new_fb_id));
421 do_or_die(do_wait_for_vblank(o, o->pipe, target_seq,
423 if (o->flags & TEST_VBLANK_BLOCK) {
424 event_handler(&o->vblank_state, vbl_reply.sequence,
426 vbl_reply.ts.tv_usec);
427 completed_events = EVENT_VBLANK;
431 if (do_flip && (o->flags & TEST_EBUSY))
432 assert(do_page_flip(o, new_fb_id) == -EBUSY);
434 /* pan before the flip completes */
435 if (o->flags & TEST_PAN) {
436 int count = do_flip ?
437 o->flip_state.count : o->vblank_state.count;
438 int x_ofs = count * 10 > o->mode.hdisplay ?
439 o->mode.hdisplay : count * 10;
441 if (drmModeSetCrtc(drm_fd, o->crtc, o->fb_ids[o->current_fb_id],
442 x_ofs, 0, &o->id, 1, &o->mode)) {
443 fprintf(stderr, "failed to pan (%dx%d@%dHz): %s\n",
444 o->fb_width, o->fb_height,
445 o->mode.vrefresh, strerror(errno));
450 if (o->flags & TEST_DPMS)
451 do_or_die(set_dpms(o, DRM_MODE_DPMS_OFF));
453 if (o->flags & TEST_MODESET) {
454 if (drmModeSetCrtc(drm_fd, o->crtc,
458 fprintf(stderr, "failed to disable output: %s\n",
464 if (do_vblank && (o->flags & TEST_EINVAL) && o->vblank_state.count > 0)
465 assert(do_wait_for_vblank(o, o->pipe, target_seq, &vbl_reply)
468 if (do_flip && (o->flags & TEST_EINVAL))
469 assert(do_page_flip(o, new_fb_id) == expected_einval);
471 return completed_events;
474 static void update_state(struct event_state *es)
476 es->last_received_ts = es->current_received_ts;
477 es->last_ts = es->current_ts;
478 es->last_seq = es->current_seq;
482 static void update_all_state(struct test_output *o,
483 unsigned int completed_events)
485 if (completed_events & EVENT_FLIP)
486 update_state(&o->flip_state);
488 if (completed_events & EVENT_VBLANK)
489 update_state(&o->vblank_state);
492 static void connector_find_preferred_mode(struct test_output *o, int crtc_id)
494 drmModeConnector *connector;
495 drmModeEncoder *encoder = NULL;
498 /* First, find the connector & mode */
501 connector = drmModeGetConnector(drm_fd, o->id);
504 if (connector->connection != DRM_MODE_CONNECTED) {
505 drmModeFreeConnector(connector);
509 if (!connector->count_modes) {
510 fprintf(stderr, "connector %d has no modes\n", o->id);
511 drmModeFreeConnector(connector);
515 if (connector->connector_id != o->id) {
516 fprintf(stderr, "connector id doesn't match (%d != %d)\n",
517 connector->connector_id, o->id);
518 drmModeFreeConnector(connector);
522 for (j = 0; j < connector->count_modes; j++) {
523 o->mode = connector->modes[j];
524 if (o->mode.type & DRM_MODE_TYPE_PREFERRED) {
530 if (!o->mode_valid) {
531 if (connector->count_modes > 0) {
532 /* use the first mode as test mode */
533 o->mode = connector->modes[0];
537 fprintf(stderr, "failed to find any modes on connector %d\n",
543 /* Now get the encoder */
544 for (i = 0; i < connector->count_encoders; i++) {
545 encoder = drmModeGetEncoder(drm_fd, connector->encoders[i]);
548 fprintf(stderr, "could not get encoder %i: %s\n",
549 resources->encoders[i], strerror(errno));
550 drmModeFreeEncoder(encoder);
557 o->encoder = encoder;
559 if (i == resources->count_encoders) {
560 fprintf(stderr, "failed to find encoder\n");
565 /* Find first CRTC not in use */
566 for (i = 0; i < resources->count_crtcs; i++) {
567 if (resources->crtcs[i] != crtc_id)
569 if (resources->crtcs[i] &&
570 (o->encoder->possible_crtcs & (1<<i))) {
571 o->crtc = resources->crtcs[i];
577 fprintf(stderr, "could not find requested crtc %d\n", crtc_id);
582 o->connector = connector;
586 paint_flip_mode(cairo_t *cr, int width, int height, void *priv)
588 bool odd_frame = (bool) priv;
591 cairo_rectangle(cr, width/4, height/2, width/4, height/8);
593 cairo_rectangle(cr, width/2, height/2, width/4, height/8);
595 cairo_set_source_rgb(cr, 1, 1, 1);
600 fb_is_bound(struct test_output *o, int fb)
602 struct drm_mode_crtc mode;
604 mode.crtc_id = o->crtc;
605 if (drmIoctl(drm_fd, DRM_IOCTL_MODE_GETCRTC, &mode))
608 return mode.mode_valid && mode.fb_id == fb;
611 static void check_final_state(struct test_output *o, struct event_state *es,
612 unsigned int ellapsed)
614 if (es->count == 0) {
615 fprintf(stderr, "no %s event received\n", es->name);
619 /* Verify we drop no frames, but only if it's not a TV encoder, since
620 * those use some funny fake timings behind userspace's back. */
621 if (o->flags & TEST_CHECK_TS && !analog_tv_connector(o)) {
623 int count = es->count;
625 count *= es->seq_step;
626 expected = ellapsed * o->mode.vrefresh / (1000 * 1000);
627 if (count < expected * 99/100) {
628 fprintf(stderr, "dropped frames, expected %d, counted %d, encoder type %d\n",
629 expected, count, o->encoder->encoder_type);
636 * Wait until at least one pending event completes. Return mask of completed
639 static unsigned int wait_for_events(struct test_output *o)
641 drmEventContext evctx;
642 struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
644 unsigned int event_mask;
647 event_mask = o->pending_events;
650 memset(&evctx, 0, sizeof evctx);
651 evctx.version = DRM_EVENT_CONTEXT_VERSION;
652 evctx.vblank_handler = vblank_handler;
653 evctx.page_flip_handler = page_flip_handler;
655 /* make timeout lax with the dummy load */
656 if (o->flags & TEST_WITH_DUMMY_LOAD)
657 timeout.tv_sec *= 10;
661 FD_SET(drm_fd, &fds);
662 ret = select(drm_fd + 1, &fds, NULL, NULL, &timeout);
665 fprintf(stderr, "select timed out or error (ret %d)\n",
668 } else if (FD_ISSET(0, &fds)) {
669 fprintf(stderr, "no fds active, breaking\n");
673 do_or_die(drmHandleEvent(drm_fd, &evctx));
675 event_mask ^= o->pending_events;
681 /* Returned the ellapsed time in us */
682 static unsigned event_loop(struct test_output *o, unsigned duration_sec)
684 struct timeval start, end;
685 struct timeval tv_dur;
687 gettimeofday(&start, NULL);
688 end.tv_sec = start.tv_sec + duration_sec;
689 end.tv_usec = start.tv_usec;
693 unsigned int completed_events;
695 completed_events = run_test_step(o);
696 if (o->pending_events)
697 completed_events |= wait_for_events(o);
698 check_all_state(o, completed_events);
699 update_all_state(o, completed_events);
701 gettimeofday(&now, NULL);
702 if (!timercmp(&now, &end, <))
706 gettimeofday(&end, NULL);
707 timersub(&end, &start, &tv_dur);
709 /* Flush any remaining events */
710 if (o->pending_events)
713 return tv_dur.tv_sec * 1000 * 1000 + tv_dur.tv_usec;
716 static void run_test_on_crtc(struct test_output *o, int crtc, int duration)
718 int bpp = 32, depth = 24;
721 connector_find_preferred_mode(o, crtc);
725 fprintf(stdout, "Beginning %s on crtc %d, connector %d\n",
726 o->test_name, crtc, o->id);
728 o->fb_width = o->mode.hdisplay;
729 o->fb_height = o->mode.vdisplay;
731 if (o->flags & TEST_PAN)
734 o->fb_ids[0] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height, bpp,
735 depth, false, &o->fb_info[0],
736 paint_flip_mode, (void *)false);
737 o->fb_ids[1] = kmstest_create_fb(drm_fd, o->fb_width, o->fb_height, bpp,
738 depth, false, &o->fb_info[1],
739 paint_flip_mode, (void *)true);
741 if (!o->fb_ids[0] || !o->fb_ids[1]) {
742 fprintf(stderr, "failed to create fbs\n");
746 kmstest_dump_mode(&o->mode);
747 if (drmModeSetCrtc(drm_fd, o->crtc, o->fb_ids[0], 0, 0,
748 &o->id, 1, &o->mode)) {
749 fprintf(stderr, "failed to set mode (%dx%d@%dHz): %s\n",
750 o->fb_width, o->fb_height, o->mode.vrefresh,
754 assert(fb_is_bound(o, o->fb_ids[0]));
756 /* quiescent the hw a bit so ensure we don't miss a single frame */
757 if (o->flags & TEST_CHECK_TS)
760 gettimeofday(&o->flip_state.last_ts, NULL);
761 gettimeofday(&o->vblank_state.last_ts, NULL);
763 if (do_page_flip(o, o->fb_ids[1])) {
764 fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
769 o->current_fb_id = 1;
770 o->flip_state.seq_step = 1;
771 if (o->flags & TEST_VBLANK_ABSOLUTE)
772 o->vblank_state.seq_step = 5;
774 o->vblank_state.seq_step = 1;
776 ellapsed = event_loop(o, duration);
778 if (o->flags & TEST_FLIP)
779 check_final_state(o, &o->flip_state, ellapsed);
780 if (o->flags & TEST_VBLANK)
781 check_final_state(o, &o->vblank_state, ellapsed);
783 fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n",
784 o->test_name, crtc, o->id);
786 kmstest_remove_fb(drm_fd, o->fb_ids[1]);
787 kmstest_remove_fb(drm_fd, o->fb_ids[0]);
789 drmModeFreeEncoder(o->encoder);
790 drmModeFreeConnector(o->connector);
793 static int get_pipe_from_crtc_id(int crtc_id)
795 struct drm_i915_get_pipe_from_crtc_id pfci;
798 memset(&pfci, 0, sizeof(pfci));
799 pfci.crtc_id = crtc_id;
800 ret = drmIoctl(drm_fd, DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, &pfci);
806 static int run_test(int duration, int flags, const char *test_name)
808 struct test_output o;
811 resources = drmModeGetResources(drm_fd);
813 fprintf(stderr, "drmModeGetResources failed: %s\n",
818 /* Find any connected displays */
819 for (c = 0; c < resources->count_connectors; c++) {
820 for (i = 0; i < resources->count_crtcs; i++) {
823 memset(&o, 0, sizeof(o));
824 o.test_name = test_name;
825 o.id = resources->connectors[c];
827 o.flip_state.name = "flip";
828 o.vblank_state.name = "vblank";
829 crtc = resources->crtcs[i];
830 o.pipe = get_pipe_from_crtc_id(crtc);
832 run_test_on_crtc(&o, crtc, duration);
836 drmModeFreeResources(resources);
840 int main(int argc, char **argv)
847 { 15, TEST_VBLANK | TEST_CHECK_TS, "wf-vblank" },
848 { 15, TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_CHECK_TS,
849 "blocking wf-vblank" },
850 { 5, TEST_VBLANK | TEST_VBLANK_ABSOLUTE,
851 "absolute wf-vblank" },
852 { 5, TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_VBLANK_ABSOLUTE,
853 "blocking absolute wf-vblank" },
854 { 30, TEST_VBLANK | TEST_DPMS | TEST_EINVAL, "wf-vblank vs dpms" },
855 { 30, TEST_VBLANK | TEST_DPMS | TEST_WITH_DUMMY_LOAD,
856 "delayed wf-vblank vs dpms" },
857 { 30, TEST_VBLANK | TEST_MODESET | TEST_EINVAL, "wf-vblank vs modeset" },
858 { 30, TEST_VBLANK | TEST_MODESET | TEST_WITH_DUMMY_LOAD,
859 "delayed wf-vblank vs modeset" },
861 { 15, TEST_FLIP | TEST_CHECK_TS | TEST_EBUSY , "plain flip" },
862 { 30, TEST_FLIP | TEST_DPMS | TEST_EINVAL, "flip vs dpms" },
863 { 30, TEST_FLIP | TEST_DPMS | TEST_WITH_DUMMY_LOAD, "delayed flip vs dpms" },
864 { 5, TEST_FLIP | TEST_PAN, "flip vs panning" },
865 { 30, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_LOAD, "delayed flip vs panning" },
866 { 30, TEST_FLIP | TEST_MODESET | TEST_EINVAL, "flip vs modeset" },
867 { 30, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_LOAD, "delayed flip vs modeset" },
869 { 5, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_ABSOLUTE |
870 TEST_CHECK_TS, "flip vs absolute wf-vblank" },
871 { 5, TEST_FLIP | TEST_VBLANK | TEST_CHECK_TS,
872 "flip vs wf-vblank" },
873 { 5, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_BLOCK |
874 TEST_CHECK_TS, "flip vs blocking wf-vblank" },
878 drm_fd = drm_open_any();
880 bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
881 devid = intel_get_drm_devid(drm_fd);
882 batch = intel_batchbuffer_alloc(bufmgr, devid);
884 for (i = 0; i < sizeof(tests) / sizeof (tests[0]); i++) {
885 printf("running testcase: %s\n", tests[i].name);
886 run_test(tests[i].duration, tests[i].flags, tests[i].name);