xf86-video-intel: 4 commits - src/sna/sna_dri2.c src/sna/sna_present.c test/dri2-test.c test/present-speed.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Apr 2 15:11:53 PDT 2015


 src/sna/sna_dri2.c    |   29 +++++----
 src/sna/sna_present.c |   13 ++--
 test/dri2-test.c      |   48 ++++++++++-----
 test/present-speed.c  |  159 +++++++++++++++++++++++++++++++++++---------------
 4 files changed, 171 insertions(+), 78 deletions(-)

New commits:
commit 459efa036e64bd4875b79d42bdd8416ede2223d3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 2 22:50:54 2015 +0100

    test/dri2: Reset swap-interval after testing async swapping
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/dri2-test.c b/test/dri2-test.c
index b88e65c..88c0e4c 100644
--- a/test/dri2-test.c
+++ b/test/dri2-test.c
@@ -154,6 +154,7 @@ static void run(Display *dpy, int width, int height,
 	XMapWindow(dpy, win);
 
 	DRI2CreateDrawable(dpy, win);
+	DRI2SwapInterval(dpy, win, 1);
 	start_msc = check_msc(dpy, win, 0);
 
 	buffers = DRI2GetBuffers(dpy, win, &width, &height,
commit 3c3f7d7df4cfb6e1f22fe850f3cf35c6e334b4a1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 2 22:50:19 2015 +0100

    test/dri2: Check vblank waits
    
    Make sure that waiting 60 times for a vblank, 60 msc pass
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/dri2-test.c b/test/dri2-test.c
index d44ed99..b88e65c 100644
--- a/test/dri2-test.c
+++ b/test/dri2-test.c
@@ -105,6 +105,12 @@ static uint64_t check_msc(Display *dpy, Window win, uint64_t last_msc)
 	return current_msc;
 }
 
+static void wait_next_vblank(Display *dpy, Window win)
+{
+	uint64_t msc, ust, sbc;
+	DRI2WaitMSC(dpy, win, 0, 1, 0, &ust, &msc, &sbc);
+}
+
 static void swap_buffers(xcb_connection_t *c, Window win,
 		unsigned int *attachments, int nattachments)
 {
@@ -133,7 +139,7 @@ static void run(Display *dpy, int width, int height,
 	int count;
 	DRI2Buffer *buffers;
 	struct timespec start, end;
-	uint64_t msc;
+	uint64_t start_msc, end_msc;
 
 	/* Be nasty and install a fullscreen window on top so that we
 	 * can guarantee we do not get clipped by children.
@@ -148,7 +154,7 @@ static void run(Display *dpy, int width, int height,
 	XMapWindow(dpy, win);
 
 	DRI2CreateDrawable(dpy, win);
-	msc = check_msc(dpy, win, 0);
+	start_msc = check_msc(dpy, win, 0);
 
 	buffers = DRI2GetBuffers(dpy, win, &width, &height,
 				 attachments, nattachments, &count);
@@ -156,37 +162,50 @@ static void run(Display *dpy, int width, int height,
 		return;
 
 	swap_buffers(c, win, attachments, nattachments);
-	msc = check_msc(dpy, win, msc);
+	start_msc = check_msc(dpy, win, start_msc);
 	clock_gettime(CLOCK_MONOTONIC, &start);
 	for (count = 0; count < COUNT; count++)
 		swap_buffers(c, win, attachments, nattachments);
-	msc = check_msc(dpy, win, msc);
+	end_msc = check_msc(dpy, win, start_msc);
 	clock_gettime(CLOCK_MONOTONIC, &end);
-	printf("%d %s (%dx%d) swaps in %fs.\n",
-	       count, name, width, height, elapsed(&start, &end));
+	printf("%d [%ld] %s (%dx%d) swaps in %fs.\n",
+	       count, (long)(end_msc - start_msc),
+	       name, width, height, elapsed(&start, &end));
 
 	swap_buffers(c, win, attachments, nattachments);
-	msc = check_msc(dpy, win, msc);
+	start_msc = check_msc(dpy, win, end_msc);
 	clock_gettime(CLOCK_MONOTONIC, &start);
 	for (count = 0; count < COUNT; count++)
 		dri2_copy_swap(dpy, win, width, height, nattachments == 2);
-	msc = check_msc(dpy, win, msc);
+	end_msc = check_msc(dpy, win, start_msc);
 	clock_gettime(CLOCK_MONOTONIC, &end);
 
-	printf("%d %s (%dx%d) blits in %fs.\n",
-	       count, name, width, height, elapsed(&start, &end));
+	printf("%d [%ld] %s (%dx%d) blits in %fs.\n",
+	       count, (long)(end_msc - start_msc),
+	       name, width, height, elapsed(&start, &end));
 
 	DRI2SwapInterval(dpy, win, 0);
 
 	swap_buffers(c, win, attachments, nattachments);
-	msc = check_msc(dpy, win, msc);
+	start_msc = check_msc(dpy, win, end_msc);
 	clock_gettime(CLOCK_MONOTONIC, &start);
 	for (count = 0; count < COUNT; count++)
 		swap_buffers(c, win, attachments, nattachments);
-	msc = check_msc(dpy, win, msc);
+	end_msc = check_msc(dpy, win, start_msc);
+	clock_gettime(CLOCK_MONOTONIC, &end);
+	printf("%d [%ld] %s (%dx%d) vblank=0 swaps in %fs.\n",
+	       count, (long)(end_msc - start_msc),
+	       name, width, height, elapsed(&start, &end));
+
+	start_msc = check_msc(dpy, win, end_msc);
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (count = 0; count < COUNT; count++)
+		wait_next_vblank(dpy, win);
+	end_msc = check_msc(dpy, win, start_msc);
 	clock_gettime(CLOCK_MONOTONIC, &end);
-	printf("%d %s (%dx%d) vblank=0 swaps in %fs.\n",
-	       count, name, width, height, elapsed(&start, &end));
+	printf("%d [%ld] %s waits in %fs.\n",
+	       count, (long)(end_msc - start_msc),
+	       name, elapsed(&start, &end));
 
 	XDestroyWindow(dpy, win);
 	free(buffers);
commit ef8f5236f2b7698d026be42de99cb8e7f86a4a6b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 2 15:14:24 2015 +0100

    sna/dri2: Fix multimonitor swap elision
    
    We were not updating the window->crtc for the immediate swaps with the
    result that after switching CRTCs, we were requesting a vblank on the
    wrong pipe and triggering an error path (forcing the blit and negating
    the elision).
    
    Testcase: test/dri2-speed
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 7868d03..4eec9db 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1450,7 +1450,10 @@ static bool add_event_to_client(struct sna_dri2_event *info, struct sna *sna, Cl
 }
 
 static struct sna_dri2_event *
-sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client)
+sna_dri2_add_event(struct sna *sna,
+		   DrawablePtr draw,
+		   ClientPtr client,
+		   xf86CrtcPtr crtc)
 {
 	struct dri2_window *priv;
 	struct sna_dri2_event *info, *chain;
@@ -1470,8 +1473,8 @@ sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client)
 	list_init(&info->cache);
 	info->sna = sna;
 	info->draw = draw;
-	info->crtc = priv->crtc;
-	info->pipe = sna_crtc_to_pipe(priv->crtc);
+	info->crtc = crtc;
+	info->pipe = sna_crtc_to_pipe(crtc);
 
 	if (!add_event_to_client(info, sna, client)) {
 		free(info);
@@ -2349,8 +2352,8 @@ sna_dri2_immediate_blit(struct sna *sna,
 	if (sna->flags & SNA_NO_WAIT)
 		sync = false;
 
-	DBG(("%s: emitting immediate blit, throttling client, synced? %d, chained? %d\n",
-	     __FUNCTION__, sync, chain != info));
+	DBG(("%s: emitting immediate blit, throttling client, synced? %d, chained? %d, pipe %d\n",
+	     __FUNCTION__, sync, chain != info, info->pipe));
 
 	info->type = SWAP_THROTTLE;
 	info->sync = sync;
@@ -2557,13 +2560,15 @@ static uint64_t
 get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc)
 {
 	union drm_wait_vblank vbl;
-	uint64_t ret = -1;
+	uint64_t ret;
 
 	VG_CLEAR(vbl);
 	vbl.request.type = _DRM_VBLANK_RELATIVE;
 	vbl.request.sequence = 0;
 	if (sna_wait_vblank(sna, &vbl, sna_crtc_to_pipe(crtc)) == 0)
 		ret = sna_crtc_record_vblank(crtc, &vbl);
+	else
+		ret = sna_crtc_last_swap(crtc)->msc;
 
 	return draw_current_msc(draw, crtc, ret);
 }
@@ -2703,7 +2708,7 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 				goto new_back;
 		}
 
-		info = sna_dri2_add_event(sna, draw, client);
+		info = sna_dri2_add_event(sna, draw, client, crtc);
 		if (info == NULL)
 			return false;
 
@@ -2761,7 +2766,7 @@ queue:
 		info->keepalive = 1;
 	}
 
-	info = sna_dri2_add_event(sna, draw, client);
+	info = sna_dri2_add_event(sna, draw, client, crtc);
 	if (info == NULL)
 		return false;
 
@@ -2823,7 +2828,7 @@ sna_dri2_schedule_xchg(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 	if (sync) {
 		struct sna_dri2_event *info;
 
-		info = sna_dri2_add_event(sna, draw, client);
+		info = sna_dri2_add_event(sna, draw, client, crtc);
 		if (!info)
 			goto complete;
 
@@ -2885,7 +2890,7 @@ sna_dri2_schedule_xchg_crtc(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc
 	if (sync) {
 		struct sna_dri2_event *info;
 
-		info = sna_dri2_add_event(sna, draw, client);
+		info = sna_dri2_add_event(sna, draw, client, crtc);
 		if (!info)
 			goto complete;
 
@@ -3067,7 +3072,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 
 	VG_CLEAR(vbl);
 
-	info = sna_dri2_add_event(sna, draw, client);
+	info = sna_dri2_add_event(sna, draw, client, crtc);
 	if (!info)
 		goto blit;
 
@@ -3218,7 +3223,7 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc
 	if (divisor == 0 && current_msc >= target_msc)
 		goto out_complete;
 
-	info = sna_dri2_add_event(sna, draw, client);
+	info = sna_dri2_add_event(sna, draw, client, crtc);
 	if (!info)
 		goto out_complete;
 
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 1992b9b..912bbe7 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -178,7 +178,7 @@ static bool sna_fake_vblank(struct sna_present_event *info)
 		delay = 0;
 
 	DBG(("%s(event=%lld, target_msc=%lld, msc=%lld, delay=%ums)\n",
-	     __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, msc, delay));
+	     __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc, delay));
 	if (delay == 0) {
 		const struct ust_msc *swap = sna_crtc_last_swap(info->crtc);
 		present_event_notify(info->event_id[0], swap_ust(swap), swap->msc);
@@ -197,7 +197,10 @@ sna_present_get_crtc(WindowPtr window)
 	BoxRec box;
 	xf86CrtcPtr crtc;
 
-	DBG(("%s\n", __FUNCTION__));
+	DBG(("%s: window=%ld (pixmap=%ld), box=(%d, %d)x(%d, %d)\n",
+	     __FUNCTION__, window->drawable.id, get_window_pixmap(window)->drawable.serialNumber,
+	     window->drawable.x, window->drawable.y,
+	     window->drawable.width, window->drawable.height));
 
 	box.x1 = window->drawable.x;
 	box.y1 = window->drawable.y;
@@ -440,9 +443,9 @@ flip__async(struct sna *sna,
 		return FALSE;
 	}
 
-	DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
+	DBG(("%s: pipe=%d tv=%ld.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__,
 	     pipe_from_crtc(crtc),
-	     gettime_ust64() / 1000000, gettime_ust64() % 1000000,
+	     (long)(gettime_ust64() / 1000000), (int)(gettime_ust64() % 1000000),
 	     crtc ? (long long)sna_crtc_last_swap(crtc->devPrivate)->msc : 0LL,
 	     (long long)target_msc, (long long)event_id));
 	present_event_notify(event_id, gettime_ust64(), target_msc);
@@ -474,7 +477,7 @@ present_flip_handler(struct drm_event_vblank *event, void *data)
 	present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc);
 
 	if (info->sna->present.unflip) {
-		DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, info->sna->present.unflip));
+		DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip));
 		sna_present_unflip(xf86ScrnToScreen(info->sna->scrn),
 				   info->sna->present.unflip);
 		info->sna->present.unflip = 0;
commit 0814dc41c3fa23c1d6d20f5696a9fb87671ae0c7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 2 15:13:43 2015 +0100

    test/present-speed: Include a measure for fence signalling overhead
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/test/present-speed.c b/test/present-speed.c
index 1d3411b..60add81 100644
--- a/test/present-speed.c
+++ b/test/present-speed.c
@@ -37,6 +37,7 @@
 #include <X11/extensions/Xrandr.h>
 #include <xcb/xcb.h>
 #include <xcb/present.h>
+#include <xcb/dri3.h>
 #include <xf86drm.h>
 #include <i915_drm.h>
 
@@ -49,6 +50,8 @@
 #include <setjmp.h>
 #include <signal.h>
 
+#include "dri3.h"
+
 static int _x_error_occurred;
 static uint32_t stamp;
 
@@ -86,12 +89,13 @@ static double elapsed(const struct timespec *start,
 	return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000;
 }
 
-static void run(Display *dpy, Window win, const char *name)
+static void run(Display *dpy, Window win, const char *name, int use_dri3)
 {
 	xcb_connection_t *c = XGetXCBConnection(dpy);
 	struct timespec start, end;
 	Pixmap pixmap[4];
 	int busy[4];
+	struct dri3_fence fence[4];
 	Window root;
 	unsigned int width, height;
 	unsigned border, depth;
@@ -106,6 +110,12 @@ static void run(Display *dpy, Window win, const char *name)
 
 	for (n = 0; n < 4; n++) {
 		pixmap[n] = XCreatePixmap(dpy, win, width, height, depth);
+		if (use_dri3) {
+			if (dri3_create_fence(dpy, win, &fence[n]))
+				return;
+			/* start idle */
+			xshmfence_trigger(fence[n].addr);
+		}
 		busy[n] = 0;
 	}
 
@@ -143,35 +153,43 @@ static void run(Display *dpy, Window win, const char *name)
 
 			back = j;
 			busy[back] = 1;
-
-			xcb_present_pixmap(c, win, p, back++,
+			if (use_dri3) {
+				xshmfence_await(fence[back].addr);
+				xshmfence_reset(fence[back].addr);
+			}
+			xcb_present_pixmap(c, win, p, back,
 					   0, /* valid */
 					   0, /* update */
 					   0, /* x_off */
 					   0, /* y_off */
 					   None,
 					   None, /* wait fence */
-					   None,
+					   use_dri3 ? fence[back].xid : None,
 					   XCB_PRESENT_OPTION_ASYNC,
 					   0, /* target msc */
 					   0, /* divisor */
 					   0, /* remainder */
 					   0, NULL);
 			xcb_flush(c);
+			back++;
 		}
 		clock_gettime(CLOCK_MONOTONIC, &end);
 	} while (end.tv_sec < start.tv_sec + 10);
 
