1/* 2 * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. 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 Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane 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 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE 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: Alan Hourihane, <alanh@fairlite.demon.co.uk> 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 "trident.h" 33#include "trident_regs.h" 34#include "dgaproc.h" 35 36 37static Bool TRIDENT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 38 int *, int *, int *); 39static Bool TRIDENT_SetMode(ScrnInfoPtr, DGAModePtr); 40static int TRIDENT_GetViewport(ScrnInfoPtr); 41static void TRIDENT_SetViewport(ScrnInfoPtr, int, int, int); 42#ifdef HAVE_XAA_H 43static void TRIDENT_Sync(ScrnInfoPtr); 44static void TRIDENT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 45static void TRIDENT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 46#if 0 47static void TRIDENT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 48 unsigned long); 49#endif 50#endif 51 52static 53DGAFunctionRec TRIDENTDGAFuncs = { 54 TRIDENT_OpenFramebuffer, 55 NULL, 56 TRIDENT_SetMode, 57 TRIDENT_SetViewport, 58 TRIDENT_GetViewport, 59#ifdef HAVE_XAA_H 60 TRIDENT_Sync, 61 TRIDENT_FillRect, 62 TRIDENT_BlitRect, 63#if 0 64 TRIDENT_BlitTransRect 65#else 66 NULL 67#endif 68#else 69 NULL, NULL, NULL 70#endif 71}; 72 73Bool 74TRIDENTDGAInit(ScreenPtr pScreen) 75{ 76 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 77 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 78 DGAModePtr modes = NULL, newmodes = NULL, currentMode; 79 DisplayModePtr pMode, firstMode; 80 int Bpp = pScrn->bitsPerPixel >> 3; 81 int num = 0; 82 Bool oneMore; 83 84 pMode = firstMode = pScrn->modes; 85 86 while(pMode) { 87 88 if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 89 newmodes = realloc(modes, (num + 2) * sizeof(DGAModeRec)); 90 oneMore = TRUE; 91 } else { 92 newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); 93 oneMore = FALSE; 94 } 95 96 if(!newmodes) { 97 free(modes); 98 return FALSE; 99 } 100 modes = newmodes; 101 102SECOND_PASS: 103 104 currentMode = modes + num; 105 num++; 106 107 currentMode->mode = pMode; 108 currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 109#ifdef HAVE_XAA_H 110 if(!pTrident->NoAccel) 111 currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 112#endif 113 if(pMode->Flags & V_DBLSCAN) 114 currentMode->flags |= DGA_DOUBLESCAN; 115 if(pMode->Flags & V_INTERLACE) 116 currentMode->flags |= DGA_INTERLACED; 117 currentMode->byteOrder = pScrn->imageByteOrder; 118 currentMode->depth = pScrn->depth; 119 currentMode->bitsPerPixel = pScrn->bitsPerPixel; 120 currentMode->red_mask = pScrn->mask.red; 121 currentMode->green_mask = pScrn->mask.green; 122 currentMode->blue_mask = pScrn->mask.blue; 123 currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 124 currentMode->viewportWidth = pMode->HDisplay; 125 currentMode->viewportHeight = pMode->VDisplay; 126 currentMode->xViewportStep = 1; 127 currentMode->yViewportStep = 1; 128 currentMode->viewportFlags = DGA_FLIP_RETRACE; 129 currentMode->offset = 0; 130 currentMode->address = pTrident->FbBase; 131 132 if(oneMore) { /* first one is narrow width */ 133 currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 134 currentMode->imageWidth = pMode->HDisplay; 135 currentMode->imageHeight = pMode->VDisplay; 136 currentMode->pixmapWidth = currentMode->imageWidth; 137 currentMode->pixmapHeight = currentMode->imageHeight; 138 currentMode->maxViewportX = currentMode->imageWidth - 139 currentMode->viewportWidth; 140 /* this might need to get clamped to some maximum */ 141 currentMode->maxViewportY = currentMode->imageHeight - 142 currentMode->viewportHeight; 143 oneMore = FALSE; 144 goto SECOND_PASS; 145 } else { 146 currentMode->bytesPerScanline = 147 ((pScrn->displayWidth * Bpp) + 3) & ~3L; 148 currentMode->imageWidth = pScrn->displayWidth; 149 currentMode->imageHeight = pMode->VDisplay; 150 currentMode->pixmapWidth = currentMode->imageWidth; 151 currentMode->pixmapHeight = currentMode->imageHeight; 152 currentMode->maxViewportX = currentMode->imageWidth - 153 currentMode->viewportWidth; 154 /* this might need to get clamped to some maximum */ 155 currentMode->maxViewportY = currentMode->imageHeight - 156 currentMode->viewportHeight; 157 } 158 159 pMode = pMode->next; 160 if(pMode == firstMode) 161 break; 162 } 163 164 pTrident->numDGAModes = num; 165 pTrident->DGAModes = modes; 166 167 return DGAInit(pScreen, &TRIDENTDGAFuncs, modes, num); 168} 169 170 171static Bool 172TRIDENT_SetMode( 173 ScrnInfoPtr pScrn, 174 DGAModePtr pMode 175){ 176 static int OldDisplayWidth[MAXSCREENS]; 177 int index = pScrn->pScreen->myNum; 178 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 179 180 if(!pMode) { /* restore the original mode */ 181 /* put the ScreenParameters back */ 182 183 pScrn->displayWidth = OldDisplayWidth[index]; 184 185 TRIDENTSwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); 186 pTrident->DGAactive = FALSE; 187 } else { 188 if(!pTrident->DGAactive) { /* save the old parameters */ 189 OldDisplayWidth[index] = pScrn->displayWidth; 190 191 pTrident->DGAactive = TRUE; 192 } 193 194 pScrn->displayWidth = pMode->bytesPerScanline / 195 (pMode->bitsPerPixel >> 3); 196 197 TRIDENTSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); 198 } 199 200 return TRUE; 201} 202 203 204 205static int 206TRIDENT_GetViewport( 207 ScrnInfoPtr pScrn 208){ 209 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 210 211 return pTrident->DGAViewportStatus; 212} 213 214static void 215TRIDENT_SetViewport( 216 ScrnInfoPtr pScrn, 217 int x, int y, 218 int flags 219){ 220 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 221 222 TRIDENTAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); 223 pTrident->DGAViewportStatus = 0; /* TRIDENTAdjustFrame loops until finished */ 224} 225 226#ifdef HAVE_XAA_H 227static void 228TRIDENT_FillRect ( 229 ScrnInfoPtr pScrn, 230 int x, int y, int w, int h, 231 unsigned long color 232){ 233 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 234 235 if(pTrident->AccelInfoRec) { 236 (*pTrident->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 237 (*pTrident->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 238 SET_SYNC_FLAG(pTrident->AccelInfoRec); 239 } 240} 241 242static void 243TRIDENT_Sync( 244 ScrnInfoPtr pScrn 245){ 246 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 247 248 if(pTrident->AccelInfoRec) { 249 (*pTrident->AccelInfoRec->Sync)(pScrn); 250 } 251} 252 253static void 254TRIDENT_BlitRect( 255 ScrnInfoPtr pScrn, 256 int srcx, int srcy, 257 int w, int h, 258 int dstx, int dsty 259){ 260 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 261 262 if(pTrident->AccelInfoRec) { 263 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 264 int ydir = (srcy < dsty) ? -1 : 1; 265 266 (*pTrident->AccelInfoRec->SetupForScreenToScreenCopy)( 267 pScrn, xdir, ydir, GXcopy, ~0, -1); 268 (*pTrident->AccelInfoRec->SubsequentScreenToScreenCopy)( 269 pScrn, srcx, srcy, dstx, dsty, w, h); 270 SET_SYNC_FLAG(pTrident->AccelInfoRec); 271 } 272} 273 274#if 0 275static void 276TRIDENT_BlitTransRect( 277 ScrnInfoPtr pScrn, 278 int srcx, int srcy, 279 int w, int h, 280 int dstx, int dsty, 281 unsigned long color 282){ 283 /* this one should be separate since the XAA function would 284 prohibit usage of ~0 as the key */ 285} 286#endif 287#endif 288 289static Bool 290TRIDENT_OpenFramebuffer( 291 ScrnInfoPtr pScrn, 292 char **name, 293 unsigned char **mem, 294 int *size, 295 int *offset, 296 int *flags 297){ 298 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 299 300 *name = NULL; /* no special device */ 301 *mem = (unsigned char*)pTrident->FbAddress; 302 *size = pTrident->FbMapSize; 303 *offset = 0; 304 *flags = DGA_NEED_ROOT; 305 306 return TRUE; 307} 308