aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes2009-12-03 16:17:26 -0600
committerJesse Barnes2009-12-03 16:17:26 -0600
commit53addc5d6ef7406d9fab5ea481cf68fa011870f1 (patch)
treeeb43991923600b5751e04539438e5fffebb61cb3
parentdb50f5127421ac8f4e3ce4eb7c27d27475781488 (diff)
parentee746a83cecd99d4c380fbc5d391399a6d9fde9e (diff)
downloadexternal-libgbm-53addc5d6ef7406d9fab5ea481cf68fa011870f1.tar.gz
external-libgbm-53addc5d6ef7406d9fab5ea481cf68fa011870f1.tar.xz
external-libgbm-53addc5d6ef7406d9fab5ea481cf68fa011870f1.zip
Merge branch 'pageflip' of git://people.freedesktop.org/~jbarnes/drm
Conflicts: include/drm/drm.h - RMFB had its signature changed to avoid uint32_t
-rw-r--r--include/drm/drm.h4
-rw-r--r--include/drm/drm_mode.h11
-rw-r--r--include/drm/i915_drm.h1
-rw-r--r--tests/modetest/modetest.c146
-rw-r--r--xf86drm.h6
-rw-r--r--xf86drmMode.c25
-rw-r--r--xf86drmMode.h2
7 files changed, 186 insertions, 9 deletions
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 649c46f3..5408c08c 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -696,6 +696,9 @@ struct drm_gem_open {
696#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) 696#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
697#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) 697#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
698#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) 698#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
699#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
700
701/*@}*/
699 702
700/** 703/**
701 * Device specific ioctls should only be in their respective headers 704 * Device specific ioctls should only be in their respective headers
@@ -726,6 +729,7 @@ struct drm_event {
726}; 729};
727 730
728#define DRM_EVENT_VBLANK 0x01 731#define DRM_EVENT_VBLANK 0x01
732#define DRM_EVENT_FLIP_COMPLETE 0x02
729 733
730struct drm_event_vblank { 734struct drm_event_vblank {
731 struct drm_event base; 735 struct drm_event base;
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 852505e7..1fd30266 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -265,4 +265,15 @@ struct drm_mode_crtc_lut {
265 __u64 blue; 265 __u64 blue;
266}; 266};
267 267
268#define DRM_MODE_PAGE_FLIP_EVENT 0x01
269#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
270
271struct drm_mode_crtc_page_flip {
272 uint32_t crtc_id;
273 uint32_t fb_id;
274 uint32_t flags;
275 uint32_t reserved;
276 uint64_t user_data;
277};
278
268#endif 279#endif
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 25ff7b79..75b0e1d5 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -271,6 +271,7 @@ typedef struct drm_i915_irq_wait {
271#define I915_PARAM_HAS_GEM 5 271#define I915_PARAM_HAS_GEM 5
272#define I915_PARAM_NUM_FENCES_AVAIL 6 272#define I915_PARAM_NUM_FENCES_AVAIL 6
273#define I915_PARAM_HAS_OVERLAY 7 273#define I915_PARAM_HAS_OVERLAY 7
274#define I915_PARAM_HAS_PAGEFLIPPING 8
274 275
275typedef struct drm_i915_getparam { 276typedef struct drm_i915_getparam {
276 int param; 277 int param;
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 6c69a570..4739a78b 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -46,6 +46,7 @@
46#include <unistd.h> 46#include <unistd.h>
47#include <string.h> 47#include <string.h>
48#include <errno.h> 48#include <errno.h>
49#include <sys/poll.h>
49 50
50#include "xf86drm.h" 51#include "xf86drm.h"
51#include "xf86drmMode.h" 52#include "xf86drmMode.h"
@@ -172,7 +173,7 @@ void dump_connectors(void)
172 int i, j; 173 int i, j;
173 174
174 printf("Connectors:\n"); 175 printf("Connectors:\n");
175 printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n"); 176 printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");
176 for (i = 0; i < resources->count_connectors; i++) { 177 for (i = 0; i < resources->count_connectors; i++) {
177 connector = drmModeGetConnector(fd, resources->connectors[i]); 178 connector = drmModeGetConnector(fd, resources->connectors[i]);
178 179
@@ -182,7 +183,7 @@ void dump_connectors(void)
182 continue; 183 continue;
183 } 184 }
184 185
185 printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n", 186 printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",
186 connector->connector_id, 187 connector->connector_id,
187 connector->encoder_id, 188 connector->encoder_id,
188 connector_status_str(connector->connection), 189 connector_status_str(connector->connection),
@@ -190,6 +191,10 @@ void dump_connectors(void)
190 connector->mmWidth, connector->mmHeight, 191 connector->mmWidth, connector->mmHeight,
191 connector->count_modes); 192 connector->count_modes);
192 193
194 for (j = 0; j < connector->count_encoders; j++)
195 printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]);
196 printf("\n");
197
193 if (!connector->count_modes) 198 if (!connector->count_modes)
194 continue; 199 continue;
195 200
@@ -271,6 +276,10 @@ struct connector {
271 drmModeModeInfo *mode; 276 drmModeModeInfo *mode;
272 drmModeEncoder *encoder; 277 drmModeEncoder *encoder;
273 int crtc; 278 int crtc;
279 unsigned int fb_id[2], current_fb_id;
280 struct timeval start;
281
282 int swap_count;
274}; 283};
275 284
276static void 285static void
@@ -457,16 +466,83 @@ create_test_buffer(drm_intel_bufmgr *bufmgr,
457 466
458#endif 467#endif
459 468
469static int
470create_grey_buffer(drm_intel_bufmgr *bufmgr,
471 int width, int height, int *stride_out, drm_intel_bo **bo_out)
472{
473 drm_intel_bo *bo;
474 unsigned int *fb_ptr;
475 int size, ret, i, stride;
476 div_t d;
477
478 /* Mode size at 32 bpp */
479 stride = width * 4;
480 size = stride * height;
481
482 bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
483 if (!bo) {
484 fprintf(stderr, "failed to alloc buffer: %s\n",
485 strerror(errno));
486 return -1;
487 }
488
489 ret = drm_intel_gem_bo_map_gtt(bo);
490 if (ret) {
491 fprintf(stderr, "failed to GTT map buffer: %s\n",
492 strerror(errno));
493 return -1;
494 }
495
496 memset(bo->virtual, 0x77, size);
497 drm_intel_gem_bo_unmap_gtt(bo);
498
499 *bo_out = bo;
500 *stride_out = stride;
501
502 return 0;
503}
504
505void
506page_flip_handler(int fd, unsigned int frame,
507 unsigned int sec, unsigned int usec, void *data)
508{
509 struct connector *c;
510 unsigned int new_fb_id;
511 int len, ms;
512 struct timeval end;
513 double t;
514
515 c = data;
516 if (c->current_fb_id == c->fb_id[0])
517 new_fb_id = c->fb_id[1];
518 else
519 new_fb_id = c->fb_id[0];
520
521 drmModePageFlip(fd, c->crtc, new_fb_id,
522 DRM_MODE_PAGE_FLIP_EVENT, c);
523 c->current_fb_id = new_fb_id;
524 c->swap_count++;
525 if (c->swap_count == 60) {
526 gettimeofday(&end, NULL);
527 t = end.tv_sec + end.tv_usec * 1e-6 -
528 (c->start.tv_sec + c->start.tv_usec * 1e-6);
529 fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
530 c->swap_count = 0;
531 c->start = end;
532 }
533}
534
460static void 535static void
461set_mode(struct connector *c, int count) 536set_mode(struct connector *c, int count, int page_flip)
462{ 537{
463 drmModeConnector *connector; 538 drmModeConnector *connector;
464 drmModeEncoder *encoder = NULL; 539 drmModeEncoder *encoder = NULL;
465 struct drm_mode_modeinfo *mode = NULL; 540 struct drm_mode_modeinfo *mode = NULL;
466 drm_intel_bufmgr *bufmgr; 541 drm_intel_bufmgr *bufmgr;
467 drm_intel_bo *bo; 542 drm_intel_bo *bo, *other_bo;
468 unsigned int fb_id; 543 unsigned int fb_id, other_fb_id;
469 int i, j, ret, width, height, x, stride; 544 int i, j, ret, width, height, x, stride;
545 drmEventContext evctx;
470 546
471 width = 0; 547 width = 0;
472 height = 0; 548 height = 0;
@@ -497,7 +573,6 @@ set_mode(struct connector *c, int count)
497 573
498 x = 0; 574 x = 0;
499 for (i = 0; i < count; i++) { 575 for (i = 0; i < count; i++) {
500 int crtc_id;
501 if (c[i].mode == NULL) 576 if (c[i].mode == NULL)
502 continue; 577 continue;
503 578
@@ -513,11 +588,61 @@ set_mode(struct connector *c, int count)
513 return; 588 return;
514 } 589 }
515 } 590 }
591
592 if (!page_flip)
593 return;
594
595 if (create_grey_buffer(bufmgr, width, height, &stride, &other_bo))
596 return;
597
598 ret = drmModeAddFB(fd, width, height, 32, 32, stride, other_bo->handle,
599 &other_fb_id);
600 if (ret) {
601 fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
602 return;
603 }
604
605 for (i = 0; i < count; i++) {
606 if (c[i].mode == NULL)
607 continue;
608
609 drmModePageFlip(fd, c[i].crtc, other_fb_id,
610 DRM_MODE_PAGE_FLIP_EVENT, &c[i]);
611 gettimeofday(&c[i].start, NULL);
612 c[i].swap_count = 0;
613 c[i].fb_id[0] = fb_id;
614 c[i].fb_id[1] = other_fb_id;
615 c[i].current_fb_id = fb_id;
616 }
617
618 memset(&evctx, 0, sizeof evctx);
619 evctx.version = DRM_EVENT_CONTEXT_VERSION;
620 evctx.vblank_handler = NULL;
621 evctx.pageflip_handler = page_flip_handler;
622
623 while (1) {
624 struct pollfd pfd[2];
625
626 pfd[0].fd = 0;
627 pfd[0].events = POLLIN;
628 pfd[1].fd = fd;
629 pfd[1].events = POLLIN;
630
631 if (poll(pfd, 2, -1) < 0) {
632 fprintf(stderr, "poll error\n");
633 break;
634 }
635
636 if (pfd[0].revents)
637 break;
638
639 drmHandleEvent(fd, &evctx);
640 }
516} 641}
517 642
518extern char *optarg; 643extern char *optarg;
519extern int optind, opterr, optopt; 644extern int optind, opterr, optopt;
520static char optstr[] = "ecpmfs:"; 645static char optstr[] = "ecpmfs:v";
521 646
522void usage(char *name) 647void usage(char *name)
523{ 648{
@@ -527,6 +652,7 @@ void usage(char *name)
527 fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n"); 652 fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
528 fprintf(stderr, "\t-m\tlist modes\n"); 653 fprintf(stderr, "\t-m\tlist modes\n");
529 fprintf(stderr, "\t-f\tlist framebuffers\n"); 654 fprintf(stderr, "\t-f\tlist framebuffers\n");
655 fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
530 fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n"); 656 fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
531 fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n"); 657 fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
532 fprintf(stderr, "\n\tDefault is to dump all info.\n"); 658 fprintf(stderr, "\n\tDefault is to dump all info.\n");
@@ -539,6 +665,7 @@ int main(int argc, char **argv)
539{ 665{
540 int c; 666 int c;
541 int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; 667 int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
668 int test_vsync = 0;
542 char *modules[] = { "i915", "radeon" }; 669 char *modules[] = { "i915", "radeon" };
543 char *modeset = NULL, *mode, *connector; 670 char *modeset = NULL, *mode, *connector;
544 int i, connector_id, count = 0; 671 int i, connector_id, count = 0;
@@ -562,6 +689,9 @@ int main(int argc, char **argv)
562 case 'f': 689 case 'f':
563 framebuffers = 1; 690 framebuffers = 1;
564 break; 691 break;
692 case 'v':
693 test_vsync = 1;
694 break;
565 case 's': 695 case 's':
566 modeset = strdup(optarg); 696 modeset = strdup(optarg);
567 con_args[count].crtc = -1; 697 con_args[count].crtc = -1;
@@ -614,7 +744,7 @@ int main(int argc, char **argv)
614 dump_resource(framebuffers); 744 dump_resource(framebuffers);
615 745
616 if (count > 0) { 746 if (count > 0) {
617 set_mode(con_args, count); 747 set_mode(con_args, count, test_vsync);
618 getchar(); 748 getchar();
619 } 749 }
620 750
diff --git a/xf86drm.h b/xf86drm.h
index 496d95d8..89f1db18 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -707,6 +707,12 @@ typedef struct _drmEventContext {
707 unsigned int tv_usec, 707 unsigned int tv_usec,
708 void *user_data); 708 void *user_data);
709 709
710 void (*page_flip_handler)(int fd,
711 unsigned int sequence,
712 unsigned int tv_sec,
713 unsigned int tv_usec,
714 void *user_data);
715
710} drmEventContext, *drmEventContextPtr; 716} drmEventContext, *drmEventContextPtr;
711 717
712extern int drmHandleEvent(int fd, drmEventContextPtr evctx); 718extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 6d85113a..e9516851 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -700,7 +700,17 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
700 vblank->tv_usec, 700 vblank->tv_usec,
701 U642VOID (vblank->user_data)); 701 U642VOID (vblank->user_data));
702 break; 702 break;
703 703 case DRM_EVENT_FLIP_COMPLETE:
704 if (evctx->version < 1 ||
705 evctx->page_flip_handler == NULL)
706 break;
707 vblank = (struct drm_event_vblank *) e;
708 evctx->page_flip_handler(fd,
709 vblank->sequence,
710 vblank->tv_sec,
711 vblank->tv_usec,
712 U642VOID (vblank->user_data));
713 break;
704 default: 714 default:
705 break; 715 break;
706 } 716 }
@@ -710,3 +720,16 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
710 return 0; 720 return 0;
711} 721}
712 722
723int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
724 uint32_t flags, void *user_data)
725{
726 struct drm_mode_crtc_page_flip flip;
727
728 flip.fb_id = fb_id;
729 flip.crtc_id = crtc_id;
730 flip.user_data = VOID2U64(user_data);
731 flip.flags = flags;
732 flip.reserved = 0;
733
734 return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
735}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 62304bb9..705369fe 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -362,3 +362,5 @@ extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
362 uint16_t *red, uint16_t *green, uint16_t *blue); 362 uint16_t *red, uint16_t *green, uint16_t *blue);
363extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, 363extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
364 uint16_t *red, uint16_t *green, uint16_t *blue); 364 uint16_t *red, uint16_t *green, uint16_t *blue);
365extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
366 uint32_t flags, void *user_data);