xserver-xorg-video-nouveau: Changes to 'ubuntu'
debian/changelog | 14 ++++
debian/patches/101-bounds.diff | 42 ++++++++++++
debian/patches/102-vblank-race.diff | 124 ++++++++++++++++++++++++++++++++++++
debian/patches/103-solidfill.diff | 75 +++++++++++++++++++++
debian/patches/104-fix-access.diff | 79 ++++++++++++++++++++++
debian/patches/series | 4 +
6 files changed, 338 insertions(+)
New commits:
commit 1ae6f9c4bc371d8d035febc4b24399dd8a8593be
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Tue Oct 23 20:23:26 2012 +0200
Add upstream commits for cleaning up download/upload screen functions (LP: #1010794)
diff --git a/debian/changelog b/debian/changelog
index 102c186..5f94377 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,8 +5,10 @@ xserver-xorg-video-nouveau (1:1.0.2-0ubuntu4) UNRELEASED; urgency=low
- 101-bounds.diff
* Fix race condition in vblank
- 102-vblank.diff
- * Fix corruption in software center (LP: #1010794)
+ * Add solid fill acceleration (LP: #1010794)
- 103-solidfill.diff
+ * Cleanup download/upload screen functions (LP: #1010794)
+ - 104-fix-access.diff
-- Maarten Lankhorst <maarten.lankhorst@canonical.com> Mon, 22 Oct 2012 12:24:31 +0200
diff --git a/debian/patches/104-fix-access.diff b/debian/patches/104-fix-access.diff
new file mode 100644
index 0000000..d086882
--- /dev/null
+++ b/debian/patches/104-fix-access.diff
@@ -0,0 +1,79 @@
+diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
+index 13d7e1f..8191aeb 100644
+--- a/src/nouveau_exa.c
++++ b/src/nouveau_exa.c
+@@ -269,7 +269,7 @@ nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h,
+ goto memcpy;
+
+ nouveau_bo_wait(tmp, NOUVEAU_BO_RD, pNv->client);
+- if (src_pitch == tmp_pitch) {
++ if (dst_pitch == tmp_pitch) {
+ memcpy(dst, tmp->map + tmp_offset, dst_pitch * lines);
+ dst += dst_pitch * lines;
+ } else {
+@@ -285,9 +285,14 @@ nouveau_exa_download_from_screen(PixmapPtr pspix, int x, int y, int w, int h,
+ h -= lines;
+ y += lines;
+ }
++ return TRUE;
+
+ memcpy:
+ bo = nouveau_pixmap_bo(pspix);
++ if (nv50_style_tiled_pixmap(pspix))
++ ErrorF("%s:%d - falling back to memcpy ignores tiling\n",
++ __func__, __LINE__);
++
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD, pNv->client))
+ return FALSE;
+ src = (char *)bo->map + (y * src_pitch) + (x * cpp);
+@@ -316,20 +321,17 @@ nouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h,
+ if (pNv->Architecture < NV_ARCH_50) {
+ if (NV04EXAUploadIFC(pScrn, src, src_pitch, pdpix,
+ x, y, w, h, cpp)) {
+- exaMarkSync(pdpix->drawable.pScreen);
+ return TRUE;
+ }
+ } else
+ if (pNv->Architecture < NV_ARCH_C0) {
+ if (NV50EXAUploadSIFC(src, src_pitch, pdpix,
+ x, y, w, h, cpp)) {
+- exaMarkSync(pdpix->drawable.pScreen);
+ return TRUE;
+ }
+ } else {
+ if (NVC0EXAUploadSIFC(src, src_pitch, pdpix,
+ x, y, w, h, cpp)) {
+- exaMarkSync(pdpix->drawable.pScreen);
+ return TRUE;
+ }
+ }
+@@ -367,12 +369,15 @@ nouveau_exa_upload_to_screen(PixmapPtr pdpix, int x, int y, int w, int h,
+ y += lines;
+ }
+
+- exaMarkSync(pdpix->drawable.pScreen);
+ return TRUE;
+
+ /* fallback to memcpy-based transfer */
+ memcpy:
+ bo = nouveau_pixmap_bo(pdpix);
++ if (nv50_style_tiled_pixmap(pdpix))
++ ErrorF("%s:%d - falling back to memcpy ignores tiling\n",
++ __func__, __LINE__);
++
+ if (nouveau_bo_map(bo, NOUVEAU_BO_WR, pNv->client))
+ return FALSE;
+ dst = (char *)bo->map + (y * dst_pitch) + (x * cpp);
+diff --git a/src/nv_type.h b/src/nv_type.h
+index 5a99dbd..d882e7c 100644
+--- a/src/nv_type.h
++++ b/src/nv_type.h
+@@ -167,8 +167,6 @@ typedef struct _NVPortPrivRec {
+
+ struct nouveau_pixmap {
+ struct nouveau_bo *bo;
+- void *linear;
+- unsigned size;
+ Bool shared;
+ };
+
diff --git a/debian/patches/series b/debian/patches/series
index cfd9165..aeca4e9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,3 +7,4 @@
101-bounds.diff
102-vblank-race.diff
103-solidfill.diff
+104-fix-access.diff
commit 443a9d95db47578bfc26462198a26578a85956fa
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Mon Oct 22 13:39:02 2012 +0200
Add upstream commits fixing some issues
* Add upstream commits fixing some issues
* Fix SIBABRT in NVRefreshArea (LP: #1056511)
- 101-bounds.diff
* Fix race condition in vblank
- 102-vblank.diff
* Fix corruption in software center (LP: #1010794)
- 103-solidfill.diff
diff --git a/debian/changelog b/debian/changelog
index c1fef59..102c186 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+xserver-xorg-video-nouveau (1:1.0.2-0ubuntu4) UNRELEASED; urgency=low
+
+ * Add upstream commits fixing some issues
+ * Fix SIBABRT in NVRefreshArea (LP: #1056511)
+ - 101-bounds.diff
+ * Fix race condition in vblank
+ - 102-vblank.diff
+ * Fix corruption in software center (LP: #1010794)
+ - 103-solidfill.diff
+
+ -- Maarten Lankhorst <maarten.lankhorst@canonical.com> Mon, 22 Oct 2012 12:24:31 +0200
+
xserver-xorg-video-nouveau (1:1.0.2-0ubuntu3) quantal; urgency=low
* Add upstream exa rendering fix (FDo: #55310)
diff --git a/debian/patches/101-bounds.diff b/debian/patches/101-bounds.diff
new file mode 100644
index 0000000..e8511f0
--- /dev/null
+++ b/debian/patches/101-bounds.diff
@@ -0,0 +1,42 @@
+commit 01c9a9cff7d6232ca6eafa59dd60833a0d9cdc5b
+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>
+
+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;
+
diff --git a/debian/patches/102-vblank-race.diff b/debian/patches/102-vblank-race.diff
new file mode 100644
index 0000000..2dccf98
--- /dev/null
+++ b/debian/patches/102-vblank-race.diff
@@ -0,0 +1,124 @@
+commit b4231dd715a8a7f86b04519b5f4e8a8d93c2f561
+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>
+
+diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
+index 7bd0b3a..8d21dca 100644
+--- a/src/nouveau_dri2.c
++++ b/src/nouveau_dri2.c
+@@ -479,6 +479,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 */
+@@ -490,9 +491,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,
+- ¤t_msc, NULL, NULL);
++ ¤t_msc, ¤t_ust, NULL);
+ if (ret)
+ goto fail;
+
+@@ -512,24 +513,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 */
diff --git a/debian/patches/103-solidfill.diff b/debian/patches/103-solidfill.diff
new file mode 100644
index 0000000..fb84d06
--- /dev/null
+++ b/debian/patches/103-solidfill.diff
@@ -0,0 +1,75 @@
+commit 0b2a548316b0ce88ba19d5e05fdca205fc139962
+Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+Date: Mon Oct 22 13:12:06 2012 +0200
+
+ nvc0/exa: make solid fill actually work
+
+ Some investigation showed that the code for accelerating solid fill
+ didn't actually work because NVC0EXACheckTexture would fail.
+
+ Making the check the same as in NV50EXACheckTexture fixes this, and
+ seems to get acceleration for solid fills working right.
+
+ Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
+
+diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
+index 7bd7294..8717eb9 100644
+--- a/src/nvc0_exa.c
++++ b/src/nvc0_exa.c
+@@ -459,14 +459,19 @@ NVC0EXARenderTarget(PixmapPtr ppix, PicturePtr ppict)
+ static Bool
+ NVC0EXACheckTexture(PicturePtr ppict, PicturePtr pdpict, int op)
+ {
+- if (!ppict->pDrawable)
+- NOUVEAU_FALLBACK("Solid and gradient pictures unsupported.\n");
+-
+- if (ppict->pDrawable->width > 8192 ||
+- ppict->pDrawable->height > 8192)
+- NOUVEAU_FALLBACK("texture dimensions exceeded %dx%d\n",
+- ppict->pDrawable->width,
+- ppict->pDrawable->height);
++ if (ppict->pDrawable) {
++ if (ppict->pDrawable->width > 8192 ||
++ ppict->pDrawable->height > 8192)
++ NOUVEAU_FALLBACK("texture too large\n");
++ } else {
++ switch (ppict->pSourcePict->type) {
++ case SourcePictTypeSolidFill:
++ break;
++ default:
++ NOUVEAU_FALLBACK("pict %d\n", ppict->pSourcePict->type);
++ break;
++ }
++ }
+
+ switch (ppict->format) {
+ case PICT_a8r8g8b8:
+@@ -826,10 +831,8 @@ NVC0EXAPrepareComposite(int op,
+ PicturePtr pspict, PicturePtr pmpict, PicturePtr pdpict,
+ PixmapPtr pspix, PixmapPtr pmpix, PixmapPtr pdpix)
+ {
+- struct nouveau_bo *src = nouveau_pixmap_bo(pspix);
+ struct nouveau_bo *dst = nouveau_pixmap_bo(pdpix);
+- struct nouveau_bo *mask = pmpix ? nouveau_pixmap_bo(pmpix) : NULL;
+- NVC0EXA_LOCALS(pspix);
++ NVC0EXA_LOCALS(pdpix);
+
+ if (!PUSH_SPACE(push, 256))
+ NOUVEAU_FALLBACK("space\n");
+@@ -881,10 +884,13 @@ NVC0EXAPrepareComposite(int op,
+
+ PUSH_RESET(push);
+ PUSH_REFN (push, pNv->scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+- PUSH_REFN (push, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
++ if (pspict->pDrawable)
++ PUSH_REFN (push, nouveau_pixmap_bo(pspix),
++ NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ PUSH_REFN (push, dst, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+- if (pmpict)
+- PUSH_REFN (push, mask, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
++ if (pmpict && pmpict->pDrawable)
++ PUSH_REFN (push, nouveau_pixmap_bo(pmpix),
++ NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+ nouveau_pushbuf_bufctx(push, pNv->bufctx);
+ if (nouveau_pushbuf_validate(push)) {
diff --git a/debian/patches/series b/debian/patches/series
index 1c3eb9d..cfd9165 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,6 @@
# Ubuntu patches
100-vblank-on.diff
+101-bounds.diff
+102-vblank-race.diff
+103-solidfill.diff
Reply to: