summaryrefslogtreecommitdiff
path: root/driver/xf86-video-intel/src/i830_dri.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2007-11-24 20:08:20 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2007-11-24 20:08:20 +0000
commit6a3b94f3d640fd972b5ec8b244a66c92c5ebec20 (patch)
treeba3dd1c53b25c79ae7efbfa26a0dd8fd2cbea9ab /driver/xf86-video-intel/src/i830_dri.c
parent621df55ad49646572010dd46760717472a2cf8f4 (diff)
merge xf86-video-intel 2.2.0
Diffstat (limited to 'driver/xf86-video-intel/src/i830_dri.c')
-rw-r--r--driver/xf86-video-intel/src/i830_dri.c1038
1 files changed, 637 insertions, 401 deletions
diff --git a/driver/xf86-video-intel/src/i830_dri.c b/driver/xf86-video-intel/src/i830_dri.c
index 56db194b4..b223b02e7 100644
--- a/driver/xf86-video-intel/src/i830_dri.c
+++ b/driver/xf86-video-intel/src/i830_dri.c
@@ -81,12 +81,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i830_dri.h"
-#include "dristruct.h"
+#include "i915_drm.h"
+
+/* This block and the corresponding configure test can be removed when
+ * libdrm >= 2.3.1 is required.
+ */
+#ifndef HAVE_I915_FLIP
+
+#define DRM_VBLANK_FLIP 0x8000000
+
+typedef struct drm_i915_flip {
+ int pipes;
+} drm_i915_flip_t;
+
+#undef DRM_IOCTL_I915_FLIP
+#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \
+ drm_i915_flip_t)
-static char I830KernelDriverName[] = "i915";
-static char I830ClientDriverName[] = "i915tex";
-static char I965ClientDriverName[] = "i965";
-static char I830LegacyClientDriverName[] = "i915";
+#endif
+
+#include "dristruct.h"
static Bool I830InitVisualConfigs(ScreenPtr pScreen);
static Bool I830CreateContext(ScreenPtr pScreen, VisualPtr visual,
@@ -105,11 +119,24 @@ static void I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
static void I830DRITransitionTo2d(ScreenPtr pScreen);
static void I830DRITransitionTo3d(ScreenPtr pScreen);
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+#define DRI_SUPPORTS_CLIP_NOTIFY 1
+#else
+#define DRI_SUPPORTS_CLIP_NOTIFY 0
static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen);
+#endif
-#if 0
-static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+#if (DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 4))
+#define DRI_DRIVER_FRAMEBUFFER_MAP 1
+#else
+#define DRI_DRIVER_FRAMEBUFFER_MAP 0
+#endif
+
+#ifdef DRI_SUPPORTS_CLIP_NOTIFY
+static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
#endif
extern void GlxSetVisualConfigs(int nconfigs,
@@ -145,22 +172,22 @@ I830InitDma(ScrnInfoPtr pScrn)
memset(&info, 0, sizeof(drmI830Init));
info.func = I830_INIT_DMA;
- info.ring_start = ring->mem.Start + pI830->LinearAddr;
- info.ring_end = ring->mem.End + pI830->LinearAddr;
- info.ring_size = ring->mem.Size;
+ info.ring_start = ring->mem->offset + pI830->LinearAddr;
+ info.ring_end = ring->mem->end + pI830->LinearAddr;
+ info.ring_size = ring->mem->size;
info.mmio_offset = (unsigned int)pI830DRI->regs;
info.sarea_priv_offset = sizeof(XF86DRISAREARec);
- info.front_offset = pI830->FrontBuffer.Start;
- info.back_offset = pI830->BackBuffer.Start;
- info.depth_offset = pI830->DepthBuffer.Start;
+ info.front_offset = pI830->front_buffer->offset;
+ info.back_offset = pI830->back_buffer->offset;
+ info.depth_offset = pI830->depth_buffer->offset;
info.w = pScrn->virtualX;
info.h = pScrn->virtualY;
- info.pitch = pI830->displayWidth;
- info.back_pitch = pI830->displayWidth;
- info.depth_pitch = pI830->displayWidth;
+ info.pitch = pScrn->displayWidth;
+ info.back_pitch = pScrn->displayWidth;
+ info.depth_pitch = pScrn->displayWidth;
info.cpp = pI830->cpp;
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT,
@@ -209,6 +236,22 @@ I830SetParam(ScrnInfoPtr pScrn, int param, int value)
return TRUE;
}
+static Bool
+I830SetHWS(ScrnInfoPtr pScrn, int addr)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ drmI830HWS hws;
+
+ hws.addr = addr;
+
+ if (drmCommandWrite(pI830->drmSubFD, DRM_I830_HWS_PAGE_ADDR,
+ &hws, sizeof(drmI830HWS))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "G33 status page initialization Failed\n");
+ return FALSE;
+ }
+ return TRUE;
+}
static Bool
I830InitVisualConfigs(ScreenPtr pScreen)
@@ -216,9 +259,9 @@ I830InitVisualConfigs(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int numConfigs = 0;
- __GLXvisualConfig *pConfigs = 0;
- I830ConfigPrivPtr pI830Configs = 0;
- I830ConfigPrivPtr *pI830ConfigPtrs = 0;
+ __GLXvisualConfig *pConfigs = NULL;
+ I830ConfigPrivPtr pI830Configs = NULL;
+ I830ConfigPrivPtr *pI830ConfigPtrs = NULL;
int accum, stencil, db, depth;
int i;
@@ -426,15 +469,24 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
/* Check that the GLX, DRI, and DRM modules have been loaded by testing
* for known symbols in each module. */
- if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs"))
+ if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] %s failed: glx not loaded\n", __FUNCTION__);
return FALSE;
- if (!xf86LoaderCheckSymbol("DRIScreenInit"))
+ }
+ if (!xf86LoaderCheckSymbol("DRIScreenInit")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] %s failed: dri not loaded\n", __FUNCTION__);
return FALSE;
- if (!xf86LoaderCheckSymbol("drmAvailable"))
+ }
+ if (!xf86LoaderCheckSymbol("drmAvailable")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[dri] %s failed: libdrm not loaded\n", __FUNCTION__);
return FALSE;
+ }
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[dri] %s failed (libdri.a too old)\n", "I830CheckDRIAvailable");
+ "[dri] %s failed (libdri.a too old)\n", __FUNCTION__);
return FALSE;
}
@@ -443,7 +495,8 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
int major, minor, patch;
DRIQueryVersion(&major, &minor, &patch);
- if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+ if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ||
+ major < 5) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed because of a version mismatch.\n"
"[dri] libDRI version is %d.%d.%d but version %d.%d.x is needed.\n"
@@ -480,34 +533,30 @@ I830DRIScreenInit(ScreenPtr pScreen)
pI830->pDRIInfo = pDRIInfo;
pI830->LockHeld = 0;
- pDRIInfo->drmDriverName = I830KernelDriverName;
- if (IS_I96X(pI830))
- pDRIInfo->clientDriverName = I965ClientDriverName;
- else
- pDRIInfo->clientDriverName = I830ClientDriverName;
+ pDRIInfo->drmDriverName = "i915";
+ if (IS_I965G(pI830))
+ pDRIInfo->clientDriverName = "i965";
+ else
+ pDRIInfo->clientDriverName = "i915";
if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
pDRIInfo->busIdString = DRICreatePCIBusID(pI830->PciInfo);
} else {
pDRIInfo->busIdString = xalloc(64);
sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+#if XSERVER_LIBPCIACCESS
+ ((pI830->PciInfo->domain << 8) | pI830->PciInfo->bus),
+ pI830->PciInfo->dev, pI830->PciInfo->func
+#else
((pciConfigPtr) pI830->PciInfo->thisCard)->busnum,
((pciConfigPtr) pI830->PciInfo->thisCard)->devnum,
- ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum);
+ ((pciConfigPtr) pI830->PciInfo->thisCard)->funcnum
+#endif
+ );
}
pDRIInfo->ddxDriverMajorVersion = I830_MAJOR_VERSION;
pDRIInfo->ddxDriverMinorVersion = I830_MINOR_VERSION;
pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL;
-#if 1 /* Remove this soon - see bug 5714 */
- pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr +
- pI830->FrontBuffer.Start;
- pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
- pScrn->virtualY * pI830->cpp);
-#else
- /* For rotation we map a 0 length framebuffer as we remap ourselves later */
- pDRIInfo->frameBufferSize = 0;
-#endif
- pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
pDRIInfo->ddxDrawableTableEntry = I830_MAX_DRAWABLES;
if (SAREA_MAX_DRAWABLES < I830_MAX_DRAWABLES)
@@ -529,7 +578,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
if (!(pI830DRI = (I830DRIPtr) xcalloc(sizeof(I830DRIRec), 1))) {
DRIDestroyInfoRec(pI830->pDRIInfo);
- pI830->pDRIInfo = 0;
+ pI830->pDRIInfo = NULL;
return FALSE;
}
pDRIInfo->devPrivate = pI830DRI;
@@ -542,42 +591,70 @@ I830DRIScreenInit(ScreenPtr pScreen)
pDRIInfo->InitBuffers = I830DRIInitBuffers;
pDRIInfo->MoveBuffers = I830DRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+#if DRIINFO_MAJOR_VERSION > 5 || \
+ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
+ if (pI830->useEXA)
+ pDRIInfo->texOffsetStart = I830TexOffsetStart;
+#endif
+
+#if DRI_SUPPORTS_CLIP_NOTIFY
+ pDRIInfo->ClipNotify = I830DRIClipNotify;
+#endif
+
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+ /* DRI version is high enough that we can get the DRI code to not
+ * try to manage the framebuffer.
+ */
+ pDRIInfo->frameBufferPhysicalAddress = 0;
+ pDRIInfo->frameBufferSize = 0;
+ pDRIInfo->frameBufferStride = 0;
+ pDRIInfo->dontMapFrameBuffer = TRUE;
+#else
+ /* Supply a dummy mapping info required by DRI setup.
+ */
+ pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr;
+ pDRIInfo->frameBufferSize = GTT_PAGE_SIZE;
+ pDRIInfo->frameBufferStride = 1;
+#endif
+
pDRIInfo->TransitionTo2d = I830DRITransitionTo2d;
pDRIInfo->TransitionTo3d = I830DRITransitionTo3d;
+
+#if !DRI_SUPPORTS_CLIP_NOTIFY
pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d;
pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d;
+#endif
/* do driver-independent DRI screen initialization here */
if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] DRIScreenInit failed. Disabling DRI.\n");
xfree(pDRIInfo->devPrivate);
- pDRIInfo->devPrivate = 0;
+ pDRIInfo->devPrivate = NULL;
DRIDestroyInfoRec(pI830->pDRIInfo);
- pI830->pDRIInfo = 0;
+ pI830->pDRIInfo = NULL;
return FALSE;
}
-#if 0 /* disabled now, see frameBufferSize above being set to 0 */
- /* for this driver, get rid of the front buffer mapping now */
- if (xf86LoaderCheckSymbol("DRIGetScreenPrivate")) {
- DRIScreenPrivPtr pDRIPriv
- = (DRIScreenPrivPtr) DRIGetScreenPrivate(pScreen);
-
- if (pDRIPriv && pDRIPriv->drmFD && pDRIPriv->hFrameBuffer) {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[intel] removing original screen mapping\n");
- drmRmMap(pDRIPriv->drmFD, pDRIPriv->hFrameBuffer);
- pDRIPriv->hFrameBuffer = 0;
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[intel] done removing original screen mapping\n");
- }
+ /* Now, nuke dri.c's dummy frontbuffer map setup if we did that. */
+ if (pDRIInfo->frameBufferSize != 0) {
+ int tmp;
+ drm_handle_t fb_handle;
+ void *ptmp;
+
+ /* With the compat method, it will continue to report
+ * the wrong map out of GetDeviceInfo, which will break AIGLX.
+ */
+ DRIGetDeviceInfo(pScreen, &fb_handle, &tmp, &tmp, &tmp, &tmp, &ptmp);
+ drmRmMap(pI830->drmSubFD, fb_handle);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Removed DRI frontbuffer mapping in compatibility mode.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRIGetDeviceInfo will report incorrect frontbuffer "
+ "handle.\n");
}
- else {
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[intel] DRIGetScreenPrivate not found!!!!\n");
- }
-#endif
/* Check the i915 DRM versioning */
{
@@ -637,164 +714,67 @@ I830DRIScreenInit(ScreenPtr pScreen)
drmFreeVersion(version);
return FALSE;
}
- if (strncmp(version->name, I830KernelDriverName, strlen(I830KernelDriverName))) {
- xf86DrvMsg(pScreen->myNum, X_WARNING,
- "i830 Kernel module detected, Use the i915 Kernel module instead, aborting DRI init.\n");
+ /* Check whether the kernel module attached to the device isn't the
+ * one we expected (meaning it's the old i830 module).
+ */
+ if (strncmp(version->name, pDRIInfo->drmDriverName,
+ strlen(pDRIInfo->drmDriverName)))
+ {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "Detected i830 kernel module. The i915 kernel module "
+ "is required for DRI. Aborting.\n");
I830DRICloseScreen(pScreen);
drmFreeVersion(version);
return FALSE;
}
pI830->drmMinor = version->version_minor;
- if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) {
- if ((version->version_major > 1) ||
- ((version->version_minor >= 7) &&
- (version->version_major == 1))) {
- pI830->mmModeFlags |= I830_KERNEL_MM;
- } else {
- pI830->mmModeFlags |= I830_KERNEL_TEX;
- }
- } else {
- xf86DrvMsg(pScreen->myNum, X_INFO,
- "Not enabling the DRM memory manager.\n");
- }
+#ifdef DAMAGE
+ if (pI830->allowPageFlip && pI830->drmMinor < 9) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRM version 1.9 or newer required for Page flipping. "
+ "Disabling.\n");
+ pI830->allowPageFlip = FALSE;
+ }
+#endif
drmFreeVersion(version);
}
}
- /*
- * Backwards compatibility
- */
-
- if ((pDRIInfo->clientDriverName == I830ClientDriverName) &&
- (pI830->mmModeFlags & I830_KERNEL_TEX)) {
- pDRIInfo->clientDriverName = I830LegacyClientDriverName;
- }
-
return TRUE;
}
-Bool
-I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
-{
- ScreenPtr pScreen = pScrn->pScreen;
- I830Ptr pI830 = I830PTR(pScrn);
-
-#if 1 /* Remove this soon - see bug 5714 */
- pI830->pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth *
- pScrn->virtualY * pI830->cpp);
-#endif
-
- /* The I965 isn't ready for the front buffer mapping to be moved around,
- * because of issues with rmmap, it seems.
- */
- if (!IS_I96X(pI830)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] Mapping front buffer\n");
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)(sarea->front_offset + pI830->LinearAddr),
- sarea->front_size,
- DRM_AGP,
- 0,
- (drmAddress) &sarea->front_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(front_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Front Buffer = 0x%08x\n",
- (int)sarea->front_handle);
- }
-
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)(sarea->back_offset + pI830->LinearAddr),
- sarea->back_size, DRM_AGP, 0,
- (drmAddress) &sarea->back_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(back_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n",
- (int)sarea->back_handle);
-
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)sarea->depth_offset + pI830->LinearAddr,
- sarea->depth_size, DRM_AGP, 0,
- (drmAddress) &sarea->depth_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Depth Buffer = 0x%08x\n",
- (int)sarea->depth_handle);
-
- if (pI830->mmModeFlags & I830_KERNEL_TEX) {
- if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)sarea->tex_offset + pI830->LinearAddr,
- sarea->tex_size, DRM_AGP, 0,
- (drmAddress) &sarea->tex_handle) < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n");
- DRICloseScreen(pScreen);
- return FALSE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] textures = 0x%08x\n",
- (int)sarea->tex_handle);
- }
- return TRUE;
-}
-
-
-void
-I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
-{
- I830Ptr pI830 = I830PTR(pScrn);
-
- if (sarea->front_handle) {
- drmRmMap(pI830->drmSubFD, sarea->front_handle);
- sarea->front_handle = 0;
- }
- if (sarea->back_handle) {
- drmRmMap(pI830->drmSubFD, sarea->back_handle);
- sarea->back_handle = 0;
- }
- if (sarea->depth_handle) {
- drmRmMap(pI830->drmSubFD, sarea->depth_handle);
- sarea->depth_handle = 0;
- }
- if (sarea->tex_handle) {
- drmRmMap(pI830->drmSubFD, sarea->tex_handle);
- sarea->tex_handle = 0;
- }
-}
-
static void
-I830InitTextureHeap(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+I830InitTextureHeap(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ if (pI830->textures == NULL)
+ return;
+
/* Start up the simple memory manager for agp space */
drmI830MemInitHeap drmHeap;
drmHeap.region = I830_MEM_REGION_AGP;
drmHeap.start = 0;
- drmHeap.size = sarea->tex_size;
-
+ drmHeap.size = pI830->textures->size;
+
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT_HEAP,
&drmHeap, sizeof(drmHeap))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] Failed to initialized agp heap manager\n");
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] Initialized kernel agp heap manager, %d\n",
- sarea->tex_size);
+ "[drm] Initialized kernel agp heap manager, %ld\n",
+ pI830->textures->size);
I830SetParam(pScrn, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY,
- sarea->log_tex_granularity);
+ pI830->TexGranularity);
}
}
+/**
+ * Sets up mappings for static, lifetime-fixed allocations, and inital SAREA
+ * setup.
+ */
Bool
I830DRIDoMappings(ScreenPtr pScreen)
{
@@ -817,8 +797,8 @@ I830DRIDoMappings(ScreenPtr pScreen)
(int)pI830DRI->regs);
if (drmAddMap(pI830->drmSubFD,
- (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr,
- pI830->LpRing->mem.Size, DRM_AGP, 0,
+ (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr,
+ pI830->LpRing->mem->size, DRM_AGP, 0,
(drmAddress) &pI830->ring_map) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAddMap(ring_map) failed. Disabling DRI\n");
@@ -833,9 +813,16 @@ I830DRIDoMappings(ScreenPtr pScreen)
return FALSE;
}
+ if (IS_G33CLASS(pI830)) {
+ if (!I830SetHWS(pScrn, pI830->hw_status->offset)) {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ }
/* init to zero to be safe */
sarea->front_handle = 0;
sarea->back_handle = 0;
+ sarea->third_handle = 0;
sarea->depth_handle = 0;
sarea->tex_handle = 0;
@@ -846,21 +833,31 @@ I830DRIDoMappings(ScreenPtr pScreen)
pScrn->pScreen->width = pScrn->virtualX;
pScrn->pScreen->height = pScrn->virtualY;
- /* this will map the screen regions */
- if (!I830UpdateDRIBuffers(pScrn, sarea)) {
- /* screen mappings probably failed */
- xf86DrvMsg(pScreen->myNum, X_ERROR,
- "[drm] drmAddMap(screen mappings) failed. Disabling DRI\n");
- return FALSE;
+ /* If we are using the kernel memory manager, we have to delay SAREA and
+ * mapping setup until our buffers are pinned at EnterVT, losing the
+ * opportunity to fail cleanly early on.
+ */
+ if (pI830->memory_manager == NULL) {
+ if (!i830_update_dri_buffers(pScrn)) {
+ /* screen mappings probably failed */
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] drmAddMap(screen mappings) failed. "
+ "Disabling DRI\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
}
- if (pI830->PciInfo->chipType != PCI_CHIP_845_G &&
- pI830->PciInfo->chipType != PCI_CHIP_I830_M) {
+ if (pI830->allocate_classic_textures)
+ I830InitTextureHeap(pScrn);
+
+ if (DEVICE_ID(pI830->PciInfo) != PCI_CHIP_845_G &&
+ DEVICE_ID(pI830->PciInfo) != PCI_CHIP_I830_M) {
I830SetParam(pScrn, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 );
}
pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
- pI830DRI->deviceID = pI830->PciInfo->chipType;
+ pI830DRI->deviceID = DEVICE_ID(pI830->PciInfo);
pI830DRI->width = pScrn->virtualX;
pI830DRI->height = pScrn->virtualY;
pI830DRI->mem = pScrn->videoRam * 1024;
@@ -896,12 +893,20 @@ I830DRIResume(ScreenPtr pScreen)
{
pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
+#if XSERVER_LIBPCIACCESS
+ ((pI830->PciInfo->domain << 8) |
+ pI830->PciInfo->bus),
+ pI830->PciInfo->dev,
+ pI830->PciInfo->func
+#else
((pciConfigPtr) pI830->
PciInfo->thisCard)->busnum,
((pciConfigPtr) pI830->
PciInfo->thisCard)->devnum,
((pciConfigPtr) pI830->
- PciInfo->thisCard)->funcnum);
+ PciInfo->thisCard)->funcnum
+#endif
+ );
if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -927,6 +932,10 @@ I830DRICloseScreen(ScreenPtr pScreen)
DPRINTF(PFX, "I830DRICloseScreen\n");
+#ifdef DAMAGE
+ REGION_UNINIT(pScreen, &pI830->driRegion);
+#endif
+
if (pI830DRI->irq) {
drmCtlUninstHandler(pI830->drmSubFD);
pI830DRI->irq = 0;
@@ -939,10 +948,10 @@ I830DRICloseScreen(ScreenPtr pScreen)
if (pI830->pDRIInfo) {
if (pI830->pDRIInfo->devPrivate) {
xfree(pI830->pDRIInfo->devPrivate);
- pI830->pDRIInfo->devPrivate = 0;
+ pI830->pDRIInfo->devPrivate = NULL;
}
DRIDestroyInfoRec(pI830->pDRIInfo);
- pI830->pDRIInfo = 0;
+ pI830->pDRIInfo = NULL;
}
if (pI830->pVisualConfigs)
xfree(pI830->pVisualConfigs);
@@ -972,17 +981,6 @@ I830DRIFinishScreenInit(ScreenPtr pScreen)
DPRINTF(PFX, "I830DRIFinishScreenInit\n");
- /* Have shadow run only while there is 3d active.
- */
-#if 0
- if (pI830->allowPageFlip && pI830->drmMinor >= 1) {
- shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0);
- }
- else
-#endif
- pI830->allowPageFlip = 0;
-
-
if (!DRIFinishScreenInit(pScreen))
return FALSE;
@@ -991,12 +989,20 @@ I830DRIFinishScreenInit(ScreenPtr pScreen)
I830DRIPtr pI830DRI = (I830DRIPtr) pI830->pDRIInfo->devPrivate;
pI830DRI->irq = drmGetInterruptFromBusID(pI830->drmSubFD,
+#if XSERVER_LIBPCIACCESS
+ ((pI830->PciInfo->domain << 8) |
+ pI830->PciInfo->bus),
+ pI830->PciInfo->dev,
+ pI830->PciInfo->func
+#else
((pciConfigPtr) pI830->
PciInfo->thisCard)->busnum,
((pciConfigPtr) pI830->
PciInfo->thisCard)->devnum,
((pciConfigPtr) pI830->
- PciInfo->thisCard)->funcnum);
+ PciInfo->thisCard)->funcnum
+#endif
+ );
if (drmCtlInstHandler(pI830->drmSubFD, pI830DRI->irq)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1013,7 +1019,62 @@ I830DRIFinishScreenInit(ScreenPtr pScreen)
}
}
-void
+#ifdef DAMAGE
+/* This should be done *before* XAA syncs,
+ * Otherwise will have to sync again???
+ */
+static void
+I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, CARD32 dst)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
+
+ if (pScrn->bitsPerPixel == 32) {
+ cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+ br13 |= 3 << 24;
+ } else {
+ cmd = (XY_SRC_COPY_BLT_CMD);
+ br13 |= 1 << 24;
+ }
+
+ for (i = 0 ; i < num ; i++, pbox++) {
+ BEGIN_LP_RING(8);
+ OUT_RING(cmd);
+ OUT_RING(br13);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING((pbox->y2 << 16) | pbox->x2);
+ OUT_RING(dst);
+ OUT_RING((pbox->y1 << 16) | pbox->x1);
+ OUT_RING(br13 & 0xffff);
+ OUT_RING(pI830->front_buffer->offset);
+ ADVANCE_LP_RING();
+ }
+}
+
+static void
+I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
+ return;
+
+ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->back_buffer->offset);
+
+ if (pI830->third_buffer) {
+ I830DRIDoRefreshArea(pScrn, num, pbox, pI830->third_buffer->offset);
+ }
+
+ DamageEmpty(pI830->pDamage);
+}
+#endif
+
+static void
I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
DRIContextType newContextType, void *newContext)
@@ -1023,21 +1084,102 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
if (syncType == DRI_3D_SYNC &&
oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (in)\n");
+ *pI830->last_3d = LAST_3D_OTHER;
+
if (!pScrn->vtSema)
return;
pI830->LockHeld = 1;
- I830RefreshRing(pScrn);
+ i830_refresh_ring(pScrn);
+
+ I830EmitFlush(pScrn);
+
+#ifdef DAMAGE
+ if (!pI830->pDamage && pI830->allowPageFlip) {
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+ pI830->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, pPix);
+
+ if (pI830->pDamage == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen damage record, page flipping disabled\n");
+ pI830->allowPageFlip = FALSE;
+ } else {
+ DamageRegister(&pPix->drawable, pI830->pDamage);
+
+ DamageDamageRegion(&pPix->drawable,
+ &WindowTable[pScreen->myNum]->winSize);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Damage tracking initialized for page flipping\n");
+ }
+ }
+#endif
} else if (syncType == DRI_2D_SYNC &&
oldContextType == DRI_NO_CONTEXT &&
newContextType == DRI_2D_CONTEXT) {
- pI830->LockHeld = 0;
+#ifdef DAMAGE
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+#endif
+
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (out)\n");
+
+ if (!pScrn->vtSema)
+ return;
+
+#ifdef DAMAGE
+ if (pI830->pDamage) {
+ RegionPtr pDamageReg = DamageRegion(pI830->pDamage);
+
+ if (pDamageReg) {
+ RegionRec region;
+ int nrects;
+
+ REGION_NULL(pScreen, &region);
+ REGION_SUBTRACT(pScreen, &region, pDamageReg, &pI830->driRegion);
+
+ if ((nrects = REGION_NUM_RECTS(&region)))
+ I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(&region));
+
+ REGION_UNINIT(pScreen, &region);
+ }
+ }
+#endif
+
+ I830EmitFlush(pScrn);
+
+#ifdef DAMAGE
+ /* Try flipping back to the front page if necessary */
+ if (sPriv && !sPriv->pf_enabled && sPriv->pf_current_page != 0) {
+ drm_i915_flip_t flip = { .pipes = 0 };
+
+ if (sPriv->pf_current_page & (0x3 << 2)) {
+ sPriv->pf_current_page = sPriv->pf_current_page & 0x3;
+ sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2;
+
+ flip.pipes |= 0x2;
+ }
+
+ if (sPriv->pf_current_page & 0x3) {
+ sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2);
+ sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1;
+
+ flip.pipes |= 0x1;
+ }
+
+ drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip));
+
+ if (sPriv->pf_current_page != 0)
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[dri] %s: kernel failed to unflip buffers.\n", __func__);
+ }
+#endif
+
+ pI830->LockHeld = 0;
} else if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (other)\n");
}
@@ -1047,7 +1189,6 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pbox = REGION_RECTS(prgn);
int nbox = REGION_NUM_RECTS(prgn);
@@ -1059,6 +1200,13 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+
+ if (I830PTR(pScrn)->third_buffer) {
+ I830SelectBuffer(pScrn, I830_SELECT_THIRD);
+ I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+
pbox++;
}
@@ -1085,7 +1233,7 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
- pI830->AccelInfoRec->NeedToSync = TRUE;
+ i830MarkSync(pScrn);
}
/* This routine is a modified form of XAADoBitBlt with the calls to
@@ -1115,9 +1263,9 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
BoxPtr pbox = REGION_RECTS(prgnSrc);
int nbox = REGION_NUM_RECTS(prgnSrc);
- BoxPtr pboxNew1 = 0;
- BoxPtr pboxNew2 = 0;
- DDXPointPtr pptNew1 = 0;
+ BoxPtr pboxNew1 = NULL;
+ BoxPtr pboxNew2 = NULL;
+ DDXPointPtr pptNew1 = NULL;
DDXPointPtr pptSrc = &ptOldOrg;
int dx = pParent->drawable.x - ptOldOrg.x;
@@ -1232,7 +1380,11 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
I830SelectBuffer(pScrn, I830_SELECT_BACK);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
- if (!IS_I96X(pI830)) {
+ if (pI830->third_buffer) {
+ I830SelectBuffer(pScrn, I830_SELECT_THIRD);
+ I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ }
+ if (!IS_I965G(pI830)) {
I830SelectBuffer(pScrn, I830_SELECT_DEPTH);
I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
}
@@ -1248,8 +1400,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
}
-
- pI830->AccelInfoRec->NeedToSync = TRUE;
+ i830MarkSync(pScrn);
}
/* Use callbacks from dri.c to support pageflipping mode for a single
@@ -1259,10 +1410,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
* allocate and free 3d-specific memory on demand.
*/
-
-
-
-
/* Use the miext/shadow module to maintain a list of dirty rectangles.
* These are blitted to the back buffer to keep both buffers clean
* during page-flipping when the 3d application isn't fullscreen.
@@ -1275,99 +1422,21 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
* might be faster, but seems like a lot more work...
*/
-
-#if 0
-/* This should be done *before* XAA syncs,
- * Otherwise will have to sync again???
- */
static void
-I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+I830DRISetPfMask(ScreenPtr pScreen, int pfMask)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- RegionPtr damage = &pBuf->damage;
- int i, num = REGION_NUM_RECTS(damage);
- BoxPtr pbox = REGION_RECTS(damage);
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
- int cmd, br13;
-
- /* Don't want to do this when no 3d is active and pages are
- * right-way-round :
- */
- if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0)
- return;
- br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
-
- if (pScrn->bitsPerPixel == 32) {
- cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- br13 |= 3 << 24;
- } else {
- cmd = (XY_SRC_COPY_BLT_CMD);
- br13 |= 1 << 24;
- }
-
- for (i = 0 ; i < num ; i++, pbox++) {
- BEGIN_LP_RING(8);
- OUT_RING(cmd);
- OUT_RING(br13);
- OUT_RING((pbox->y1 << 16) | pbox->x1);
- OUT_RING((pbox->y2 << 16) | pbox->x2);
- OUT_RING(pI830->BackBuffer.Start);
- OUT_RING((pbox->y1 << 16) | pbox->x1);
- OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
- ADVANCE_LP_RING();
- }
-}
-#endif
-
-static void
-I830EnablePageFlip(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- I830Ptr pI830 = I830PTR(pScrn);
- drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
-
- pSAREAPriv->pf_enabled = pI830->allowPageFlip;
- pSAREAPriv->pf_active = 0;
-
- if (pI830->allowPageFlip) {
- int br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16);
-
- BEGIN_LP_RING(8);
- if (pScrn->bitsPerPixel == 32) {
- OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- br13 |= 3 << 24;
- } else {
- OUT_RING(XY_SRC_COPY_BLT_CMD);
- br13 |= 1 << 24;
- }
-
- OUT_RING(br13);
- OUT_RING(0);
- OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX);
- OUT_RING(pI830->BackBuffer.Start);
- OUT_RING(0);
- OUT_RING(br13 & 0xffff);
- OUT_RING(pI830->FrontBuffer.Start);
- ADVANCE_LP_RING();
-
- pSAREAPriv->pf_active = 1;
- }
+ if (pI830->allowPageFlip && pfMask) {
+ pSAREAPriv->pf_enabled = pI830->allowPageFlip;
+ pSAREAPriv->pf_active = pfMask;
+ } else
+ pSAREAPriv->pf_active = 0;
}
-static void
-I830DisablePageFlip(ScreenPtr pScreen)
-{
- drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen);
-
- pSAREAPriv->pf_active = 0;
-}
-
-
+#if !DRI_SUPPORTS_CLIP_NOTIFY
static void
I830DRITransitionSingleToMulti3d(ScreenPtr pScreen)
{
@@ -1375,16 +1444,20 @@ I830DRITransitionSingleToMulti3d(ScreenPtr pScreen)
* -- Field in sarea, plus bumping the window counters.
* -- DRM needs to cope with Front-to-Back swapbuffers.
*/
- I830DisablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, 0);
}
static void
I830DRITransitionMultiToSingle3d(ScreenPtr pScreen)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I830Ptr pI830 = I830PTR(pScrn);
+
/* Let the remaining 3d app start page flipping again.
*/
- I830EnablePageFlip(pScreen);
+ I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
}
+#endif /* !DRI_SUPPORTS_CLIP_NOTIFY */
static void
I830DRITransitionTo3d(ScreenPtr pScreen)
@@ -1392,10 +1465,11 @@ I830DRITransitionTo3d(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- I830EnablePageFlip(pScreen);
- pI830->have3DWindows = 1;
-}
+ I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0);
+ pI830->want_vblank_interrupts = TRUE;
+ I830DRISetVBlankInterrupt(pScrn, TRUE);
+}
static void
I830DRITransitionTo2d(ScreenPtr pScreen)
@@ -1404,128 +1478,290 @@ I830DRITransitionTo2d(ScreenPtr pScreen)
I830Ptr pI830 = I830PTR(pScrn);
drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
- /* Try flipping back to the front page if necessary */
- if (sPriv->pf_current_page == 1)
- drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP);
-
- /* Shut down shadowing if we've made it back to the front page:
- */
- if (sPriv->pf_current_page == 0) {
- I830DisablePageFlip(pScreen);
- }
+ I830DRISetPfMask(pScreen, 0);
- pI830->have3DWindows = 0;
+ sPriv->pf_enabled = 0;
+ pI830->want_vblank_interrupts = FALSE;
+ I830DRISetVBlankInterrupt(pScrn, FALSE);
}
-
-/**
- * Update the SAREA fields with the most recent values.
- * This gets called after the screen orientation/rotation changes.
- */
-Bool
-I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+#if DRI_SUPPORTS_CLIP_NOTIFY
+static void
+I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
- Bool success;
-
- I830DRIUnmapScreenRegions(pScrn, sarea);
+ unsigned pfMask = 0;
+
+ REGION_UNINIT(pScreen, &pI830->driRegion);
+ REGION_NULL(pScreen, &pI830->driRegion);
+
+ if (num > 0) {
+ drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+ BoxRec crtcBox[2];
+ unsigned numvisible[2] = { 0, 0 };
+ int i, j;
+
+ crtcBox[0].x1 = sPriv->planeA_x;
+ crtcBox[0].y1 = sPriv->planeA_y;
+ crtcBox[0].x2 = crtcBox[0].x1 + sPriv->planeA_w;
+ crtcBox[0].y2 = crtcBox[0].y1 + sPriv->planeA_h;
+ crtcBox[1].x1 = sPriv->planeB_x;
+ crtcBox[1].y1 = sPriv->planeB_y;
+ crtcBox[1].x2 = crtcBox[1].x1 + sPriv->planeB_w;
+ crtcBox[1].y2 = crtcBox[1].y1 + sPriv->planeB_h;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < num; j++) {
+ WindowPtr pWin = ppWin[j];
+
+ if (pWin) {
+ if (RECT_IN_REGION(pScreen, &pWin->clipList, &crtcBox[i]) !=
+ rgnOUT)
+ numvisible[i]++;
+
+ if (i == 0)
+ REGION_UNION(pScreen, &pI830->driRegion, &pWin->clipList,
+ &pI830->driRegion);
+ }
+ }
- sarea->front_tiled = pI830->front_tiled;
- sarea->back_tiled = pI830->back_tiled;
- sarea->depth_tiled = pI830->depth_tiled;
- sarea->rotated_tiled = pI830->rotated_tiled;
-#if 0
- sarea->rotated2_tiled = pI830->rotated2_tiled;
-#endif
+ if (numvisible[i] == 1)
+ pfMask |= 1 << i;
+ }
+ } else
+ REGION_NULL(pScreen, &pI830->driRegion);
- if (pI830->rotation == RR_Rotate_0) {
- sarea->front_offset = pI830->FrontBuffer.Start;
- /* Don't use FrontBuffer.Size here as it includes the pixmap cache area
- * Instead, calculate the entire framebuffer.
- */
- sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp;
- } else {
- /* Need to deal with rotated2 once we have dual head DRI */
- sarea->front_offset = pI830->RotatedMem.Start;
- sarea->front_size = pI830->RotatedMem.Size;
- }
+ I830DRISetPfMask(pScreen, pfMask);
+}
+#endif /* DRI_SUPPORTS_CLIP_NOTIFY */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "[drm] init sarea width,height = %d x %d (pitch %d)\n",
- pScreen->width, pScreen->height,pScrn->displayWidth);
+/**
+ * Update the SAREA fields with current buffer information.
+ *
+ * Most of the SAREA fields are already updated by i830_do_addmap().
+ *
+ * This does include other SAREA initialization which will actually be constant
+ * over the lifetime of the server.
+ */
+static void
+i830_update_sarea(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ I830Ptr pI830 = I830PTR(pScrn);
sarea->width = pScreen->width;
sarea->height = pScreen->height;
- sarea->back_offset = pI830->BackBuffer.Start;
- sarea->back_size = pI830->BackBuffer.Size;
- sarea->depth_offset = pI830->DepthBuffer.Start;
- sarea->depth_size = pI830->DepthBuffer.Size;
- sarea->tex_offset = pI830->TexMem.Start;
- sarea->tex_size = pI830->TexMem.Size;
- sarea->log_tex_granularity = pI830->TexGranularity;
sarea->pitch = pScrn->displayWidth;
sarea->virtualX = pScrn->virtualX;
sarea->virtualY = pScrn->virtualY;
- switch (pI830->rotation) {
- case RR_Rotate_0:
- sarea->rotation = 0;
- break;
- case RR_Rotate_90:
- sarea->rotation = 90;
- break;
- case RR_Rotate_180:
- sarea->rotation = 180;
- break;
- case RR_Rotate_270:
- sarea->rotation = 270;
- break;
- default:
- sarea->rotation = 0;
+ sarea->front_tiled = (pI830->front_buffer->tiling != TILE_NONE);
+ sarea->back_tiled = (pI830->back_buffer->tiling != TILE_NONE);
+ if (pI830->third_buffer != NULL)
+ sarea->third_tiled = (pI830->third_buffer->tiling != TILE_NONE);
+ else
+ sarea->third_tiled = FALSE;
+ sarea->depth_tiled = (pI830->depth_buffer->tiling != TILE_NONE);
+ sarea->rotated_tiled = FALSE;
+
+ sarea->log_tex_granularity = pI830->TexGranularity;
+
+ sarea->front_bo_handle = -1;
+ sarea->back_bo_handle = -1;
+ sarea->third_bo_handle = -1;
+ sarea->depth_bo_handle = -1;
+#ifdef XF86DRI_MM
+ if (pI830->front_buffer->bo.size)
+ sarea->front_bo_handle = pI830->front_buffer->bo.handle;
+ if (pI830->back_buffer->bo.size)
+ sarea->back_bo_handle = pI830->back_buffer->bo.handle;
+ if (pI830->third_buffer != NULL && pI830->third_buffer->bo.size)
+ sarea->third_bo_handle = pI830->third_buffer->bo.handle;
+ if (pI830->depth_buffer->bo.size)
+ sarea->depth_bo_handle = pI830->depth_buffer->bo.handle;
+#endif
+
+ /* The rotation is now handled entirely by the X Server, so just leave the
+ * DRI unaware.
+ */
+ sarea->rotation = 0;
+ sarea->rotated_offset = -1;
+ sarea->rotated_size = 0;
+ sarea->rotated_pitch = pScrn->displayWidth;
+}
+
+/**
+ * Updates the DRI mapping for the given i830_memory struct, with the given
+ * flags.
+ */
+static int
+i830_do_addmap(ScrnInfoPtr pScrn, i830_memory *mem,
+ drm_handle_t *sarea_handle, int *sarea_size, int *sarea_offset)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int size = mem->size;
+
+ if (mem == pI830->front_buffer) {
+ /* Workaround for XAA pixmap cache: Don't use front_buffer->size
+ * and instead, calculate the visible frontbuffer size and round to
+ * avoid irritating the assertions of older DRI drivers.
+ */
+ size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY *
+ pI830->cpp);
+ }
+
+ if (*sarea_handle != 0 &&
+ (*sarea_size != size || *sarea_offset != mem->offset))
+ {
+ drmRmMap(pI830->drmSubFD, *sarea_handle);
+ *sarea_handle = 0;
+ *sarea_size = 0;
+ *sarea_offset = 0;
+ }
+
+ if (*sarea_handle == 0) {
+ int ret;
+
+ ret = drmAddMap(pI830->drmSubFD,
+ (drm_handle_t)(mem->offset + pI830->LinearAddr),
+ size, DRM_AGP, 0,
+ (drmAddress) sarea_handle);
+ if (ret == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] mapped %s at 0x%08lx, handle = 0x%08x\n",
+ mem->name, mem->offset + pI830->LinearAddr,
+ (int)*sarea_handle);
+ *sarea_size = size;
+ *sarea_offset = mem->offset;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to map %s at 0x%08lx\n",
+ mem->name, mem->offset + pI830->LinearAddr);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * Updates the DRM mappings with the current buffer information.
+ *
+ * Some old DRI drivers may be unprepared for buffers actually moving at
+ * runtime, which would likely result in bus errors on software fallbacks or
+ * hangs or misrendering on hardware rendering.
+ */
+static Bool
+i830_update_dri_mappings(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (!i830_do_addmap(pScrn, pI830->front_buffer, &sarea->front_handle,
+ &sarea->front_size, &sarea->front_offset)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
+ return FALSE;
+ }
+
+ if (!i830_do_addmap(pScrn, pI830->back_buffer, &sarea->back_handle,
+ &sarea->back_size, &sarea->back_offset)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
+ return FALSE;
+ }
+
+ if (pI830->third_buffer) {
+ if (!i830_do_addmap(pScrn, pI830->third_buffer, &sarea->third_handle,
+ &sarea->third_size, &sarea->third_offset)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
+ return FALSE;
+ }
+ } else {
+ sarea->third_handle = 0;
+ sarea->third_offset = 0;
+ sarea->third_size = 0;
}
- if (pI830->rotation == RR_Rotate_0) {
- sarea->rotated_offset = -1;
- sarea->rotated_size = 0;
+
+ if (!i830_do_addmap(pScrn, pI830->depth_buffer, &sarea->depth_handle,
+ &sarea->depth_size, &sarea->depth_offset)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
+ return FALSE;
}
- else {
- sarea->rotated_offset = pI830->FrontBuffer.Start;
- sarea->rotated_size = pI830->FrontBuffer.Size;
+
+ if (pI830->allocate_classic_textures) {
+ if (!i830_do_addmap(pScrn, pI830->textures, &sarea->tex_handle,
+ &sarea->tex_size, &sarea->tex_offset)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n");
+ return FALSE;
+ }
}
- /* This is the original pitch */
- sarea->rotated_pitch = pI830->displayWidth;
+ return TRUE;
+}
- success = I830DRIMapScreenRegions(pScrn, sarea);
+static void
+i830_update_screen_private(ScrnInfoPtr pScrn, drmI830Sarea *sarea)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
- if (success && (pI830->mmModeFlags & I830_KERNEL_TEX))
- I830InitTextureHeap(pScrn, sarea);
+ pI830->pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr;
+ pI830->pDRIInfo->frameBufferStride = pScrn->displayWidth * pI830->cpp;
+ pI830->pDRIInfo->frameBufferSize = sarea->front_size;
+#if DRI_DRIVER_FRAMEBUFFER_MAP
+ pI830->pDRIInfo->hFrameBuffer = sarea->front_handle;
+#endif
+}
- return success;
+/**
+ * Update the SAREA fields, DRI mappings, and screen info passed through the
+ * protocol.
+ *
+ * This gets called both at startup and after any of the buffers might have
+ * been relocated.
+ */
+Bool
+i830_update_dri_buffers(ScrnInfoPtr pScrn)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ drmI830Sarea *sarea = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen);
+ Bool success;
+
+ success = i830_update_dri_mappings(pScrn, sarea);
+ if (!success)
+ return FALSE;
+ i830_update_sarea(pScrn, sarea);
+ i830_update_screen_private(pScrn, sarea);
+
+ return TRUE;
}
Bool
I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
{
I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
drmI830VBlankPipe pipe;
+ /* If we have no 3d running, then don't bother enabling the vblank
+ * interrupt.
+ */
+ if (!pI830->want_vblank_interrupts)
+ on = FALSE;
+
if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
if (on) {
- if (pI830->planeEnabled[1]) {
+ if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
if (pI830->drmMinor >= 6)
pipe.pipe = DRM_I830_VBLANK_PIPE_A | DRM_I830_VBLANK_PIPE_B;
else
pipe.pipe = DRM_I830_VBLANK_PIPE_B;
- } else
+ else
pipe.pipe = DRM_I830_VBLANK_PIPE_A;
} else {
pipe.pipe = 0;
}
if (drmCommandWrite(pI830->drmSubFD, DRM_I830_SET_VBLANK_PIPE,
&pipe, sizeof (pipe))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830 Vblank Pipe Setup Failed\n");
return FALSE;
}
}
@@ -1541,7 +1777,7 @@ I830DRILock(ScrnInfoPtr pScrn)
if (pI830->directRenderingEnabled && !pI830->LockHeld) {
DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
pI830->LockHeld = 1;
- I830RefreshRing(pScrn);
+ i830_refresh_ring(pScrn);
return TRUE;
}
else