1#ifdef HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include "riva_local.h" 6#include "riva_include.h" 7#include "riva_type.h" 8#include "riva_proto.h" 9#ifdef HAVE_XAA_H 10#include "xaalocal.h" 11#endif 12#include "dgaproc.h" 13 14static Bool Riva_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 15 int *, int *, int *); 16static Bool Riva_SetMode(ScrnInfoPtr, DGAModePtr); 17static int Riva_GetViewport(ScrnInfoPtr); 18static void Riva_SetViewport(ScrnInfoPtr, int, int, int); 19#ifdef HAVE_XAA_H 20static void Riva_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 21static void Riva_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 22static void Riva_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 23 unsigned long); 24#endif 25 26static 27DGAFunctionRec Riva_DGAFuncs = { 28 Riva_OpenFramebuffer, 29 NULL, 30 Riva_SetMode, 31 Riva_SetViewport, 32 Riva_GetViewport, 33 RivaSync, 34#ifdef HAVE_XAA_H 35 Riva_FillRect, 36 Riva_BlitRect, 37 Riva_BlitTransRect 38#else 39 NULL, NULL, NULL 40#endif 41}; 42 43 44 45static DGAModePtr 46RivaSetupDGAMode( 47 ScrnInfoPtr pScrn, 48 DGAModePtr modes, 49 int *num, 50 int bitsPerPixel, 51 int depth, 52 Bool pixmap, 53 int secondPitch, 54 unsigned long red, 55 unsigned long green, 56 unsigned long blue, 57 short visualClass 58){ 59 DisplayModePtr firstMode, pMode; 60 RivaPtr pRiva = RivaPTR(pScrn); 61 DGAModePtr mode, newmodes; 62 int size, pitch, Bpp = bitsPerPixel >> 3; 63 64SECOND_PASS: 65 66 pMode = firstMode = pScrn->modes; 67 68 while(1) { 69 70 pitch = (pMode->HDisplay + 31) & ~31; 71 size = pitch * Bpp * pMode->VDisplay; 72 73 if((!secondPitch || (pitch != secondPitch)) && 74 (size <= pRiva->FbUsableSize)) { 75 76 if(secondPitch) 77 pitch = secondPitch; 78 79 if(!(newmodes = realloc(modes, (*num + 1) * sizeof(DGAModeRec)))) 80 break; 81 82 modes = newmodes; 83 mode = modes + *num; 84 85 mode->mode = pMode; 86 mode->flags = DGA_CONCURRENT_ACCESS; 87 88 if(pixmap) 89 mode->flags |= DGA_PIXMAP_AVAILABLE; 90#ifdef HAVE_XAA_H 91 if(!pRiva->NoAccel) 92 mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 93#endif 94 if(pMode->Flags & V_DBLSCAN) 95 mode->flags |= DGA_DOUBLESCAN; 96 if(pMode->Flags & V_INTERLACE) 97 mode->flags |= DGA_INTERLACED; 98 mode->byteOrder = pScrn->imageByteOrder; 99 mode->depth = depth; 100 mode->bitsPerPixel = bitsPerPixel; 101 mode->red_mask = red; 102 mode->green_mask = green; 103 mode->blue_mask = blue; 104 mode->visualClass = visualClass; 105 mode->viewportWidth = pMode->HDisplay; 106 mode->viewportHeight = pMode->VDisplay; 107 mode->xViewportStep = 4 / Bpp; 108 mode->yViewportStep = 1; 109 mode->viewportFlags = DGA_FLIP_RETRACE; 110 mode->offset = 0; 111 mode->address = pRiva->FbStart; 112 mode->bytesPerScanline = pitch * Bpp; 113 mode->imageWidth = pitch; 114 mode->imageHeight = pRiva->FbUsableSize / mode->bytesPerScanline; 115 mode->pixmapWidth = mode->imageWidth; 116 mode->pixmapHeight = mode->imageHeight; 117 mode->maxViewportX = mode->imageWidth - mode->viewportWidth; 118 mode->maxViewportY = mode->imageHeight - mode->viewportHeight; 119 (*num)++; 120 } 121 122 pMode = pMode->next; 123 if(pMode == firstMode) 124 break; 125 } 126 127 if(secondPitch) { 128 secondPitch = 0; 129 goto SECOND_PASS; 130 } 131 132 return modes; 133} 134 135 136Bool 137RivaDGAInit(ScreenPtr pScreen) 138{ 139 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 140 RivaPtr pRiva = RivaPTR(pScrn); 141 DGAModePtr modes = NULL; 142 int num = 0; 143 144 /* 8 */ 145 modes = RivaSetupDGAMode (pScrn, modes, &num, 8, 8, 146 (pScrn->bitsPerPixel == 8), 147 (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, 148 0, 0, 0, PseudoColor); 149 150 /* 15 */ 151 modes = RivaSetupDGAMode (pScrn, modes, &num, 16, 15, 152 (pScrn->bitsPerPixel == 16), 153 (pScrn->depth != 15) ? 0 : pScrn->displayWidth, 154 0x7c00, 0x03e0, 0x001f, TrueColor); 155 156 /* 32 */ 157 modes = RivaSetupDGAMode (pScrn, modes, &num, 32, 24, 158 (pScrn->bitsPerPixel == 32), 159 (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, 160 0xff0000, 0x00ff00, 0x0000ff, TrueColor); 161 162 pRiva->numDGAModes = num; 163 pRiva->DGAModes = modes; 164 165 return DGAInit(pScreen, &Riva_DGAFuncs, modes, num); 166} 167 168 169static int 170BitsSet(unsigned long data) 171{ 172 unsigned long mask; 173 int set = 0; 174 175 for(mask = 1; mask; mask <<= 1) 176 if(mask & data) set++; 177 178 return set; 179} 180 181static Bool 182Riva_SetMode( 183 ScrnInfoPtr pScrn, 184 DGAModePtr pMode 185){ 186 static RivaFBLayout SavedLayouts[MAXSCREENS]; 187 int index = pScrn->pScreen->myNum; 188 189 RivaPtr pRiva = RivaPTR(pScrn); 190 191 if(!pMode) { /* restore the original mode */ 192 if(pRiva->DGAactive) 193 memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout)); 194 195 pScrn->currentMode = pRiva->CurrentLayout.mode; 196 RivaSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 197 RivaAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 198 pRiva->DGAactive = FALSE; 199 } else { 200 if(!pRiva->DGAactive) { /* save the old parameters */ 201 memcpy(&SavedLayouts[index], &pRiva->CurrentLayout, sizeof(RivaFBLayout)); 202 pRiva->DGAactive = TRUE; 203 } 204 205 /* update CurrentLayout */ 206 pRiva->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; 207 pRiva->CurrentLayout.depth = pMode->depth; 208 pRiva->CurrentLayout.displayWidth = pMode->bytesPerScanline / 209 (pMode->bitsPerPixel >> 3); 210 pRiva->CurrentLayout.weight.red = BitsSet(pMode->red_mask); 211 pRiva->CurrentLayout.weight.green = BitsSet(pMode->green_mask); 212 pRiva->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask); 213 /* RivaModeInit() will set the mode field */ 214 RivaSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 215 } 216 217 return TRUE; 218} 219 220 221 222static int 223Riva_GetViewport( 224 ScrnInfoPtr pScrn 225){ 226 RivaPtr pRiva = RivaPTR(pScrn); 227 228 return pRiva->DGAViewportStatus; 229} 230 231static void 232Riva_SetViewport( 233 ScrnInfoPtr pScrn, 234 int x, int y, 235 int flags 236){ 237 RivaPtr pRiva = RivaPTR(pScrn); 238 239 RivaAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 240 241 while(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08); 242 while(!(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08)); 243 244 pRiva->DGAViewportStatus = 0; 245} 246 247#ifdef HAVE_XAA_H 248static void 249Riva_FillRect ( 250 ScrnInfoPtr pScrn, 251 int x, int y, int w, int h, 252 unsigned long color 253){ 254 RivaPtr pRiva = RivaPTR(pScrn); 255 256 if(!pRiva->AccelInfoRec) return; 257 258 (*pRiva->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 259 (*pRiva->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 260 261 SET_SYNC_FLAG(pRiva->AccelInfoRec); 262} 263 264static void 265Riva_BlitRect( 266 ScrnInfoPtr pScrn, 267 int srcx, int srcy, 268 int w, int h, 269 int dstx, int dsty 270){ 271 RivaPtr pRiva = RivaPTR(pScrn); 272 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 273 int ydir = (srcy < dsty) ? -1 : 1; 274 275 if(!pRiva->AccelInfoRec) return; 276 277 (*pRiva->AccelInfoRec->SetupForScreenToScreenCopy)( 278 pScrn, xdir, ydir, GXcopy, ~0, -1); 279 280 (*pRiva->AccelInfoRec->SubsequentScreenToScreenCopy)( 281 pScrn, srcx, srcy, dstx, dsty, w, h); 282 283 SET_SYNC_FLAG(pRiva->AccelInfoRec); 284} 285 286 287static void 288Riva_BlitTransRect( 289 ScrnInfoPtr pScrn, 290 int srcx, int srcy, 291 int w, int h, 292 int dstx, int dsty, 293 unsigned long color 294){ 295 /* not implemented... yet */ 296} 297#endif 298 299static Bool 300Riva_OpenFramebuffer( 301 ScrnInfoPtr pScrn, 302 char **name, 303 unsigned char **mem, 304 int *size, 305 int *offset, 306 int *flags 307){ 308 RivaPtr pRiva = RivaPTR(pScrn); 309 310 *name = NULL; /* no special device */ 311 *mem = (unsigned char*)pRiva->FbAddress; 312 *size = pRiva->FbMapSize; 313 *offset = 0; 314 *flags = DGA_NEED_ROOT; 315 316 return TRUE; 317} 318