diff options
-rw-r--r-- | src/nouveau_dri2.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c index f17e788..7b700f6 100644 --- a/src/nouveau_dri2.c +++ b/src/nouveau_dri2.c @@ -103,6 +103,63 @@ nouveau_dri2_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buf) free(nvbuf); } +static PixmapPtr +nouveau_dri2_create_buffer_pixmap(ScreenPtr pScreen, PixmapPtr pPixmap, + unsigned attachment, unsigned format, + int w, int h, uint32_t *name) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); + NVPtr pNv = NVPTR(scrn); + struct nouveau_pixmap *nvpix; + PixmapPtr ppix = NULL; + + if (attachment == DRI2BufferFrontLeft) { + ppix = pPixmap; + /* TODO set swap limit */ + ppix->refcnt++; + } else { + int bpp; + unsigned int usage_hint = NOUVEAU_CREATE_PIXMAP_TILED; + + /* 'format' is just depth (or 0, or maybe it depends on the caller) */ + bpp = round_up_pow2(format ? format : pPixmap->drawable.depth); + + if (attachment == DRI2BufferDepth || + attachment == DRI2BufferDepthStencil) + usage_hint |= NOUVEAU_CREATE_PIXMAP_ZETA; + else + usage_hint |= NOUVEAU_CREATE_PIXMAP_SCANOUT; + + ppix = pScreen->CreatePixmap(pScreen, w, h, bpp, + usage_hint); + } + pNv->exa_force_cp = TRUE; + exaMoveInPixmap(ppix); + pNv->exa_force_cp = FALSE; + + nvpix = nouveau_pixmap(ppix); + if (!nvpix || !nvpix->bo || + nouveau_bo_name_get(nvpix->bo, name)) { + pScreen->DestroyPixmap(ppix); + return NULL; + } + return ppix; +} + +static void +nouveau_dri2_destroy_buffer_pixmap(PixmapPtr pixmap) +{ + pixmap->drawable.pScreen->DestroyPixmap(pixmap); +} + +static void +nouveau_dri2_copy_region_pixmap(PixmapPtr src, PixmapPtr dst, + RegionPtr pRegion, RegionPtr f_c, + DRI2CopyPixmapPtrCB cb) +{ + cb(src, dst, pRegion, f_c); +} + void nouveau_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer) @@ -693,6 +750,15 @@ nouveau_dri2_init(ScreenPtr pScreen) dri2.SwapLimitValidate = nouveau_dri2_swap_limit_validate; #endif +#if DRI2INFOREC_VERSION >= 7 + dri2.version = 7; + if (pScreen->isGPU) { + dri2.CreateBufferPixmap = nouveau_dri2_create_buffer_pixmap; + dri2.DestroyBufferPixmap = nouveau_dri2_destroy_buffer_pixmap; + dri2.CopyRegionPixmap = nouveau_dri2_copy_region_pixmap; + dri2.ScheduleSwapPixmap = NULL; + } +#endif return DRI2ScreenInit(pScreen, &dri2); } |