[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-nouveau: Changes to 'debian-unstable'



 .gitignore             |    1 
 autogen.sh             |    4 
 configure.ac           |   26 ++
 debian/changelog       |    7 
 debian/control         |    2 
 man/nouveau.man        |   33 ++-
 src/Makefile.am        |   12 +
 src/drmmode_display.c  |  389 +++++++++++++++++++++------------------
 src/nouveau_copy.c     |  129 +++++++++++++
 src/nouveau_copy.h     |   18 +
 src/nouveau_copy85b5.c |  104 ++++++++++
 src/nouveau_copy90b5.c |  100 ++++++++++
 src/nouveau_copya0b5.c |   97 +++++++++
 src/nouveau_dri2.c     |  482 ++++++++++++++++++++++++++++++++++---------------
 src/nouveau_exa.c      |   54 +++--
 src/nouveau_glamor.c   |  246 +++++++++++++++++++++++++
 src/nouveau_glamor.h   |   33 +++
 src/nouveau_present.c  |  328 +++++++++++++++++++++++++++++++++
 src/nouveau_present.h  |   19 +
 src/nouveau_sync.c     |  117 +++++++++++
 src/nouveau_sync.h     |   34 +++
 src/nouveau_wfb.c      |   12 +
 src/nouveau_xv.c       |  115 ++++++++++-
 src/nv04_exa.c         |    2 
 src/nv10_exa.c         |   14 -
 src/nv50_accel.c       |   38 ---
 src/nv50_exa.c         |   59 -----
 src/nv50_xv.c          |    2 
 src/nv_accel_common.c  |  155 ++++++++++-----
 src/nv_const.h         |    2 
 src/nv_dma.c           |  139 --------------
 src/nv_driver.c        |  265 ++++++++++++++++++--------
 src/nv_proto.h         |   32 +--
 src/nv_type.h          |   36 +++
 src/nvc0_accel.c       |   42 +---
 src/nvc0_accel.h       |    2 
 src/nvc0_exa.c         |  112 -----------
 37 files changed, 2360 insertions(+), 902 deletions(-)

New commits:
commit 8e5dd140952e420a4a2f17cf081a379bed70271e
Author: Sven Joachim <svenjoac@gmx.de>
Date:   Wed Sep 3 22:24:19 2014 +0200

    Bump Standards-Version to 3.9.5

diff --git a/debian/changelog b/debian/changelog
index 8cbe4c8..3ac886e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 xserver-xorg-video-nouveau (1:1.0.11-1) UNRELEASED; urgency=low
 
   * New upstream release (Closes: #760265).
+  * Bump Standards-Version to 3.9.5, no changes needed.
 
  -- Sven Joachim <svenjoac@gmx.de>  Wed, 03 Sep 2014 22:16:53 +0200
 
diff --git a/debian/control b/debian/control
index 6fe2823..3f6ee6b 100644
--- a/debian/control
+++ b/debian/control
@@ -23,7 +23,7 @@ Build-Depends:
  libtool,
  xutils-dev,
  quilt,
-Standards-Version: 3.9.4
+Standards-Version: 3.9.5
 Homepage: http://nouveau.freedesktop.org/wiki/
 Vcs-Git: git://anonscm.debian.org/pkg-xorg/driver/xserver-xorg-video-nouveau
 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-xorg/driver/xserver-xorg-video-nouveau.git

commit f69a907685a0ca0744465bd3bc3b95835c9073ee
Author: Sven Joachim <svenjoac@gmx.de>
Date:   Wed Sep 3 22:18:19 2014 +0200

    New upstream release

diff --git a/debian/changelog b/debian/changelog
index 11a3a4d..8cbe4c8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xserver-xorg-video-nouveau (1:1.0.11-1) UNRELEASED; urgency=low
+
+  * New upstream release (Closes: #760265).
+
+ -- Sven Joachim <svenjoac@gmx.de>  Wed, 03 Sep 2014 22:16:53 +0200
+
 xserver-xorg-video-nouveau (1:1.0.10-1) unstable; urgency=low
 
   * New upstream release.

commit 3cd4c8494c296c7583dfa7f0823a272c9e932e03
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Thu Aug 28 03:57:48 2014 +0200

    Bump version to 1.0.11 for release.
    
    Highlights:
    
    - Support for server managed fd's.
    - Glamor support.
    - Maxwell support.
    - DRI3 and initial Present support.
    - vsync'ed kms pageflip performance fixes when running on Linux 3.13+
    - Multi-display vsync, vblank, swap scheduling, timestamping fixes.
    - Multi x-screen support fixes.
    - ZaphodHead support on for multiple outputs per x-screen.
    - EXA nv-10 fixes.
    - Enable sync of swaps to vblank by default (Option GLXVblank "on").
    - Disable pseudo-triplebuffering by default (Option SwapLimit "1").
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/configure.ac b/configure.ac
index dbaf623..ccf320a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-nouveau],
-        [1.0.10],
+        [1.0.11],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-nouveau])
 

commit 6d49f3f7aaaec872b6f9841f744a0bf09cc98492
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Thu Aug 28 03:49:55 2014 +0200

    dri2: Set default SwapLimit to 1 for double-buffering.
    
    This used to be 2 for pseudo-triplebuffering on XOrg 1.12+.
    
    However, it caused problems like unthrottled swapping
    at up to twice the video refresh rate for redirected
    windows under desktop composition, which can't be easily
    fixed under dri2.
    
    Default to double-buffering. Users can override this, but
    dri3 provides better solutions for this.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/man/nouveau.man b/man/nouveau.man
index 0bf6e1e..129bb7f 100644
--- a/man/nouveau.man
+++ b/man/nouveau.man
@@ -124,7 +124,7 @@ OpenML OML_sync_control specification and will cause failure of software
 that relies on correct presentation timing behaviour as defined in that
 specification.
 .br
-Default: 2 for XOrg 1.12+, 1 for older servers.
+Default: 1.
 .SH "SEE ALSO"
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
 .SH AUTHORS
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 6045095..4bad985 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1138,10 +1138,10 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
 			reason = ": Caution: Use of this swap limit > 1 violates OML_sync_control spec on this X-Server!\n";
 		}
 	} else {
-		/* Driver default: Double buffering on old servers, triple-buffering
-		 * on Xorg 1.12+.
+		/* Always default to double-buffering, because it avoids artifacts like
+		 * unthrottled rendering of non-fullscreen clients under desktop composition.
 		 */
-		pNv->swap_limit = (DRI2INFOREC_VERSION < 6) ? 1 : 2;
+		pNv->swap_limit = 1;
 		reason = "";
 		from = X_DEFAULT;
 	}

commit 10729a442be3cf018c5806c95ec4218977917ef3
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Mon Aug 18 09:53:27 2014 +0200

    xv/dri2/dri3: Switch to optimized crtc selection for drawables.
    
    Make crtc selection consistent with ati and intel ddx.
    
    Pick the crtc to use for vblank events, swap scheduling and
    kms-pageflip completion events as the one with maximum pixel area
    intersection between its viewport and the drawable. If multiple
    crtc's viewports display the same amount of area of a drawable,
    select the crtc whose output is the designated "primary output"
    for the x-screen. The latter allows, e.g., in a clone display
    setup, to select the important output on which tearing should be
    minimized. The former makes sure to minimize or avoid tearing on
    the display which shows the largest part of the drawable.
    
    This method is transplanted from the ati ddx.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index cc16cb1..3361869 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -434,7 +434,7 @@ nouveau_dri2_flip_handler(void *priv, uint64_t name, uint64_t ust, uint32_t msc)
 
 static Bool
 dri2_page_flip(DrawablePtr draw, PixmapPtr back, void *priv,
-		  unsigned int ref_crtc_hw_id)
+			   xf86CrtcPtr ref_crtc)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -489,7 +489,7 @@ dri2_page_flip(DrawablePtr draw, PixmapPtr back, void *priv,
 		/* Only the reference crtc will finally deliver its page flip
 		 * completion event. All other crtc's events will be discarded.
 		 */
-		flipcarrier->dispatch_me = ((1 << i) == ref_crtc_hw_id);
+		flipcarrier->dispatch_me = (config->crtc[i] == ref_crtc);
 		flipcarrier->flipdata = flipdata;
 
 		ret = drmModePageFlip(pNv->dev->fd, head, next_fb,
@@ -565,20 +565,19 @@ nouveau_wait_vblank(DrawablePtr draw, int type, CARD64 msc,
 		    CARD64 *pmsc, CARD64 *pust, void *data)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
 	NVPtr pNv = NVPTR(scrn);
-	int crtcs = nv_window_belongs_to_crtc(scrn, draw->x, draw->y,
-					      draw->width, draw->height);
+	xf86CrtcPtr crtc;
 	drmVBlank vbl;
 	struct dri2_vblank *event = NULL;
 	void *token = NULL;
 	int ret;
 	int head;
 
-	/* Select crtc with smallest index from bitmask of crtcs */
-	crtcs = ffs(crtcs) - 1;
+	/* Select crtc which shows the largest part of the drawable */
+	crtc = nouveau_pick_best_crtc(scrn, FALSE,
+                                  draw->x, draw->y, draw->width, draw->height);
 
-	if (crtcs < 0) {
+	if (!crtc) {
 		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
 				   "Wait for VBlank failed: No valid crtc for drawable.\n");
 		return -EINVAL;
@@ -596,7 +595,7 @@ nouveau_wait_vblank(DrawablePtr draw, int type, CARD64 msc,
 	}
 
 	/* Map xf86CrtcPtr to drmWaitVBlank compatible display head index. */
-	head = drmmode_head(config->crtc[crtcs]);
+	head = drmmode_head(crtc);
 
 	if (head == 1)
 		type |= DRM_VBLANK_SECONDARY;
@@ -647,21 +646,14 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 	RegionRec reg;
 	int type, ret;
 	Bool front_updated, will_exchange;
+	xf86CrtcPtr ref_crtc;
 
 	REGION_INIT(0, &reg, (&(BoxRec){ 0, 0, draw->width, draw->height }), 0);
 	REGION_TRANSLATE(0, &reg, draw->x, draw->y);
 
 	/* Main crtc for this drawable shall finally deliver pageflip event. */
-	unsigned int ref_crtc_hw_id = nv_window_belongs_to_crtc(scrn, draw->x,
-								draw->y,
-								draw->width,
-								draw->height);
-
-	/* Choose crtc with smallest index as reference, as its
-	 * vblank event triggered this swap. ref_crtc_hw_id is
-	 * a bit field (crtc 0 = bit 0, crtc 1 = bit 1 ...)
-	 */
-	ref_crtc_hw_id = 1 << (ffs(ref_crtc_hw_id) - 1);
+	ref_crtc = nouveau_pick_best_crtc(scrn, FALSE, draw->x, draw->y,
+                                      draw->width, draw->height);
 
 	/* Update frontbuffer pixmap and name: Could have changed due to
 	 * window (un)redirection as part of compositing.
@@ -711,7 +703,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,
 		if (nouveau_exa_pixmap_is_onscreen(dst_pix)) {
 			type = DRI2_FLIP_COMPLETE;
 			ret = dri2_page_flip(draw, src_pix, violate_oml(draw) ?
-					     NULL : s, ref_crtc_hw_id);
+					     NULL : s, ref_crtc);
 			if (!ret)
 				goto out;
 		}
diff --git a/src/nouveau_present.c b/src/nouveau_present.c
index f4cdcc8..ea1686e 100644
--- a/src/nouveau_present.c
+++ b/src/nouveau_present.c
@@ -36,21 +36,17 @@ static RRCrtcPtr
 nouveau_present_crtc(WindowPtr window)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 	xf86CrtcPtr crtc;
-	unsigned mask;
-	int head;
 
-	mask = nv_window_belongs_to_crtc(scrn, window->drawable.x,
-					       window->drawable.y,
-					       window->drawable.width,
-					       window->drawable.height);
+	crtc = nouveau_pick_best_crtc(scrn, FALSE,
+                                  window->drawable.x,
+                                  window->drawable.y,
+                                  window->drawable.width,
+                                  window->drawable.height);
 
-	head = ffs(mask) - 1;
-	if (head < 0 || head >= xf86_config->num_crtc)
+	if (!crtc)
 		return NULL;
 
-	crtc = xf86_config->crtc[head];
 	if (crtc->rotatedData)
 		return NULL;
 
diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
index e40d6ba..a479d38 100644
--- a/src/nouveau_xv.c
+++ b/src/nouveau_xv.c
@@ -196,6 +196,100 @@ static XF86ImageRec NVImages[NUM_IMAGES_ALL] =
 	XVIMAGE_RGB
 };
 
+static void
+nouveau_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+nouveau_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+    if (crtc->enabled) {
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+    } else
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+nouveau_box_area(BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+xf86CrtcPtr
+nouveau_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
+                       int x, int y, int w, int h)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int                 coverage, best_coverage, c;
+    BoxRec              box, crtc_box, cover_box;
+    RROutputPtr         primary_output = NULL;
+    xf86CrtcPtr         best_crtc = NULL, primary_crtc = NULL;
+
+    if (!pScrn->vtSema)
+	return NULL;
+
+    box.x1 = x;
+    box.x2 = x + w;
+    box.y1 = y;
+    box.y2 = y + h;
+    best_coverage = 0;
+
+    /* Prefer the CRTC of the primary output */
+#ifdef HAS_DIXREGISTERPRIVATEKEY
+    if (dixPrivateKeyRegistered(rrPrivKey))
+#endif
+    {
+	primary_output = RRFirstOutput(pScrn->pScreen);
+    }
+    if (primary_output && primary_output->crtc)
+	primary_crtc = primary_output->crtc->devPrivate;
+
+    /* first consider only enabled CRTCs */
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (!crtc->enabled)
+	    continue;
+
+	nouveau_crtc_box(crtc, &crtc_box);
+	nouveau_box_intersect(&cover_box, &crtc_box, &box);
+	coverage = nouveau_box_area(&cover_box);
+	if (coverage > best_coverage ||
+	    (coverage == best_coverage && crtc == primary_crtc)) {
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    if (best_crtc || !consider_disabled)
+	return best_crtc;
+
+    /* if we found nothing, repeat the search including disabled CRTCs */
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	nouveau_crtc_box(crtc, &crtc_box);
+	nouveau_box_intersect(&cover_box, &crtc_box, &box);
+	coverage = nouveau_box_area(&cover_box);
+	if (coverage > best_coverage ||
+	    (coverage == best_coverage && crtc == primary_crtc)) {
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    return best_crtc;
+}
+
 unsigned int
 nv_window_belongs_to_crtc(ScrnInfoPtr pScrn, int x, int y, int w, int h)
 {
diff --git a/src/nv50_accel.c b/src/nv50_accel.c
index 3d489d0..b27f67a 100644
--- a/src/nv50_accel.c
+++ b/src/nv50_accel.c
@@ -31,25 +31,24 @@ void
 NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
-	int crtcs;
+	int head;
+	xf86CrtcPtr crtc;
 
 	if (!nouveau_exa_pixmap_is_onscreen(ppix))
 		return;
 
-	crtcs = nv_window_belongs_to_crtc(pScrn, box->x1, box->y1,
-					  box->x2 - box->x1,
-					  box->y2 - box->y1);
-	if (!crtcs)
+	crtc = nouveau_pick_best_crtc(pScrn, FALSE, box->x1, box->y1,
+                                  box->x2 - box->x1,
+                                  box->y2 - box->y1);
+	if (!crtc)
 		return;
 
 	if (!PUSH_SPACE(push, 10))
 		return;
 
-	crtcs = ffs(crtcs) - 1;
-	crtcs = drmmode_head(config->crtc[crtcs]);
+	head = drmmode_head(crtc);
 
 	BEGIN_NV04(push, SUBC_NVSW(0x0060), 2);
 	PUSH_DATA (push, pNv->vblank_sem->handle);
@@ -58,7 +57,7 @@ NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	PUSH_DATA (push, 0x22222222);
 	BEGIN_NV04(push, SUBC_NVSW(0x0404), 2);
 	PUSH_DATA (push, 0x11111111);
-	PUSH_DATA (push, crtcs);
+	PUSH_DATA (push, head);
 	BEGIN_NV04(push, SUBC_NVSW(0x0068), 1);
 	PUSH_DATA (push, 0x11111111);
 }
diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
index bd9dc8a..4484c1c 100644
--- a/src/nv_accel_common.c
+++ b/src/nv_accel_common.c
@@ -133,30 +133,29 @@ void
 NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
-	int crtcs;
+	int head;
+	xf86CrtcPtr crtc;
 
 	if (!nouveau_exa_pixmap_is_onscreen(ppix))
 		return;
 
-	crtcs = nv_window_belongs_to_crtc(pScrn, box->x1, box->y1,
-					  box->x2 - box->x1,
-					  box->y2 - box->y1);
-	if (!crtcs)
+	crtc = nouveau_pick_best_crtc(pScrn, FALSE, box->x1, box->y1,
+                                  box->x2 - box->x1,
+                                  box->y2 - box->y1);
+	if (!crtc)
 		return;
 
 	if (!PUSH_SPACE(push, 8))
 		return;
 
-	crtcs = ffs(crtcs) - 1;
-	crtcs = drmmode_head(config->crtc[crtcs]);
+	head = drmmode_head(crtc);
 
 	BEGIN_NV04(push, SUBC_BLIT(0x0000012C), 1);
 	PUSH_DATA (push, 0);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000134), 1);
-	PUSH_DATA (push, crtcs);
+	PUSH_DATA (push, head);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000100), 1);
 	PUSH_DATA (push, 0);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000130), 1);
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 27354e0..cc4fd09 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -43,6 +43,8 @@ void NVTakedownVideo(ScrnInfoPtr);
 void NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv);
 void NVXVComputeBicubicFilter(struct nouveau_bo *, unsigned, unsigned);
 unsigned int nv_window_belongs_to_crtc(ScrnInfoPtr, int, int, int, int);
+xf86CrtcPtr nouveau_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
+                                   int x, int y, int w, int h);
 
 /* in nouveau_exa.c */
 Bool nouveau_exa_init(ScreenPtr pScreen);
diff --git a/src/nvc0_accel.c b/src/nvc0_accel.c
index 375ccc8..c04e270 100644
--- a/src/nvc0_accel.c
+++ b/src/nvc0_accel.c
@@ -63,25 +63,24 @@ void
 NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
-	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
-	int crtcs;
+	int head;
+	xf86CrtcPtr crtc;
 
 	if (!pNv->NvSW || !nouveau_exa_pixmap_is_onscreen(ppix))
 		return;
 
-	crtcs = nv_window_belongs_to_crtc(pScrn, box->x1, box->y1,
-					  box->x2 - box->x1,
-					  box->y2 - box->y1);
-	if (!crtcs)
+	crtc = nouveau_pick_best_crtc(pScrn, FALSE, box->x1, box->y1,
+                                  box->x2 - box->x1,
+                                  box->y2 - box->y1);
+	if (!crtc)
 		return;
 
 	if (!PUSH_SPACE(push, 32))
 		return;
 
-	crtcs = ffs(crtcs) - 1;
-	crtcs = drmmode_head(config->crtc[crtcs]);
+	head = drmmode_head(crtc);
 
 	BEGIN_NVC0(push, NV01_SUBC(NVSW, OBJECT), 1);
 	PUSH_DATA (push, pNv->NvSW->handle);
@@ -94,7 +93,7 @@ NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));
 	PUSH_DATA (push, 0x11111111);
-	PUSH_DATA (push, crtcs);
+	PUSH_DATA (push, head);
 	BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));

commit be96a5a62df5e1f286690311a6bc4df4f2a99e57
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Sun Aug 17 02:30:36 2014 +0200

    Add file "compile" to .gitignore
    
    Some auto-generated file by new make systems to deal with some
    old compilers.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/.gitignore b/.gitignore
index 186b1c8..2694d9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ missing
 stamp-h1
 ChangeLog
 INSTALL
+compile

commit 16c885ce9c7bebcfa1252a5d500956dd5f551043
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Tue Aug 12 11:08:24 2014 +0200

    Fix event handling on multi-x-screen configs.
    
    Only register the wakeup handler and event socket
    once per card fd and server generation, as the fd
    and device file is shared between all x-screens for
    a given card during a given server generation.
    
    Without this fix, vblank and kms-pageflip completion
    event processing don't work properly, as the server
    doesn't kick the wakeup handler for gpu events, and
    therefore the desktop will freeze, unless the user
    manually kicks the wakeup handler by moving the mouse
    or hitting the keyboard.
    
    Add proper reference counting and checks to make it so.
    This fix is derived from a similar and proven fix in
    the ati ddx for the same problem.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index dc15221..6d225cb 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1596,6 +1596,7 @@ drmmode_screen_init(ScreenPtr pScreen)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
 	drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+	NVEntPtr pNVEnt = NVEntPriv(scrn);
 
 	/* Setup handler for DRM events */
 	drmmode_event_init(scrn);
