i740_dga.c revision 34d2f1a1
1/* 2 * Copyright 2001 by Patrick LERDA 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Patrick LERDA not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Patrick LERDA makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * PATRICK LERDA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL PATRICK LERDA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Authors: Patrick LERDA 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include "xf86.h" 30#include "xf86_OSproc.h" 31#include "xf86Pci.h" 32#include "xf86PciInfo.h" 33#include "vgaHW.h" 34#include "xf86xv.h" 35#include "i740.h" 36#ifdef HAVE_XAA_H 37#include "xaalocal.h" 38#endif 39#include "dgaproc.h" 40#include "i740_dga.h" 41 42static Bool I740_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, int *, int *, int *); 43static Bool I740_SetMode(ScrnInfoPtr, DGAModePtr); 44static int I740_GetViewport(ScrnInfoPtr); 45static void I740_SetViewport(ScrnInfoPtr, int, int, int); 46#ifdef HAVE_XAA_H 47static void I740_Sync(ScrnInfoPtr); 48static void I740_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 49static void I740_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 50#if 0 51static void I740_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, unsigned long); 52#endif 53#endif 54static DGAFunctionRec I740DGAFuncs = { 55 I740_OpenFramebuffer, 56 NULL, 57 I740_SetMode, 58 I740_SetViewport, 59 I740_GetViewport, 60#ifdef HAVE_XAA_H 61 I740_Sync, 62 I740_FillRect, 63 I740_BlitRect, 64#if 0 65 I740_BlitTransRect 66#else 67 NULL 68#endif 69#else 70 NULL, NULL, NULL 71#endif 72}; 73 74Bool I740DGAInit(ScreenPtr pScreen) 75{ 76 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 77 I740Ptr pI740 = I740PTR(pScrn); 78 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 79 DisplayModePtr pMode, firstMode; 80 int Bpp = pScrn->bitsPerPixel >> 3; 81 int num = 0; 82 83 pMode = firstMode = pScrn->modes; 84 85 while(pMode) { 86 87 newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 88 89 if(!newmodes) { 90 free(modes); 91 return FALSE; 92 } 93 modes = newmodes; 94 95 currentMode = modes + num; 96 num++; 97 98 currentMode->mode = pMode; 99 currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 100#ifdef HAVE_XAA_H 101 if(pI740->AccelInfoRec) 102 currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 103#endif 104 if(pMode->Flags & V_DBLSCAN) 105 currentMode->flags |= DGA_DOUBLESCAN; 106 if(pMode->Flags & V_INTERLACE) 107 currentMode->flags |= DGA_INTERLACED; 108 currentMode->byteOrder = pScrn->imageByteOrder; 109 currentMode->depth = pScrn->depth; 110 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 111 currentMode->red_mask = pScrn->mask.red; 112 currentMode->green_mask = pScrn->mask.green; 113 currentMode->blue_mask = pScrn->mask.blue; 114 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 115 currentMode->viewportWidth = pMode->HDisplay; 116 currentMode->viewportHeight = pMode->VDisplay; 117 currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; 118 currentMode->yViewportStep = 1; 119 currentMode->viewportFlags = DGA_FLIP_RETRACE; 120 currentMode->offset = 0; 121 currentMode->address = pI740->FbBase; 122 123 currentMode->bytesPerScanline = 124 ((pScrn->displayWidth * Bpp) + 3) & ~3L; 125 currentMode->imageWidth = pI740->FbMemBox.x2; 126 currentMode->imageHeight = pI740->FbMemBox.y2; 127 currentMode->pixmapWidth = currentMode->imageWidth; 128 currentMode->pixmapHeight = currentMode->imageHeight; 129 currentMode->maxViewportX = currentMode->imageWidth - 130 currentMode->viewportWidth; 131 /* this might need to get clamped to some maximum */ 132 currentMode->maxViewportY = currentMode->imageHeight - 133 currentMode->viewportHeight; 134 135 pMode = pMode->next; 136 if(pMode == firstMode) 137 break; 138 } 139 140 pI740->numDGAModes = num; 141 pI740->DGAModes = modes; 142 143 return DGAInit(pScreen, &I740DGAFuncs, modes, num); 144} 145 146static DisplayModePtr I740SavedDGAModes[MAXSCREENS]; 147 148static Bool I740_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) 149{ 150 int index = pScrn->pScreen->myNum; 151 I740Ptr pI740 = I740PTR(pScrn); 152 153 if(!pMode) { /* restore the original mode */ 154 if(pI740->DGAactive) { 155 pScrn->currentMode = I740SavedDGAModes[index]; 156 I740SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 157 I740AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 158 pI740->DGAactive = FALSE; 159 } 160 } else { 161 if(!pI740->DGAactive) { 162 I740SavedDGAModes[index] = pScrn->currentMode; 163 pI740->DGAactive = TRUE; 164 } 165 166 I740SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 167 } 168 169 return TRUE; 170} 171 172static int I740_GetViewport(ScrnInfoPtr pScrn) 173{ 174 I740Ptr pI740 = I740PTR(pScrn); 175 176 return pI740->DGAViewportStatus; 177} 178 179static void I740_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 180{ 181 I740Ptr pI740 = I740PTR(pScrn); 182 vgaHWPtr hwp = VGAHWPTR(pScrn); 183 184 I740AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 185 186 /* wait for retrace */ 187 while((hwp->readST01(hwp) & 0x08)); 188 while(!(hwp->readST01(hwp) & 0x08)); 189 190 pI740->DGAViewportStatus = 0; 191} 192 193#ifdef HAVE_XAA_H 194static void I740_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) 195{ 196 I740Ptr pI740 = I740PTR(pScrn); 197 198 if(pI740->AccelInfoRec) { 199 (*pI740->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 200 (*pI740->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 201 SET_SYNC_FLAG(pI740->AccelInfoRec); 202 } 203} 204 205static void I740_Sync(ScrnInfoPtr pScrn) 206{ 207 I740Ptr pI740 = I740PTR(pScrn); 208 209 if(pI740->AccelInfoRec) { 210 (*pI740->AccelInfoRec->Sync)(pScrn); 211 } 212} 213 214static void I740_BlitRect( 215 ScrnInfoPtr pScrn, 216 int srcx, int srcy, 217 int w, int h, 218 int dstx, int dsty 219 ){ 220 I740Ptr pI740 = I740PTR(pScrn); 221 222 if(pI740->AccelInfoRec) { 223 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 224 int ydir = (srcy < dsty) ? -1 : 1; 225 226 (*pI740->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, ~0, -1); 227 (*pI740->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, dstx, dsty, w, h); 228 SET_SYNC_FLAG(pI740->AccelInfoRec); 229 } 230} 231#endif 232#if 0 233static void I740_BlitTransRect(ScrnInfoPtr pScrn, 234 int srcx, int srcy, 235 int w, int h, 236 int dstx, int dsty, 237 unsigned long color 238 ) 239{ 240 /* this one should be separate since the XAA function would 241 prohibit usage of ~0 as the key */ 242} 243#endif 244 245static Bool I740_OpenFramebuffer( 246 ScrnInfoPtr pScrn, 247 char **name, 248 unsigned char **mem, 249 int *size, 250 int *offset, 251 int *flags 252 ){ 253 I740Ptr pI740 = I740PTR(pScrn); 254 255 *name = NULL; /* no special device */ 256 *mem = (unsigned char*)pI740->LinearAddr; 257 *size = pI740->FbMapSize; 258 *offset = 0; 259 *flags = DGA_NEED_ROOT; 260 261 return TRUE; 262} 263