0e825302fc
that shipped with OpenBSD 3.9/4.0 and that actually works.
1538 lines
46 KiB
C
1538 lines
46 KiB
C
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c,v 1.41 2003/09/24 02:43:23 dawes Exp $ */
|
|
/*
|
|
* Reformatted with GNU indent (2.2.8), using the following options:
|
|
*
|
|
* -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78
|
|
* -lp -npcs -psl -sob -ss -br -ce -sc -hnl
|
|
*
|
|
* This provides a good match with the original i810 code and preferred
|
|
* XFree86 formatting conventions.
|
|
*
|
|
* When editing this driver, please follow the existing formatting, and edit
|
|
* with <TAB> characters expanded at 8-column intervals.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "xf86.h"
|
|
#include "xf86_OSproc.h"
|
|
#include "xf86_ansic.h"
|
|
#include "xf86Priv.h"
|
|
|
|
#include "xf86PciInfo.h"
|
|
#include "xf86Pci.h"
|
|
|
|
#include "windowstr.h"
|
|
#include "shadow.h"
|
|
#include "shadowfb.h"
|
|
|
|
#include "GL/glxtokens.h"
|
|
|
|
#include "i810.h"
|
|
#include "i810_dri.h"
|
|
|
|
static char I810KernelDriverName[] = "i810";
|
|
static char I810ClientDriverName[] = "i810";
|
|
|
|
static Bool I810InitVisualConfigs(ScreenPtr pScreen);
|
|
static Bool I810CreateContext(ScreenPtr pScreen, VisualPtr visual,
|
|
drm_context_t hwContext, void *pVisualConfigPriv,
|
|
DRIContextType contextStore);
|
|
static void I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
|
|
DRIContextType contextStore);
|
|
static void I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
|
|
DRIContextType readContextType,
|
|
void *readContextStore,
|
|
DRIContextType writeContextType,
|
|
void *writeContextStore);
|
|
static void I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
|
|
static void I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
|
|
RegionPtr prgnSrc, CARD32 index);
|
|
|
|
|
|
static void I810EnablePageFlip(ScreenPtr pScreen);
|
|
static void I810DisablePageFlip(ScreenPtr pScreen);
|
|
static void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen);
|
|
static void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen);
|
|
static void I810DRITransitionTo3d(ScreenPtr pScreen);
|
|
static void I810DRITransitionTo2d(ScreenPtr pScreen);
|
|
|
|
static void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
|
|
|
|
extern void GlxSetVisualConfigs(int nconfigs,
|
|
__GLXvisualConfig * configs,
|
|
void **configprivs);
|
|
|
|
static int i810_pitches[] = {
|
|
512,
|
|
1024,
|
|
2048,
|
|
4096,
|
|
0
|
|
};
|
|
|
|
static int i810_pitch_flags[] = {
|
|
0x0,
|
|
0x1,
|
|
0x2,
|
|
0x3,
|
|
0
|
|
};
|
|
|
|
static unsigned int i810_drm_version = 0;
|
|
|
|
Bool
|
|
I810CleanupDma(ScrnInfoPtr pScrn)
|
|
{
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
drmI810Init info;
|
|
|
|
memset(&info, 0, sizeof(drmI810Init));
|
|
info.func = I810_CLEANUP_DMA;
|
|
|
|
if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT,
|
|
&info, sizeof(drmI810Init))) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"[dri] I810 Dma Cleanup Failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
I810InitDma(ScrnInfoPtr pScrn)
|
|
{
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
I810RingBuffer *ring = pI810->LpRing;
|
|
I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate;
|
|
drmI810Init info;
|
|
|
|
memset(&info, 0, sizeof(drmI810Init));
|
|
|
|
info.ring_start = ring->mem.Start;
|
|
info.ring_end = ring->mem.End;
|
|
info.ring_size = ring->mem.Size;
|
|
info.mmio_offset = (unsigned int)pI810DRI->regs;
|
|
info.buffers_offset = (unsigned int)pI810->buffer_map;
|
|
info.sarea_priv_offset = sizeof(XF86DRISAREARec);
|
|
|
|
info.front_offset = 0;
|
|
info.back_offset = pI810->BackBuffer.Start;
|
|
info.depth_offset = pI810->DepthBuffer.Start;
|
|
info.overlay_offset = pI810->OverlayStart;
|
|
info.overlay_physical = pI810->OverlayPhysical;
|
|
info.w = pScrn->virtualX;
|
|
info.h = pScrn->virtualY;
|
|
info.pitch = pI810->auxPitch;
|
|
info.pitch_bits = pI810->auxPitchBits;
|
|
|
|
/* We require DRM v1.2 or greater. Since DRM v1.2 broke compatibility
|
|
* we created a new v1.4 that supports a new init function. Eventually the
|
|
* old init function will go away. If you change the drm interface, make a
|
|
* new init type too so that we can detect the new client.
|
|
*/
|
|
switch(i810_drm_version) {
|
|
case ((1<<16) | 0):
|
|
case ((1<<16) | 1):
|
|
case ((1<<16) | 2):
|
|
case ((1<<16) | 3):
|
|
/* Use OLD drm < 1.4 init */
|
|
info.func = I810_INIT_DMA;
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init PRE v1.4 interface.\n");
|
|
break;
|
|
default:
|
|
case ((1<<16) | 4):
|
|
/* DRM version 1.3 or greater init */
|
|
info.func = I810_INIT_DMA_1_4;
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init v1.4 interface.\n");
|
|
break;
|
|
}
|
|
|
|
if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT,
|
|
&info, sizeof(drmI810Init))) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"[drm] I810 Dma Initialization failed.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
I810InitVisualConfigs(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
int numConfigs = 0;
|
|
__GLXvisualConfig *pConfigs = 0;
|
|
I810ConfigPrivPtr pI810Configs = 0;
|
|
I810ConfigPrivPtr *pI810ConfigPtrs = 0;
|
|
int accum, stencil, db, depth;
|
|
int i;
|
|
|
|
switch (pScrn->bitsPerPixel) {
|
|
case 8:
|
|
case 24:
|
|
case 32:
|
|
break;
|
|
case 16:
|
|
numConfigs = 8;
|
|
|
|
pConfigs =
|
|
(__GLXvisualConfig *) xcalloc(sizeof(__GLXvisualConfig),
|
|
numConfigs);
|
|
if (!pConfigs)
|
|
return FALSE;
|
|
|
|
pI810Configs =
|
|
(I810ConfigPrivPtr) xcalloc(sizeof(I810ConfigPrivRec),
|
|
numConfigs);
|
|
if (!pI810Configs) {
|
|
xfree(pConfigs);
|
|
return FALSE;
|
|
}
|
|
|
|
pI810ConfigPtrs =
|
|
(I810ConfigPrivPtr *) xcalloc(sizeof(I810ConfigPrivPtr),
|
|
numConfigs);
|
|
if (!pI810ConfigPtrs) {
|
|
xfree(pConfigs);
|
|
xfree(pI810Configs);
|
|
return FALSE;
|
|
}
|
|
|
|
for (i = 0; i < numConfigs; i++)
|
|
pI810ConfigPtrs[i] = &pI810Configs[i];
|
|
|
|
i = 0;
|
|
depth = 1;
|
|
for (accum = 0; accum <= 1; accum++) {
|
|
for (stencil = 0; stencil <= 1; stencil++) {
|
|
for (db = 1; db >= 0; db--) {
|
|
pConfigs[i].vid = -1;
|
|
pConfigs[i].class = -1;
|
|
pConfigs[i].rgba = TRUE;
|
|
pConfigs[i].redSize = 5;
|
|
pConfigs[i].greenSize = 6;
|
|
pConfigs[i].blueSize = 5;
|
|
pConfigs[i].redMask = 0x0000F800;
|
|
pConfigs[i].greenMask = 0x000007E0;
|
|
pConfigs[i].blueMask = 0x0000001F;
|
|
pConfigs[i].alphaMask = 0;
|
|
if (accum) {
|
|
pConfigs[i].accumRedSize = 16;
|
|
pConfigs[i].accumGreenSize = 16;
|
|
pConfigs[i].accumBlueSize = 16;
|
|
pConfigs[i].accumAlphaSize = 0;
|
|
} else {
|
|
pConfigs[i].accumRedSize = 0;
|
|
pConfigs[i].accumGreenSize = 0;
|
|
pConfigs[i].accumBlueSize = 0;
|
|
pConfigs[i].accumAlphaSize = 0;
|
|
}
|
|
pConfigs[i].doubleBuffer = db ? TRUE : FALSE;
|
|
pConfigs[i].stereo = FALSE;
|
|
pConfigs[i].bufferSize = 16;
|
|
if (depth)
|
|
pConfigs[i].depthSize = 16;
|
|
else
|
|
pConfigs[i].depthSize = 0;
|
|
if (stencil)
|
|
pConfigs[i].stencilSize = 8;
|
|
else
|
|
pConfigs[i].stencilSize = 0;
|
|
pConfigs[i].auxBuffers = 0;
|
|
pConfigs[i].level = 0;
|
|
if (stencil || accum)
|
|
pConfigs[i].visualRating = GLX_SLOW_CONFIG;
|
|
else
|
|
pConfigs[i].visualRating = GLX_NONE;
|
|
pConfigs[i].transparentPixel = GLX_NONE;
|
|
pConfigs[i].transparentRed = 0;
|
|
pConfigs[i].transparentGreen = 0;
|
|
pConfigs[i].transparentBlue = 0;
|
|
pConfigs[i].transparentAlpha = 0;
|
|
pConfigs[i].transparentIndex = 0;
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
assert(i == numConfigs);
|
|
break;
|
|
}
|
|
pI810->numVisualConfigs = numConfigs;
|
|
pI810->pVisualConfigs = pConfigs;
|
|
pI810->pVisualConfigsPriv = pI810Configs;
|
|
GlxSetVisualConfigs(numConfigs, pConfigs, (void **)pI810ConfigPtrs);
|
|
return TRUE;
|
|
}
|
|
|
|
static unsigned int
|
|
mylog2(unsigned int n)
|
|
{
|
|
unsigned int log2 = 1;
|
|
|
|
while (n > 1)
|
|
n >>= 1, log2++;
|
|
return log2;
|
|
}
|
|
|
|
Bool
|
|
I810DRIScreenInit(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
DRIInfoPtr pDRIInfo;
|
|
I810DRIPtr pI810DRI;
|
|
unsigned long tom;
|
|
drm_handle_t agpHandle;
|
|
drm_handle_t dcacheHandle;
|
|
int sysmem_size = 0;
|
|
int back_size = 0;
|
|
unsigned int pitch_idx = 0;
|
|
int bufs;
|
|
int width = pScrn->displayWidth * pI810->cpp;
|
|
int i;
|
|
|
|
/* Hardware 3D rendering only implemented for 16bpp */
|
|
/* And it only works for 5:6:5 (Mark) */
|
|
if (pScrn->depth != 16)
|
|
return FALSE;
|
|
|
|
/* Check that the GLX, DRI, and DRM modules have been loaded by testing
|
|
* for known symbols in each module. */
|
|
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs"))
|
|
return FALSE;
|
|
if (!xf86LoaderCheckSymbol("drmAvailable"))
|
|
return FALSE;
|
|
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] I810DRIScreenInit failed (libdri.a too old)\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* Check the DRI version */
|
|
{
|
|
int major, minor, patch;
|
|
|
|
DRIQueryVersion(&major, &minor, &patch);
|
|
if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] I810DRIScreenInit failed because of a version mismatch.\n"
|
|
"[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
|
|
"[dri] Disabling DRI.\n", major, minor, patch,
|
|
DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
pDRIInfo = DRICreateInfoRec();
|
|
if (!pDRIInfo) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] DRICreateInfoRec failed. Disabling DRI.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* pDRIInfo->wrap.ValidateTree = 0; */
|
|
/* pDRIInfo->wrap.PostValidateTree = 0; */
|
|
|
|
pI810->pDRIInfo = pDRIInfo;
|
|
pI810->LockHeld = 0;
|
|
|
|
pDRIInfo->drmDriverName = I810KernelDriverName;
|
|
pDRIInfo->clientDriverName = I810ClientDriverName;
|
|
if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
|
|
pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo);
|
|
} else {
|
|
pDRIInfo->busIdString = xalloc(64);
|
|
sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
|
|
((pciConfigPtr) pI810->PciInfo->thisCard)->busnum,
|
|
((pciConfigPtr) pI810->PciInfo->thisCard)->devnum,
|
|
((pciConfigPtr) pI810->PciInfo->thisCard)->funcnum);
|
|
}
|
|
pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION;
|
|
pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION;
|
|
pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL;
|
|
pDRIInfo->frameBufferPhysicalAddress = pI810->LinearAddr;
|
|
pDRIInfo->frameBufferSize = (((pScrn->displayWidth *
|
|
pScrn->virtualY * pI810->cpp) +
|
|
4096 - 1) / 4096) * 4096;
|
|
|
|
pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp;
|
|
pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES;
|
|
|
|
if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES)
|
|
pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
|
|
else
|
|
pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES;
|
|
|
|
/* For now the mapping works by using a fixed size defined
|
|
* in the SAREA header
|
|
*/
|
|
if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] Data does not fit in SAREA\n");
|
|
return FALSE;
|
|
}
|
|
pDRIInfo->SAREASize = SAREA_MAX;
|
|
|
|
if (!(pI810DRI = (I810DRIPtr) xcalloc(sizeof(I810DRIRec), 1))) {
|
|
DRIDestroyInfoRec(pI810->pDRIInfo);
|
|
pI810->pDRIInfo = 0;
|
|
return FALSE;
|
|
}
|
|
pDRIInfo->devPrivate = pI810DRI;
|
|
pDRIInfo->devPrivateSize = sizeof(I810DRIRec);
|
|
pDRIInfo->contextSize = sizeof(I810DRIContextRec);
|
|
|
|
pDRIInfo->CreateContext = I810CreateContext;
|
|
pDRIInfo->DestroyContext = I810DestroyContext;
|
|
pDRIInfo->SwapContext = I810DRISwapContext;
|
|
pDRIInfo->InitBuffers = I810DRIInitBuffers;
|
|
pDRIInfo->MoveBuffers = I810DRIMoveBuffers;
|
|
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
|
|
pDRIInfo->TransitionTo2d = I810DRITransitionTo2d;
|
|
pDRIInfo->TransitionTo3d = I810DRITransitionTo3d;
|
|
pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d;
|
|
pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d;
|
|
|
|
pDRIInfo->createDummyCtx = TRUE;
|
|
pDRIInfo->createDummyCtxPriv = FALSE;
|
|
|
|
/* This adds the framebuffer as a drm map *before* we have asked agp
|
|
* to allocate it. Scary stuff, hold on...
|
|
*/
|
|
if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] DRIScreenInit failed. Disabling DRI.\n");
|
|
xfree(pDRIInfo->devPrivate);
|
|
pDRIInfo->devPrivate = 0;
|
|
DRIDestroyInfoRec(pI810->pDRIInfo);
|
|
pI810->pDRIInfo = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
/* Check the i810 DRM versioning */
|
|
{
|
|
drmVersionPtr version;
|
|
|
|
/* Check the DRM lib version.
|
|
* drmGetLibVersion was not supported in version 1.0, so check for
|
|
* symbol first to avoid possible crash or hang.
|
|
*/
|
|
if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
|
|
version = drmGetLibVersion(pI810->drmSubFD);
|
|
} else
|
|
{
|
|
/* drmlib version 1.0.0 didn't have the drmGetLibVersion
|
|
* entry point. Fake it by allocating a version record
|
|
* via drmGetVersion and changing it to version 1.0.0
|
|
*/
|
|
version = drmGetVersion(pI810->drmSubFD);
|
|
version->version_major = 1;
|
|
version->version_minor = 0;
|
|
version->version_patchlevel = 0;
|
|
}
|
|
|
|
#define REQ_MAJ 1
|
|
#define REQ_MIN 1
|
|
if (version) {
|
|
if (version->version_major != REQ_MAJ ||
|
|
version->version_minor < REQ_MIN) {
|
|
/* incompatible drm library version */
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] I810DRIScreenInit failed because of a version mismatch.\n"
|
|
"[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n"
|
|
"[dri] Disabling DRI.\n",
|
|
version->version_major,
|
|
version->version_minor, version->version_patchlevel,
|
|
REQ_MAJ, REQ_MIN);
|
|
drmFreeVersion(version);
|
|
I810DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
drmFreeVersion(version);
|
|
}
|
|
|
|
/* Check the i810 DRM version */
|
|
version = drmGetVersion(pI810->drmSubFD);
|
|
if (version) {
|
|
i810_drm_version = (version->version_major<<16) |
|
|
version->version_minor;
|
|
if (version->version_major != 1 || version->version_minor < 2) {
|
|
/* incompatible drm version */
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] I810DRIScreenInit failed because of a version mismatch.\n"
|
|
"[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n"
|
|
"[dri] Disabling DRI.\n",
|
|
version->version_major,
|
|
version->version_minor, version->version_patchlevel);
|
|
I810DRICloseScreen(pScreen);
|
|
drmFreeVersion(version);
|
|
return FALSE;
|
|
}
|
|
pI810->drmMinor = version->version_minor;
|
|
drmFreeVersion(version);
|
|
}
|
|
}
|
|
|
|
pI810DRI->regsSize = I810_REG_SIZE;
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr,
|
|
pI810DRI->regsSize, DRM_REGISTERS, 0, &pI810DRI->regs) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
|
|
pI810DRI->regs);
|
|
|
|
pI810->backHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->zHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->cursorHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->xvmcHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->sysmemHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->agpAcquired = FALSE;
|
|
pI810->dcacheHandle = DRM_AGP_NO_HANDLE;
|
|
|
|
/* Agp Support - Need this just to get the framebuffer.
|
|
*/
|
|
if (drmAgpAcquire(pI810->drmSubFD) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
pI810->agpAcquired = TRUE;
|
|
|
|
if (drmAgpEnable(pI810->drmSubFD, 0) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
|
|
memset(&pI810->BackBuffer, 0, sizeof(I810MemRange));
|
|
memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange));
|
|
pI810->CursorPhysical = 0;
|
|
pI810->CursorARGBPhysical = 0;
|
|
|
|
/* Dcache - half the speed of normal ram, but has use as a Z buffer
|
|
* under the DRI.
|
|
*/
|
|
|
|
drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, &dcacheHandle);
|
|
pI810->dcacheHandle = dcacheHandle;
|
|
|
|
xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n",
|
|
dcacheHandle);
|
|
|
|
#define Elements(x) sizeof(x)/sizeof(*x)
|
|
for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)
|
|
if (width <= i810_pitches[pitch_idx])
|
|
break;
|
|
|
|
if (pitch_idx == Elements(i810_pitches)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[dri] Couldn't find depth/back buffer pitch");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
} else {
|
|
/* for tiled memory to work, the buffer needs to have the
|
|
* number of lines as a multiple of 16 (the tile size),
|
|
* - airlied */
|
|
int lines = (pScrn->virtualY + 15) / 16 * 16;
|
|
back_size = i810_pitches[pitch_idx] * lines;
|
|
back_size = ((back_size + 4096 - 1) / 4096) * 4096;
|
|
}
|
|
|
|
sysmem_size = pScrn->videoRam * 1024;
|
|
if (dcacheHandle != DRM_AGP_NO_HANDLE) {
|
|
if (back_size > 4 * 1024 * 1024) {
|
|
xf86DrvMsg(pScreen->myNum, X_INFO,
|
|
"[dri] Backsize is larger then 4 meg\n");
|
|
sysmem_size = sysmem_size - 2 * back_size;
|
|
drmAgpFree(pI810->drmSubFD, dcacheHandle);
|
|
pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
|
|
} else {
|
|
sysmem_size = sysmem_size - back_size;
|
|
}
|
|
} else {
|
|
sysmem_size = sysmem_size - 2 * back_size;
|
|
}
|
|
|
|
/* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */
|
|
if (pI810->numSurfaces && (pI810->numSurfaces == 6)) {
|
|
if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) {
|
|
sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024);
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"User requested more memory then fits in the agp aperture\n"
|
|
"Truncating to %d bytes of memory\n", sysmem_size);
|
|
}
|
|
}
|
|
if (pI810->numSurfaces && (pI810->numSurfaces == 7)) {
|
|
if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) {
|
|
sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024);
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"User requested more memory then fits in the agp aperture\n"
|
|
"Truncating to %d bytes of memory\n", sysmem_size);
|
|
}
|
|
}
|
|
|
|
if (sysmem_size > pI810->FbMapSize) {
|
|
sysmem_size = pI810->FbMapSize;
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[dri] User requested more memory then fits in the agp"
|
|
" aperture\n\tTruncating to %d bytes of memory\n",
|
|
sysmem_size);
|
|
}
|
|
|
|
sysmem_size -= 4096; /* remove 4k for the hw cursor */
|
|
sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */
|
|
|
|
pI810->SysMem.Start = 0;
|
|
pI810->SysMem.Size = sysmem_size;
|
|
pI810->SysMem.End = sysmem_size;
|
|
tom = sysmem_size;
|
|
|
|
pI810->SavedSysMem = pI810->SysMem;
|
|
|
|
if (dcacheHandle != DRM_AGP_NO_HANDLE) {
|
|
if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) {
|
|
memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: Found 4096K Z buffer memory\n");
|
|
pI810->DcacheMem.Start = pI810->DepthOffset;
|
|
pI810->DcacheMem.Size = 1024 * 4096;
|
|
pI810->DcacheMem.End =
|
|
pI810->DcacheMem.Start + pI810->DcacheMem.Size;
|
|
if (!I810AllocLow
|
|
(&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Depth buffer allocation failed\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: dcache bind failed\n");
|
|
drmAgpFree(pI810->drmSubFD, dcacheHandle);
|
|
pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: no dcache memory found\n");
|
|
}
|
|
|
|
drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle);
|
|
pI810->backHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Bound backbuffer memory\n");
|
|
|
|
pI810->BackBuffer.Start = pI810->BackOffset;
|
|
pI810->BackBuffer.Size = back_size;
|
|
pI810->BackBuffer.End = (pI810->BackBuffer.Start +
|
|
pI810->BackBuffer.Size);
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Unable to bind backbuffer. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[dri] Unable to allocate backbuffer memory. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
if (dcacheHandle == DRM_AGP_NO_HANDLE) {
|
|
drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, &agpHandle);
|
|
|
|
pI810->zHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Bound depthbuffer memory\n");
|
|
pI810->DepthBuffer.Start = pI810->DepthOffset;
|
|
pI810->DepthBuffer.Size = back_size;
|
|
pI810->DepthBuffer.End = (pI810->DepthBuffer.Start +
|
|
pI810->DepthBuffer.Size);
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Unable to bind depthbuffer. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Now allocate and bind the agp space. This memory will include the
|
|
* regular framebuffer as well as texture memory.
|
|
*/
|
|
drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, &agpHandle);
|
|
pI810->sysmemHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] Bound System Texture Memory\n");
|
|
} else {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled
|
|
regions and required surface pitches. (Numbers are adjusted if the
|
|
AGP region is only 32MB
|
|
For numSurfaces == 6
|
|
44 - 48MB = 4MB Fence, 8 Tiles wide
|
|
43 - 44MB = 1MB Fence, 8 Tiles wide
|
|
42 - 43MB = 1MB Fence, 4 Tiles wide
|
|
41 - 42MB = 1MB Fence, 4 Tiles wide
|
|
For numSurfaces == 7
|
|
44 - 48MB = 4MB Fence, 8 Tiles wide
|
|
43 - 44MB = 1MB Fence, 8 Tiles wide
|
|
42.5 - 43MB = 0.5MB Fence, 8 Tiles wide
|
|
42 - 42.5MB = 0.5MB Fence, 4 Tiles wide
|
|
40 - 42MB = 2MB Fence, 4 Tiles wide
|
|
*/
|
|
if (pI810->numSurfaces) {
|
|
if (pI810->numSurfaces == 6) {
|
|
pI810->MC.Size = 7 * 1024 * 1024;
|
|
pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024;
|
|
|
|
}
|
|
if (pI810->numSurfaces == 7) {
|
|
pI810->MC.Size = 8 * 1024 * 1024;
|
|
pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024;
|
|
}
|
|
drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, &agpHandle);
|
|
|
|
pI810->xvmcHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"GART: Allocated 7MB for HWMC\n");
|
|
pI810->MC.End = pI810->MC.Start + pI810->MC.Size;
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n");
|
|
pI810->MC.Start = 0;
|
|
pI810->MC.Size = 0;
|
|
pI810->MC.End = 0;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n");
|
|
pI810->MC.Start = 0;
|
|
pI810->MC.Size = 0;
|
|
pI810->MC.End = 0;
|
|
}
|
|
pI810->xvmcContext = 0;
|
|
}
|
|
|
|
drmAgpAlloc(pI810->drmSubFD, 4096, 2,
|
|
(unsigned long *)&pI810->CursorPhysical, &agpHandle);
|
|
|
|
pI810->cursorHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
tom = sysmem_size;
|
|
|
|
if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: Allocated 4K for mouse cursor image\n");
|
|
pI810->CursorStart = tom;
|
|
tom += 4096;
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: cursor bind failed\n");
|
|
pI810->CursorPhysical = 0;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: cursor alloc failed\n");
|
|
pI810->CursorPhysical = 0;
|
|
}
|
|
|
|
drmAgpAlloc(pI810->drmSubFD, 16384, 2,
|
|
(unsigned long *)&pI810->CursorARGBPhysical, &agpHandle);
|
|
|
|
pI810->cursorARGBHandle = agpHandle;
|
|
|
|
if (agpHandle != DRM_AGP_NO_HANDLE) {
|
|
int r;
|
|
|
|
if ((r = drmAgpBind(pI810->drmSubFD, agpHandle, tom)) == 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: Allocated 16K for ARGB mouse cursor image\n");
|
|
pI810->CursorARGBStart = tom;
|
|
tom += 16384;
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: ARGB cursor bind failed\n");
|
|
pI810->CursorARGBPhysical = 0;
|
|
}
|
|
} else {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[agp] GART: ARGB cursor alloc failed\n");
|
|
pI810->CursorARGBPhysical = 0;
|
|
}
|
|
|
|
/* Steal some of the excess cursor space for the overlay regs.
|
|
*/
|
|
pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
|
|
pI810->OverlayStart = pI810->CursorStart + 1024;
|
|
|
|
I810SetTiledMemory(pScrn, 1,
|
|
pI810->DepthBuffer.Start,
|
|
i810_pitches[pitch_idx], 8 * 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 2,
|
|
pI810->BackBuffer.Start,
|
|
i810_pitches[pitch_idx], 8 * 1024 * 1024);
|
|
|
|
/* These are for HWMC surfaces */
|
|
if (pI810->numSurfaces == 6) {
|
|
I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 4,
|
|
pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 5,
|
|
pI810->MC.Start + 1024 * 1024 * 2,
|
|
1024, 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 6,
|
|
pI810->MC.Start + 1024 * 1024 * 3,
|
|
1024, 4 * 1024 * 1024);
|
|
}
|
|
if (pI810->numSurfaces == 7) {
|
|
I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 4,
|
|
pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 5,
|
|
pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024,
|
|
1024, 512 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 6,
|
|
pI810->MC.Start + 3 * 1024 * 1024,
|
|
1024, 1 * 1024 * 1024);
|
|
|
|
I810SetTiledMemory(pScrn, 7,
|
|
pI810->MC.Start + 4 * 1024 * 1024,
|
|
1024, 4 * 1024 * 1024);
|
|
|
|
}
|
|
|
|
pI810->auxPitch = i810_pitches[pitch_idx];
|
|
pI810->auxPitchBits = i810_pitch_flags[pitch_idx];
|
|
pI810->SavedDcacheMem = pI810->DcacheMem;
|
|
pI810DRI->backbufferSize = pI810->BackBuffer.Size;
|
|
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start,
|
|
pI810->BackBuffer.Size, DRM_AGP, 0,
|
|
&pI810DRI->backbuffer) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] drmAddMap(backbuffer) failed. Disabling DRI\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
pI810DRI->depthbufferSize = pI810->DepthBuffer.Size;
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start,
|
|
pI810->DepthBuffer.Size, DRM_AGP, 0,
|
|
&pI810DRI->depthbuffer) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Allocate FrontBuffer etc. */
|
|
if (!I810AllocateFront(pScrn)) {
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Allocate buffer memory */
|
|
I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem),
|
|
I810_DMA_BUF_NR * I810_DMA_BUF_SZ);
|
|
|
|
xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n",
|
|
pI810->BufferMem.Start);
|
|
|
|
if (pI810->BufferMem.Start == 0 ||
|
|
pI810->BufferMem.End - pI810->BufferMem.Start >
|
|
I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] Not enough memory for dma buffers. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start,
|
|
pI810->BufferMem.Size, DRM_AGP, 0, &pI810->buffer_map) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
pI810DRI->agp_buffers = pI810->buffer_map;
|
|
pI810DRI->agp_buf_size = pI810->BufferMem.Size;
|
|
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start,
|
|
pI810->LpRing->mem.Size, DRM_AGP, 0, &pI810->ring_map) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] drmAddMap(ring_map) failed. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Use the rest of memory for textures. */
|
|
pI810DRI->textureSize = pI810->SysMem.Size;
|
|
|
|
i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS);
|
|
|
|
if (i < I810_LOG_MIN_TEX_REGION_SIZE)
|
|
i = I810_LOG_MIN_TEX_REGION_SIZE;
|
|
|
|
pI810DRI->logTextureGranularity = i;
|
|
pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */
|
|
|
|
if (pI810DRI->textureSize < 512 * 1024) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] Less then 512k memory left for textures. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize);
|
|
|
|
if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start,
|
|
pI810->TexMem.Size, DRM_AGP, 0, &pI810DRI->textures) < 0) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[drm] drmAddMap(textures) failed. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
if ((bufs = drmAddBufs(pI810->drmSubFD,
|
|
I810_DMA_BUF_NR,
|
|
I810_DMA_BUF_SZ,
|
|
DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[drm] failure adding %d %d byte DMA buffers. Disabling DRI.\n",
|
|
I810_DMA_BUF_NR, I810_DMA_BUF_SZ);
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ);
|
|
|
|
I810InitDma(pScrn);
|
|
|
|
/* Okay now initialize the dma engine */
|
|
|
|
if (!pI810DRI->irq) {
|
|
pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD,
|
|
((pciConfigPtr) pI810->
|
|
PciInfo->thisCard)->busnum,
|
|
((pciConfigPtr) pI810->
|
|
PciInfo->thisCard)->devnum,
|
|
((pciConfigPtr) pI810->
|
|
PciInfo->thisCard)->funcnum);
|
|
if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[drm] failure adding irq handler, there is a device "
|
|
"already using that irq\n Consider rearranging your "
|
|
"PCI cards. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq);
|
|
|
|
pI810DRI->deviceID = pI810->PciInfo->chipType;
|
|
pI810DRI->width = pScrn->virtualX;
|
|
pI810DRI->height = pScrn->virtualY;
|
|
pI810DRI->mem = pScrn->videoRam * 1024;
|
|
pI810DRI->cpp = pI810->cpp;
|
|
|
|
pI810DRI->fbOffset = pI810->FrontBuffer.Start;
|
|
pI810DRI->fbStride = pI810->auxPitch;
|
|
|
|
pI810DRI->bitsPerPixel = pScrn->bitsPerPixel;
|
|
|
|
pI810DRI->textureOffset = pI810->TexMem.Start;
|
|
|
|
pI810DRI->backOffset = pI810->BackBuffer.Start;
|
|
pI810DRI->depthOffset = pI810->DepthBuffer.Start;
|
|
|
|
pI810DRI->ringOffset = pI810->LpRing->mem.Start;
|
|
pI810DRI->ringSize = pI810->LpRing->mem.Size;
|
|
|
|
pI810DRI->auxPitch = pI810->auxPitch;
|
|
pI810DRI->auxPitchBits = pI810->auxPitchBits;
|
|
pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
|
|
|
|
if (!(I810InitVisualConfigs(pScreen))) {
|
|
xf86DrvMsg(pScreen->myNum, X_ERROR,
|
|
"[dri] I810InitVisualConfigs failed. Disabling DRI.\n");
|
|
DRICloseScreen(pScreen);
|
|
return FALSE;
|
|
}
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"[dri] visual configs initialized.\n");
|
|
pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
I810DRICloseScreen(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate;
|
|
|
|
if (pI810DRI->irq) {
|
|
drmCtlUninstHandler(pI810->drmSubFD);
|
|
pI810DRI->irq = 0;
|
|
}
|
|
|
|
I810CleanupDma(pScrn);
|
|
|
|
if (pI810->dcacheHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle);
|
|
if (pI810->backHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->backHandle);
|
|
if (pI810->zHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->zHandle);
|
|
if (pI810->cursorHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->cursorHandle);
|
|
if (pI810->xvmcHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->xvmcHandle);
|
|
if (pI810->sysmemHandle!=DRM_AGP_NO_HANDLE)
|
|
drmAgpFree(pI810->drmSubFD, pI810->sysmemHandle);
|
|
|
|
if (pI810->agpAcquired == TRUE)
|
|
drmAgpRelease(pI810->drmSubFD);
|
|
|
|
pI810->backHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->zHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->cursorHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->xvmcHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->sysmemHandle = DRM_AGP_NO_HANDLE;
|
|
pI810->agpAcquired = FALSE;
|
|
pI810->dcacheHandle = DRM_AGP_NO_HANDLE;
|
|
|
|
DRICloseScreen(pScreen);
|
|
|
|
if (pI810->pDRIInfo) {
|
|
if (pI810->pDRIInfo->devPrivate) {
|
|
xfree(pI810->pDRIInfo->devPrivate);
|
|
pI810->pDRIInfo->devPrivate = 0;
|
|
}
|
|
DRIDestroyInfoRec(pI810->pDRIInfo);
|
|
pI810->pDRIInfo = 0;
|
|
}
|
|
if (pI810->pVisualConfigs)
|
|
xfree(pI810->pVisualConfigs);
|
|
if (pI810->pVisualConfigsPriv)
|
|
xfree(pI810->pVisualConfigsPriv);
|
|
}
|
|
|
|
static Bool
|
|
I810CreateContext(ScreenPtr pScreen, VisualPtr visual,
|
|
drm_context_t hwContext, void *pVisualConfigPriv,
|
|
DRIContextType contextStore)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
|
|
DRIContextType contextStore)
|
|
{
|
|
}
|
|
|
|
Bool
|
|
I810DRIFinishScreenInit(ScreenPtr pScreen)
|
|
{
|
|
I810SAREARec *sPriv = (I810SAREARec *) DRIGetSAREAPrivate(pScreen);
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr info = I810PTR(pScrn);
|
|
|
|
memset(sPriv, 0, sizeof(sPriv));
|
|
|
|
/* Have shadow run only while there is 3d active.
|
|
*/
|
|
if (info->allowPageFlip && info->drmMinor >= 3) {
|
|
ShadowFBInit( pScreen, I810DRIRefreshArea );
|
|
}
|
|
else
|
|
info->allowPageFlip = 0;
|
|
return DRIFinishScreenInit(pScreen);
|
|
}
|
|
|
|
void
|
|
I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
|
|
DRIContextType oldContextType, void *oldContext,
|
|
DRIContextType newContextType, void *newContext)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
|
|
if (syncType == DRI_3D_SYNC &&
|
|
oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) {
|
|
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
|
|
ErrorF("I810DRISwapContext (in)\n");
|
|
|
|
if (!pScrn->vtSema)
|
|
return;
|
|
pI810->LockHeld = 1;
|
|
I810RefreshRing(pScrn);
|
|
} else if (syncType == DRI_2D_SYNC &&
|
|
oldContextType == DRI_NO_CONTEXT &&
|
|
newContextType == DRI_2D_CONTEXT) {
|
|
pI810->LockHeld = 0;
|
|
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
|
|
ErrorF("I810DRISwapContext (out)\n");
|
|
} else if (I810_DEBUG & DEBUG_VERBOSE_DRI)
|
|
ErrorF("I810DRISwapContext (other)\n");
|
|
}
|
|
|
|
static void
|
|
I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
|
|
{
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
BoxPtr pbox = REGION_RECTS(prgn);
|
|
int nbox = REGION_NUM_RECTS(prgn);
|
|
|
|
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
|
|
ErrorF("I810DRIInitBuffers\n");
|
|
|
|
I810SetupForSolidFill(pScrn, 0, GXcopy, -1);
|
|
while (nbox--) {
|
|
I810SelectBuffer(pScrn, I810_SELECT_BACK);
|
|
I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
|
|
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
|
|
pbox++;
|
|
}
|
|
|
|
/* Clear the depth buffer - uses 0xffff rather than 0.
|
|
*/
|
|
pbox = REGION_RECTS(prgn);
|
|
nbox = REGION_NUM_RECTS(prgn);
|
|
I810SelectBuffer(pScrn, I810_SELECT_DEPTH);
|
|
I810SetupForSolidFill(pScrn, 0xffff, GXcopy, -1);
|
|
while (nbox--) {
|
|
I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
|
|
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
|
|
pbox++;
|
|
}
|
|
I810SelectBuffer(pScrn, I810_SELECT_FRONT);
|
|
pI810->AccelInfoRec->NeedToSync = TRUE;
|
|
}
|
|
|
|
/* This routine is a modified form of XAADoBitBlt with the calls to
|
|
* ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
|
|
* instead of destination. My origin is upside down so the ydir cases
|
|
* are reversed.
|
|
*
|
|
* KW: can you believe that this is called even when a 2d window moves?
|
|
*/
|
|
static void
|
|
I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
|
|
RegionPtr prgnSrc, CARD32 index)
|
|
{
|
|
ScreenPtr pScreen = pParent->drawable.pScreen;
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
BoxPtr pboxTmp, pboxNext, pboxBase;
|
|
DDXPointPtr pptTmp, pptNew2;
|
|
int xdir, ydir;
|
|
|
|
int screenwidth = pScrn->virtualX;
|
|
int screenheight = pScrn->virtualY;
|
|
|
|
BoxPtr pbox = REGION_RECTS(prgnSrc);
|
|
int nbox = REGION_NUM_RECTS(prgnSrc);
|
|
|
|
BoxPtr pboxNew1 = 0;
|
|
BoxPtr pboxNew2 = 0;
|
|
DDXPointPtr pptNew1 = 0;
|
|
DDXPointPtr pptSrc = &ptOldOrg;
|
|
|
|
int dx = pParent->drawable.x - ptOldOrg.x;
|
|
int dy = pParent->drawable.y - ptOldOrg.y;
|
|
|
|
/* If the copy will overlap in Y, reverse the order */
|
|
if (dy > 0) {
|
|
ydir = -1;
|
|
|
|
if (nbox > 1) {
|
|
/* Keep ordering in each band, reverse order of bands */
|
|
pboxNew1 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
|
|
if (!pboxNew1)
|
|
return;
|
|
pptNew1 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
|
|
if (!pptNew1) {
|
|
DEALLOCATE_LOCAL(pboxNew1);
|
|
return;
|
|
}
|
|
pboxBase = pboxNext = pbox + nbox - 1;
|
|
while (pboxBase >= pbox) {
|
|
while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
|
|
pboxNext--;
|
|
pboxTmp = pboxNext + 1;
|
|
pptTmp = pptSrc + (pboxTmp - pbox);
|
|
while (pboxTmp <= pboxBase) {
|
|
*pboxNew1++ = *pboxTmp++;
|
|
*pptNew1++ = *pptTmp++;
|
|
}
|
|
pboxBase = pboxNext;
|
|
}
|
|
pboxNew1 -= nbox;
|
|
pbox = pboxNew1;
|
|
pptNew1 -= nbox;
|
|
pptSrc = pptNew1;
|
|
}
|
|
} else {
|
|
/* No changes required */
|
|
ydir = 1;
|
|
}
|
|
|
|
/* If the regions will overlap in X, reverse the order */
|
|
if (dx > 0) {
|
|
xdir = -1;
|
|
|
|
if (nbox > 1) {
|
|
/*reverse orderof rects in each band */
|
|
pboxNew2 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
|
|
pptNew2 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
|
|
if (!pboxNew2 || !pptNew2) {
|
|
if (pptNew2)
|
|
DEALLOCATE_LOCAL(pptNew2);
|
|
if (pboxNew2)
|
|
DEALLOCATE_LOCAL(pboxNew2);
|
|
if (pboxNew1) {
|
|
DEALLOCATE_LOCAL(pptNew1);
|
|
DEALLOCATE_LOCAL(pboxNew1);
|
|
}
|
|
return;
|
|
}
|
|
pboxBase = pboxNext = pbox;
|
|
while (pboxBase < pbox + nbox) {
|
|
while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1))
|
|
pboxNext++;
|
|
pboxTmp = pboxNext;
|
|
pptTmp = pptSrc + (pboxTmp - pbox);
|
|
while (pboxTmp != pboxBase) {
|
|
*pboxNew2++ = *--pboxTmp;
|
|
*pptNew2++ = *--pptTmp;
|
|
}
|
|
pboxBase = pboxNext;
|
|
}
|
|
pboxNew2 -= nbox;
|
|
pbox = pboxNew2;
|
|
pptNew2 -= nbox;
|
|
pptSrc = pptNew2;
|
|
}
|
|
} else {
|
|
/* No changes are needed */
|
|
xdir = 1;
|
|
}
|
|
|
|
/* SelectBuffer isn't really a good concept for the i810.
|
|
*/
|
|
I810EmitFlush(pScrn);
|
|
I810SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
|
|
for (; nbox--; pbox++) {
|
|
|
|
int x1 = pbox->x1;
|
|
int y1 = pbox->y1;
|
|
int destx = x1 + dx;
|
|
int desty = y1 + dy;
|
|
int w = pbox->x2 - x1 + 1;
|
|
int h = pbox->y2 - y1 + 1;
|
|
|
|
if (destx < 0)
|
|
x1 -= destx, w += destx, destx = 0;
|
|
if (desty < 0)
|
|
y1 -= desty, h += desty, desty = 0;
|
|
if (destx + w > screenwidth)
|
|
w = screenwidth - destx;
|
|
if (desty + h > screenheight)
|
|
h = screenheight - desty;
|
|
if (w <= 0)
|
|
continue;
|
|
if (h <= 0)
|
|
continue;
|
|
|
|
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
|
|
ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n",
|
|
x1, y1, w, h, dx, dy);
|
|
|
|
I810SelectBuffer(pScrn, I810_SELECT_BACK);
|
|
I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
|
|
I810SelectBuffer(pScrn, I810_SELECT_DEPTH);
|
|
I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
|
|
}
|
|
I810SelectBuffer(pScrn, I810_SELECT_FRONT);
|
|
I810EmitFlush(pScrn);
|
|
|
|
if (pboxNew2) {
|
|
DEALLOCATE_LOCAL(pptNew2);
|
|
DEALLOCATE_LOCAL(pboxNew2);
|
|
}
|
|
if (pboxNew1) {
|
|
DEALLOCATE_LOCAL(pptNew1);
|
|
DEALLOCATE_LOCAL(pboxNew1);
|
|
}
|
|
|
|
pI810->AccelInfoRec->NeedToSync = TRUE;
|
|
}
|
|
|
|
|
|
/* 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.
|
|
*
|
|
* Unlike most use of the shadow code, both buffers are in video memory.
|
|
*
|
|
* An alternative to this would be to organize for all on-screen drawing
|
|
* operations to be duplicated for the two buffers. That might be
|
|
* faster, but seems like a lot more work...
|
|
*/
|
|
|
|
|
|
/* This should be done *before* XAA syncs or fires its buffer.
|
|
* Otherwise will have to fire it again???
|
|
*/
|
|
static void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
|
|
{
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
int i;
|
|
I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
|
|
unsigned int br13;
|
|
int cpp=2;
|
|
|
|
|
|
/* 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 = (pI810->auxPitch) | (0xcc << 16);
|
|
|
|
for (i = 0 ; i < num ; i++, pbox++) {
|
|
unsigned int w = min(pbox->y2, pScrn->virtualY-1) - max(pbox->y1, 0) + 1;
|
|
unsigned int h = min(pbox->x2, pScrn->virtualX-1) - max(pbox->x1, 0) + 1;
|
|
unsigned int dst = max(pbox->x1, 0)*cpp + (max(pbox->y1, 0)*pI810->auxPitch);
|
|
|
|
BEGIN_LP_RING(6);
|
|
|
|
OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
|
|
OUT_RING(br13);
|
|
OUT_RING( (h<<16) | (w*cpp) );
|
|
OUT_RING(pI810->BackBuffer.Start + dst);
|
|
OUT_RING(br13 & 0xffff);
|
|
OUT_RING(dst);
|
|
|
|
ADVANCE_LP_RING();
|
|
}
|
|
|
|
}
|
|
|
|
static void I810EnablePageFlip(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
|
|
int cpp=2;
|
|
pSAREAPriv->pf_enabled = pI810->allowPageFlip;
|
|
pSAREAPriv->pf_active = 0;
|
|
|
|
if (pI810->allowPageFlip) {
|
|
unsigned int br13 = pI810->auxPitch | (0xcc << 16);
|
|
|
|
BEGIN_LP_RING(6);
|
|
|
|
OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
|
|
OUT_RING(br13);
|
|
OUT_RING((pScrn->virtualY << 16) | (pScrn->virtualX*cpp));
|
|
OUT_RING(pI810->BackBuffer.Start);
|
|
OUT_RING(br13 & 0xFFFF);
|
|
OUT_RING(0);
|
|
ADVANCE_LP_RING();
|
|
|
|
pSAREAPriv->pf_active = 1;
|
|
}
|
|
|
|
}
|
|
|
|
static void I810DisablePageFlip(ScreenPtr pScreen)
|
|
{
|
|
I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
|
|
|
|
pSAREAPriv->pf_active=0;
|
|
}
|
|
|
|
static void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen)
|
|
{
|
|
/* Tell the clients not to pageflip. How?
|
|
* -- Field in sarea, plus bumping the window counters.
|
|
* -- DRM needs to cope with Front-to-Back swapbuffers.
|
|
*/
|
|
I810DisablePageFlip(pScreen);
|
|
}
|
|
|
|
static void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen)
|
|
{
|
|
/* Let the remaining 3d app start page flipping again */
|
|
I810EnablePageFlip(pScreen);
|
|
}
|
|
|
|
static void I810DRITransitionTo3d(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
|
|
I810EnablePageFlip(pScreen);
|
|
pI810->have3DWindows = 1;
|
|
}
|
|
|
|
static void I810DRITransitionTo2d(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
|
|
|
|
/* Try flipping back to the front page if necessary */
|
|
if (pSAREAPriv->pf_current_page == 1)
|
|
drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP);
|
|
|
|
/* Shut down shadowing if we've made it back to the front page */
|
|
if (pSAREAPriv->pf_current_page == 0) {
|
|
I810DisablePageFlip(pScreen);
|
|
}
|
|
pI810->have3DWindows = 0;
|
|
}
|
|
|
|
Bool
|
|
I810DRILeave(ScrnInfoPtr pScrn)
|
|
{
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
|
|
if (pI810->directRenderingEnabled) {
|
|
if (pI810->dcacheHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->backHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->zHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->sysmemHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->xvmcHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->cursorHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->cursorARGBHandle != 0)
|
|
if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
if (pI810->agpAcquired == TRUE)
|
|
drmAgpRelease(pI810->drmSubFD);
|
|
pI810->agpAcquired = FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
I810DRIEnter(ScrnInfoPtr pScrn)
|
|
{
|
|
I810Ptr pI810 = I810PTR(pScrn);
|
|
|
|
if (pI810->directRenderingEnabled) {
|
|
|
|
if (pI810->agpAcquired == FALSE)
|
|
drmAgpAcquire(pI810->drmSubFD);
|
|
pI810->agpAcquired = TRUE;
|
|
if (pI810->dcacheHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle,
|
|
pI810->DepthOffset) != 0)
|
|
return FALSE;
|
|
if (pI810->backHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->backHandle,
|
|
pI810->BackOffset) != 0)
|
|
return FALSE;
|
|
if (pI810->zHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->zHandle,
|
|
pI810->DepthOffset) != 0)
|
|
return FALSE;
|
|
if (pI810->sysmemHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, 0) != 0)
|
|
return FALSE;
|
|
if (pI810->xvmcHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle,
|
|
pI810->MC.Start) != 0)
|
|
return FALSE;
|
|
if (pI810->cursorHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle,
|
|
pI810->CursorStart) != 0)
|
|
return FALSE;
|
|
if (pI810->cursorARGBHandle != 0)
|
|
if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle,
|
|
pI810->CursorARGBStart) != 0)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|