nv_dga.c revision fc5a983d
1#ifdef HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include "nv_local.h" 6#include "nv_include.h" 7#include "nv_type.h" 8#include "nv_proto.h" 9#include "xaalocal.h" 10#include "dgaproc.h" 11 12 13static Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 14 int *, int *, int *); 15static Bool NV_SetMode(ScrnInfoPtr, DGAModePtr); 16static int NV_GetViewport(ScrnInfoPtr); 17static void NV_SetViewport(ScrnInfoPtr, int, int, int); 18static void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 19static void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 20static void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 21 unsigned long); 22 23static 24DGAFunctionRec NV_DGAFuncs = { 25 NV_OpenFramebuffer, 26 NULL, 27 NV_SetMode, 28 NV_SetViewport, 29 NV_GetViewport, 30 NVSync, 31 NV_FillRect, 32 NV_BlitRect, 33 NV_BlitTransRect 34}; 35 36 37 38static DGAModePtr 39NVSetupDGAMode( 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 NVPtr pNv = NVPTR(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 <= pNv->ScratchBufferStart)) { 68 69 if(secondPitch) 70 pitch = secondPitch; 71 72 if(!(newmodes = xrealloc(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(!pNv->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 = pNv->FbStart; 103 mode->bytesPerScanline = pitch * Bpp; 104 mode->imageWidth = pitch; 105 mode->imageHeight = pNv->ScratchBufferStart / 106 mode->bytesPerScanline; 107 mode->pixmapWidth = mode->imageWidth; 108 mode->pixmapHeight = mode->imageHeight; 109 mode->maxViewportX = mode->imageWidth - mode->viewportWidth; 110 mode->maxViewportY = mode->imageHeight - mode->viewportHeight; 111 (*num)++; 112 } 113 114 pMode = pMode->next; 115 if(pMode == firstMode) 116 break; 117 } 118 119 if(secondPitch) { 120 secondPitch = 0; 121 goto SECOND_PASS; 122 } 123 124 return modes; 125} 126 127 128Bool 129NVDGAInit(ScreenPtr pScreen) 130{ 131 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 132 NVPtr pNv = NVPTR(pScrn); 133 DGAModePtr modes = NULL; 134 int num = 0; 135 136 /* 8 */ 137 modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8, 138 (pScrn->bitsPerPixel == 8), 139 (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, 140 0, 0, 0, PseudoColor); 141 142 /* 15 */ 143 modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15, 144 (pScrn->bitsPerPixel == 16), 145 (pScrn->depth != 15) ? 0 : pScrn->displayWidth, 146 0x7c00, 0x03e0, 0x001f, TrueColor); 147 148 /* 16 */ 149 modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16, 150 (pScrn->bitsPerPixel == 16), 151 (pScrn->depth != 16) ? 0 : pScrn->displayWidth, 152 0xf800, 0x07e0, 0x001f, TrueColor); 153 154 /* 32 */ 155 modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24, 156 (pScrn->bitsPerPixel == 32), 157 (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, 158 0xff0000, 0x00ff00, 0x0000ff, TrueColor); 159 160 pNv->numDGAModes = num; 161 pNv->DGAModes = modes; 162 163 return DGAInit(pScreen, &NV_DGAFuncs, modes, num); 164} 165 166 167static int 168BitsSet(unsigned long data) 169{ 170 unsigned long mask; 171 int set = 0; 172 173 for(mask = 1; mask; mask <<= 1) 174 if(mask & data) set++; 175 176 return set; 177} 178 179static Bool 180NV_SetMode( 181 ScrnInfoPtr pScrn, 182 DGAModePtr pMode 183){ 184 static NVFBLayout SavedLayouts[MAXSCREENS]; 185 int index = pScrn->pScreen->myNum; 186 187 NVPtr pNv = NVPTR(pScrn); 188 189 if(!pMode) { /* restore the original mode */ 190 if(pNv->DGAactive) 191 memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout)); 192 193 pScrn->currentMode = pNv->CurrentLayout.mode; 194 NVSwitchMode(index, pScrn->currentMode, 0); 195 NVAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0); 196 pNv->DGAactive = FALSE; 197 } else { 198 if(!pNv->DGAactive) { /* save the old parameters */ 199 memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout)); 200 pNv->DGAactive = TRUE; 201 } 202 203 /* update CurrentLayout */ 204 pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; 205 pNv->CurrentLayout.depth = pMode->depth; 206 pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline / 207 (pMode->bitsPerPixel >> 3); 208 pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask); 209 pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask); 210 pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask); 211 /* NVModeInit() will set the mode field */ 212 NVSwitchMode(index, pMode->mode, 0); 213 } 214 215 return TRUE; 216} 217 218 219 220static int 221NV_GetViewport( 222 ScrnInfoPtr pScrn 223){ 224 NVPtr pNv = NVPTR(pScrn); 225 226 return pNv->DGAViewportStatus; 227} 228 229static void 230NV_SetViewport( 231 ScrnInfoPtr pScrn, 232 int x, int y, 233 int flags 234){ 235 NVPtr pNv = NVPTR(pScrn); 236 237 NVAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 238 239 while(VGA_RD08(pNv->PCIO, 0x3da) & 0x08); 240 while(!(VGA_RD08(pNv->PCIO, 0x3da) & 0x08)); 241 242 pNv->DGAViewportStatus = 0; 243} 244 245static void 246NV_FillRect ( 247 ScrnInfoPtr pScrn, 248 int x, int y, int w, int h, 249 unsigned long color 250){ 251 NVPtr pNv = NVPTR(pScrn); 252 253 if(!pNv->AccelInfoRec) return; 254 255 (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 256 (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 257 258 SET_SYNC_FLAG(pNv->AccelInfoRec); 259} 260 261static void 262NV_BlitRect( 263 ScrnInfoPtr pScrn, 264 int srcx, int srcy, 265 int w, int h, 266 int dstx, int dsty 267){ 268 NVPtr pNv = NVPTR(pScrn); 269 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 270 int ydir = (srcy < dsty) ? -1 : 1; 271 272 if(!pNv->AccelInfoRec) return; 273 274 (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)( 275 pScrn, xdir, ydir, GXcopy, ~0, -1); 276 277 (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)( 278 pScrn, srcx, srcy, dstx, dsty, w, h); 279 280 SET_SYNC_FLAG(pNv->AccelInfoRec); 281} 282 283 284static void 285NV_BlitTransRect( 286 ScrnInfoPtr pScrn, 287 int srcx, int srcy, 288 int w, int h, 289 int dstx, int dsty, 290 unsigned long color 291){ 292 /* not implemented */ 293} 294 295 296static Bool 297NV_OpenFramebuffer( 298 ScrnInfoPtr pScrn, 299 char **name, 300 unsigned char **mem, 301 int *size, 302 int *offset, 303 int *flags 304){ 305 NVPtr pNv = NVPTR(pScrn); 306 307 *name = NULL; /* no special device */ 308 *mem = (unsigned char*)pNv->FbAddress; 309 *size = pNv->FbMapSize; 310 *offset = 0; 311 *flags = DGA_NEED_ROOT; 312 313 return TRUE; 314} 315