riva_dga.c revision fc5a983d
11.44Slukem#ifdef HAVE_CONFIG_H
21.31Slukem#include "config.h"
31.31Slukem#endif
41.35Slukem
51.31Slukem#include "riva_local.h"
61.31Slukem#include "riva_include.h"
71.31Slukem#include "riva_type.h"
81.31Slukem#include "riva_proto.h"
91.31Slukem#include "xaalocal.h"
101.31Slukem#include "dgaproc.h"
111.31Slukem
121.31Slukem
131.31Slukemstatic Bool Riva_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
141.31Slukem					int *, int *, int *);
151.31Slukemstatic Bool Riva_SetMode(ScrnInfoPtr, DGAModePtr);
161.31Slukemstatic int  Riva_GetViewport(ScrnInfoPtr);
171.31Slukemstatic void Riva_SetViewport(ScrnInfoPtr, int, int, int);
181.31Slukemstatic void Riva_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
191.31Slukemstatic void Riva_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
201.31Slukemstatic void Riva_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
211.31Slukem					unsigned long);
221.31Slukem
231.31Slukemstatic
241.31SlukemDGAFunctionRec Riva_DGAFuncs = {
251.31Slukem   Riva_OpenFramebuffer,
261.31Slukem   NULL,
271.31Slukem   Riva_SetMode,
281.31Slukem   Riva_SetViewport,
291.31Slukem   Riva_GetViewport,
301.31Slukem   RivaSync,
311.31Slukem   Riva_FillRect,
321.31Slukem   Riva_BlitRect,
331.31Slukem   Riva_BlitTransRect
341.31Slukem};
351.31Slukem
361.31Slukem
371.31Slukem
381.6Stlsstatic DGAModePtr
391.1ScgdRivaSetupDGAMode(
401.3Scgd   ScrnInfoPtr pScrn,
411.3Scgd   DGAModePtr modes,
421.1Scgd   int *num,
431.1Scgd   int bitsPerPixel,
441.1Scgd   int depth,
451.1Scgd   Bool pixmap,
461.1Scgd   int secondPitch,
471.1Scgd   unsigned long red,
481.1Scgd   unsigned long green,
491.1Scgd   unsigned long blue,
501.1Scgd   short visualClass
511.41Sagc){
521.1Scgd   DisplayModePtr firstMode, pMode;
531.1Scgd   RivaPtr pRiva = RivaPTR(pScrn);
541.1Scgd   DGAModePtr mode, newmodes;
551.1Scgd   int size, pitch, Bpp = bitsPerPixel >> 3;
561.1Scgd
571.1ScgdSECOND_PASS:
581.1Scgd
591.1Scgd   pMode = firstMode = pScrn->modes;
601.1Scgd
611.1Scgd   while(1) {
621.1Scgd
631.1Scgd	pitch = (pMode->HDisplay + 31) & ~31;
641.1Scgd	size = pitch * Bpp * pMode->VDisplay;
651.1Scgd
661.1Scgd	if((!secondPitch || (pitch != secondPitch)) &&
671.1Scgd		(size <= pRiva->FbUsableSize)) {
681.16Slukem
691.1Scgd	    if(secondPitch)
701.6Stls		pitch = secondPitch;
711.6Stls
721.6Stls	    if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
731.44Slukem		break;
741.6Stls
751.1Scgd	    modes = newmodes;
761.1Scgd	    mode = modes + *num;
771.3Scgd
781.1Scgd	    mode->mode = pMode;
791.1Scgd	    mode->flags = DGA_CONCURRENT_ACCESS;
801.1Scgd
811.1Scgd	    if(pixmap)
821.1Scgd		mode->flags |= DGA_PIXMAP_AVAILABLE;
831.1Scgd	    if(!pRiva->NoAccel)
841.42Schristos		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
851.42Schristos	    if(pMode->Flags & V_DBLSCAN)
861.42Schristos		mode->flags |= DGA_DOUBLESCAN;
871.42Schristos	    if(pMode->Flags & V_INTERLACE)
881.42Schristos		mode->flags |= DGA_INTERLACED;
891.42Schristos	    mode->byteOrder = pScrn->imageByteOrder;
901.42Schristos	    mode->depth = depth;
911.42Schristos	    mode->bitsPerPixel = bitsPerPixel;
921.42Schristos	    mode->red_mask = red;
931.42Schristos	    mode->green_mask = green;
941.42Schristos	    mode->blue_mask = blue;
951.42Schristos	    mode->visualClass = visualClass;
961.42Schristos	    mode->viewportWidth = pMode->HDisplay;
971.42Schristos	    mode->viewportHeight = pMode->VDisplay;
981.42Schristos	    mode->xViewportStep = 4 / Bpp;
991.42Schristos	    mode->yViewportStep = 1;
1001.42Schristos	    mode->viewportFlags = DGA_FLIP_RETRACE;
1011.42Schristos	    mode->offset = 0;
1021.42Schristos	    mode->address = pRiva->FbStart;
1031.42Schristos	    mode->bytesPerScanline = pitch * Bpp;
1041.42Schristos	    mode->imageWidth = pitch;
1051.42Schristos	    mode->imageHeight =  pRiva->FbUsableSize / mode->bytesPerScanline;
1061.42Schristos	    mode->pixmapWidth = mode->imageWidth;
1071.42Schristos	    mode->pixmapHeight = mode->imageHeight;
1081.42Schristos	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
1091.42Schristos	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
1101.42Schristos	    (*num)++;
1111.42Schristos	}
1121.42Schristos
1131.42Schristos	pMode = pMode->next;
1141.42Schristos	if(pMode == firstMode)
1151.42Schristos	   break;
1161.42Schristos    }
1171.42Schristos
1181.42Schristos    if(secondPitch) {
1191.42Schristos	secondPitch = 0;
1201.42Schristos	goto SECOND_PASS;
1211.42Schristos    }
1221.42Schristos
1231.36Slukem    return modes;
1241.42Schristos}
1251.42Schristos
1261.42Schristos
1271.42SchristosBool
1281.42SchristosRivaDGAInit(ScreenPtr pScreen)
1291.42Schristos{
1301.42Schristos   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1311.42Schristos   RivaPtr pRiva = RivaPTR(pScrn);
1321.42Schristos   DGAModePtr modes = NULL;
1331.42Schristos   int num = 0;
1341.42Schristos
1351.42Schristos   /* 8 */
1361.36Slukem   modes = RivaSetupDGAMode (pScrn, modes, &num, 8, 8,
1371.42Schristos		(pScrn->bitsPerPixel == 8),
1381.42Schristos		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
1391.19Slukem		0, 0, 0, PseudoColor);
1401.42Schristos
1411.42Schristos   /* 15 */
1421.42Schristos   modes = RivaSetupDGAMode (pScrn, modes, &num, 16, 15,
1431.42Schristos		(pScrn->bitsPerPixel == 16),
1441.42Schristos		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
1451.42Schristos		0x7c00, 0x03e0, 0x001f, TrueColor);
1461.42Schristos
1471.42Schristos   /* 32 */
1481.42Schristos   modes = RivaSetupDGAMode (pScrn, modes, &num, 32, 24,
1491.42Schristos		(pScrn->bitsPerPixel == 32),
1501.42Schristos		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
1511.42Schristos		0xff0000, 0x00ff00, 0x0000ff, TrueColor);
1521.42Schristos
1531.42Schristos   pRiva->numDGAModes = num;
1541.42Schristos   pRiva->DGAModes = modes;
1551.42Schristos
1561.42Schristos   return DGAInit(pScreen, &Riva_DGAFuncs, modes, num);
1571.42Schristos}
1581.42Schristos
1591.42Schristos
1601.10Slukemstatic int
1611.10SlukemBitsSet(unsigned long data)
1621.42Schristos{
1631.42Schristos   unsigned long mask;
1641.42Schristos   int set = 0;
1651.42Schristos
1661.42Schristos   for(mask = 1; mask; mask <<= 1)
1671.42Schristos        if(mask & data) set++;
1681.42Schristos
1691.42Schristos   return set;
1701.42Schristos}
1711.42Schristos
1721.42Schristosstatic Bool
1731.42SchristosRiva_SetMode(
1741.42Schristos   ScrnInfoPtr pScrn,
1751.42Schristos   DGAModePtr pMode
1761.42Schristos){
1771.42Schristos   static RivaFBLayout SavedLayouts[MAXSCREENS];
1781.42Schristos   int index = pScrn->pScreen->myNum;
1791.42Schristos
1801.42Schristos   RivaPtr pRiva = RivaPTR(pScrn);
1811.42Schristos
1821.42Schristos   if(!pMode) { /* restore the original mode */
1831.42Schristos      if(pRiva->DGAactive)
1841.42Schristos        memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout));
1851.1Scgd
1861.21Scgd      pScrn->currentMode = pRiva->CurrentLayout.mode;
1871.32Slukem      RivaSwitchMode(index, pScrn->currentMode, 0);
1881.32Slukem      RivaAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
1891.21Scgd      pRiva->DGAactive = FALSE;
1901.38Slukem   } else {
1911.44Slukem      if(!pRiva->DGAactive) {  /* save the old parameters */
1921.21Scgd	memcpy(&SavedLayouts[index], &pRiva->CurrentLayout, sizeof(RivaFBLayout));
1931.12Slukem	pRiva->DGAactive = TRUE;
1941.1Scgd      }
1951.42Schristos
1961.42Schristos      /* update CurrentLayout */
1971.42Schristos      pRiva->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
1981.42Schristos      pRiva->CurrentLayout.depth = pMode->depth;
1991.42Schristos      pRiva->CurrentLayout.displayWidth = pMode->bytesPerScanline /
2001.42Schristos                              (pMode->bitsPerPixel >> 3);
2011.42Schristos      pRiva->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
2021.42Schristos      pRiva->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
2031.42Schristos      pRiva->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
2041.42Schristos      /* RivaModeInit() will set the mode field */
2051.42Schristos      RivaSwitchMode(index, pMode->mode, 0);
2061.42Schristos   }
2071.42Schristos
2081.42Schristos   return TRUE;
2091.42Schristos}
2101.42Schristos
2111.42Schristos
2121.42Schristos
2131.42Schristosstatic int
2141.42SchristosRiva_GetViewport(
2151.42Schristos  ScrnInfoPtr pScrn
2161.42Schristos){
2171.42Schristos    RivaPtr pRiva = RivaPTR(pScrn);
2181.42Schristos
2191.42Schristos    return pRiva->DGAViewportStatus;
2201.42Schristos}
2211.42Schristos
2221.42Schristosstatic void
2231.42SchristosRiva_SetViewport(
2241.43Slukem   ScrnInfoPtr pScrn,
2251.42Schristos   int x, int y,
2261.42Schristos   int flags
2271.42Schristos){
2281.42Schristos   RivaPtr pRiva = RivaPTR(pScrn);
2291.42Schristos
2301.42Schristos   RivaAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
2311.42Schristos
2321.42Schristos   while(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08);
2331.42Schristos   while(!(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08));
2341.42Schristos
2351.42Schristos   pRiva->DGAViewportStatus = 0;
2361.42Schristos}
2371.42Schristos
2381.42Schristosstatic void
2391.42SchristosRiva_FillRect (
2401.42Schristos   ScrnInfoPtr pScrn,
2411.42Schristos   int x, int y, int w, int h,
2421.42Schristos   unsigned long color
2431.42Schristos){
2441.42Schristos    RivaPtr pRiva = RivaPTR(pScrn);
2451.42Schristos
2461.42Schristos    if(!pRiva->AccelInfoRec) return;
2471.42Schristos
2481.42Schristos    (*pRiva->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
2491.42Schristos    (*pRiva->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
2501.42Schristos
2511.42Schristos    SET_SYNC_FLAG(pRiva->AccelInfoRec);
2521.42Schristos}
2531.42Schristos
2541.42Schristosstatic void
2551.42SchristosRiva_BlitRect(
2561.42Schristos   ScrnInfoPtr pScrn,
2571.42Schristos   int srcx, int srcy,
2581.42Schristos   int w, int h,
2591.42Schristos   int dstx, int dsty
2601.42Schristos){
2611.42Schristos    RivaPtr pRiva = RivaPTR(pScrn);
2621.42Schristos    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
2631.42Schristos    int ydir = (srcy < dsty) ? -1 : 1;
2641.42Schristos
2651.42Schristos    if(!pRiva->AccelInfoRec) return;
2661.42Schristos
2671.42Schristos    (*pRiva->AccelInfoRec->SetupForScreenToScreenCopy)(
2681.42Schristos		pScrn, xdir, ydir, GXcopy, ~0, -1);
2691.42Schristos
2701.42Schristos    (*pRiva->AccelInfoRec->SubsequentScreenToScreenCopy)(
2711.42Schristos		pScrn, srcx, srcy, dstx, dsty, w, h);
2721.43Slukem
2731.42Schristos    SET_SYNC_FLAG(pRiva->AccelInfoRec);
2741.42Schristos}
2751.42Schristos
2761.42Schristos
2771.42Schristosstatic void
2781.42SchristosRiva_BlitTransRect(
2791.42Schristos   ScrnInfoPtr pScrn,
2801.42Schristos   int srcx, int srcy,
2811.42Schristos   int w, int h,
2821.42Schristos   int dstx, int dsty,
2831.42Schristos   unsigned long color
2841.42Schristos){
2851.42Schristos   /* not implemented... yet */
2861.42Schristos}
2871.42Schristos
2881.42Schristos
2891.42Schristosstatic Bool
2901.42SchristosRiva_OpenFramebuffer(
2911.42Schristos   ScrnInfoPtr pScrn,
2921.42Schristos   char **name,
2931.42Schristos   unsigned char **mem,
2941.42Schristos   int *size,
2951.42Schristos   int *offset,
2961.42Schristos   int *flags
2971.1Scgd){
2981.1Scgd    RivaPtr pRiva = RivaPTR(pScrn);
2991.1Scgd
3001.32Slukem    *name = NULL; 		/* no special device */
3011.32Slukem    *mem = (unsigned char*)pRiva->FbAddress;
3021.32Slukem    *size = pRiva->FbMapSize;
3031.32Slukem    *offset = 0;
3041.32Slukem    *flags = DGA_NEED_ROOT;
3051.32Slukem
3061.33Slukem    return TRUE;
3071.34Slukem}
3081.32Slukem