tdfx_dri.c revision 880ed95a
102be438aSmrg
202be438aSmrg#ifdef HAVE_CONFIG_H
302be438aSmrg#include "config.h"
402be438aSmrg#endif
502be438aSmrg
602be438aSmrg#include "xf86.h"
702be438aSmrg#include "xf86_OSproc.h"
802be438aSmrg#include "xf86Priv.h"
902be438aSmrg#include "xf86PciInfo.h"
1002be438aSmrg#include "xf86Pci.h"
1102be438aSmrg#include "fb.h"
1202be438aSmrg#include "miline.h"
1302be438aSmrg#include "GL/glxint.h"
1402be438aSmrg#include "GL/glxtokens.h"
1502be438aSmrg#include "tdfx.h"
1602be438aSmrg#include "tdfx_dri.h"
1702be438aSmrg#include "tdfx_dripriv.h"
1802be438aSmrg
1902be438aSmrgstatic char TDFXKernelDriverName[] = "tdfx";
2002be438aSmrgstatic char TDFXClientDriverName[] = "tdfx";
2102be438aSmrg
2202be438aSmrgstatic Bool TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
2302be438aSmrg			      drm_context_t hwContext, void *pVisualConfigPriv,
2402be438aSmrg			      DRIContextType contextStore);
2502be438aSmrgstatic void TDFXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
2602be438aSmrg			       DRIContextType contextStore);
2702be438aSmrgstatic void TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
2802be438aSmrg			       DRIContextType readContextType,
2902be438aSmrg			       void *readContextStore,
3002be438aSmrg			       DRIContextType writeContextType,
3102be438aSmrg			       void *writeContextStore);
3202be438aSmrgstatic Bool TDFXDRIOpenFullScreen(ScreenPtr pScreen);
3302be438aSmrgstatic Bool TDFXDRICloseFullScreen(ScreenPtr pScreen);
3402be438aSmrgstatic void TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
3502be438aSmrgstatic void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
3602be438aSmrg			       RegionPtr prgnSrc, CARD32 index);
3702be438aSmrgstatic void TDFXDRITransitionTo2d(ScreenPtr pScreen);
3802be438aSmrgstatic void TDFXDRITransitionTo3d(ScreenPtr pScreen);
3902be438aSmrg
4002be438aSmrgstatic Bool
4102be438aSmrgTDFXInitVisualConfigs(ScreenPtr pScreen)
4202be438aSmrg{
4302be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
4402be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
4502be438aSmrg  int numConfigs = 0;
4602be438aSmrg  __GLXvisualConfig *pConfigs = 0;
4702be438aSmrg  TDFXConfigPrivPtr pTDFXConfigs = 0;
4802be438aSmrg  TDFXConfigPrivPtr *pTDFXConfigPtrs = 0;
4902be438aSmrg  int i, db, stencil, accum, depth;
5002be438aSmrg
5102be438aSmrg  switch (pScrn->bitsPerPixel) {
5202be438aSmrg  case 8:
5302be438aSmrg  case 16:
5402be438aSmrg    numConfigs = 16;
5502be438aSmrg
5602be438aSmrg    if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),
5702be438aSmrg						   numConfigs))) {
5802be438aSmrg      return FALSE;
5902be438aSmrg    }
6002be438aSmrg    if (!(pTDFXConfigs = (TDFXConfigPrivPtr)xcalloc(sizeof(TDFXConfigPrivRec),
6102be438aSmrg						     numConfigs))) {
6202be438aSmrg      xfree(pConfigs);
6302be438aSmrg      return FALSE;
6402be438aSmrg    }
6502be438aSmrg    if (!(pTDFXConfigPtrs = (TDFXConfigPrivPtr*)xcalloc(sizeof(TDFXConfigPrivPtr),
6602be438aSmrg							 numConfigs))) {
6702be438aSmrg      xfree(pConfigs);
6802be438aSmrg      xfree(pTDFXConfigs);
6902be438aSmrg      return FALSE;
7002be438aSmrg    }
7102be438aSmrg    for (i=0; i<numConfigs; i++)
7202be438aSmrg      pTDFXConfigPtrs[i] = &pTDFXConfigs[i];
7302be438aSmrg
7402be438aSmrg    i=0;
7502be438aSmrg    depth=1;
7602be438aSmrg    for (db = 0; db <=1; db++) {
7702be438aSmrg      for (depth = 0; depth<=1; depth++) {
7802be438aSmrg	for (accum = 0; accum <= 1; accum++) {
7902be438aSmrg	  for (stencil = 0; stencil <= 1; stencil++) {
8002be438aSmrg	    pConfigs[i].vid = -1;
8102be438aSmrg	    pConfigs[i].class = -1;
8202be438aSmrg	    pConfigs[i].rgba = TRUE;
8302be438aSmrg	    pConfigs[i].redSize = 5;
8402be438aSmrg	    pConfigs[i].greenSize = 6;
8502be438aSmrg	    pConfigs[i].blueSize = 5;
8602be438aSmrg	    pConfigs[i].redMask = 0x0000F800;
8702be438aSmrg	    pConfigs[i].greenMask = 0x000007E0;
8802be438aSmrg	    pConfigs[i].blueMask = 0x0000001F;
8902be438aSmrg	    pConfigs[i].alphaMask = 0;
9002be438aSmrg	    if (accum) {
9102be438aSmrg	      pConfigs[i].accumRedSize = 16;
9202be438aSmrg	      pConfigs[i].accumGreenSize = 16;
9302be438aSmrg	      pConfigs[i].accumBlueSize = 16;
9402be438aSmrg	      pConfigs[i].accumAlphaSize = 0;
9502be438aSmrg	    } else {
9602be438aSmrg	      pConfigs[i].accumRedSize = 0;
9702be438aSmrg	      pConfigs[i].accumGreenSize = 0;
9802be438aSmrg	      pConfigs[i].accumBlueSize = 0;
9902be438aSmrg	      pConfigs[i].accumAlphaSize = 0;
10002be438aSmrg	    }
10102be438aSmrg	    if (db)
10202be438aSmrg	      pConfigs[i].doubleBuffer = TRUE;
10302be438aSmrg	    else
10402be438aSmrg	      pConfigs[i].doubleBuffer = FALSE;
10502be438aSmrg	    pConfigs[i].stereo = FALSE;
10602be438aSmrg	    pConfigs[i].bufferSize = 16;
10702be438aSmrg	    if (depth) {
10802be438aSmrg	      if (pTDFX->cpp>2)
10902be438aSmrg		pConfigs[i].depthSize = 24;
11002be438aSmrg	      else
11102be438aSmrg		pConfigs[i].depthSize = 16;
11202be438aSmrg	    } else {
11302be438aSmrg	      pConfigs[i].depthSize = 0;
11402be438aSmrg	    }
11502be438aSmrg	    if (stencil)
11602be438aSmrg	      pConfigs[i].stencilSize = 8;
11702be438aSmrg	    else
11802be438aSmrg	      pConfigs[i].stencilSize = 0;
11902be438aSmrg	    pConfigs[i].auxBuffers = 0;
12002be438aSmrg	    pConfigs[i].level = 0;
12102be438aSmrg	    if (stencil || accum)
12202be438aSmrg	      pConfigs[i].visualRating = GLX_SLOW_CONFIG;
12302be438aSmrg	    else
12402be438aSmrg	      pConfigs[i].visualRating = GLX_NONE;
12502be438aSmrg	    pConfigs[i].transparentPixel = GLX_NONE;
12602be438aSmrg	    pConfigs[i].transparentRed = 0;
12702be438aSmrg	    pConfigs[i].transparentGreen = 0;
12802be438aSmrg	    pConfigs[i].transparentBlue = 0;
12902be438aSmrg	    pConfigs[i].transparentAlpha = 0;
13002be438aSmrg	    pConfigs[i].transparentIndex = 0;
13102be438aSmrg	    i++;
13202be438aSmrg	  }
13302be438aSmrg	}
13402be438aSmrg      }
13502be438aSmrg    }
13602be438aSmrg    if (i!=numConfigs) {
13702be438aSmrg      xf86DrvMsg(pScreen->myNum, X_ERROR,
13802be438aSmrg                 "[dri] TDFXInitVisualConfigs: wrong number of visuals\n");
13902be438aSmrg      return FALSE;
14002be438aSmrg    }
14102be438aSmrg    break; /* 16bpp */
14202be438aSmrg
14302be438aSmrg  case 24:
14402be438aSmrg  case 32:
14502be438aSmrg    numConfigs = 8;
14602be438aSmrg
14702be438aSmrg    pConfigs = (__GLXvisualConfig*) xcalloc(sizeof(__GLXvisualConfig), numConfigs);
14802be438aSmrg    if (!pConfigs)
14902be438aSmrg      return FALSE;
15002be438aSmrg
15102be438aSmrg    pTDFXConfigs = (TDFXConfigPrivPtr) xcalloc(sizeof(TDFXConfigPrivRec), numConfigs);
15202be438aSmrg    if (!pTDFXConfigs) {
15302be438aSmrg      xfree(pConfigs);
15402be438aSmrg      return FALSE;
15502be438aSmrg    }
15602be438aSmrg
15702be438aSmrg    pTDFXConfigPtrs = (TDFXConfigPrivPtr *) xcalloc(sizeof(TDFXConfigPrivPtr), numConfigs);
15802be438aSmrg    if (!pTDFXConfigPtrs) {
15902be438aSmrg      xfree(pConfigs);
16002be438aSmrg      xfree(pTDFXConfigs);
16102be438aSmrg      return FALSE;
16202be438aSmrg    }
16302be438aSmrg
16402be438aSmrg    for (i = 0; i < numConfigs; i++)
16502be438aSmrg      pTDFXConfigPtrs[i] = &pTDFXConfigs[i];
16602be438aSmrg
16702be438aSmrg    i=0;
16802be438aSmrg    for (db = 0; db <=1; db++) {
16902be438aSmrg      for (depth = 0; depth<=1; depth++) {
17002be438aSmrg         /*stencil = depth;*/  /* Z and stencil share the same memory */
17102be438aSmrg	for (accum = 0; accum <= 1; accum++) {
17202be438aSmrg           /*for (stencil = 0; stencil <=1; stencil++) {*/
17302be438aSmrg           stencil = depth;
17402be438aSmrg	    pConfigs[i].vid = -1;
17502be438aSmrg	    pConfigs[i].class = -1;
17602be438aSmrg	    pConfigs[i].rgba = TRUE;
17702be438aSmrg	    pConfigs[i].redSize = 8;
17802be438aSmrg	    pConfigs[i].greenSize = 8;
17902be438aSmrg	    pConfigs[i].blueSize = 8;
18002be438aSmrg	    pConfigs[i].alphaSize = (pScrn->bitsPerPixel==32) ? 8 : 0;
18102be438aSmrg	    pConfigs[i].redMask   = 0x00ff0000;
18202be438aSmrg	    pConfigs[i].greenMask = 0x0000ff00;
18302be438aSmrg	    pConfigs[i].blueMask  = 0x000000ff;
18402be438aSmrg	    pConfigs[i].alphaMask = (pScrn->bitsPerPixel==32) ? 0xff000000 : 0;
18502be438aSmrg	    if (accum) {
18602be438aSmrg	      pConfigs[i].accumRedSize = 16;
18702be438aSmrg	      pConfigs[i].accumGreenSize = 16;
18802be438aSmrg	      pConfigs[i].accumBlueSize = 16;
18902be438aSmrg	      pConfigs[i].accumAlphaSize = (pScrn->bitsPerPixel==32) ? 16 : 0;
19002be438aSmrg	    } else {
19102be438aSmrg	      pConfigs[i].accumRedSize = 0;
19202be438aSmrg	      pConfigs[i].accumGreenSize = 0;
19302be438aSmrg	      pConfigs[i].accumBlueSize = 0;
19402be438aSmrg	      pConfigs[i].accumAlphaSize = 0;
19502be438aSmrg	    }
19602be438aSmrg	    if (db)
19702be438aSmrg	      pConfigs[i].doubleBuffer = TRUE;
19802be438aSmrg	    else
19902be438aSmrg	      pConfigs[i].doubleBuffer = FALSE;
20002be438aSmrg	    pConfigs[i].stereo = FALSE;
20102be438aSmrg	    pConfigs[i].bufferSize = (pScrn->bitsPerPixel==32) ? 32 : 24;
20202be438aSmrg	    if (depth) {
20302be438aSmrg	      if (pTDFX->cpp > 2)
20402be438aSmrg		pConfigs[i].depthSize = 24;
20502be438aSmrg	      else
20602be438aSmrg		pConfigs[i].depthSize = 16;
20702be438aSmrg	    } else {
20802be438aSmrg	      pConfigs[i].depthSize = 0;
20902be438aSmrg	    }
21002be438aSmrg	    if (stencil)
21102be438aSmrg	      pConfigs[i].stencilSize = 8;
21202be438aSmrg	    else
21302be438aSmrg	      pConfigs[i].stencilSize = 0;
21402be438aSmrg	    pConfigs[i].auxBuffers = 0;
21502be438aSmrg	    pConfigs[i].level = 0;
21602be438aSmrg	    if (accum)
21702be438aSmrg	      pConfigs[i].visualRating = GLX_SLOW_CONFIG;
21802be438aSmrg	    else
21902be438aSmrg	      pConfigs[i].visualRating = GLX_NONE;
22002be438aSmrg	    pConfigs[i].transparentPixel = GLX_NONE;
22102be438aSmrg	    pConfigs[i].transparentRed = 0;
22202be438aSmrg	    pConfigs[i].transparentGreen = 0;
22302be438aSmrg	    pConfigs[i].transparentBlue = 0;
22402be438aSmrg	    pConfigs[i].transparentAlpha = 0;
22502be438aSmrg	    pConfigs[i].transparentIndex = 0;
22602be438aSmrg	    i++;
22702be438aSmrg         /*}*/
22802be438aSmrg	}
22902be438aSmrg      }
23002be438aSmrg    }
23102be438aSmrg    if (i!=numConfigs) {
23202be438aSmrg      xf86DrvMsg(pScreen->myNum, X_ERROR,
23302be438aSmrg                 "[dri] TDFXInitVisualConfigs: wrong number of visuals\n");
23402be438aSmrg      return FALSE;
23502be438aSmrg    }
23602be438aSmrg    break;
23702be438aSmrg  }
23802be438aSmrg  pTDFX->numVisualConfigs = numConfigs;
23902be438aSmrg  pTDFX->pVisualConfigs = pConfigs;
24002be438aSmrg  pTDFX->pVisualConfigsPriv = pTDFXConfigs;
24102be438aSmrg  GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pTDFXConfigPtrs);
24202be438aSmrg  return TRUE;
24302be438aSmrg}
24402be438aSmrg
24502be438aSmrgstatic void
24602be438aSmrgTDFXDoWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
24702be438aSmrg		    pointer pReadmask)
24802be438aSmrg{
24902be438aSmrg  ScreenPtr pScreen = screenInfo.screens[screenNum];
25002be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
25102be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
25202be438aSmrg
25302be438aSmrg  pTDFX->pDRIInfo->wrap.WakeupHandler = pTDFX->coreWakeupHandler;
25402be438aSmrg  (*pTDFX->pDRIInfo->wrap.WakeupHandler) (screenNum, wakeupData, result, pReadmask);
25502be438aSmrg  pTDFX->pDRIInfo->wrap.WakeupHandler = TDFXDoWakeupHandler;
25602be438aSmrg
25702be438aSmrg
25802be438aSmrg  TDFXNeedSync(pScrn);
25902be438aSmrg}
26002be438aSmrg
26102be438aSmrgstatic void
26202be438aSmrgTDFXDoBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
26302be438aSmrg		  pointer pReadmask)
26402be438aSmrg{
26502be438aSmrg  ScreenPtr pScreen = screenInfo.screens[screenNum];
26602be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
26702be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
26802be438aSmrg
26902be438aSmrg  TDFXCheckSync(pScrn);
27002be438aSmrg
27102be438aSmrg  pTDFX->pDRIInfo->wrap.BlockHandler = pTDFX->coreBlockHandler;
27202be438aSmrg  (*pTDFX->pDRIInfo->wrap.BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
27302be438aSmrg  pTDFX->pDRIInfo->wrap.BlockHandler = TDFXDoBlockHandler;
27402be438aSmrg
27502be438aSmrg}
27602be438aSmrg
27702be438aSmrgBool TDFXDRIScreenInit(ScreenPtr pScreen)
27802be438aSmrg{
27902be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
28002be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
28102be438aSmrg  DRIInfoPtr pDRIInfo;
28202be438aSmrg  TDFXDRIPtr pTDFXDRI;
28302be438aSmrg  Bool bppOk = FALSE;
28402be438aSmrg
28502be438aSmrg  switch (pScrn->bitsPerPixel) {
28602be438aSmrg  case 16:
28702be438aSmrg    bppOk = TRUE;
28802be438aSmrg    break;
28902be438aSmrg  case 32:
29002be438aSmrg    if (pTDFX->ChipType > PCI_CHIP_VOODOO3) {
29102be438aSmrg      bppOk = TRUE;
29202be438aSmrg    }
29302be438aSmrg    break;
29402be438aSmrg  }
29502be438aSmrg  if (!bppOk) {
29602be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR,
29702be438aSmrg            "[dri] tdfx DRI not supported in %d bpp mode, disabling DRI.\n",
29802be438aSmrg            (pScrn->bitsPerPixel));
29902be438aSmrg    if (pTDFX->ChipType <= PCI_CHIP_VOODOO3) {
30002be438aSmrg      xf86DrvMsg(pScreen->myNum, X_INFO,
30102be438aSmrg              "[dri] To use DRI, invoke the server using 16 bpp\n"
30202be438aSmrg	      "\t(-depth 15 or -depth 16).\n");
30302be438aSmrg    } else {
30402be438aSmrg      xf86DrvMsg(pScreen->myNum, X_INFO,
30502be438aSmrg              "[dri] To use DRI, invoke the server using 16 bpp\n"
30602be438aSmrg	      "\t(-depth 15 or -depth 16) or 32 bpp (-depth 24 -fbbpp 32).\n");
30702be438aSmrg    }
30802be438aSmrg    return FALSE;
30902be438aSmrg  }
31002be438aSmrg
31102be438aSmrg    /* Check that the GLX, DRI, and DRM modules have been loaded by testing
31202be438aSmrg       for canonical symbols in each module. */
31302be438aSmrg    if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
31402be438aSmrg    if (!xf86LoaderCheckSymbol("drmAvailable"))        return FALSE;
31502be438aSmrg    if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
31602be438aSmrg      xf86DrvMsg(pScreen->myNum, X_ERROR,
31702be438aSmrg                 "TDFXDRIScreenInit failed (libdri.a too old)\n");
31802be438aSmrg      return FALSE;
31902be438aSmrg    }
32002be438aSmrg
32102be438aSmrg  /* Check the DRI version */
32202be438aSmrg  {
32302be438aSmrg    int major, minor, patch;
32402be438aSmrg    DRIQueryVersion(&major, &minor, &patch);
32502be438aSmrg    if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
32602be438aSmrg      xf86DrvMsg(pScreen->myNum, X_ERROR,
32702be438aSmrg                 "[dri] TDFXDRIScreenInit failed because of a version mismatch.\n"
32802be438aSmrg                 "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
32902be438aSmrg                 "[dri] Disabling the DRI.\n",
33002be438aSmrg                 major, minor, patch,
33102be438aSmrg                 DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
33202be438aSmrg      return FALSE;
33302be438aSmrg    }
33402be438aSmrg  }
33502be438aSmrg
33602be438aSmrg  pDRIInfo = DRICreateInfoRec();
33702be438aSmrg  if (!pDRIInfo) {
33802be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR,
33902be438aSmrg               "[dri] DRICreateInfoRect() failed, disabling DRI.\n");
34002be438aSmrg    return FALSE;
34102be438aSmrg  }
34202be438aSmrg
34302be438aSmrg  pTDFX->pDRIInfo = pDRIInfo;
34402be438aSmrg
34502be438aSmrg  pDRIInfo->drmDriverName = TDFXKernelDriverName;
34602be438aSmrg  pDRIInfo->clientDriverName = TDFXClientDriverName;
347880ed95aSmrg#ifdef XSERVER_LIBPCIACCESS
348880ed95aSmrg    pDRIInfo->busIdString = DRICreatePCIBusID(pTDFX->PciInfo[0]);
349880ed95aSmrg#else
35002be438aSmrg  if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
35102be438aSmrg    pDRIInfo->busIdString = DRICreatePCIBusID(pTDFX->PciInfo);
35202be438aSmrg  } else {
35302be438aSmrg    pDRIInfo->busIdString = xalloc(64);
35402be438aSmrg    sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
35502be438aSmrg	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->busnum,
35602be438aSmrg	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->devnum,
35702be438aSmrg	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->funcnum);
35802be438aSmrg  }
359880ed95aSmrg#endif
36002be438aSmrg  pDRIInfo->ddxDriverMajorVersion = TDFX_MAJOR_VERSION;
36102be438aSmrg  pDRIInfo->ddxDriverMinorVersion = TDFX_MINOR_VERSION;
36202be438aSmrg  pDRIInfo->ddxDriverPatchVersion = TDFX_PATCHLEVEL;
36302be438aSmrg  pDRIInfo->frameBufferPhysicalAddress = pTDFX->LinearAddr[0];
36402be438aSmrg  pDRIInfo->frameBufferSize = pTDFX->FbMapSize;
36502be438aSmrg  pDRIInfo->frameBufferStride = pTDFX->stride;
36602be438aSmrg  pDRIInfo->ddxDrawableTableEntry = TDFX_MAX_DRAWABLES;
36702be438aSmrg
36802be438aSmrg  pDRIInfo->wrap.ValidateTree = 0;
36902be438aSmrg  pDRIInfo->wrap.PostValidateTree = 0;
37002be438aSmrg  pTDFX->coreBlockHandler = pDRIInfo->wrap.BlockHandler;
37102be438aSmrg  pDRIInfo->wrap.BlockHandler = TDFXDoBlockHandler;
37202be438aSmrg  pTDFX->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler;
37302be438aSmrg  pDRIInfo->wrap.WakeupHandler = TDFXDoWakeupHandler;
37402be438aSmrg
37502be438aSmrg  if (SAREA_MAX_DRAWABLES < TDFX_MAX_DRAWABLES)
37602be438aSmrg    pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
37702be438aSmrg  else
37802be438aSmrg    pDRIInfo->maxDrawableTableEntry = TDFX_MAX_DRAWABLES;
37902be438aSmrg
38002be438aSmrg#ifdef NOT_DONE
38102be438aSmrg  /* FIXME need to extend DRI protocol to pass this size back to client
38202be438aSmrg   * for SAREA mapping that includes a device private record
38302be438aSmrg   */
38402be438aSmrg  pDRIInfo->SAREASize =
38502be438aSmrg    ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
38602be438aSmrg  /* + shared memory device private rec */
38702be438aSmrg#else
38802be438aSmrg  /* For now the mapping works by using a fixed size defined
38902be438aSmrg   * in the SAREA header
39002be438aSmrg   */
39102be438aSmrg  if (sizeof(XF86DRISAREARec)+sizeof(TDFXSAREAPriv)>SAREA_MAX) {
39202be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR, "Data does not fit in SAREA\n");
39302be438aSmrg    return FALSE;
39402be438aSmrg  }
39502be438aSmrg  pDRIInfo->SAREASize = SAREA_MAX;
39602be438aSmrg#endif
39702be438aSmrg
39802be438aSmrg  if (!(pTDFXDRI = (TDFXDRIPtr)xcalloc(sizeof(TDFXDRIRec),1))) {
39902be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR,
40002be438aSmrg               "[dri] DRI memory allocation failed, disabling DRI.\n");
40102be438aSmrg    DRIDestroyInfoRec(pTDFX->pDRIInfo);
40202be438aSmrg    pTDFX->pDRIInfo=0;
40302be438aSmrg    return FALSE;
40402be438aSmrg  }
40502be438aSmrg  pDRIInfo->devPrivate = pTDFXDRI;
40602be438aSmrg  pDRIInfo->devPrivateSize = sizeof(TDFXDRIRec);
40702be438aSmrg  pDRIInfo->contextSize = sizeof(TDFXDRIContextRec);
40802be438aSmrg
40902be438aSmrg  pDRIInfo->CreateContext = TDFXCreateContext;
41002be438aSmrg  pDRIInfo->DestroyContext = TDFXDestroyContext;
41102be438aSmrg  pDRIInfo->SwapContext = TDFXDRISwapContext;
41202be438aSmrg  pDRIInfo->InitBuffers = TDFXDRIInitBuffers;
41302be438aSmrg  pDRIInfo->MoveBuffers = TDFXDRIMoveBuffers;
41402be438aSmrg  pDRIInfo->OpenFullScreen = TDFXDRIOpenFullScreen;
41502be438aSmrg  pDRIInfo->CloseFullScreen = TDFXDRICloseFullScreen;
41602be438aSmrg  pDRIInfo->TransitionTo2d = TDFXDRITransitionTo2d;
41702be438aSmrg  pDRIInfo->TransitionTo3d = TDFXDRITransitionTo3d;
41802be438aSmrg  pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
41902be438aSmrg
42002be438aSmrg  pDRIInfo->createDummyCtx = FALSE;
42102be438aSmrg  pDRIInfo->createDummyCtxPriv = FALSE;
42202be438aSmrg
42302be438aSmrg  if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) {
42402be438aSmrg    xfree(pDRIInfo->devPrivate);
42502be438aSmrg    pDRIInfo->devPrivate=0;
42602be438aSmrg    DRIDestroyInfoRec(pTDFX->pDRIInfo);
42702be438aSmrg    pTDFX->pDRIInfo=0;
42802be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR,
42902be438aSmrg               "[dri] DRIScreenInit failed, disabling DRI.\n");
43002be438aSmrg
43102be438aSmrg    return FALSE;
43202be438aSmrg  }
43302be438aSmrg
43402be438aSmrg  /* Check the TDFX DRM version */
43502be438aSmrg  {
43602be438aSmrg     drmVersionPtr version = drmGetVersion(pTDFX->drmSubFD);
43702be438aSmrg     if (version) {
43802be438aSmrg        if (version->version_major != 1 ||
43902be438aSmrg            version->version_minor < 0) {
44002be438aSmrg           /* incompatible drm version */
44102be438aSmrg           xf86DrvMsg(pScreen->myNum, X_ERROR,
44202be438aSmrg                      "[dri] TDFXDRIScreenInit failed because of a version mismatch.\n"
44302be438aSmrg                      "[dri] tdfx.o kernel module version is %d.%d.%d but version 1.0.x is needed.\n"
44402be438aSmrg                      "[dri] Disabling the DRI.\n",
44502be438aSmrg                      version->version_major,
44602be438aSmrg                      version->version_minor,
44702be438aSmrg                      version->version_patchlevel);
44802be438aSmrg           TDFXDRICloseScreen(pScreen);
44902be438aSmrg           drmFreeVersion(version);
45002be438aSmrg           return FALSE;
45102be438aSmrg        }
45202be438aSmrg        drmFreeVersion(version);
45302be438aSmrg     }
45402be438aSmrg  }
45502be438aSmrg
45602be438aSmrg  pTDFXDRI->regsSize=TDFXIOMAPSIZE;
45702be438aSmrg  if (drmAddMap(pTDFX->drmSubFD, (drm_handle_t)pTDFX->MMIOAddr[0],
45802be438aSmrg		pTDFXDRI->regsSize, DRM_REGISTERS, 0, &pTDFXDRI->regs)<0) {
45902be438aSmrg    TDFXDRICloseScreen(pScreen);
46002be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap failed, disabling DRI.\n");
46102be438aSmrg    return FALSE;
46202be438aSmrg  }
46302be438aSmrg  xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
46402be438aSmrg	       pTDFXDRI->regs);
46502be438aSmrg
46602be438aSmrg  if (!(TDFXInitVisualConfigs(pScreen))) {
46702be438aSmrg    TDFXDRICloseScreen(pScreen);
46802be438aSmrg    xf86DrvMsg(pScreen->myNum, X_ERROR, "TDFXInitVisualConfigs failed, disabling DRI.\n");
46902be438aSmrg    return FALSE;
47002be438aSmrg  }
47102be438aSmrg  xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
47202be438aSmrg
47302be438aSmrg  return TRUE;
47402be438aSmrg}
47502be438aSmrg
47602be438aSmrgvoid
47702be438aSmrgTDFXDRICloseScreen(ScreenPtr pScreen)
47802be438aSmrg{
47902be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
48002be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
48102be438aSmrg
48202be438aSmrg  DRICloseScreen(pScreen);
48302be438aSmrg
48402be438aSmrg  if (pTDFX->pDRIInfo) {
48502be438aSmrg    if (pTDFX->pDRIInfo->devPrivate) {
48602be438aSmrg      xfree(pTDFX->pDRIInfo->devPrivate);
48702be438aSmrg      pTDFX->pDRIInfo->devPrivate=0;
48802be438aSmrg    }
48902be438aSmrg    DRIDestroyInfoRec(pTDFX->pDRIInfo);
49002be438aSmrg    pTDFX->pDRIInfo=0;
49102be438aSmrg  }
49202be438aSmrg  if (pTDFX->pVisualConfigs) xfree(pTDFX->pVisualConfigs);
49302be438aSmrg  if (pTDFX->pVisualConfigsPriv) xfree(pTDFX->pVisualConfigsPriv);
49402be438aSmrg}
49502be438aSmrg
49602be438aSmrgstatic Bool
49702be438aSmrgTDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
49802be438aSmrg		  drm_context_t hwContext, void *pVisualConfigPriv,
49902be438aSmrg		  DRIContextType contextStore)
50002be438aSmrg{
50102be438aSmrg  return TRUE;
50202be438aSmrg}
50302be438aSmrg
50402be438aSmrgstatic void
50502be438aSmrgTDFXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
50602be438aSmrg		   DRIContextType contextStore)
50702be438aSmrg{
50802be438aSmrg}
50902be438aSmrg
51002be438aSmrgBool
51102be438aSmrgTDFXDRIFinishScreenInit(ScreenPtr pScreen)
51202be438aSmrg{
51302be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
51402be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
51502be438aSmrg  TDFXDRIPtr pTDFXDRI;
51602be438aSmrg
51702be438aSmrg  pTDFX->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
51802be438aSmrg
51902be438aSmrg  pTDFXDRI=(TDFXDRIPtr)pTDFX->pDRIInfo->devPrivate;
520880ed95aSmrg#ifdef XSERVER_LIBPCIACCESS
521880ed95aSmrg  pTDFXDRI->deviceID = DEVICE_ID(pTDFX->PciInfo[0]);
522880ed95aSmrg#else
523880ed95aSmrg  pTDFXDRI->deviceID = DEVICE_ID(pTDFX->PciInfo);
524880ed95aSmrg#endif
52502be438aSmrg  pTDFXDRI->width=pScrn->virtualX;
52602be438aSmrg  pTDFXDRI->height=pScrn->virtualY;
52702be438aSmrg  pTDFXDRI->mem=pScrn->videoRam*1024;
52802be438aSmrg  pTDFXDRI->cpp=pTDFX->cpp;
52902be438aSmrg  pTDFXDRI->stride=pTDFX->stride;
53002be438aSmrg  pTDFXDRI->fifoOffset=pTDFX->fifoOffset;
53102be438aSmrg  pTDFXDRI->fifoSize=pTDFX->fifoSize;
53202be438aSmrg  pTDFXDRI->textureOffset=pTDFX->texOffset;
53302be438aSmrg  pTDFXDRI->textureSize=pTDFX->texSize;
53402be438aSmrg  pTDFXDRI->fbOffset=pTDFX->fbOffset;
53502be438aSmrg  pTDFXDRI->backOffset=pTDFX->backOffset;
53602be438aSmrg  pTDFXDRI->depthOffset=pTDFX->depthOffset;
53702be438aSmrg  pTDFXDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
53802be438aSmrg  return DRIFinishScreenInit(pScreen);
53902be438aSmrg}
54002be438aSmrg
54102be438aSmrgstatic void
54202be438aSmrgTDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
54302be438aSmrg		   DRIContextType oldContextType, void *oldContext,
54402be438aSmrg		   DRIContextType newContextType, void *newContext)
54502be438aSmrg{
54602be438aSmrg}
54702be438aSmrg
54802be438aSmrgstatic void
54902be438aSmrgTDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
55002be438aSmrg{
55102be438aSmrg  ScreenPtr pScreen = pWin->drawable.pScreen;
55202be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
55302be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
55402be438aSmrg  BoxPtr pbox;
55502be438aSmrg  int nbox;
55602be438aSmrg
55702be438aSmrg  /* It looks nicer if these start out black */
55802be438aSmrg  pbox = REGION_RECTS(prgn);
55902be438aSmrg  nbox = REGION_NUM_RECTS(prgn);
56002be438aSmrg
56102be438aSmrg  TDFXSetupForSolidFill(pScrn, 0, GXcopy, -1);
56202be438aSmrg  while (nbox--) {
56302be438aSmrg    TDFXSelectBuffer(pTDFX, TDFX_BACK);
56402be438aSmrg    TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
56502be438aSmrg				pbox->x2-pbox->x1, pbox->y2-pbox->y1);
56602be438aSmrg    TDFXSelectBuffer(pTDFX, TDFX_DEPTH);
56702be438aSmrg    TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
56802be438aSmrg				pbox->x2-pbox->x1, pbox->y2-pbox->y1);
56902be438aSmrg    pbox++;
57002be438aSmrg  }
57102be438aSmrg  TDFXSelectBuffer(pTDFX, TDFX_FRONT);
57202be438aSmrg
57302be438aSmrg  pTDFX->AccelInfoRec->NeedToSync = TRUE;
57402be438aSmrg}
57502be438aSmrg
57602be438aSmrgstatic void
57702be438aSmrgTDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
57802be438aSmrg		   RegionPtr prgnSrc, CARD32 index)
57902be438aSmrg{
58002be438aSmrg  ScreenPtr pScreen = pParent->drawable.pScreen;
58102be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
58202be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
58302be438aSmrg  int dx, dy, xdir, ydir, i, x, y, nbox;
58402be438aSmrg  BoxPtr pbox;
58502be438aSmrg
58602be438aSmrg  dx = pParent->drawable.x - ptOldOrg.x;
58702be438aSmrg  dy = pParent->drawable.y - ptOldOrg.y;
58802be438aSmrg
58902be438aSmrg  DRIMoveBuffersHelper(pScreen, dx, dy, &xdir, &ydir, prgnSrc);
59002be438aSmrg
59102be438aSmrg  pbox = REGION_RECTS(prgnSrc);
59202be438aSmrg  nbox = REGION_NUM_RECTS(prgnSrc);
59302be438aSmrg
59402be438aSmrg  TDFXSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, ~0, -1);
59502be438aSmrg
59602be438aSmrg  TDFXSelectBuffer(pTDFX, TDFX_BACK);
59702be438aSmrg  for(i = 0; i < nbox; i++) {
59802be438aSmrg     x = pbox[i].x1;
59902be438aSmrg     y = pbox[i].y1;
60002be438aSmrg     TDFXSubsequentScreenToScreenCopy(pScrn, x, y, x+dx, y+dy,
60102be438aSmrg                                      pbox[i].x2 - x, pbox[i].y2 - y);
60202be438aSmrg  }
60302be438aSmrg
60402be438aSmrg  TDFXSelectBuffer(pTDFX, TDFX_DEPTH);
60502be438aSmrg  for(i = 0; i < nbox; i++) {
60602be438aSmrg     x = pbox[i].x1;
60702be438aSmrg     y = pbox[i].y1;
60802be438aSmrg     TDFXSubsequentScreenToScreenCopy(pScrn, x, y, x+dx, y+dy,
60902be438aSmrg                                      pbox[i].x2 - x, pbox[i].y2 - y);
61002be438aSmrg  }
61102be438aSmrg
61202be438aSmrg  TDFXSelectBuffer(pTDFX, TDFX_FRONT);
61302be438aSmrg
61402be438aSmrg  pTDFX->AccelInfoRec->NeedToSync = TRUE;
61502be438aSmrg}
61602be438aSmrg
61702be438aSmrg/*
61802be438aSmrg * the FullScreen DRI code is dead; this is just left in place to show how
61902be438aSmrg * to set up SLI mode.
62002be438aSmrg */
62102be438aSmrgstatic Bool
62202be438aSmrgTDFXDRIOpenFullScreen(ScreenPtr pScreen)
62302be438aSmrg{
62402be438aSmrg#if 0
62502be438aSmrg  ScrnInfoPtr pScrn;
62602be438aSmrg  TDFXPtr pTDFX;
62702be438aSmrg
62802be438aSmrg  xf86DrvMsg(pScreen->myNum, X_INFO, "OpenFullScreen\n");
62902be438aSmrg  pScrn = xf86Screens[pScreen->myNum];
63002be438aSmrg  pTDFX=TDFXPTR(pScrn);
63102be438aSmrg  if (pTDFX->numChips>1) {
63202be438aSmrg    TDFXSetupSLI(pScrn);
63302be438aSmrg  }
63402be438aSmrg#endif
63502be438aSmrg  return TRUE;
63602be438aSmrg}
63702be438aSmrg
63802be438aSmrgstatic Bool
63902be438aSmrgTDFXDRICloseFullScreen(ScreenPtr pScreen)
64002be438aSmrg{
64102be438aSmrg#if 0
64202be438aSmrg  ScrnInfoPtr pScrn;
64302be438aSmrg
64402be438aSmrg  xf86DrvMsg(pScreen->myNum, X_INFO, "CloseFullScreen\n");
64502be438aSmrg  pScrn = xf86Screens[pScreen->myNum];
64602be438aSmrg  TDFXDisableSLI(pScrn);
64702be438aSmrg#endif
64802be438aSmrg  return TRUE;
64902be438aSmrg}
65002be438aSmrg
65102be438aSmrgstatic void
65202be438aSmrgTDFXDRITransitionTo2d(ScreenPtr pScreen)
65302be438aSmrg{
65402be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
65502be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
65602be438aSmrg
65702be438aSmrg  xf86FreeOffscreenArea(pTDFX->reservedArea);
65802be438aSmrg}
65902be438aSmrg
66002be438aSmrgstatic void
66102be438aSmrgTDFXDRITransitionTo3d(ScreenPtr pScreen)
66202be438aSmrg{
66302be438aSmrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
66402be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
66502be438aSmrg  FBAreaPtr pArea;
66602be438aSmrg
66702be438aSmrg  if(pTDFX->overlayBuffer) {
66802be438aSmrg	xf86FreeOffscreenLinear(pTDFX->overlayBuffer);
66902be438aSmrg	pTDFX->overlayBuffer = NULL;
67002be438aSmrg  }
67102be438aSmrg
67202be438aSmrg  if(pTDFX->overlayBuffer2) {
67302be438aSmrg	xf86FreeOffscreenLinear(pTDFX->overlayBuffer2);
67402be438aSmrg	pTDFX->overlayBuffer2 = NULL;
67502be438aSmrg  }
67602be438aSmrg
67702be438aSmrg  if(pTDFX->textureBuffer) {
67802be438aSmrg	xf86FreeOffscreenArea(pTDFX->textureBuffer);
67902be438aSmrg	pTDFX->textureBuffer = NULL;
68002be438aSmrg  }
68102be438aSmrg
68202be438aSmrg  xf86PurgeUnlockedOffscreenAreas(pScreen);
68302be438aSmrg
68402be438aSmrg  pArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
68502be438aSmrg				    pTDFX->pixmapCacheLinesMin,
68602be438aSmrg				    pScrn->displayWidth, NULL, NULL, NULL);
68702be438aSmrg  pTDFX->reservedArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
68802be438aSmrg			pTDFX->pixmapCacheLinesMax - pTDFX->pixmapCacheLinesMin,
68902be438aSmrg			pScrn->displayWidth, NULL, NULL, NULL);
69002be438aSmrg  xf86FreeOffscreenArea(pArea);
69102be438aSmrg}
692