mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 13:40:13 +01:00
Merge branch 'pageflip' of git://people.freedesktop.org/~jbarnes/drm
Conflicts: include/drm/drm.h - RMFB had its signature changed to avoid uint32_t
This commit is contained in:
commit
53addc5d6e
7 changed files with 186 additions and 9 deletions
|
|
@ -696,6 +696,9 @@ struct drm_gem_open {
|
||||||
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
|
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
|
||||||
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
|
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
|
||||||
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
|
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
|
||||||
|
#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip)
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device specific ioctls should only be in their respective headers
|
* Device specific ioctls should only be in their respective headers
|
||||||
|
|
@ -726,6 +729,7 @@ struct drm_event {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DRM_EVENT_VBLANK 0x01
|
#define DRM_EVENT_VBLANK 0x01
|
||||||
|
#define DRM_EVENT_FLIP_COMPLETE 0x02
|
||||||
|
|
||||||
struct drm_event_vblank {
|
struct drm_event_vblank {
|
||||||
struct drm_event base;
|
struct drm_event base;
|
||||||
|
|
|
||||||
|
|
@ -265,4 +265,15 @@ struct drm_mode_crtc_lut {
|
||||||
__u64 blue;
|
__u64 blue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DRM_MODE_PAGE_FLIP_EVENT 0x01
|
||||||
|
#define DRM_MODE_PAGE_FLIP_FLAGS DRM_MODE_PAGE_FLIP_EVENT
|
||||||
|
|
||||||
|
struct drm_mode_crtc_page_flip {
|
||||||
|
uint32_t crtc_id;
|
||||||
|
uint32_t fb_id;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t reserved;
|
||||||
|
uint64_t user_data;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ typedef struct drm_i915_irq_wait {
|
||||||
#define I915_PARAM_HAS_GEM 5
|
#define I915_PARAM_HAS_GEM 5
|
||||||
#define I915_PARAM_NUM_FENCES_AVAIL 6
|
#define I915_PARAM_NUM_FENCES_AVAIL 6
|
||||||
#define I915_PARAM_HAS_OVERLAY 7
|
#define I915_PARAM_HAS_OVERLAY 7
|
||||||
|
#define I915_PARAM_HAS_PAGEFLIPPING 8
|
||||||
|
|
||||||
typedef struct drm_i915_getparam {
|
typedef struct drm_i915_getparam {
|
||||||
int param;
|
int param;
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
#include "xf86drm.h"
|
#include "xf86drm.h"
|
||||||
#include "xf86drmMode.h"
|
#include "xf86drmMode.h"
|
||||||
|
|
@ -172,7 +173,7 @@ void dump_connectors(void)
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
printf("Connectors:\n");
|
printf("Connectors:\n");
|
||||||
printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n");
|
printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");
|
||||||
for (i = 0; i < resources->count_connectors; i++) {
|
for (i = 0; i < resources->count_connectors; i++) {
|
||||||
connector = drmModeGetConnector(fd, resources->connectors[i]);
|
connector = drmModeGetConnector(fd, resources->connectors[i]);
|
||||||
|
|
||||||
|
|
@ -182,7 +183,7 @@ void dump_connectors(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
|
printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",
|
||||||
connector->connector_id,
|
connector->connector_id,
|
||||||
connector->encoder_id,
|
connector->encoder_id,
|
||||||
connector_status_str(connector->connection),
|
connector_status_str(connector->connection),
|
||||||
|
|
@ -190,6 +191,10 @@ void dump_connectors(void)
|
||||||
connector->mmWidth, connector->mmHeight,
|
connector->mmWidth, connector->mmHeight,
|
||||||
connector->count_modes);
|
connector->count_modes);
|
||||||
|
|
||||||
|
for (j = 0; j < connector->count_encoders; j++)
|
||||||
|
printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
if (!connector->count_modes)
|
if (!connector->count_modes)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -271,6 +276,10 @@ struct connector {
|
||||||
drmModeModeInfo *mode;
|
drmModeModeInfo *mode;
|
||||||
drmModeEncoder *encoder;
|
drmModeEncoder *encoder;
|
||||||
int crtc;
|
int crtc;
|
||||||
|
unsigned int fb_id[2], current_fb_id;
|
||||||
|
struct timeval start;
|
||||||
|
|
||||||
|
int swap_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -457,16 +466,83 @@ create_test_buffer(drm_intel_bufmgr *bufmgr,
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_grey_buffer(drm_intel_bufmgr *bufmgr,
|
||||||
|
int width, int height, int *stride_out, drm_intel_bo **bo_out)
|
||||||
|
{
|
||||||
|
drm_intel_bo *bo;
|
||||||
|
unsigned int *fb_ptr;
|
||||||
|
int size, ret, i, stride;
|
||||||
|
div_t d;
|
||||||
|
|
||||||
|
/* Mode size at 32 bpp */
|
||||||
|
stride = width * 4;
|
||||||
|
size = stride * height;
|
||||||
|
|
||||||
|
bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
|
||||||
|
if (!bo) {
|
||||||
|
fprintf(stderr, "failed to alloc buffer: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_intel_gem_bo_map_gtt(bo);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to GTT map buffer: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(bo->virtual, 0x77, size);
|
||||||
|
drm_intel_gem_bo_unmap_gtt(bo);
|
||||||
|
|
||||||
|
*bo_out = bo;
|
||||||
|
*stride_out = stride;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
page_flip_handler(int fd, unsigned int frame,
|
||||||
|
unsigned int sec, unsigned int usec, void *data)
|
||||||
|
{
|
||||||
|
struct connector *c;
|
||||||
|
unsigned int new_fb_id;
|
||||||
|
int len, ms;
|
||||||
|
struct timeval end;
|
||||||
|
double t;
|
||||||
|
|
||||||
|
c = data;
|
||||||
|
if (c->current_fb_id == c->fb_id[0])
|
||||||
|
new_fb_id = c->fb_id[1];
|
||||||
|
else
|
||||||
|
new_fb_id = c->fb_id[0];
|
||||||
|
|
||||||
|
drmModePageFlip(fd, c->crtc, new_fb_id,
|
||||||
|
DRM_MODE_PAGE_FLIP_EVENT, c);
|
||||||
|
c->current_fb_id = new_fb_id;
|
||||||
|
c->swap_count++;
|
||||||
|
if (c->swap_count == 60) {
|
||||||
|
gettimeofday(&end, NULL);
|
||||||
|
t = end.tv_sec + end.tv_usec * 1e-6 -
|
||||||
|
(c->start.tv_sec + c->start.tv_usec * 1e-6);
|
||||||
|
fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
|
||||||
|
c->swap_count = 0;
|
||||||
|
c->start = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_mode(struct connector *c, int count)
|
set_mode(struct connector *c, int count, int page_flip)
|
||||||
{
|
{
|
||||||
drmModeConnector *connector;
|
drmModeConnector *connector;
|
||||||
drmModeEncoder *encoder = NULL;
|
drmModeEncoder *encoder = NULL;
|
||||||
struct drm_mode_modeinfo *mode = NULL;
|
struct drm_mode_modeinfo *mode = NULL;
|
||||||
drm_intel_bufmgr *bufmgr;
|
drm_intel_bufmgr *bufmgr;
|
||||||
drm_intel_bo *bo;
|
drm_intel_bo *bo, *other_bo;
|
||||||
unsigned int fb_id;
|
unsigned int fb_id, other_fb_id;
|
||||||
int i, j, ret, width, height, x, stride;
|
int i, j, ret, width, height, x, stride;
|
||||||
|
drmEventContext evctx;
|
||||||
|
|
||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
|
|
@ -497,7 +573,6 @@ set_mode(struct connector *c, int count)
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
int crtc_id;
|
|
||||||
if (c[i].mode == NULL)
|
if (c[i].mode == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -513,11 +588,61 @@ set_mode(struct connector *c, int count)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!page_flip)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (create_grey_buffer(bufmgr, width, height, &stride, &other_bo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = drmModeAddFB(fd, width, height, 32, 32, stride, other_bo->handle,
|
||||||
|
&other_fb_id);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (c[i].mode == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
drmModePageFlip(fd, c[i].crtc, other_fb_id,
|
||||||
|
DRM_MODE_PAGE_FLIP_EVENT, &c[i]);
|
||||||
|
gettimeofday(&c[i].start, NULL);
|
||||||
|
c[i].swap_count = 0;
|
||||||
|
c[i].fb_id[0] = fb_id;
|
||||||
|
c[i].fb_id[1] = other_fb_id;
|
||||||
|
c[i].current_fb_id = fb_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&evctx, 0, sizeof evctx);
|
||||||
|
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||||
|
evctx.vblank_handler = NULL;
|
||||||
|
evctx.pageflip_handler = page_flip_handler;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct pollfd pfd[2];
|
||||||
|
|
||||||
|
pfd[0].fd = 0;
|
||||||
|
pfd[0].events = POLLIN;
|
||||||
|
pfd[1].fd = fd;
|
||||||
|
pfd[1].events = POLLIN;
|
||||||
|
|
||||||
|
if (poll(pfd, 2, -1) < 0) {
|
||||||
|
fprintf(stderr, "poll error\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfd[0].revents)
|
||||||
|
break;
|
||||||
|
|
||||||
|
drmHandleEvent(fd, &evctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind, opterr, optopt;
|
extern int optind, opterr, optopt;
|
||||||
static char optstr[] = "ecpmfs:";
|
static char optstr[] = "ecpmfs:v";
|
||||||
|
|
||||||
void usage(char *name)
|
void usage(char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -527,6 +652,7 @@ void usage(char *name)
|
||||||
fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
|
fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
|
||||||
fprintf(stderr, "\t-m\tlist modes\n");
|
fprintf(stderr, "\t-m\tlist modes\n");
|
||||||
fprintf(stderr, "\t-f\tlist framebuffers\n");
|
fprintf(stderr, "\t-f\tlist framebuffers\n");
|
||||||
|
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
|
||||||
fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
|
fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
|
||||||
fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
|
fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
|
||||||
fprintf(stderr, "\n\tDefault is to dump all info.\n");
|
fprintf(stderr, "\n\tDefault is to dump all info.\n");
|
||||||
|
|
@ -539,6 +665,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
|
int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
|
||||||
|
int test_vsync = 0;
|
||||||
char *modules[] = { "i915", "radeon" };
|
char *modules[] = { "i915", "radeon" };
|
||||||
char *modeset = NULL, *mode, *connector;
|
char *modeset = NULL, *mode, *connector;
|
||||||
int i, connector_id, count = 0;
|
int i, connector_id, count = 0;
|
||||||
|
|
@ -562,6 +689,9 @@ int main(int argc, char **argv)
|
||||||
case 'f':
|
case 'f':
|
||||||
framebuffers = 1;
|
framebuffers = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'v':
|
||||||
|
test_vsync = 1;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
modeset = strdup(optarg);
|
modeset = strdup(optarg);
|
||||||
con_args[count].crtc = -1;
|
con_args[count].crtc = -1;
|
||||||
|
|
@ -614,7 +744,7 @@ int main(int argc, char **argv)
|
||||||
dump_resource(framebuffers);
|
dump_resource(framebuffers);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
set_mode(con_args, count);
|
set_mode(con_args, count, test_vsync);
|
||||||
getchar();
|
getchar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -707,6 +707,12 @@ typedef struct _drmEventContext {
|
||||||
unsigned int tv_usec,
|
unsigned int tv_usec,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
|
void (*page_flip_handler)(int fd,
|
||||||
|
unsigned int sequence,
|
||||||
|
unsigned int tv_sec,
|
||||||
|
unsigned int tv_usec,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
} drmEventContext, *drmEventContextPtr;
|
} drmEventContext, *drmEventContextPtr;
|
||||||
|
|
||||||
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
|
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
|
||||||
|
|
|
||||||
|
|
@ -700,7 +700,17 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
|
||||||
vblank->tv_usec,
|
vblank->tv_usec,
|
||||||
U642VOID (vblank->user_data));
|
U642VOID (vblank->user_data));
|
||||||
break;
|
break;
|
||||||
|
case DRM_EVENT_FLIP_COMPLETE:
|
||||||
|
if (evctx->version < 1 ||
|
||||||
|
evctx->page_flip_handler == NULL)
|
||||||
|
break;
|
||||||
|
vblank = (struct drm_event_vblank *) e;
|
||||||
|
evctx->page_flip_handler(fd,
|
||||||
|
vblank->sequence,
|
||||||
|
vblank->tv_sec,
|
||||||
|
vblank->tv_usec,
|
||||||
|
U642VOID (vblank->user_data));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -710,3 +720,16 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
|
||||||
|
uint32_t flags, void *user_data)
|
||||||
|
{
|
||||||
|
struct drm_mode_crtc_page_flip flip;
|
||||||
|
|
||||||
|
flip.fb_id = fb_id;
|
||||||
|
flip.crtc_id = crtc_id;
|
||||||
|
flip.user_data = VOID2U64(user_data);
|
||||||
|
flip.flags = flags;
|
||||||
|
flip.reserved = 0;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -362,3 +362,5 @@ extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
uint16_t *red, uint16_t *green, uint16_t *blue);
|
uint16_t *red, uint16_t *green, uint16_t *blue);
|
||||||
extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
uint16_t *red, uint16_t *green, uint16_t *blue);
|
uint16_t *red, uint16_t *green, uint16_t *blue);
|
||||||
|
extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
|
||||||
|
uint32_t flags, void *user_data);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue