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

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



 debian/changelog   |   10 ++++++++++
 src/nouveau_dri2.c |   51 ++++++++++++++++++++++++++++++++++++++-------------
 src/nv40_exa.c     |    6 +++---
 src/nv50_exa.c     |    6 +++---
 src/nv_shadow.c    |    7 +++----
 src/nvc0_exa.c     |    6 +++---
 6 files changed, 60 insertions(+), 26 deletions(-)

New commits:
commit 095415b8cdbc9fb80c4be28a0873c38715d2e76d
Author: Sven Joachim <svenjoac@gmx.de>
Date:   Wed Nov 7 19:02:10 2012 +0100

    Document the cherry-picks

diff --git a/debian/changelog b/debian/changelog
index 0c1344e..1d196e0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+xserver-xorg-video-nouveau (1:1.0.1-4) UNRELEASED; urgency=low
+
+  * Cherry-pick some bugfixes from upstream:
+    - exa: use CLAMP_TO_EDGE for RepeatPad.
+    - shadowfb: fix segfault due to reading outside of shadow buffer.
+    - dri2: Fix potential race and crash for swap at next vblank.
+      (Closes: #686474)
+
+ -- Sven Joachim <svenjoac@gmx.de>  Wed, 07 Nov 2012 19:01:51 +0100
+
 xserver-xorg-video-nouveau (1:1.0.1-3) unstable; urgency=low
 
   * Update NEWS.Debian, Debian kernels from 3.2.23-1 onward are

commit 97b056bdf96b933f54b45fb8a97e6853edbe1097
Author: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Date:   Tue Oct 9 09:06:59 2012 +0200

    dri2: Fix potential race and crash for swap at next vblank.
    
    This fixes a potential race + crash that wasn't properly
    handled by commit 248de8cdbd6d0bc062633b49896fa4791148cd3b
    and happened at least on one users machine.
    
    That commit wrongly assumed no special action would be needed
    for swaps at next vblank while triple-buffering is enabled on
    XOrg server 1.12 or later.
    
    Closer inspection of the x-server main dispatch loop shows
    it is possible that the client manages to get the server
    to dispatch a new DRI2GetBuffersWithFormat() call before
    the server calls the vblank event handler and executes
    the nouveau_dri2_finish_swap() routine. Such a race would
    cause a crash, as described in above commit.
    
    This commit handles the "swap at next vblank" case by
    calling nouveau_dri2_finish_swap() immediately without
    the roundtrip (queue vblank_event -> kernel -> deliver event
    -> x-server processes event -> nouveau vblank event handler),
    before control gets returned to the client.
    
    This avoids the race while retaining triple-buffering. As
    a bonus, time-critical swaps at next vblank get processed
    without roundtrip delay, increasing the chance of not
    skipping a frame due to vblank miss while sync to vblank is
    on.
    
    Thanks to Anssi for reporting this problem on the nouveau
    mailing list at 12th July 2012 and for testing this patch.
    
    Reported-by: Anssi Hannula <anssi.hannula@iki.fi>
    Tested-by: Anssi Hannula <anssi.hannula@iki.fi>
    Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    (cherry picked from commit b4231dd715a8a7f86b04519b5f4e8a8d93c2f561)

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index 0b3cc38..44fa255 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -412,6 +412,7 @@ nouveau_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 {
 	struct nouveau_dri2_vblank_state *s;
 	CARD64 current_msc, expect_msc;
+	CARD64 current_ust;
 	int ret;
 
 	/* Initialize a swap structure */
@@ -423,9 +424,9 @@ nouveau_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 		{ SWAP, client, draw->id, dst, src, func, data, 0 };
 
 	if (can_sync_to_vblank(draw)) {
-		/* Get current sequence */
+		/* Get current sequence and vblank time*/
 		ret = nouveau_wait_vblank(draw, DRM_VBLANK_RELATIVE, 0,
-					  &current_msc, NULL, NULL);
+					  &current_msc, &current_ust, NULL);
 		if (ret)
 			goto fail;
 
@@ -445,24 +446,48 @@ nouveau_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
 		if (*target_msc == 0)
 			*target_msc = 1;
 
+		/* Swap at next possible vblank requested? */
+		if (current_msc >= *target_msc - 1) {
+			/* Special case: Need to swap at next vblank.
+			 * Schedule swap immediately, bypassing the kernel
+			 * vblank event mechanism to avoid a dangerous race
+			 * between the client and the x-server vblank event
+			 * dispatch in the main x-server dispatch loop when
+			 * the swap_limit is set to 2 for triple-buffering.
+			 *
+			 * This also optimizes for the common case of swap
+			 * at next vblank, avoiding vblank dispatch delay.
+			 */
+			s->frame = 1 + ((unsigned int) current_msc & 0xffffffff);
+			*target_msc = 1 + current_msc;
+			nouveau_dri2_finish_swap(draw, current_msc,
+						 (unsigned int) (current_ust / 1000000),
+						 (unsigned int) (current_ust % 1000000),
+						 s);
+			return TRUE;
+		}
+
+		/* This is a swap in the future, ie. the vblank event will
+		 * only get dispatched at least 2 vblanks into the future.
+		 */
+
 #if DRI2INFOREC_VERSION >= 6
-		/* Is this a swap in the future, ie. the vblank event will
-		 * not be immediately dispatched, but only at a future vblank?
-		 * If so, we need to temporarily lower the swaplimit to 1, so
-		 * that DRI2GetBuffersWithFormat() requests from the client get
+		/* On XOrg 1.12+ we need to temporarily lower the swaplimit to 1,
+		 * so that DRI2GetBuffersWithFormat() requests from the client get
 		 * deferred in the x-server until the vblank event has been
 		 * dispatched to us and nouveau_dri2_finish_swap() is done. If
 		 * we wouldn't do this, DRI2GetBuffersWithFormat() would operate
 		 * on wrong (pre-swap) buffers, and cause a segfault later on in
-		 * nouveau_dri2_finish_swap(). Our vblank event handler restores
+		 * nouveau_dri2_finish_swap(). Our vblank event handler will restore
 		 * the old swaplimit immediately after nouveau_dri2_finish_swap()
-		 * is done, so we still get 1 video refresh cycle worth of
-		 * triple-buffering. For a swap at next vblank, dispatch of the
-		 * vblank event happens immediately, so there isn't any need
-		 * for this lowered swaplimit.
+		 * is done, so we still get 1 video refresh cycle worth of triple-
+		 * buffering, because the client can start rendering again 1 cycle
+		 * before the pending swap is completed.
+		 *
+		 * The same race would happen for the "swap at next vblank" case,
+		 * but the special case "swap immediately" code above prevents this.
 		 */
-		if (current_msc < *target_msc - 1)
-			DRI2SwapLimit(draw, 1);
+		DRI2SwapLimit(draw, 1);
 #endif
 
 		/* Request a vblank event one frame before the target */

commit 16b243ea7cd3a3c0ef487c272d8b22ee17a108c2
Author: Ben Skeggs <bskeggs@redhat.com>
Date:   Thu Oct 18 18:38:21 2012 +1000

    shadowfb: fix segfault due to reading outside of shadow buffer
    
    Probably caused by the new libdrm port, the new libdrm sets the bo
    size field to the *allocated* size and not the *requested* size,
    making the max_height calculation here invalid.
    
    Switched to using virtualX/virtualY as the bounds, which should
    hopefully do the right thing..
    
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
    (cherry picked from commit 01c9a9cff7d6232ca6eafa59dd60833a0d9cdc5b)

diff --git a/src/nv_shadow.c b/src/nv_shadow.c
index 67d9ea5..4ad2357 100644
--- a/src/nv_shadow.c
+++ b/src/nv_shadow.c
@@ -32,19 +32,18 @@ void
 NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
 	NVPtr pNv = NVPTR(pScrn);
-	int x1, y1, x2, y2, width, height, cpp, FBPitch, max_height;
+	int x1, y1, x2, y2, width, height, cpp, FBPitch;
 	unsigned char *src, *dst;
    
 	cpp = pScrn->bitsPerPixel >> 3;
 	FBPitch = pScrn->displayWidth * cpp;
-	max_height = pNv->scanout->size/FBPitch;
 
 	nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR, pNv->client);
 	while(num--) {
 		x1 = MAX(pbox->x1, 0);
 		y1 = MAX(pbox->y1, 0);
-		x2 = MIN(pbox->x2, pScrn->displayWidth);
-		y2 = MIN(pbox->y2, max_height);
+		x2 = MIN(pbox->x2, pScrn->virtualX);
+		y2 = MIN(pbox->y2, pScrn->virtualY);
 		width = (x2 - x1) * cpp;
 		height = y2 - y1;
 

commit 62f96347f0f9e4aced6f332dd4e35c47dd32d29e
Author: Sebastian Keller <sebastian-keller@gmx.de>
Date:   Tue Sep 25 11:35:35 2012 +0200

    exa: use CLAMP_TO_EDGE for RepeatPad
    
    This fixes border rendering in some gtk3 themes.
    https://bugs.freedesktop.org/show_bug.cgi?id=55310
    
    v2 (Ben Skeggs): implement same fix for fermi/kepler too
    
    Signed-off-by: Sebastian Keller <sebastian-keller@gmx.de>
    Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
    (cherry picked from commit 5c9379b14cdabc81fd5d4c916dcd93dc77c4f683)

diff --git a/src/nv40_exa.c b/src/nv40_exa.c
index 87ed5b2..c9e99e0 100644
--- a/src/nv40_exa.c
+++ b/src/nv40_exa.c
@@ -260,9 +260,9 @@ NV40EXAPictTexture(NVPtr pNv, PixmapPtr pPix, PicturePtr pPict, int unit)
 	if (pPict->repeat) {
 		switch(pPict->repeatType) {
 		case RepeatPad:
-			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP | 
-					 NV30_3D_TEX_WRAP_T_CLAMP |
-					 NV30_3D_TEX_WRAP_R_CLAMP);
+			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE |
+					 NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE |
+					 NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE);
 			break;
 		case RepeatReflect:
 			PUSH_DATA (push, NV30_3D_TEX_WRAP_S_MIRRORED_REPEAT |
diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index 2a25e74..1ce081a 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -664,9 +664,9 @@ NV50EXAPictTexture(NVPtr pNv, PixmapPtr ppix, PicturePtr ppict, unsigned unit)
 	if (ppict->repeat) {
 		switch (ppict->repeatType) {
 		case RepeatPad:
-			PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP |
-				 NV50TSC_1_0_WRAPT_CLAMP |
-				 NV50TSC_1_0_WRAPR_CLAMP | 0x00024000);
+			PUSH_DATA (push, NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
+				 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
+				 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE | 0x00024000);
 			break;
 		case RepeatReflect:
 			PUSH_DATA (push, NV50TSC_1_0_WRAPS_MIRROR_REPEAT |
diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
index 6a8f1a1..a75fdee 100644
--- a/src/nvc0_exa.c
+++ b/src/nvc0_exa.c
@@ -658,9 +658,9 @@ NVC0EXAPictTexture(NVPtr pNv, PixmapPtr ppix, PicturePtr ppict, unsigned unit)
 		switch (ppict->repeatType) {
 		case RepeatPad:
 			PUSH_DATA (push, 0x00024000 |
-					 NV50TSC_1_0_WRAPS_CLAMP |
-					 NV50TSC_1_0_WRAPT_CLAMP |
-					 NV50TSC_1_0_WRAPR_CLAMP);
+					 NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE |
+					 NV50TSC_1_0_WRAPT_CLAMP_TO_EDGE |
+					 NV50TSC_1_0_WRAPR_CLAMP_TO_EDGE);
 			break;
 		case RepeatReflect:
 			PUSH_DATA (push, 0x00024000 |


Reply to: