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