-	for (n = 0; n < 4; n++)
+	for (n = 0; n < 4; n++) {
+		if (use_dri3)
+			dri3_fence_free(dpy, &fence[n]);
 		XFreePixmap(dpy, pixmap[n]);
+	}
 
 	XSync(dpy, True);
 	teardown_msc(dpy, Q);
 	if (_x_error_occurred)
 		abort();
 
-	printf("%s: Completed %d presents in %.1fs, %.3fus each (%.1f FPS)\n",
-	       name, completed, elapsed(&start, &end) / 1000000,
+	printf("%s%s: Completed %d presents in %.1fs, %.3fus each (%.1f FPS)\n",
+	       name, use_dri3 ? " (dri3)" : "",
+	       completed, elapsed(&start, &end) / 1000000,
 	       elapsed(&start, &end) / completed,
 	       completed / (elapsed(&start, &end) / 1000000));
 }
@@ -198,6 +216,45 @@ static int has_present(Display *dpy)
 	return 1;
 }
 
+static int dri3_query_version(Display *dpy, int *major, int *minor)
+{
+	xcb_connection_t *c = XGetXCBConnection(dpy);
+	xcb_dri3_query_version_reply_t *reply;
+	xcb_generic_error_t *error;
+
+	*major = *minor = -1;
+
+	reply = xcb_dri3_query_version_reply(c,
+					     xcb_dri3_query_version(c,
+								    XCB_DRI3_MAJOR_VERSION,
+								    XCB_DRI3_MINOR_VERSION),
+					     &error);
+	free(error);
+	if (reply == NULL)
+		return -1;
+
+	*major = reply->major_version;
+	*minor = reply->minor_version;
+	free(reply);
+
+	return 0;
+}
+
+static int has_dri3(Display *dpy)
+{
+	const xcb_query_extension_reply_t *ext;
+	int major, minor;
+
+	ext = xcb_get_extension_data(XGetXCBConnection(dpy), &xcb_dri3_id);
+	if (ext == NULL || !ext->present)
+		return 0;
+
+	if (dri3_query_version(dpy, &major, &minor) < 0)
+		return 0;
+
+	return major >= 0;
+}
+
 static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window)
 {
 	XRRScreenResources *res;
@@ -230,48 +287,16 @@ static void fullscreen(Display *dpy, Window win)
 			(unsigned char *)&atom, 1);
 }
 