@@ -1603,10 +1604,17 @@ drmmode_screen_init(ScreenPtr pScreen)
 	/* Setup handler for udevevents */
 	drmmode_uevent_init(scrn);
 
-	/* Register a wakeup handler to get informed on DRM events */
-	AddGeneralSocket(drmmode->fd);
-	RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-				       drmmode_wakeup_handler, scrn);
+	/* Register wakeup handler only once per servergen, so ZaphodHeads work */
+	if (pNVEnt->fd_wakeup_registered != serverGeneration) {
+		/* Register a wakeup handler to get informed on DRM events */
+		AddGeneralSocket(drmmode->fd);
+		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+		                               drmmode_wakeup_handler, scrn);
+		pNVEnt->fd_wakeup_registered = serverGeneration;
+		pNVEnt->fd_wakeup_ref = 1;
+	}
+	else
+		pNVEnt->fd_wakeup_ref++;
 }
 
 void
@@ -1614,11 +1622,17 @@ drmmode_screen_fini(ScreenPtr pScreen)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
 	drmmode_ptr drmmode = drmmode_from_scrn(scrn);
+	NVEntPtr pNVEnt = NVEntPriv(scrn);
 
-	/* Unregister wakeup handler */
-	RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-				     drmmode_wakeup_handler, scrn);
-	RemoveGeneralSocket(drmmode->fd);
+	/* Unregister wakeup handler after last x-screen for this servergen dies. */
+	if (pNVEnt->fd_wakeup_registered == serverGeneration &&
+		!--pNVEnt->fd_wakeup_ref) {
+
+		/* Unregister wakeup handler */
+		RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+		                             drmmode_wakeup_handler, scrn);
+		RemoveGeneralSocket(drmmode->fd);
+	}
 
 	/* Tear down udev event handler */
 	drmmode_uevent_fini(scrn);
diff --git a/src/nv_type.h b/src/nv_type.h
index 3e7c234..c0517c6 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -34,6 +34,8 @@ typedef struct {
 	unsigned long reinitGeneration;
 	struct xf86_platform_device *platform_dev;
 	unsigned int assigned_crtcs;
+	unsigned long fd_wakeup_registered;
+	int fd_wakeup_ref;
 } NVEntRec, *NVEntPtr;
 
 NVEntPtr NVEntPriv(ScrnInfoPtr pScrn);

commit 7eab6806927ea8938b9bd143d1702e87fde2f2cc
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Wed Aug 13 06:48:10 2014 +0200

    Make new ZaphodHeads work across server regenerations.
    
    Reset the mask of already assigned crtc's at start
    of each new server generation.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nv_driver.c b/src/nv_driver.c
index a9524a0..6045095 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -276,6 +276,14 @@ NVInitScrn(ScrnInfoPtr pScrn, struct xf86_platform_device *platform_dev,
 		pPriv->ptr = xnfcalloc(sizeof(NVEntRec), 1);
 		pNVEnt = pPriv->ptr;
 		pNVEnt->platform_dev = platform_dev;
+	}
+	else
+		pNVEnt = pPriv->ptr;
+
+	/* Reset settings which must not persist across server regeneration */
+	if (pNVEnt->reinitGeneration != serverGeneration) {
+		pNVEnt->reinitGeneration = serverGeneration;
+		/* Clear mask of assigned crtc's in this generation to "none" */
 		pNVEnt->assigned_crtcs = 0;
 	}
 
diff --git a/src/nv_type.h b/src/nv_type.h
index 0f4b0bc..3e7c234 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -31,6 +31,7 @@ typedef struct _NVRec *NVPtr;
 
 typedef struct {
 	int fd;
+	unsigned long reinitGeneration;
 	struct xf86_platform_device *platform_dev;
 	unsigned int assigned_crtcs;
 } NVEntRec, *NVEntPtr;

commit 6ad053788e804f3a8bd36ee3653ec95e7df62623
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Wed Aug 6 07:37:32 2014 +0200

    dri2 and xv: Fix NVxxSyncToVBlank() for multi-x-screen's.
    
    Use helper function drmmode_head() to choose proper hw-crtc
    to sync to. Fixes xv blits, and dri2 Copy-Swaps.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nv50_accel.c b/src/nv50_accel.c
