tdfx_dga.c revision 909209ee
102be438aSmrg
202be438aSmrg#ifdef HAVE_CONFIG_H
302be438aSmrg#include "config.h"
402be438aSmrg#endif
502be438aSmrg
602be438aSmrg#include "xf86.h"
702be438aSmrg#include "xf86_OSproc.h"
802be438aSmrg#include "dgaproc.h"
902be438aSmrg
1002be438aSmrg#include "tdfx.h"
1102be438aSmrg#include "vgaHW.h"
1202be438aSmrg
1302be438aSmrgstatic Bool TDFX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
1402be438aSmrg				 int *, int *, int *);
1502be438aSmrgstatic Bool TDFX_SetMode(ScrnInfoPtr, DGAModePtr);
1602be438aSmrgstatic int  TDFX_GetViewport(ScrnInfoPtr);
1702be438aSmrgstatic void TDFX_SetViewport(ScrnInfoPtr, int, int, int);
18909209eeSmrg#ifdef HAVE_XAA_H
1902be438aSmrgstatic void TDFX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
2002be438aSmrgstatic void TDFX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
2102be438aSmrgstatic void TDFX_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
2202be438aSmrg			       unsigned long);
23909209eeSmrg#endif
2402be438aSmrg
2502be438aSmrg
2602be438aSmrgstatic
2702be438aSmrgDGAFunctionRec TDFX_DGAFuncs = {
2802be438aSmrg  TDFX_OpenFramebuffer,
2902be438aSmrg  0,
3002be438aSmrg  TDFX_SetMode,
3102be438aSmrg  TDFX_SetViewport,
3202be438aSmrg  TDFX_GetViewport,
3302be438aSmrg  TDFXSync,
34909209eeSmrg#ifdef HAVE_XAA_H
3502be438aSmrg  TDFX_FillRect,
3602be438aSmrg  TDFX_BlitRect,
3702be438aSmrg  TDFX_BlitTransRect
38909209eeSmrg#else
39909209eeSmrg  NULL, NULL, NULL
40909209eeSmrg#endif
4102be438aSmrg};
4202be438aSmrg
4302be438aSmrg
4402be438aSmrgBool
4502be438aSmrgTDFXDGAInit(ScreenPtr pScreen)
4602be438aSmrg{
47909209eeSmrg  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
4802be438aSmrg  TDFXPtr pTDFX;
4902be438aSmrg  DisplayModePtr pMode, firstMode;
5002be438aSmrg  DGAModePtr modes=0, newmodes=0, currentMode;
5102be438aSmrg  int num=0;
5202be438aSmrg
5302be438aSmrg  pTDFX = TDFXPTR(pScrn);
5402be438aSmrg  pMode = firstMode = pScrn->modes;
5502be438aSmrg
5602be438aSmrg  while (pMode) {
57909209eeSmrg    newmodes = realloc(modes, (num+1)*sizeof(DGAModeRec));
5802be438aSmrg
5902be438aSmrg    if (!newmodes) {
60909209eeSmrg      free(modes);
6102be438aSmrg      return FALSE;
6202be438aSmrg    }
6302be438aSmrg    modes = newmodes;
6402be438aSmrg
6502be438aSmrg    currentMode = modes+num;
6602be438aSmrg    num++;
6702be438aSmrg    currentMode->mode = pMode;
6802be438aSmrg    currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
69909209eeSmrg#ifdef HAVE_XAA_H
7002be438aSmrg    if (!pTDFX->NoAccel)
7102be438aSmrg      currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
72909209eeSmrg#endif
7302be438aSmrg    if (pMode->Flags & V_DBLSCAN)
7402be438aSmrg      currentMode->flags |= DGA_DOUBLESCAN;
7502be438aSmrg    if (pMode->Flags & V_INTERLACE)
7602be438aSmrg      currentMode->flags |= DGA_INTERLACED;
7702be438aSmrg    currentMode->byteOrder = pScrn->imageByteOrder;
7802be438aSmrg    currentMode->depth = pScrn->depth;
7902be438aSmrg    currentMode->bitsPerPixel = pScrn->bitsPerPixel;
8002be438aSmrg    currentMode->red_mask = pScrn->mask.red;
8102be438aSmrg    currentMode->green_mask = pScrn->mask.green;
8202be438aSmrg    currentMode->blue_mask = pScrn->mask.blue;
8302be438aSmrg    currentMode->visualClass = pScrn->defaultVisual;
8402be438aSmrg    currentMode->viewportWidth = pMode->HDisplay;
8502be438aSmrg    currentMode->viewportHeight = pMode->VDisplay;
8602be438aSmrg    currentMode->xViewportStep = 1;
8702be438aSmrg    currentMode->yViewportStep = 1;
8802be438aSmrg    currentMode->viewportFlags = DGA_FLIP_RETRACE;
8902be438aSmrg    currentMode->offset = 0;
9002be438aSmrg    currentMode->address = pTDFX->FbBase;
9102be438aSmrg    currentMode->bytesPerScanline = ((pScrn->displayWidth*pTDFX->cpp)+3) & ~3L;
9202be438aSmrg    currentMode->imageWidth = pScrn->displayWidth;
9302be438aSmrg    currentMode->imageHeight =  pTDFX->pixmapCacheLinesMax;
9402be438aSmrg    currentMode->pixmapWidth = currentMode->imageWidth;
9502be438aSmrg    currentMode->pixmapHeight = currentMode->imageHeight;
9602be438aSmrg    currentMode->maxViewportX = currentMode->imageWidth -
9702be438aSmrg                                currentMode->viewportWidth;
9802be438aSmrg    /* this might need to get clamped to some maximum */
9902be438aSmrg    currentMode->maxViewportY = currentMode->imageHeight -
10002be438aSmrg                                currentMode->viewportHeight;
10102be438aSmrg
10202be438aSmrg    pMode = pMode->next;
10302be438aSmrg    if (pMode == firstMode) break;
10402be438aSmrg  }
10502be438aSmrg
10602be438aSmrg  pTDFX->DGAModes = modes;
10702be438aSmrg
10802be438aSmrg  return DGAInit(pScreen, &TDFX_DGAFuncs, modes, num);
10902be438aSmrg}
11002be438aSmrg
11102be438aSmrgstatic Bool
11202be438aSmrgTDFX_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
11302be438aSmrg{
11402be438aSmrg   static DisplayModePtr OldModes[MAXSCREENS];
11502be438aSmrg   int index = pScrn->pScreen->myNum;
11602be438aSmrg
11702be438aSmrg   TDFXPtr pTDFX = TDFXPTR(pScrn);
11802be438aSmrg
11902be438aSmrg   if (!pMode) { /* restore the original mode */
12002be438aSmrg     /* put the ScreenParameters back */
12102be438aSmrg     if(pTDFX->DGAactive) {
122909209eeSmrg	TDFXSwitchMode(SWITCH_MODE_ARGS(pScrn, OldModes[index]));
123909209eeSmrg	TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0));
12402be438aSmrg	pTDFX->DGAactive = FALSE;
12502be438aSmrg     }
12602be438aSmrg   } else {
12702be438aSmrg     if (!pTDFX->DGAactive) {  /* save the old parameters */
12802be438aSmrg        OldModes[index] = pScrn->currentMode;
12902be438aSmrg        pTDFX->DGAactive = TRUE;
13002be438aSmrg     }
13102be438aSmrg
132909209eeSmrg     TDFXSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
13302be438aSmrg   }
13402be438aSmrg
13502be438aSmrg   return TRUE;
13602be438aSmrg}
13702be438aSmrg
13802be438aSmrgstatic int
13902be438aSmrgTDFX_GetViewport(ScrnInfoPtr pScrn)
14002be438aSmrg{
14102be438aSmrg    TDFXPtr pTDFX = TDFXPTR(pScrn);
14202be438aSmrg
14302be438aSmrg    return pTDFX->DGAViewportStatus;
14402be438aSmrg}
14502be438aSmrg
14602be438aSmrgstatic void
14702be438aSmrgTDFX_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
14802be438aSmrg{
14902be438aSmrg   TDFXPtr pTDFX = TDFXPTR(pScrn);
15002be438aSmrg   vgaHWPtr hwp = VGAHWPTR(pScrn);
15102be438aSmrg
152909209eeSmrg   TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
15302be438aSmrg
15402be438aSmrg   /* fixme */
15502be438aSmrg   while(hwp->readST01(hwp) & 0x08);
15602be438aSmrg   while(!(hwp->readST01(hwp) & 0x08));
15702be438aSmrg
15802be438aSmrg   pTDFX->DGAViewportStatus = 0;
15902be438aSmrg}
16002be438aSmrg
161909209eeSmrg#ifdef HAVE_XAA_H
16202be438aSmrgstatic void
16302be438aSmrgTDFX_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
16402be438aSmrg	      unsigned long color)
16502be438aSmrg{
16602be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
16702be438aSmrg
16802be438aSmrg  if (pTDFX->AccelInfoRec) {
16902be438aSmrg    (*pTDFX->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
17002be438aSmrg    (*pTDFX->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
17102be438aSmrg  }
17202be438aSmrg}
17302be438aSmrg
17402be438aSmrgstatic void
17502be438aSmrgTDFX_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
17602be438aSmrg	      int dstx, int dsty)
17702be438aSmrg{
17802be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
17902be438aSmrg
18002be438aSmrg  if (pTDFX->AccelInfoRec) {
18102be438aSmrg    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
18202be438aSmrg    int ydir = (srcy < dsty) ? -1 : 1;
18302be438aSmrg
18402be438aSmrg    (*pTDFX->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, ~0, -1);
18502be438aSmrg    (*pTDFX->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, dstx, dsty, w, h);
18602be438aSmrg  }
18702be438aSmrg}
18802be438aSmrg
18902be438aSmrg
19002be438aSmrgstatic void
19102be438aSmrgTDFX_BlitTransRect(
19202be438aSmrg   ScrnInfoPtr pScrn,
19302be438aSmrg   int srcx, int srcy,
19402be438aSmrg   int w, int h,
19502be438aSmrg   int dstx, int dsty,
19602be438aSmrg   unsigned long color
19702be438aSmrg){
19802be438aSmrg  /* this one should be separate since the XAA function would
19902be438aSmrg     prohibit usage of ~0 as the key */
20002be438aSmrg}
201909209eeSmrg#endif
20202be438aSmrg
20302be438aSmrg
20402be438aSmrgstatic Bool
20502be438aSmrgTDFX_OpenFramebuffer(
20602be438aSmrg   ScrnInfoPtr pScrn,
20702be438aSmrg   char **name,
20802be438aSmrg   unsigned char **mem,
20902be438aSmrg   int *size,
21002be438aSmrg   int *offset,
21102be438aSmrg   int *flags
21202be438aSmrg){
21302be438aSmrg    TDFXPtr pTDFX = TDFXPTR(pScrn);
21402be438aSmrg
21502be438aSmrg    *name = NULL; 		/* no special device */
21602be438aSmrg    *mem = (unsigned char*)pTDFX->LinearAddr[0] + pTDFX->fbOffset;
21702be438aSmrg    *size = pTDFX->FbMapSize;
21802be438aSmrg    *offset = /* pTDFX->fbOffset */ 0 ;  /* DGA is broken */
21902be438aSmrg    *flags = DGA_NEED_ROOT;
22002be438aSmrg
22102be438aSmrg    return TRUE;
22202be438aSmrg}
223