trident_dga.c revision 95b296d0
195b296d0Smrg/* 295b296d0Smrg * Copyright 1997-2003 by Alan Hourihane, North Wales, UK. 395b296d0Smrg * 495b296d0Smrg * Permission to use, copy, modify, distribute, and sell this software and its 595b296d0Smrg * documentation for any purpose is hereby granted without fee, provided that 695b296d0Smrg * the above copyright notice appear in all copies and that both that 795b296d0Smrg * copyright notice and this permission notice appear in supporting 895b296d0Smrg * documentation, and that the name of Alan Hourihane not be used in 995b296d0Smrg * advertising or publicity pertaining to distribution of the software without 1095b296d0Smrg * specific, written prior permission. Alan Hourihane makes no representations 1195b296d0Smrg * about the suitability of this software for any purpose. It is provided 1295b296d0Smrg * "as is" without express or implied warranty. 1395b296d0Smrg * 1495b296d0Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1595b296d0Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1695b296d0Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1795b296d0Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1895b296d0Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1995b296d0Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2095b296d0Smrg * PERFORMANCE OF THIS SOFTWARE. 2195b296d0Smrg * 2295b296d0Smrg * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 2395b296d0Smrg */ 2495b296d0Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c,v 1.4 2002/10/08 22:14:11 tsi Exp $ */ 2595b296d0Smrg 2695b296d0Smrg#ifdef HAVE_CONFIG_H 2795b296d0Smrg#include "config.h" 2895b296d0Smrg#endif 2995b296d0Smrg 3095b296d0Smrg#include "xf86.h" 3195b296d0Smrg#include "xf86_OSproc.h" 3295b296d0Smrg#include "xf86Pci.h" 3395b296d0Smrg#include "xf86PciInfo.h" 3495b296d0Smrg#include "xaa.h" 3595b296d0Smrg#include "xaalocal.h" 3695b296d0Smrg#include "trident.h" 3795b296d0Smrg#include "trident_regs.h" 3895b296d0Smrg#include "dgaproc.h" 3995b296d0Smrg 4095b296d0Smrg 4195b296d0Smrgstatic Bool TRIDENT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, 4295b296d0Smrg int *, int *, int *); 4395b296d0Smrgstatic Bool TRIDENT_SetMode(ScrnInfoPtr, DGAModePtr); 4495b296d0Smrgstatic void TRIDENT_Sync(ScrnInfoPtr); 4595b296d0Smrgstatic int TRIDENT_GetViewport(ScrnInfoPtr); 4695b296d0Smrgstatic void TRIDENT_SetViewport(ScrnInfoPtr, int, int, int); 4795b296d0Smrgstatic void TRIDENT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 4895b296d0Smrgstatic void TRIDENT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 4995b296d0Smrg#if 0 5095b296d0Smrgstatic void TRIDENT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, 5195b296d0Smrg unsigned long); 5295b296d0Smrg#endif 5395b296d0Smrg 5495b296d0Smrgstatic 5595b296d0SmrgDGAFunctionRec TRIDENTDGAFuncs = { 5695b296d0Smrg TRIDENT_OpenFramebuffer, 5795b296d0Smrg NULL, 5895b296d0Smrg TRIDENT_SetMode, 5995b296d0Smrg TRIDENT_SetViewport, 6095b296d0Smrg TRIDENT_GetViewport, 6195b296d0Smrg TRIDENT_Sync, 6295b296d0Smrg TRIDENT_FillRect, 6395b296d0Smrg TRIDENT_BlitRect, 6495b296d0Smrg#if 0 6595b296d0Smrg TRIDENT_BlitTransRect 6695b296d0Smrg#else 6795b296d0Smrg NULL 6895b296d0Smrg#endif 6995b296d0Smrg}; 7095b296d0Smrg 7195b296d0SmrgBool 7295b296d0SmrgTRIDENTDGAInit(ScreenPtr pScreen) 7395b296d0Smrg{ 7495b296d0Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 7595b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 7695b296d0Smrg DGAModePtr modes = NULL, newmodes = NULL, currentMode; 7795b296d0Smrg DisplayModePtr pMode, firstMode; 7895b296d0Smrg int Bpp = pScrn->bitsPerPixel >> 3; 7995b296d0Smrg int num = 0; 8095b296d0Smrg Bool oneMore; 8195b296d0Smrg 8295b296d0Smrg pMode = firstMode = pScrn->modes; 8395b296d0Smrg 8495b296d0Smrg while(pMode) { 8595b296d0Smrg 8695b296d0Smrg if(0 /*pScrn->displayWidth != pMode->HDisplay*/) { 8795b296d0Smrg newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec)); 8895b296d0Smrg oneMore = TRUE; 8995b296d0Smrg } else { 9095b296d0Smrg newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec)); 9195b296d0Smrg oneMore = FALSE; 9295b296d0Smrg } 9395b296d0Smrg 9495b296d0Smrg if(!newmodes) { 9595b296d0Smrg xfree(modes); 9695b296d0Smrg return FALSE; 9795b296d0Smrg } 9895b296d0Smrg modes = newmodes; 9995b296d0Smrg 10095b296d0SmrgSECOND_PASS: 10195b296d0Smrg 10295b296d0Smrg currentMode = modes + num; 10395b296d0Smrg num++; 10495b296d0Smrg 10595b296d0Smrg currentMode->mode = pMode; 10695b296d0Smrg currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 10795b296d0Smrg if(!pTrident->NoAccel) 10895b296d0Smrg currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 10995b296d0Smrg if(pMode->Flags & V_DBLSCAN) 11095b296d0Smrg currentMode->flags |= DGA_DOUBLESCAN; 11195b296d0Smrg if(pMode->Flags & V_INTERLACE) 11295b296d0Smrg currentMode->flags |= DGA_INTERLACED; 11395b296d0Smrg currentMode->byteOrder = pScrn->imageByteOrder; 11495b296d0Smrg currentMode->depth = pScrn->depth; 11595b296d0Smrg currentMode->bitsPerPixel = pScrn->bitsPerPixel; 11695b296d0Smrg currentMode->red_mask = pScrn->mask.red; 11795b296d0Smrg currentMode->green_mask = pScrn->mask.green; 11895b296d0Smrg currentMode->blue_mask = pScrn->mask.blue; 11995b296d0Smrg currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; 12095b296d0Smrg currentMode->viewportWidth = pMode->HDisplay; 12195b296d0Smrg currentMode->viewportHeight = pMode->VDisplay; 12295b296d0Smrg currentMode->xViewportStep = 1; 12395b296d0Smrg currentMode->yViewportStep = 1; 12495b296d0Smrg currentMode->viewportFlags = DGA_FLIP_RETRACE; 12595b296d0Smrg currentMode->offset = 0; 12695b296d0Smrg currentMode->address = pTrident->FbBase; 12795b296d0Smrg 12895b296d0Smrg if(oneMore) { /* first one is narrow width */ 12995b296d0Smrg currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; 13095b296d0Smrg currentMode->imageWidth = pMode->HDisplay; 13195b296d0Smrg currentMode->imageHeight = pMode->VDisplay; 13295b296d0Smrg currentMode->pixmapWidth = currentMode->imageWidth; 13395b296d0Smrg currentMode->pixmapHeight = currentMode->imageHeight; 13495b296d0Smrg currentMode->maxViewportX = currentMode->imageWidth - 13595b296d0Smrg currentMode->viewportWidth; 13695b296d0Smrg /* this might need to get clamped to some maximum */ 13795b296d0Smrg currentMode->maxViewportY = currentMode->imageHeight - 13895b296d0Smrg currentMode->viewportHeight; 13995b296d0Smrg oneMore = FALSE; 14095b296d0Smrg goto SECOND_PASS; 14195b296d0Smrg } else { 14295b296d0Smrg currentMode->bytesPerScanline = 14395b296d0Smrg ((pScrn->displayWidth * Bpp) + 3) & ~3L; 14495b296d0Smrg currentMode->imageWidth = pScrn->displayWidth; 14595b296d0Smrg currentMode->imageHeight = pMode->VDisplay; 14695b296d0Smrg currentMode->pixmapWidth = currentMode->imageWidth; 14795b296d0Smrg currentMode->pixmapHeight = currentMode->imageHeight; 14895b296d0Smrg currentMode->maxViewportX = currentMode->imageWidth - 14995b296d0Smrg currentMode->viewportWidth; 15095b296d0Smrg /* this might need to get clamped to some maximum */ 15195b296d0Smrg currentMode->maxViewportY = currentMode->imageHeight - 15295b296d0Smrg currentMode->viewportHeight; 15395b296d0Smrg } 15495b296d0Smrg 15595b296d0Smrg pMode = pMode->next; 15695b296d0Smrg if(pMode == firstMode) 15795b296d0Smrg break; 15895b296d0Smrg } 15995b296d0Smrg 16095b296d0Smrg pTrident->numDGAModes = num; 16195b296d0Smrg pTrident->DGAModes = modes; 16295b296d0Smrg 16395b296d0Smrg return DGAInit(pScreen, &TRIDENTDGAFuncs, modes, num); 16495b296d0Smrg} 16595b296d0Smrg 16695b296d0Smrg 16795b296d0Smrgstatic Bool 16895b296d0SmrgTRIDENT_SetMode( 16995b296d0Smrg ScrnInfoPtr pScrn, 17095b296d0Smrg DGAModePtr pMode 17195b296d0Smrg){ 17295b296d0Smrg static int OldDisplayWidth[MAXSCREENS]; 17395b296d0Smrg int index = pScrn->pScreen->myNum; 17495b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 17595b296d0Smrg 17695b296d0Smrg if(!pMode) { /* restore the original mode */ 17795b296d0Smrg /* put the ScreenParameters back */ 17895b296d0Smrg 17995b296d0Smrg pScrn->displayWidth = OldDisplayWidth[index]; 18095b296d0Smrg 18195b296d0Smrg TRIDENTSwitchMode(index, pScrn->currentMode, 0); 18295b296d0Smrg pTrident->DGAactive = FALSE; 18395b296d0Smrg } else { 18495b296d0Smrg if(!pTrident->DGAactive) { /* save the old parameters */ 18595b296d0Smrg OldDisplayWidth[index] = pScrn->displayWidth; 18695b296d0Smrg 18795b296d0Smrg pTrident->DGAactive = TRUE; 18895b296d0Smrg } 18995b296d0Smrg 19095b296d0Smrg pScrn->displayWidth = pMode->bytesPerScanline / 19195b296d0Smrg (pMode->bitsPerPixel >> 3); 19295b296d0Smrg 19395b296d0Smrg TRIDENTSwitchMode(index, pMode->mode, 0); 19495b296d0Smrg } 19595b296d0Smrg 19695b296d0Smrg return TRUE; 19795b296d0Smrg} 19895b296d0Smrg 19995b296d0Smrg 20095b296d0Smrg 20195b296d0Smrgstatic int 20295b296d0SmrgTRIDENT_GetViewport( 20395b296d0Smrg ScrnInfoPtr pScrn 20495b296d0Smrg){ 20595b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 20695b296d0Smrg 20795b296d0Smrg return pTrident->DGAViewportStatus; 20895b296d0Smrg} 20995b296d0Smrg 21095b296d0Smrgstatic void 21195b296d0SmrgTRIDENT_SetViewport( 21295b296d0Smrg ScrnInfoPtr pScrn, 21395b296d0Smrg int x, int y, 21495b296d0Smrg int flags 21595b296d0Smrg){ 21695b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 21795b296d0Smrg 21895b296d0Smrg TRIDENTAdjustFrame(pScrn->pScreen->myNum, x, y, flags); 21995b296d0Smrg pTrident->DGAViewportStatus = 0; /* TRIDENTAdjustFrame loops until finished */ 22095b296d0Smrg} 22195b296d0Smrg 22295b296d0Smrgstatic void 22395b296d0SmrgTRIDENT_FillRect ( 22495b296d0Smrg ScrnInfoPtr pScrn, 22595b296d0Smrg int x, int y, int w, int h, 22695b296d0Smrg unsigned long color 22795b296d0Smrg){ 22895b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 22995b296d0Smrg 23095b296d0Smrg if(pTrident->AccelInfoRec) { 23195b296d0Smrg (*pTrident->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); 23295b296d0Smrg (*pTrident->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 23395b296d0Smrg SET_SYNC_FLAG(pTrident->AccelInfoRec); 23495b296d0Smrg } 23595b296d0Smrg} 23695b296d0Smrg 23795b296d0Smrgstatic void 23895b296d0SmrgTRIDENT_Sync( 23995b296d0Smrg ScrnInfoPtr pScrn 24095b296d0Smrg){ 24195b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 24295b296d0Smrg 24395b296d0Smrg if(pTrident->AccelInfoRec) { 24495b296d0Smrg (*pTrident->AccelInfoRec->Sync)(pScrn); 24595b296d0Smrg } 24695b296d0Smrg} 24795b296d0Smrg 24895b296d0Smrgstatic void 24995b296d0SmrgTRIDENT_BlitRect( 25095b296d0Smrg ScrnInfoPtr pScrn, 25195b296d0Smrg int srcx, int srcy, 25295b296d0Smrg int w, int h, 25395b296d0Smrg int dstx, int dsty 25495b296d0Smrg){ 25595b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 25695b296d0Smrg 25795b296d0Smrg if(pTrident->AccelInfoRec) { 25895b296d0Smrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 25995b296d0Smrg int ydir = (srcy < dsty) ? -1 : 1; 26095b296d0Smrg 26195b296d0Smrg (*pTrident->AccelInfoRec->SetupForScreenToScreenCopy)( 26295b296d0Smrg pScrn, xdir, ydir, GXcopy, ~0, -1); 26395b296d0Smrg (*pTrident->AccelInfoRec->SubsequentScreenToScreenCopy)( 26495b296d0Smrg pScrn, srcx, srcy, dstx, dsty, w, h); 26595b296d0Smrg SET_SYNC_FLAG(pTrident->AccelInfoRec); 26695b296d0Smrg } 26795b296d0Smrg} 26895b296d0Smrg 26995b296d0Smrg#if 0 27095b296d0Smrgstatic void 27195b296d0SmrgTRIDENT_BlitTransRect( 27295b296d0Smrg ScrnInfoPtr pScrn, 27395b296d0Smrg int srcx, int srcy, 27495b296d0Smrg int w, int h, 27595b296d0Smrg int dstx, int dsty, 27695b296d0Smrg unsigned long color 27795b296d0Smrg){ 27895b296d0Smrg /* this one should be separate since the XAA function would 27995b296d0Smrg prohibit usage of ~0 as the key */ 28095b296d0Smrg} 28195b296d0Smrg#endif 28295b296d0Smrg 28395b296d0Smrgstatic Bool 28495b296d0SmrgTRIDENT_OpenFramebuffer( 28595b296d0Smrg ScrnInfoPtr pScrn, 28695b296d0Smrg char **name, 28795b296d0Smrg unsigned char **mem, 28895b296d0Smrg int *size, 28995b296d0Smrg int *offset, 29095b296d0Smrg int *flags 29195b296d0Smrg){ 29295b296d0Smrg TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 29395b296d0Smrg 29495b296d0Smrg *name = NULL; /* no special device */ 29595b296d0Smrg *mem = (unsigned char*)pTrident->FbAddress; 29695b296d0Smrg *size = pTrident->FbMapSize; 29795b296d0Smrg *offset = 0; 29895b296d0Smrg *flags = DGA_NEED_ROOT; 29995b296d0Smrg 30095b296d0Smrg return TRUE; 30195b296d0Smrg} 302