index 16ff643..3d489d0 100644
--- a/src/nv50_accel.c
+++ b/src/nv50_accel.c
@@ -31,6 +31,7 @@ void
 NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
 	int crtcs;
@@ -47,6 +48,9 @@ NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	if (!PUSH_SPACE(push, 10))
 		return;
 
+	crtcs = ffs(crtcs) - 1;
+	crtcs = drmmode_head(config->crtc[crtcs]);
+
 	BEGIN_NV04(push, SUBC_NVSW(0x0060), 2);
 	PUSH_DATA (push, pNv->vblank_sem->handle);
 	PUSH_DATA (push, 0);
@@ -54,7 +58,7 @@ NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	PUSH_DATA (push, 0x22222222);
 	BEGIN_NV04(push, SUBC_NVSW(0x0404), 2);
 	PUSH_DATA (push, 0x11111111);
-	PUSH_DATA (push, ffs(crtcs) - 1);
+	PUSH_DATA (push, crtcs);
 	BEGIN_NV04(push, SUBC_NVSW(0x0068), 1);
 	PUSH_DATA (push, 0x11111111);
 }
diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
index 579d20d..bd9dc8a 100644
--- a/src/nv_accel_common.c
+++ b/src/nv_accel_common.c
@@ -133,6 +133,7 @@ void
 NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
 	int crtcs;
@@ -149,10 +150,13 @@ NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	if (!PUSH_SPACE(push, 8))
 		return;
 
+	crtcs = ffs(crtcs) - 1;
+	crtcs = drmmode_head(config->crtc[crtcs]);
+
 	BEGIN_NV04(push, SUBC_BLIT(0x0000012C), 1);
 	PUSH_DATA (push, 0);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000134), 1);
-	PUSH_DATA (push, ffs(crtcs) - 1);
+	PUSH_DATA (push, crtcs);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000100), 1);
 	PUSH_DATA (push, 0);
 	BEGIN_NV04(push, SUBC_BLIT(0x00000130), 1);
diff --git a/src/nvc0_accel.c b/src/nvc0_accel.c
index f76cbfa..375ccc8 100644
--- a/src/nvc0_accel.c
+++ b/src/nvc0_accel.c
@@ -63,6 +63,7 @@ void
 NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 {
 	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
 	NVPtr pNv = NVPTR(pScrn);
 	struct nouveau_pushbuf *push = pNv->pushbuf;
 	int crtcs;
@@ -79,6 +80,9 @@ NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	if (!PUSH_SPACE(push, 32))
 		return;
 
+	crtcs = ffs(crtcs) - 1;
+	crtcs = drmmode_head(config->crtc[crtcs]);
+
 	BEGIN_NVC0(push, NV01_SUBC(NVSW, OBJECT), 1);
 	PUSH_DATA (push, pNv->NvSW->handle);
 	BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4);
@@ -90,7 +94,7 @@ NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));
 	PUSH_DATA (push, 0x11111111);
-	PUSH_DATA (push, ffs(crtcs) - 1);
+	PUSH_DATA (push, crtcs);
 	BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
 	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));

commit 17de663a71bcad6f69414eb6bc6bf9b76a6bf5f4
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Mon Aug 11 09:48:42 2014 +1000

    fix glamor header check
    
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/configure.ac b/configure.ac
index 2177c24..dbaf623 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,14 +140,10 @@ if test "x$have_list_h" = xyes; then
                    #include "list.h"])
 fi
 
+AC_CHECK_HEADERS([glamor.h],[found_glamor_header=yes],[found_glamor_header=no],
+		 [#include "xorg-server.h"])
 AC_MSG_CHECKING([whether to include GLAMOR support])
-
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
-[[
-  #include <glamor.h>
-]],[[]]),[found_glamor_header=yes],[found_glamor_header=no])
-
-if test "$found_glamor_header" = "yes" && pkg-config --exists "xorg-server >= 1.15.99.901"
+if test "x$found_glamor_header" = xyes && pkg-config --exists "xorg-server >= 1.15.99.901"
 then
 	AC_DEFINE(HAVE_GLAMOR, 1, [Build support for glamor acceleration])
 	AC_MSG_RESULT([yes])

