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