tdfx_dri.c revision 880ed95a
1
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif
5
6#include "xf86.h"
7#include "xf86_OSproc.h"
8#include "xf86Priv.h"
9#include "xf86PciInfo.h"
10#include "xf86Pci.h"
11#include "fb.h"
12#include "miline.h"
13#include "GL/glxint.h"
14#include "GL/glxtokens.h"
15#include "tdfx.h"
16#include "tdfx_dri.h"
17#include "tdfx_dripriv.h"
18
19static char TDFXKernelDriverName[] = "tdfx";
20static char TDFXClientDriverName[] = "tdfx";
21
22static Bool TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
23			      drm_context_t hwContext, void *pVisualConfigPriv,
24			      DRIContextType contextStore);
25static void TDFXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
26			       DRIContextType contextStore);
27static void TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
28			       DRIContextType readContextType,
29			       void *readContextStore,
30			       DRIContextType writeContextType,
31			       void *writeContextStore);
32static Bool TDFXDRIOpenFullScreen(ScreenPtr pScreen);
33static Bool TDFXDRICloseFullScreen(ScreenPtr pScreen);
34static void TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
35static void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
36			       RegionPtr prgnSrc, CARD32 index);
37static void TDFXDRITransitionTo2d(ScreenPtr pScreen);
38static void TDFXDRITransitionTo3d(ScreenPtr pScreen);
39
40static Bool
41TDFXInitVisualConfigs(ScreenPtr pScreen)
42{
43  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
44  TDFXPtr pTDFX = TDFXPTR(pScrn);
45  int numConfigs = 0;
46  __GLXvisualConfig *pConfigs = 0;
47  TDFXConfigPrivPtr pTDFXConfigs = 0;
48  TDFXConfigPrivPtr *pTDFXConfigPtrs = 0;
49  int i, db, stencil, accum, depth;
50
51  switch (pScrn->bitsPerPixel) {
52  case 8:
53  case 16:
54    numConfigs = 16;
55
56    if (!(pConfigs = (__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),
57						   numConfigs))) {
58      return FALSE;
59    }
60    if (!(pTDFXConfigs = (TDFXConfigPrivPtr)xcalloc(sizeof(TDFXConfigPrivRec),
61						     numConfigs))) {
62      xfree(pConfigs);
63      return FALSE;
64    }
65    if (!(pTDFXConfigPtrs = (TDFXConfigPrivPtr*)xcalloc(sizeof(TDFXConfigPrivPtr),
66							 numConfigs))) {
67      xfree(pConfigs);
68      xfree(pTDFXConfigs);
69      return FALSE;
70    }
71    for (i=0; i<numConfigs; i++)
72      pTDFXConfigPtrs[i] = &pTDFXConfigs[i];
73
74    i=0;
75    depth=1;
76    for (db = 0; db <=1; db++) {
77      for (depth = 0; depth<=1; depth++) {
78	for (accum = 0; accum <= 1; accum++) {
79	  for (stencil = 0; stencil <= 1; stencil++) {
80	    pConfigs[i].vid = -1;
81	    pConfigs[i].class = -1;
82	    pConfigs[i].rgba = TRUE;
83	    pConfigs[i].redSize = 5;
84	    pConfigs[i].greenSize = 6;
85	    pConfigs[i].blueSize = 5;
86	    pConfigs[i].redMask = 0x0000F800;
87	    pConfigs[i].greenMask = 0x000007E0;
88	    pConfigs[i].blueMask = 0x0000001F;
89	    pConfigs[i].alphaMask = 0;
90	    if (accum) {
91	      pConfigs[i].accumRedSize = 16;
92	      pConfigs[i].accumGreenSize = 16;
93	      pConfigs[i].accumBlueSize = 16;
94	      pConfigs[i].accumAlphaSize = 0;
95	    } else {
96	      pConfigs[i].accumRedSize = 0;
97	      pConfigs[i].accumGreenSize = 0;
98	      pConfigs[i].accumBlueSize = 0;
99	      pConfigs[i].accumAlphaSize = 0;
100	    }
101	    if (db)
102	      pConfigs[i].doubleBuffer = TRUE;
103	    else
104	      pConfigs[i].doubleBuffer = FALSE;
105	    pConfigs[i].stereo = FALSE;
106	    pConfigs[i].bufferSize = 16;
107	    if (depth) {
108	      if (pTDFX->cpp>2)
109		pConfigs[i].depthSize = 24;
110	      else
111		pConfigs[i].depthSize = 16;
112	    } else {
113	      pConfigs[i].depthSize = 0;
114	    }
115	    if (stencil)
116	      pConfigs[i].stencilSize = 8;
117	    else
118	      pConfigs[i].stencilSize = 0;
119	    pConfigs[i].auxBuffers = 0;
120	    pConfigs[i].level = 0;
121	    if (stencil || accum)
122	      pConfigs[i].visualRating = GLX_SLOW_CONFIG;
123	    else
124	      pConfigs[i].visualRating = GLX_NONE;
125	    pConfigs[i].transparentPixel = GLX_NONE;
126	    pConfigs[i].transparentRed = 0;
127	    pConfigs[i].transparentGreen = 0;
128	    pConfigs[i].transparentBlue = 0;
129	    pConfigs[i].transparentAlpha = 0;
130	    pConfigs[i].transparentIndex = 0;
131	    i++;
132	  }
133	}
134      }
135    }
136    if (i!=numConfigs) {
137      xf86DrvMsg(pScreen->myNum, X_ERROR,
138                 "[dri] TDFXInitVisualConfigs: wrong number of visuals\n");
139      return FALSE;
140    }
141    break; /* 16bpp */
142
143  case 24:
144  case 32:
145    numConfigs = 8;
146
147    pConfigs = (__GLXvisualConfig*) xcalloc(sizeof(__GLXvisualConfig), numConfigs);
148    if (!pConfigs)
149      return FALSE;
150
151    pTDFXConfigs = (TDFXConfigPrivPtr) xcalloc(sizeof(TDFXConfigPrivRec), numConfigs);
152    if (!pTDFXConfigs) {
153      xfree(pConfigs);
154      return FALSE;
155    }
156
157    pTDFXConfigPtrs = (TDFXConfigPrivPtr *) xcalloc(sizeof(TDFXConfigPrivPtr), numConfigs);
158    if (!pTDFXConfigPtrs) {
159      xfree(pConfigs);
160      xfree(pTDFXConfigs);
161      return FALSE;
162    }
163
164    for (i = 0; i < numConfigs; i++)
165      pTDFXConfigPtrs[i] = &pTDFXConfigs[i];
166
167    i=0;
168    for (db = 0; db <=1; db++) {
169      for (depth = 0; depth<=1; depth++) {
170         /*stencil = depth;*/  /* Z and stencil share the same memory */
171	for (accum = 0; accum <= 1; accum++) {
172           /*for (stencil = 0; stencil <=1; stencil++) {*/
173           stencil = depth;
174	    pConfigs[i].vid = -1;
175	    pConfigs[i].class = -1;
176	    pConfigs[i].rgba = TRUE;
177	    pConfigs[i].redSize = 8;
178	    pConfigs[i].greenSize = 8;
179	    pConfigs[i].blueSize = 8;
180	    pConfigs[i].alphaSize = (pScrn->bitsPerPixel==32) ? 8 : 0;
181	    pConfigs[i].redMask   = 0x00ff0000;
182	    pConfigs[i].greenMask = 0x0000ff00;
183	    pConfigs[i].blueMask  = 0x000000ff;
184	    pConfigs[i].alphaMask = (pScrn->bitsPerPixel==32) ? 0xff000000 : 0;
185	    if (accum) {
186	      pConfigs[i].accumRedSize = 16;
187	      pConfigs[i].accumGreenSize = 16;
188	      pConfigs[i].accumBlueSize = 16;
189	      pConfigs[i].accumAlphaSize = (pScrn->bitsPerPixel==32) ? 16 : 0;
190	    } else {
191	      pConfigs[i].accumRedSize = 0;
192	      pConfigs[i].accumGreenSize = 0;
193	      pConfigs[i].accumBlueSize = 0;
194	      pConfigs[i].accumAlphaSize = 0;
195	    }
196	    if (db)
197	      pConfigs[i].doubleBuffer = TRUE;
198	    else
199	      pConfigs[i].doubleBuffer = FALSE;
200	    pConfigs[i].stereo = FALSE;
201	    pConfigs[i].bufferSize = (pScrn->bitsPerPixel==32) ? 32 : 24;
202	    if (depth) {
203	      if (pTDFX->cpp > 2)
204		pConfigs[i].depthSize = 24;
205	      else
206		pConfigs[i].depthSize = 16;
207	    } else {
208	      pConfigs[i].depthSize = 0;
209	    }
210	    if (stencil)
211	      pConfigs[i].stencilSize = 8;
212	    else
213	      pConfigs[i].stencilSize = 0;
214	    pConfigs[i].auxBuffers = 0;
215	    pConfigs[i].level = 0;
216	    if (accum)
217	      pConfigs[i].visualRating = GLX_SLOW_CONFIG;
218	    else
219	      pConfigs[i].visualRating = GLX_NONE;
220	    pConfigs[i].transparentPixel = GLX_NONE;
221	    pConfigs[i].transparentRed = 0;
222	    pConfigs[i].transparentGreen = 0;
223	    pConfigs[i].transparentBlue = 0;
224	    pConfigs[i].transparentAlpha = 0;
225	    pConfigs[i].transparentIndex = 0;
226	    i++;
227         /*}*/
228	}
229      }
230    }
231    if (i!=numConfigs) {
232      xf86DrvMsg(pScreen->myNum, X_ERROR,
233                 "[dri] TDFXInitVisualConfigs: wrong number of visuals\n");
234      return FALSE;
235    }
236    break;
237  }
238  pTDFX->numVisualConfigs = numConfigs;
239  pTDFX->pVisualConfigs = pConfigs;
240  pTDFX->pVisualConfigsPriv = pTDFXConfigs;
241  GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pTDFXConfigPtrs);
242  return TRUE;
243}
244
245static void
246TDFXDoWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
247		    pointer pReadmask)
248{
249  ScreenPtr pScreen = screenInfo.screens[screenNum];
250  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
251  TDFXPtr pTDFX = TDFXPTR(pScrn);
252
253  pTDFX->pDRIInfo->wrap.WakeupHandler = pTDFX->coreWakeupHandler;
254  (*pTDFX->pDRIInfo->wrap.WakeupHandler) (screenNum, wakeupData, result, pReadmask);
255  pTDFX->pDRIInfo->wrap.WakeupHandler = TDFXDoWakeupHandler;
256
257
258  TDFXNeedSync(pScrn);
259}
260
261static void
262TDFXDoBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
263		  pointer pReadmask)
264{
265  ScreenPtr pScreen = screenInfo.screens[screenNum];
266  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
267  TDFXPtr pTDFX = TDFXPTR(pScrn);
268
269  TDFXCheckSync(pScrn);
270
271  pTDFX->pDRIInfo->wrap.BlockHandler = pTDFX->coreBlockHandler;
272  (*pTDFX->pDRIInfo->wrap.BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
273  pTDFX->pDRIInfo->wrap.BlockHandler = TDFXDoBlockHandler;
274
275}
276
277Bool TDFXDRIScreenInit(ScreenPtr pScreen)
278{
279  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
280  TDFXPtr pTDFX = TDFXPTR(pScrn);
281  DRIInfoPtr pDRIInfo;
282  TDFXDRIPtr pTDFXDRI;
283  Bool bppOk = FALSE;
284
285  switch (pScrn->bitsPerPixel) {
286  case 16:
287    bppOk = TRUE;
288    break;
289  case 32:
290    if (pTDFX->ChipType > PCI_CHIP_VOODOO3) {
291      bppOk = TRUE;
292    }
293    break;
294  }
295  if (!bppOk) {
296    xf86DrvMsg(pScreen->myNum, X_ERROR,
297            "[dri] tdfx DRI not supported in %d bpp mode, disabling DRI.\n",
298            (pScrn->bitsPerPixel));
299    if (pTDFX->ChipType <= PCI_CHIP_VOODOO3) {
300      xf86DrvMsg(pScreen->myNum, X_INFO,
301              "[dri] To use DRI, invoke the server using 16 bpp\n"
302	      "\t(-depth 15 or -depth 16).\n");
303    } else {
304      xf86DrvMsg(pScreen->myNum, X_INFO,
305              "[dri] To use DRI, invoke the server using 16 bpp\n"
306	      "\t(-depth 15 or -depth 16) or 32 bpp (-depth 24 -fbbpp 32).\n");
307    }
308    return FALSE;
309  }
310
311    /* Check that the GLX, DRI, and DRM modules have been loaded by testing
312       for canonical symbols in each module. */
313    if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE;
314    if (!xf86LoaderCheckSymbol("drmAvailable"))        return FALSE;
315    if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
316      xf86DrvMsg(pScreen->myNum, X_ERROR,
317                 "TDFXDRIScreenInit failed (libdri.a too old)\n");
318      return FALSE;
319    }
320
321  /* Check the DRI version */
322  {
323    int major, minor, patch;
324    DRIQueryVersion(&major, &minor, &patch);
325    if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
326      xf86DrvMsg(pScreen->myNum, X_ERROR,
327                 "[dri] TDFXDRIScreenInit failed because of a version mismatch.\n"
328                 "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
329                 "[dri] Disabling the DRI.\n",
330                 major, minor, patch,
331                 DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
332      return FALSE;
333    }
334  }
335
336  pDRIInfo = DRICreateInfoRec();
337  if (!pDRIInfo) {
338    xf86DrvMsg(pScreen->myNum, X_ERROR,
339               "[dri] DRICreateInfoRect() failed, disabling DRI.\n");
340    return FALSE;
341  }
342
343  pTDFX->pDRIInfo = pDRIInfo;
344
345  pDRIInfo->drmDriverName = TDFXKernelDriverName;
346  pDRIInfo->clientDriverName = TDFXClientDriverName;
347#ifdef XSERVER_LIBPCIACCESS
348    pDRIInfo->busIdString = DRICreatePCIBusID(pTDFX->PciInfo[0]);
349#else
350  if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
351    pDRIInfo->busIdString = DRICreatePCIBusID(pTDFX->PciInfo);
352  } else {
353    pDRIInfo->busIdString = xalloc(64);
354    sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
355	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->busnum,
356	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->devnum,
357	    ((pciConfigPtr)pTDFX->PciInfo->thisCard)->funcnum);
358  }
359#endif
360  pDRIInfo->ddxDriverMajorVersion = TDFX_MAJOR_VERSION;
361  pDRIInfo->ddxDriverMinorVersion = TDFX_MINOR_VERSION;
362  pDRIInfo->ddxDriverPatchVersion = TDFX_PATCHLEVEL;
363  pDRIInfo->frameBufferPhysicalAddress = pTDFX->LinearAddr[0];
364  pDRIInfo->frameBufferSize = pTDFX->FbMapSize;
365  pDRIInfo->frameBufferStride = pTDFX->stride;
366  pDRIInfo->ddxDrawableTableEntry = TDFX_MAX_DRAWABLES;
367
368  pDRIInfo->wrap.ValidateTree = 0;
369  pDRIInfo->wrap.PostValidateTree = 0;
370  pTDFX->coreBlockHandler = pDRIInfo->wrap.BlockHandler;
371  pDRIInfo->wrap.BlockHandler = TDFXDoBlockHandler;
372  pTDFX->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler;
373  pDRIInfo->wrap.WakeupHandler = TDFXDoWakeupHandler;
374
375  if (SAREA_MAX_DRAWABLES < TDFX_MAX_DRAWABLES)
376    pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
377  else
378    pDRIInfo->maxDrawableTableEntry = TDFX_MAX_DRAWABLES;
379
380#ifdef NOT_DONE
381  /* FIXME need to extend DRI protocol to pass this size back to client
382   * for SAREA mapping that includes a device private record
383   */
384  pDRIInfo->SAREASize =
385    ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
386  /* + shared memory device private rec */
387#else
388  /* For now the mapping works by using a fixed size defined
389   * in the SAREA header
390   */
391  if (sizeof(XF86DRISAREARec)+sizeof(TDFXSAREAPriv)>SAREA_MAX) {
392    xf86DrvMsg(pScreen->myNum, X_ERROR, "Data does not fit in SAREA\n");
393    return FALSE;
394  }
395  pDRIInfo->SAREASize = SAREA_MAX;
396#endif
397
398  if (!(pTDFXDRI = (TDFXDRIPtr)xcalloc(sizeof(TDFXDRIRec),1))) {
399    xf86DrvMsg(pScreen->myNum, X_ERROR,
400               "[dri] DRI memory allocation failed, disabling DRI.\n");
401    DRIDestroyInfoRec(pTDFX->pDRIInfo);
402    pTDFX->pDRIInfo=0;
403    return FALSE;
404  }
405  pDRIInfo->devPrivate = pTDFXDRI;
406  pDRIInfo->devPrivateSize = sizeof(TDFXDRIRec);
407  pDRIInfo->contextSize = sizeof(TDFXDRIContextRec);
408
409  pDRIInfo->CreateContext = TDFXCreateContext;
410  pDRIInfo->DestroyContext = TDFXDestroyContext;
411  pDRIInfo->SwapContext = TDFXDRISwapContext;
412  pDRIInfo->InitBuffers = TDFXDRIInitBuffers;
413  pDRIInfo->MoveBuffers = TDFXDRIMoveBuffers;
414  pDRIInfo->OpenFullScreen = TDFXDRIOpenFullScreen;
415  pDRIInfo->CloseFullScreen = TDFXDRICloseFullScreen;
416  pDRIInfo->TransitionTo2d = TDFXDRITransitionTo2d;
417  pDRIInfo->TransitionTo3d = TDFXDRITransitionTo3d;
418  pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
419
420  pDRIInfo->createDummyCtx = FALSE;
421  pDRIInfo->createDummyCtxPriv = FALSE;
422
423  if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) {
424    xfree(pDRIInfo->devPrivate);
425    pDRIInfo->devPrivate=0;
426    DRIDestroyInfoRec(pTDFX->pDRIInfo);
427    pTDFX->pDRIInfo=0;
428    xf86DrvMsg(pScreen->myNum, X_ERROR,
429               "[dri] DRIScreenInit failed, disabling DRI.\n");
430
431    return FALSE;
432  }
433
434  /* Check the TDFX DRM version */
435  {
436     drmVersionPtr version = drmGetVersion(pTDFX->drmSubFD);
437     if (version) {
438        if (version->version_major != 1 ||
439            version->version_minor < 0) {
440           /* incompatible drm version */
441           xf86DrvMsg(pScreen->myNum, X_ERROR,
442                      "[dri] TDFXDRIScreenInit failed because of a version mismatch.\n"
443                      "[dri] tdfx.o kernel module version is %d.%d.%d but version 1.0.x is needed.\n"
444                      "[dri] Disabling the DRI.\n",
445                      version->version_major,
446                      version->version_minor,
447                      version->version_patchlevel);
448           TDFXDRICloseScreen(pScreen);
449           drmFreeVersion(version);
450           return FALSE;
451        }
452        drmFreeVersion(version);
453     }
454  }
455
456  pTDFXDRI->regsSize=TDFXIOMAPSIZE;
457  if (drmAddMap(pTDFX->drmSubFD, (drm_handle_t)pTDFX->MMIOAddr[0],
458		pTDFXDRI->regsSize, DRM_REGISTERS, 0, &pTDFXDRI->regs)<0) {
459    TDFXDRICloseScreen(pScreen);
460    xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap failed, disabling DRI.\n");
461    return FALSE;
462  }
463  xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
464	       pTDFXDRI->regs);
465
466  if (!(TDFXInitVisualConfigs(pScreen))) {
467    TDFXDRICloseScreen(pScreen);
468    xf86DrvMsg(pScreen->myNum, X_ERROR, "TDFXInitVisualConfigs failed, disabling DRI.\n");
469    return FALSE;
470  }
471  xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
472
473  return TRUE;
474}
475
476void
477TDFXDRICloseScreen(ScreenPtr pScreen)
478{
479  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
480  TDFXPtr pTDFX = TDFXPTR(pScrn);
481
482  DRICloseScreen(pScreen);
483
484  if (pTDFX->pDRIInfo) {
485    if (pTDFX->pDRIInfo->devPrivate) {
486      xfree(pTDFX->pDRIInfo->devPrivate);
487      pTDFX->pDRIInfo->devPrivate=0;
488    }
489    DRIDestroyInfoRec(pTDFX->pDRIInfo);
490    pTDFX->pDRIInfo=0;
491  }
492  if (pTDFX->pVisualConfigs) xfree(pTDFX->pVisualConfigs);
493  if (pTDFX->pVisualConfigsPriv) xfree(pTDFX->pVisualConfigsPriv);
494}
495
496static Bool
497TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
498		  drm_context_t hwContext, void *pVisualConfigPriv,
499		  DRIContextType contextStore)
500{
501  return TRUE;
502}
503
504static void
505TDFXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
506		   DRIContextType contextStore)
507{
508}
509
510Bool
511TDFXDRIFinishScreenInit(ScreenPtr pScreen)
512{
513  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
514  TDFXPtr pTDFX = TDFXPTR(pScrn);
515  TDFXDRIPtr pTDFXDRI;
516
517  pTDFX->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
518
519  pTDFXDRI=(TDFXDRIPtr)pTDFX->pDRIInfo->devPrivate;
520#ifdef XSERVER_LIBPCIACCESS
521  pTDFXDRI->deviceID = DEVICE_ID(pTDFX->PciInfo[0]);
522#else
523  pTDFXDRI->deviceID = DEVICE_ID(pTDFX->PciInfo);
524#endif
525  pTDFXDRI->width=pScrn->virtualX;
526  pTDFXDRI->height=pScrn->virtualY;
527  pTDFXDRI->mem=pScrn->videoRam*1024;
528  pTDFXDRI->cpp=pTDFX->cpp;
529  pTDFXDRI->stride=pTDFX->stride;
530  pTDFXDRI->fifoOffset=pTDFX->fifoOffset;
531  pTDFXDRI->fifoSize=pTDFX->fifoSize;
532  pTDFXDRI->textureOffset=pTDFX->texOffset;
533  pTDFXDRI->textureSize=pTDFX->texSize;
534  pTDFXDRI->fbOffset=pTDFX->fbOffset;
535  pTDFXDRI->backOffset=pTDFX->backOffset;
536  pTDFXDRI->depthOffset=pTDFX->depthOffset;
537  pTDFXDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
538  return DRIFinishScreenInit(pScreen);
539}
540
541static void
542TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
543		   DRIContextType oldContextType, void *oldContext,
544		   DRIContextType newContextType, void *newContext)
545{
546}
547
548static void
549TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
550{
551  ScreenPtr pScreen = pWin->drawable.pScreen;
552  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
553  TDFXPtr pTDFX = TDFXPTR(pScrn);
554  BoxPtr pbox;
555  int nbox;
556
557  /* It looks nicer if these start out black */
558  pbox = REGION_RECTS(prgn);
559  nbox = REGION_NUM_RECTS(prgn);
560
561  TDFXSetupForSolidFill(pScrn, 0, GXcopy, -1);
562  while (nbox--) {
563    TDFXSelectBuffer(pTDFX, TDFX_BACK);
564    TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
565				pbox->x2-pbox->x1, pbox->y2-pbox->y1);
566    TDFXSelectBuffer(pTDFX, TDFX_DEPTH);
567    TDFXSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
568				pbox->x2-pbox->x1, pbox->y2-pbox->y1);
569    pbox++;
570  }
571  TDFXSelectBuffer(pTDFX, TDFX_FRONT);
572
573  pTDFX->AccelInfoRec->NeedToSync = TRUE;
574}
575
576static void
577TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
578		   RegionPtr prgnSrc, CARD32 index)
579{
580  ScreenPtr pScreen = pParent->drawable.pScreen;
581  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
582  TDFXPtr pTDFX = TDFXPTR(pScrn);
583  int dx, dy, xdir, ydir, i, x, y, nbox;
584  BoxPtr pbox;
585
586  dx = pParent->drawable.x - ptOldOrg.x;
587  dy = pParent->drawable.y - ptOldOrg.y;
588
589  DRIMoveBuffersHelper(pScreen, dx, dy, &xdir, &ydir, prgnSrc);
590
591  pbox = REGION_RECTS(prgnSrc);
592  nbox = REGION_NUM_RECTS(prgnSrc);
593
594  TDFXSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, ~0, -1);
595
596  TDFXSelectBuffer(pTDFX, TDFX_BACK);
597  for(i = 0; i < nbox; i++) {
598     x = pbox[i].x1;
599     y = pbox[i].y1;
600     TDFXSubsequentScreenToScreenCopy(pScrn, x, y, x+dx, y+dy,
601                                      pbox[i].x2 - x, pbox[i].y2 - y);
602  }
603
604  TDFXSelectBuffer(pTDFX, TDFX_DEPTH);
605  for(i = 0; i < nbox; i++) {
606     x = pbox[i].x1;
607     y = pbox[i].y1;
608     TDFXSubsequentScreenToScreenCopy(pScrn, x, y, x+dx, y+dy,
609                                      pbox[i].x2 - x, pbox[i].y2 - y);
610  }
611
612  TDFXSelectBuffer(pTDFX, TDFX_FRONT);
613
614  pTDFX->AccelInfoRec->NeedToSync = TRUE;
615}
616
617/*
618 * the FullScreen DRI code is dead; this is just left in place to show how
619 * to set up SLI mode.
620 */
621static Bool
622TDFXDRIOpenFullScreen(ScreenPtr pScreen)
623{
624#if 0
625  ScrnInfoPtr pScrn;
626  TDFXPtr pTDFX;
627
628  xf86DrvMsg(pScreen->myNum, X_INFO, "OpenFullScreen\n");
629  pScrn = xf86Screens[pScreen->myNum];
630  pTDFX=TDFXPTR(pScrn);
631  if (pTDFX->numChips>1) {
632    TDFXSetupSLI(pScrn);
633  }
634#endif
635  return TRUE;
636}
637
638static Bool
639TDFXDRICloseFullScreen(ScreenPtr pScreen)
640{
641#if 0
642  ScrnInfoPtr pScrn;
643
644  xf86DrvMsg(pScreen->myNum, X_INFO, "CloseFullScreen\n");
645  pScrn = xf86Screens[pScreen->myNum];
646  TDFXDisableSLI(pScrn);
647#endif
648  return TRUE;
649}
650
651static void
652TDFXDRITransitionTo2d(ScreenPtr pScreen)
653{
654  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
655  TDFXPtr pTDFX = TDFXPTR(pScrn);
656
657  xf86FreeOffscreenArea(pTDFX->reservedArea);
658}
659
660static void
661TDFXDRITransitionTo3d(ScreenPtr pScreen)
662{
663  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
664  TDFXPtr pTDFX = TDFXPTR(pScrn);
665  FBAreaPtr pArea;
666
667  if(pTDFX->overlayBuffer) {
668	xf86FreeOffscreenLinear(pTDFX->overlayBuffer);
669	pTDFX->overlayBuffer = NULL;
670  }
671
672  if(pTDFX->overlayBuffer2) {
673	xf86FreeOffscreenLinear(pTDFX->overlayBuffer2);
674	pTDFX->overlayBuffer2 = NULL;
675  }
676
677  if(pTDFX->textureBuffer) {
678	xf86FreeOffscreenArea(pTDFX->textureBuffer);
679	pTDFX->textureBuffer = NULL;
680  }
681
682  xf86PurgeUnlockedOffscreenAreas(pScreen);
683
684  pArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
685				    pTDFX->pixmapCacheLinesMin,
686				    pScrn->displayWidth, NULL, NULL, NULL);
687  pTDFX->reservedArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
688			pTDFX->pixmapCacheLinesMax - pTDFX->pixmapCacheLinesMin,
689			pScrn->displayWidth, NULL, NULL, NULL);
690  xf86FreeOffscreenArea(pArea);
691}
692