commit 64ca88570b71289a019a2d130b1a30dc474ef52d
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Mon Aug 11 08:59:30 2014 +1000

    present: use drmmode_head() where it's appropriate
    
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/nouveau_present.c b/src/nouveau_present.c
index 05cd518..f4cdcc8 100644
--- a/src/nouveau_present.c
+++ b/src/nouveau_present.c
@@ -61,21 +61,12 @@ static int
 nouveau_present_ust_msc(RRCrtcPtr rrcrtc, uint64_t *ust, uint64_t *msc)
 {
 	xf86CrtcPtr crtc = rrcrtc->devPrivate;
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	NVPtr pNv = NVPTR(crtc->scrn);
 	drmVBlank args;
-	int ret, i;
-
-	for (i = 0; i < xf86_config->num_crtc; i++) {
-		if (xf86_config->crtc[i] == crtc)
-			break;
-	}
-
-	if (i == xf86_config->num_crtc)
-		return BadMatch;
+	int ret;
 
 	args.request.type = DRM_VBLANK_RELATIVE;
-	args.request.type |= i << DRM_VBLANK_HIGH_CRTC_SHIFT;
+	args.request.type |= drmmode_head(crtc) << DRM_VBLANK_HIGH_CRTC_SHIFT;
 	args.request.sequence = 0,
 	args.request.signal = 0,
 
@@ -111,20 +102,11 @@ static int
 nouveau_present_vblank_queue(RRCrtcPtr rrcrtc, uint64_t event_id, uint64_t msc)
 {
 	xf86CrtcPtr crtc = rrcrtc->devPrivate;
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	NVPtr pNv = NVPTR(crtc->scrn);
 	drmVBlank args;
 	struct nouveau_present_vblank *event;
 	void *token;
-	int ret, i;
-
-	for (i = 0; i < xf86_config->num_crtc; i++) {
-		if (xf86_config->crtc[i] == crtc)
-			break;
-	}
-
-	if (i == xf86_config->num_crtc)
-		return BadMatch;
+	int ret;
 
 	event = drmmode_event_queue(crtc->scrn, event_id, sizeof(*event),
 				    nouveau_present_vblank, &token);
@@ -134,7 +116,7 @@ nouveau_present_vblank_queue(RRCrtcPtr rrcrtc, uint64_t event_id, uint64_t msc)
 	event->msc = msc;
 
 	args.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-	args.request.type |= i << DRM_VBLANK_HIGH_CRTC_SHIFT;
+	args.request.type |= drmmode_head(crtc) << DRM_VBLANK_HIGH_CRTC_SHIFT;
 	args.request.sequence = msc;
 	args.request.signal = (unsigned long)token;
 

commit 6e71bdf5a9da15c60694fa8543243e37a32c5faf
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date:   Mon Jun 23 11:25:41 2014 +0200

    Allow/Fix use of multiple ZaphodHead outputs per x-screen.
    
    Defining multiple ZaphodHead outputs per x-screen in a
    multiple x-screen's per gpu configuration caused all
    outputs except one per x-screen to go dark, because
    there was a fixed mapping x-screen number -> crtc number,
    limiting the number of crtc's per x-screen to one.
    
    On a ZaphodHead's setup, be more clever and assign
    as many crtc's to a given x-screen as there are
    ZaphodHeads defined for that screen, assuming
    there are enough unused crtc's available.
    
    Tested on a triple display setup with different combos
    of one, two or three ZaphodHeads per one, two or three
    x-screens.
    
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 501440a..dc15221 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -746,17 +746,18 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 };
 
 
-static void
+static unsigned int
 drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 {
 	NVPtr pNv = NVPTR(pScrn);
+	NVEntPtr pNVEnt = NVEntPriv(pScrn);
 	xf86CrtcPtr crtc;
 	drmmode_crtc_private_ptr drmmode_crtc;
 	int ret;
 
 	crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
 	if (crtc == NULL)
-		return;
+		return 0;
 
 	drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
 	drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd,
@@ -770,7 +771,12 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 
 	crtc->driver_private = drmmode_crtc;
 
-	return;
+	/* Mark num'th crtc as in use on this device. */
+	pNVEnt->assigned_crtcs |= (1 << num);
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,


Reply to: