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