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