summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nouveau_dri2.c66
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);
}