summaryrefslogtreecommitdiff
path: root/driver/xf86-video-intel
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-08-06 16:02:08 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-08-06 16:02:08 +0000
commit8072e3014d23fd3bb0d6ad53db20d4dd5b2d20e4 (patch)
tree4b1d20dad85303d49a3651a4b76d1e45bcf7c5e9 /driver/xf86-video-intel
parent63e4a046e3f3b91d71d105db23a14ce674b33b2e (diff)
Pull in some code from 2.8 and current so that dri2 works correctly with
xserver 1.6.2. When dri2 is not in use, this commit does nothing. ok matthieu@
Diffstat (limited to 'driver/xf86-video-intel')
-rw-r--r--driver/xf86-video-intel/src/i830.h19
-rw-r--r--driver/xf86-video-intel/src/i830_dri.c202
2 files changed, 210 insertions, 11 deletions
diff --git a/driver/xf86-video-intel/src/i830.h b/driver/xf86-video-intel/src/i830.h
index f93391770..3bca8f220 100644
--- a/driver/xf86-video-intel/src/i830.h
+++ b/driver/xf86-video-intel/src/i830.h
@@ -1079,4 +1079,23 @@ enum {
INTEL_CREATE_PIXMAP_TILING_Y,
};
+static inline PixmapPtr
+get_drawable_pixmap(DrawablePtr drawable)
+{
+ ScreenPtr screen = drawable->pScreen;
+
+ if (drawable->type == DRAWABLE_PIXMAP)
+ return (PixmapPtr)drawable;
+ else
+ return screen->GetWindowPixmap((WindowPtr)drawable);
+}
+
+static inline Bool
+pixmap_is_scanout(PixmapPtr pixmap)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+
+ return pixmap == screen->GetScreenPixmap(screen);
+}
+
#endif /* _I830_H_ */
diff --git a/driver/xf86-video-intel/src/i830_dri.c b/driver/xf86-video-intel/src/i830_dri.c
index 6a3249298..0635de852 100644
--- a/driver/xf86-video-intel/src/i830_dri.c
+++ b/driver/xf86-video-intel/src/i830_dri.c
@@ -93,6 +93,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef DRI2
#include "dri2.h"
+
+#if DRI2INFOREC_VERSION >= 1
+#define USE_DRI2_1_1_0
+#endif
+
+extern XF86ModuleData dri2ModuleData;
#endif
static Bool I830InitVisualConfigs(ScreenPtr pScreen);
@@ -1529,8 +1535,10 @@ I830DRIUnlock(ScrnInfoPtr pScrn)
typedef struct {
PixmapPtr pPixmap;
+ unsigned int attachment;
} I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr;
+#ifndef USE_DRI2_1_1_0
static DRI2BufferPtr
I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
{
@@ -1555,10 +1563,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
pDepthPixmap = NULL;
for (i = 0; i < count; i++) {
if (attachments[i] == DRI2BufferFrontLeft) {
- if (pDraw->type == DRAWABLE_PIXMAP)
- pPixmap = (PixmapPtr) pDraw;
- else
- pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
+ pPixmap = get_drawable_pixmap(pDraw);
pPixmap->refcnt++;
} else if (attachments[i] == DRI2BufferStencil && pDepthPixmap) {
pPixmap = pDepthPixmap;
@@ -1602,6 +1607,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
buffers[i].driverPrivate = &privates[i];
buffers[i].flags = 0; /* not tiled */
privates[i].pPixmap = pPixmap;
+ privates[i].attachment = attachments[i];
bo = i830_get_pixmap_bo (pPixmap);
if (dri_bo_flink(bo, &buffers[i].name) != 0) {
@@ -1613,6 +1619,85 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
return buffers;
}
+#else
+
+static DRI2Buffer2Ptr
+I830DRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment,
+ unsigned int format)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+ DRI2Buffer2Ptr buffer;
+ dri_bo *bo;
+ I830DRI2BufferPrivatePtr privates;
+ PixmapPtr pPixmap;
+
+ buffer = xcalloc(1, sizeof *buffer);
+ if (buffer == NULL)
+ return NULL;
+ privates = xcalloc(1, sizeof *privates);
+ if (privates == NULL) {
+ xfree(buffer);
+ return NULL;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ pPixmap = get_drawable_pixmap(pDraw);
+ pPixmap->refcnt++;
+ } else {
+ unsigned int hint = 0;
+
+ switch (attachment) {
+ case DRI2BufferDepth:
+ case DRI2BufferDepthStencil:
+ if (SUPPORTS_YTILING(pI830))
+ hint = INTEL_CREATE_PIXMAP_TILING_Y;
+ else
+ hint = INTEL_CREATE_PIXMAP_TILING_X;
+ break;
+ case DRI2BufferFakeFrontLeft:
+ case DRI2BufferFakeFrontRight:
+ case DRI2BufferBackLeft:
+ case DRI2BufferBackRight:
+ hint = INTEL_CREATE_PIXMAP_TILING_X;
+ break;
+ }
+
+ if (!pI830->tiling ||
+ (!IS_I965G(pI830) && !pI830->kernel_exec_fencing))
+ hint = 0;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen,
+ pDraw->width,
+ pDraw->height,
+ (format != 0)?format:pDraw->depth,
+ hint);
+
+ }
+
+
+ buffer->attachment = attachment;
+ buffer->pitch = pPixmap->devKind;
+ buffer->cpp = pPixmap->drawable.bitsPerPixel / 8;
+ buffer->driverPrivate = privates;
+ buffer->format = format;
+ buffer->flags = 0; /* not tiled */
+ privates->pPixmap = pPixmap;
+ privates->attachment = attachment;
+
+ bo = i830_get_pixmap_bo (pPixmap);
+ if (dri_bo_flink(bo, &buffer->name) != 0) {
+ /* failed to name buffer */
+ }
+
+ return buffer;
+}
+
+#endif
+
+#ifndef USE_DRI2_1_1_0
+
static void
I830DRI2DestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
@@ -1633,15 +1718,37 @@ I830DRI2DestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
+#else
+
+static void
+I830DRI2DestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
+{
+ if (buffer) {
+ I830DRI2BufferPrivatePtr private = buffer->driverPrivate;
+ ScreenPtr pScreen = pDraw->pScreen;
+
+ (*pScreen->DestroyPixmap)(private->pPixmap);
+
+ xfree(private);
+ xfree(buffer);
+ }
+}
+
+#endif
+
static void
I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
- DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
+ DRI2BufferPtr pDstBuffer, DRI2BufferPtr pSrcBuffer)
{
- I830DRI2BufferPrivatePtr private = pSrcBuffer->driverPrivate;
+ I830DRI2BufferPrivatePtr srcPrivate = pSrcBuffer->driverPrivate;
+ I830DRI2BufferPrivatePtr dstPrivate = pDstBuffer->driverPrivate;
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- PixmapPtr pPixmap = private->pPixmap;
+ DrawablePtr src = (srcPrivate->attachment == DRI2BufferFrontLeft)
+ ? pDraw : &srcPrivate->pPixmap->drawable;
+ DrawablePtr dst = (dstPrivate->attachment == DRI2BufferFrontLeft)
+ ? pDraw : &dstPrivate->pPixmap->drawable;
RegionPtr pCopyClip;
GCPtr pGC;
@@ -1649,9 +1756,52 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
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)(&pPixmap->drawable,
- pDraw, pGC, 0, 0, pDraw->width, pDraw->height, 0, 0);
+ ValidateGC(dst, pGC);
+
+#if 0 /* not yet */
+ /* Wait for the scanline to be outside the region to be copied */
+ if (pixmap_is_scanout(get_drawable_pixmap(dst)) && pI830->swapbuffers_wait) {
+ BoxPtr box;
+ BoxRec crtcbox;
+ int y1, y2;
+ int pipe = -1, event, load_scan_lines_pipe;
+ xf86CrtcPtr crtc;
+
+ box = REGION_EXTENTS(unused, pGC->pCompositeClip);
+ crtc = i830_covering_crtc(pScrn, box, NULL, &crtcbox);
+
+ /* Make sure the CRTC is valid and this is the real front buffer */
+ if (crtc != NULL && !crtc->rotatedData) {
+ pipe = i830_crtc_to_pipe(crtc);
+
+ if (pipe == 0) {
+ event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+ load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+ } else {
+ event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+ load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+ }
+
+ /* Make sure we don't wait for a scanline that will never occur */
+ y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
+ y2 = (box->y2 <= crtcbox.y2) ?
+ box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
+
+ BEGIN_BATCH(5);
+ /* The documentation says that the LOAD_SCAN_LINES command
+ * always comes in pairs. Don't ask me why. */
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
+ OUT_BATCH((y1 << 16) | y2);
+ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
+ OUT_BATCH((y1 << 16) | y2);
+ OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+ ADVANCE_BATCH();
+ }
+ }
+#endif
+
+ (*pGC->ops->CopyArea)(src, dst,
+ pGC, 0, 0, pDraw->width, pDraw->height, 0, 0);
FreeScratchGC(pGC);
/* Emit a flush of the rendering cache, or on the 965 and beyond
@@ -1680,12 +1830,27 @@ Bool I830DRI2ScreenInit(ScreenPtr pScreen)
int i;
struct stat sbuf;
dev_t d;
+#ifdef USE_DRI2_1_1_0
+ int dri2_major = 1;
+ int dri2_minor = 0;
+#endif
if (pI830->accel != ACCEL_UXA) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires UXA\n");
return FALSE;
}
+#ifdef USE_DRI2_1_1_0
+ if (xf86LoaderCheckSymbol("DRI2Version")) {
+ DRI2Version(& dri2_major, & dri2_minor);
+ }
+ if (dri2_minor < 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRI2 requires DRI2 module version 1.1.0 or later\n");
+ return FALSE;
+ }
+#endif
+
sprintf(buf, "pci:%04x:%02x:%02x.%d",
pI830->PciInfo->domain,
pI830->PciInfo->bus,
@@ -1730,10 +1895,25 @@ Bool I830DRI2ScreenInit(ScreenPtr pScreen)
info.driverName = IS_I965G(pI830) ? "i965" : "i915";
info.deviceName = p;
- info.version = 1;
+#if DRI2INFOREC_VERSION >= 3
+ info.version = 3;
+ info.CreateBuffer = I830DRI2CreateBuffer;
+ info.DestroyBuffer = I830DRI2DestroyBuffer;
+#else
+# ifdef USE_DRI2_1_1_0
+ info.version = 2;
+ info.CreateBuffers = NULL;
+ info.DestroyBuffers = NULL;
+ info.CreateBuffer = I830DRI2CreateBuffer;
+ info.DestroyBuffer = I830DRI2DestroyBuffer;
+# else
+ info.version = 1;
info.CreateBuffers = I830DRI2CreateBuffers;
info.DestroyBuffers = I830DRI2DestroyBuffers;
+# endif
+#endif
+
info.CopyRegion = I830DRI2CopyRegion;
pI830->drmSubFD = info.fd;