First of all, we were not forcing the pixmap to be moved in before
attempting to present it. Secondly, in certain configurations, we avoid
ever backing pixmaps with vram (in GPUs with 32MB of VRAM or less).

This fixes the observed cases where we ended up assuming that a bo was
backing a pixmap without doing the explicit move-in.

Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu>
---

This fixes some crashes on a NV5 with 32MB VRAM + xfwm4 --vblank=present,
however the failure modes (e.g. pixmap doesn't have backing) can happen
anywhere I believe, just much less likely.

 src/nouveau_dri2.c    | 18 +++++++++++++++---
 src/nouveau_present.c | 15 ++++++++++++++-
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
index ce0a573..8c29eca 100644
--- a/src/nouveau_dri2.c
+++ b/src/nouveau_dri2.c
@@ -248,9 +248,13 @@ static uint64_t dri2_sequence;
 static Bool
 update_front(DrawablePtr draw, DRI2BufferPtr front)
 {
-       int r;
-       PixmapPtr pixmap;
+       ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
+       NVPtr pNv = NVPTR(scrn);
        struct nouveau_dri2_buffer *nvbuf = nouveau_dri2_buffer(front);
+       struct nouveau_bo *pixmap_bo;
+
+       PixmapPtr pixmap;
+       int r;
 
        if (draw->type == DRAWABLE_PIXMAP)
                pixmap = (PixmapPtr)draw;
@@ -259,8 +263,16 @@ update_front(DrawablePtr draw, DRI2BufferPtr front)
 
        pixmap->refcnt++;
 
+       pNv->exa_force_cp = TRUE;
        exaMoveInPixmap(pixmap);
-       r = nouveau_bo_name_get(nouveau_pixmap_bo(pixmap), &front->name);
+       pNv->exa_force_cp = FALSE;
+       pixmap_bo = nouveau_pixmap_bo(pixmap);
+
+       if (!pixmap_bo)
+               r = -1;
+       else
+               r = nouveau_bo_name_get(pixmap_bo, &front->name);
+
        if (r) {
                (*draw->pScreen->DestroyPixmap)(pixmap);
                return FALSE;
diff --git a/src/nouveau_present.c b/src/nouveau_present.c
index 936475e..8167fd8 100644
--- a/src/nouveau_present.c
+++ b/src/nouveau_present.c
@@ -147,12 +147,25 @@ nouveau_present_flip_check(RRCrtcPtr rrcrtc, WindowPtr 
window,
                           PixmapPtr pixmap, Bool sync_flip)
 {
        ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
+       NVPtr pNv = NVPTR(scrn);
        xf86CrtcPtr crtc = rrcrtc->devPrivate;
+       struct nouveau_pixmap *priv = nouveau_pixmap(pixmap);
 
        if (!scrn->vtSema || !drmmode_crtc_on(crtc) || crtc->rotatedData)
                return FALSE;
 
-       return TRUE;
+       if (!priv) {
+               /* The pixmap may not have had backing for low-memory GPUs, or
+                * if we ran out of VRAM. Make sure it's properly backed for
+                * flipping.
+                */
+               pNv->exa_force_cp = TRUE;
+               exaMoveInPixmap(pixmap);
+               pNv->exa_force_cp = FALSE;
+               priv = nouveau_pixmap(pixmap);
+       }
+
+       return priv ? TRUE : FALSE;
 }
 
 static void
-- 
2.21.0

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to