summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-11-14 14:22:08 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-11-14 14:22:08 +1100
commit419948de3406c0446c56a0120734709e4b6b1918 (patch)
tree5552d2550adedc2bafb1b151ee7e3380bc5ace7e
parent0c340c20141c6257bb038dc646548020858e118c (diff)
Initial DRI2 support.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/nouveau_dri2.c129
-rw-r--r--src/nv_driver.c1
-rw-r--r--src/nv_proto.h4
4 files changed, 135 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8beaebe..984173b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBNOUVEAU_DRM_LIBS@
nouveau_drv_ladir = @moduledir@/drivers
nouveau_drv_la_SOURCES = \
+ nouveau_dri2.c \
nouveau_xv.c \
nv_accel_common.c \
nv_bios.c \
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
new file mode 100644
index 0000000..8c1f289
--- /dev/null
+++ b/src/nouveau_dri2.c
@@ -0,0 +1,129 @@
+#include "nv_include.h"
+#include "dri2.h"
+
+struct nouveau_dri2_buffer {
+ PixmapPtr pPixmap;
+};
+
+DRI2BufferPtr
+nouveau_dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments,
+ int count)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2BufferPtr dri2_bufs;
+ struct nouveau_dri2_buffer *nv_bufs;
+ PixmapPtr ppix, pzpix;
+ int i;
+
+ dri2_bufs = xcalloc(count, sizeof(*dri2_bufs));
+ if (!dri2_bufs)
+ return NULL;
+
+ nv_bufs = xcalloc(count, sizeof(*nv_bufs));
+ if (!nv_bufs) {
+ xfree(dri2_bufs);
+ return NULL;
+ }
+
+ pzpix = NULL;
+ for (i = 0; i < count; i++) {
+ if (attachments[i] == DRI2BufferFrontLeft) {
+ if (pDraw->type == DRAWABLE_PIXMAP) {
+ ppix = (PixmapPtr)pDraw;
+ } else {
+ WindowPtr pwin = (WindowPtr)pDraw;
+ ppix = pScreen->GetWindowPixmap(pwin);
+ }
+
+ ppix->refcnt++;
+ } else
+ if (attachments[i] == DRI2BufferStencil && pzpix) {
+ ppix = pzpix;
+ ppix->refcnt++;
+ } else {
+ ppix = pScreen->CreatePixmap(pScreen, pDraw->width,
+ pDraw->height,
+ pDraw->depth, 0);
+ }
+
+ if (attachments[i] == DRI2BufferDepth)
+ pzpix = ppix;
+
+ dri2_bufs[i].attachment = attachments[i];
+ dri2_bufs[i].pitch = ppix->devKind;
+ dri2_bufs[i].cpp = ppix->drawable.bitsPerPixel / 8;
+ dri2_bufs[i].driverPrivate = &nv_bufs[i];
+ dri2_bufs[i].flags = 0;
+ nv_bufs[i].pPixmap = ppix;
+
+ nouveau_bo_handle_get(nouveau_pixmap(ppix)->bo,
+ &dri2_bufs[i].name);
+ }
+
+ return dri2_bufs;
+}
+
+void
+nouveau_dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers,
+ int count)
+{
+ struct nouveau_dri2_buffer *nvbuf;
+
+ while (count--) {
+ nvbuf = buffers[count].driverPrivate;
+ pDraw->pScreen->DestroyPixmap(nvbuf->pPixmap);
+ }
+
+ if (buffers) {
+ xfree(buffers[0].driverPrivate);
+ xfree(buffers);
+ }
+}
+
+void
+nouveau_dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+ DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer)
+{
+ struct nouveau_dri2_buffer *nvbuf = pSrcBuffer->driverPrivate;
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ RegionPtr pCopyClip;
+ GCPtr pGC;
+
+ pGC = GetScratchGC(pDraw->depth, pScreen);
+ pCopyClip = REGION_CREATE(pScreen, NULL, 0);
+ REGION_COPY(pScreen, pCopyClip, pRegion);
+ pGC->funcs->ChangeClip(pGC, CT_REGION, pCopyClip, 0);
+ ValidateGC(pDraw, pGC);
+ pGC->ops->CopyArea(&nvbuf->pPixmap->drawable, pDraw, pGC, 0, 0,
+ pDraw->width, pDraw->height, 0, 0);
+ FreeScratchGC(pGC);
+
+ FIRE_RING(pNv->chan);
+}
+
+Bool
+nouveau_dri2_init(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ DRI2InfoRec dri2;
+
+ dri2.version = 1;
+ dri2.fd = nouveau_device(pNv->dev)->fd;
+ dri2.driverName = "nouveau";
+ dri2.deviceName = "/dev/dri/card0";
+ dri2.CreateBuffers = nouveau_dri2_create_buffers;
+ dri2.DestroyBuffers = nouveau_dri2_destroy_buffers;
+ dri2.CopyRegion = nouveau_dri2_copy_region;
+
+ return DRI2ScreenInit(pScreen, &dri2);
+}
+
+void
+nouveau_dri2_takedown(ScreenPtr pScreen)
+{
+ DRI2CloseScreen(pScreen);
+}
+
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 8f3b410..e8537bd 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1951,6 +1951,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* First init DRI/DRM */
if (!NVDRIScreenInit(pScrn))
return FALSE;
+ nouveau_dri2_init(pScreen);
/* Allocate and map memory areas we need */
if (!NVMapMem(pScrn))
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 1dee39d..85a2049 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -20,6 +20,10 @@ void NVDRICloseScreen(ScrnInfoPtr pScrn);
extern const char *drmSymbols[], *driSymbols[];
Bool NVDRIGetVersion(ScrnInfoPtr pScrn);
+/* in nouveau_dri2.c */
+Bool nouveau_dri2_init(ScreenPtr pScreen);
+void nouveau_dri2_takedown(ScreenPtr pScreen);
+
/* in nv_dac.c */
Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
void NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,