diff options
Diffstat (limited to 'test/present-speed.c')
-rw-r--r-- | test/present-speed.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/test/present-speed.c b/test/present-speed.c index c89af875..5c5b930b 100644 --- a/test/present-speed.c +++ b/test/present-speed.c @@ -38,6 +38,7 @@ #include <xcb/xcb.h> #include <xcb/present.h> #include <xcb/dri3.h> +#include <xcb/xfixes.h> #include <xf86drm.h> #include <i915_drm.h> @@ -139,16 +140,21 @@ struct buffer { int busy; }; -static void run(Display *dpy, Window win, const char *name, int use_dri3) +#define FENCE 1 +#define NOCOPY 2 +static void run(Display *dpy, Window win, const char *name, unsigned options) { xcb_connection_t *c = XGetXCBConnection(dpy); struct timespec start, end; #define N_BACK 8 + char test_name[128]; struct buffer buffer[N_BACK]; struct list mru; Window root; unsigned int width, height; unsigned border, depth; + unsigned present_flags = XCB_PRESENT_OPTION_ASYNC; + xcb_xfixes_region_t update = 0; int completed = 0; int queued = 0; uint32_t eid; @@ -166,7 +172,7 @@ static void run(Display *dpy, Window win, const char *name, int use_dri3) buffer[n].pixmap = XCreatePixmap(dpy, win, width, height, depth); buffer[n].fence.xid = 0; - if (use_dri3) { + if (options & FENCE) { if (dri3_create_fence(dpy, win, &buffer[n].fence)) return; /* start idle */ @@ -175,6 +181,11 @@ static void run(Display *dpy, Window win, const char *name, int use_dri3) buffer[n].busy = 0; list_add(&buffer[n].link, &mru); } + if (options & NOCOPY) { + update = xcb_generate_id(c); + xcb_xfixes_create_region(c, update, 0, NULL); + present_flags |= XCB_PRESENT_OPTION_COPY; + } eid = xcb_generate_id(c); xcb_present_select_input(c, eid, win, @@ -229,13 +240,13 @@ static void run(Display *dpy, Window win, const char *name, int use_dri3) } xcb_present_pixmap(c, win, b->pixmap, b - buffer, 0, /* valid */ - 0, /* update */ + update, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ b->fence.xid, - XCB_PRESENT_OPTION_ASYNC, + present_flags, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ @@ -270,6 +281,8 @@ static void run(Display *dpy, Window win, const char *name, int use_dri3) } clock_gettime(CLOCK_MONOTONIC, &end); + if (update) + xcb_xfixes_destroy_region(c, update); for (n = 0; n < N_BACK; n++) { if (buffer[n].fence.xid) dri3_fence_free(dpy, &buffer[n].fence); @@ -284,8 +297,14 @@ static void run(Display *dpy, Window win, const char *name, int use_dri3) XSync(dpy, True); xcb_unregister_for_special_event(c, Q); + test_name[0] = '\0'; + if (options) { + snprintf(test_name, sizeof(test_name), "(%s%s )", + options & NOCOPY ? " no-copy" : "", + options & FENCE ? " fence" : ""); + } printf("%s%s: Completed %d presents in %.1fs, %.3fus each (%.1f FPS)\n", - name, use_dri3 ? " (dri3)" : "", + name, test_name, completed, elapsed(&start, &end) / 1000000, elapsed(&start, &end) / completed, completed / (elapsed(&start, &end) / 1000000)); @@ -352,6 +371,26 @@ static int has_dri3(Display *dpy) return major >= 0; } +static int has_xfixes(Display *dpy) +{ + xcb_connection_t *c = XGetXCBConnection(dpy); + const xcb_query_extension_reply_t *ext; + void *reply; + + ext = xcb_get_extension_data(c, &xcb_xfixes_id); + if (ext == NULL || !ext->present) + return 0; + + reply = xcb_xfixes_query_version_reply(c, + xcb_xfixes_query_version(c, + XCB_XFIXES_MAJOR_VERSION, + XCB_XFIXES_MINOR_VERSION), + NULL); + free(reply); + + return reply != NULL; +} + static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; @@ -384,7 +423,7 @@ static void fullscreen(Display *dpy, Window win) (unsigned char *)&atom, 1); } -static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) +static void loop(Display *dpy, XRRScreenResources *res, unsigned options) { Window root = DefaultRootWindow(dpy); Window win; @@ -393,7 +432,7 @@ static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) attr.override_redirect = 1; - run(dpy, root, "off", use_dri3); + run(dpy, root, "off", options); for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; @@ -418,7 +457,7 @@ static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); - run(dpy, root, "root", use_dri3); + run(dpy, root, "root", options); win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, @@ -428,7 +467,7 @@ static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) CWOverrideRedirect, &attr); fullscreen(dpy, win); XMapWindow(dpy, win); - run(dpy, win, "fullscreen", use_dri3); + run(dpy, win, "fullscreen", options); XDestroyWindow(dpy, win); win = XCreateWindow(dpy, root, @@ -438,7 +477,7 @@ static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); - run(dpy, win, "windowed", use_dri3); + run(dpy, win, "windowed", options); XDestroyWindow(dpy, win); win = XCreateWindow(dpy, root, @@ -448,7 +487,7 @@ static void loop(Display *dpy, XRRScreenResources *res, int use_dri3) DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); - run(dpy, win, "half", use_dri3); + run(dpy, win, "half", options); XDestroyWindow(dpy, win); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, @@ -495,8 +534,10 @@ int main(void) 0, 0, None, RR_Rotate_0, NULL, 0); loop(dpy, res, 0); + if (has_xfixes(dpy)) + loop(dpy, res, NOCOPY); if (has_dri3(dpy)) - loop(dpy, res, 1); + loop(dpy, res, FENCE); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, |