-int main(void)
+static void loop(Display *dpy, XRRScreenResources *res, int use_dri3)
 {
-	Display *dpy;
-	Window root, win;
-	XRRScreenResources *res;
-	XRRCrtcInfo **original_crtc;
+	Window root = DefaultRootWindow(dpy);
+	Window win;
 	XSetWindowAttributes attr;
 	int i, j;
 
 	attr.override_redirect = 1;
 
-	dpy = XOpenDisplay(NULL);
-	if (dpy == NULL)
-		return 77;
-
-	if (!has_present(dpy))
-		return 77;
-
-	if (DPMSQueryExtension(dpy, &i, &i))
-		DPMSDisable(dpy);
-
-	root = DefaultRootWindow(dpy);
-
-	signal(SIGALRM, SIG_IGN);
-	XSetErrorHandler(_check_error_handler);
-
-	res = NULL;
-	if (XRRQueryVersion(dpy, &i, &i))
-		res = _XRRGetScreenResourcesCurrent(dpy, root);
-	if (res == NULL)
-		return 77;
-
-	original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc);
-	for (i = 0; i < res->ncrtc; i++)
-		original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]);
-
-	printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc);
-	for (i = 0; i < res->ncrtc; i++)
-		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
-				 0, 0, None, RR_Rotate_0, NULL, 0);
-
-	run(dpy, root, "off");
+	run(dpy, root, "off", use_dri3);
 
 	for (i = 0; i < res->noutput; i++) {
 		XRROutputInfo *output;
@@ -296,7 +321,7 @@ int main(void)
 			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
 					 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1);
 
