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