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