-			run(dpy, root, "root");
+			run(dpy, root, "root", use_dri3);
 
 			win = XCreateWindow(dpy, root,
 					    0, 0, mode->width, mode->height, 0,
@@ -306,7 +331,7 @@ int main(void)
 					    CWOverrideRedirect, &attr);
 			fullscreen(dpy, win);
 			XMapWindow(dpy, win);
-			run(dpy, win, "fullscreen");
+			run(dpy, win, "fullscreen", use_dri3);
 			XDestroyWindow(dpy, win);
 
 			win = XCreateWindow(dpy, root,
@@ -316,7 +341,7 @@ int main(void)
 					    DefaultVisual(dpy, DefaultScreen(dpy)),
 					    CWOverrideRedirect, &attr);
 			XMapWindow(dpy, win);
-			run(dpy, win, "windowed");
+			run(dpy, win, "windowed", use_dri3);
 			XDestroyWindow(dpy, win);
 
 			win = XCreateWindow(dpy, root,
@@ -326,7 +351,7 @@ int main(void)
 					    DefaultVisual(dpy, DefaultScreen(dpy)),
 					    CWOverrideRedirect, &attr);
 			XMapWindow(dpy, win);
-			run(dpy, win, "half");
+			run(dpy, win, "half", use_dri3);
 			XDestroyWindow(dpy, win);
 
 			XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime,
@@ -335,6 +360,46 @@ int main(void)
 
 		XRRFreeOutputInfo(output);
 	}
+}
+
+int main(void)
+{
+	Display *dpy;
+	XRRScreenResources *res;
+	XRRCrtcInfo **original_crtc;
+	int i;
+
+	dpy = XOpenDisplay(NULL);
+	if (dpy == NULL)
+		return 77;
+
+	if (!has_present(dpy))
+		return 77;
+
+	if (DPMSQueryExtension(dpy, &i, &i))
+		DPMSDisable(dpy);
+
+	signal(SIGALRM, SIG_IGN);
+	XSetErrorHandler(_check_error_handler);
+
+	res = NULL;
+	if (XRRQueryVersion(dpy, &i, &i))
+		res = _XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy));
+	if (res == NULL)
+		return 77;
+
+	original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]);
+
+	printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc);
+	for (i = 0; i < res->ncrtc; i++)
+		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
+				 0, 0, None, RR_Rotate_0, NULL, 0);
+
+	loop(dpy, res, 0);
+	if (has_dri3(dpy))
+		loop(dpy, res, 1);
 
 	for (i = 0; i < res->ncrtc; i++)
 		XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,


More information about the xorg-commit mailing list