17fd8a0c2Smacallan/* 27fd8a0c2Smacallan * Sun GX and Turbo GX acceleration support 37fd8a0c2Smacallan * 47fd8a0c2Smacallan * Copyright (C) 2005 Michael Lorenz 57fd8a0c2Smacallan * 67fd8a0c2Smacallan * Permission is hereby granted, free of charge, to any person obtaining a copy 77fd8a0c2Smacallan * of this software and associated documentation files (the "Software"), to deal 87fd8a0c2Smacallan * in the Software without restriction, including without limitation the rights 97fd8a0c2Smacallan * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 107fd8a0c2Smacallan * copies of the Software, and to permit persons to whom the Software is 117fd8a0c2Smacallan * furnished to do so, subject to the following conditions: 127fd8a0c2Smacallan * 137fd8a0c2Smacallan * The above copyright notice and this permission notice shall be included in 147fd8a0c2Smacallan * all copies or substantial portions of the Software. 157fd8a0c2Smacallan * 167fd8a0c2Smacallan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 177fd8a0c2Smacallan * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187fd8a0c2Smacallan * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 197fd8a0c2Smacallan * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 207fd8a0c2Smacallan * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 217fd8a0c2Smacallan * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 227fd8a0c2Smacallan */ 237fd8a0c2Smacallan/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/suncg6/cg6_accel.c $ */ 247fd8a0c2Smacallan 2565d21144Smrg#ifdef HAVE_CONFIG_H 2665d21144Smrg#include "config.h" 2765d21144Smrg#endif 2865d21144Smrg 297fd8a0c2Smacallan#include "cg6.h" 307fd8a0c2Smacallan#include "cg6_regs.h" 317fd8a0c2Smacallan#include "dgaproc.h" 327fd8a0c2Smacallan 337fd8a0c2Smacallan 347fd8a0c2Smacallanstatic CARD32 Cg6BlitROP[] = { 357fd8a0c2Smacallan ROP_BLIT(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 367fd8a0c2Smacallan ROP_BLIT(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 377fd8a0c2Smacallan ROP_BLIT(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 387fd8a0c2Smacallan ROP_BLIT(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 397fd8a0c2Smacallan ROP_BLIT(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 407fd8a0c2Smacallan ROP_BLIT(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 417fd8a0c2Smacallan ROP_BLIT(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 427fd8a0c2Smacallan ROP_BLIT(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 437fd8a0c2Smacallan ROP_BLIT(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 447fd8a0c2Smacallan ROP_BLIT(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 457fd8a0c2Smacallan ROP_BLIT(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 467fd8a0c2Smacallan ROP_BLIT(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 477fd8a0c2Smacallan ROP_BLIT(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 487fd8a0c2Smacallan ROP_BLIT(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 497fd8a0c2Smacallan ROP_BLIT(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 507fd8a0c2Smacallan ROP_BLIT(GX_ROP_SET, GX_ROP_SET), /* GXset */ 517fd8a0c2Smacallan}; 527fd8a0c2Smacallan 537fd8a0c2Smacallanstatic CARD32 Cg6DrawROP[] = { 547fd8a0c2Smacallan ROP_FILL(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 557fd8a0c2Smacallan ROP_FILL(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 567fd8a0c2Smacallan ROP_FILL(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 577fd8a0c2Smacallan ROP_FILL(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 587fd8a0c2Smacallan ROP_FILL(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 597fd8a0c2Smacallan ROP_FILL(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 607fd8a0c2Smacallan ROP_FILL(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 617fd8a0c2Smacallan ROP_FILL(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 627fd8a0c2Smacallan ROP_FILL(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 637fd8a0c2Smacallan ROP_FILL(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 647fd8a0c2Smacallan ROP_FILL(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 657fd8a0c2Smacallan ROP_FILL(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 667fd8a0c2Smacallan ROP_FILL(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 677fd8a0c2Smacallan ROP_FILL(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 687fd8a0c2Smacallan ROP_FILL(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 697fd8a0c2Smacallan ROP_FILL(GX_ROP_SET, GX_ROP_SET), /* GXset */ 707fd8a0c2Smacallan}; 717fd8a0c2Smacallan 727fd8a0c2Smacallanstatic CARD32 Cg6StippleROP[16]={ 737fd8a0c2Smacallan ROP_STIP(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 747fd8a0c2Smacallan ROP_STIP(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 757fd8a0c2Smacallan ROP_STIP(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 767fd8a0c2Smacallan ROP_STIP(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 777fd8a0c2Smacallan ROP_STIP(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 787fd8a0c2Smacallan ROP_STIP(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 797fd8a0c2Smacallan ROP_STIP(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 807fd8a0c2Smacallan ROP_STIP(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 817fd8a0c2Smacallan ROP_STIP(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 827fd8a0c2Smacallan ROP_STIP(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 837fd8a0c2Smacallan ROP_STIP(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 847fd8a0c2Smacallan ROP_STIP(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 857fd8a0c2Smacallan ROP_STIP(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 867fd8a0c2Smacallan ROP_STIP(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 877fd8a0c2Smacallan ROP_STIP(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 887fd8a0c2Smacallan ROP_STIP(GX_ROP_SET, GX_ROP_SET), /* GXset */ 897fd8a0c2Smacallan}; 907fd8a0c2Smacallan 917fd8a0c2Smacallanstatic CARD32 Cg6OpaqueStippleROP[16]={ 927fd8a0c2Smacallan ROP_OSTP(GX_ROP_CLEAR, GX_ROP_CLEAR), /* GXclear */ 937fd8a0c2Smacallan ROP_OSTP(GX_ROP_CLEAR, GX_ROP_NOOP), /* GXand */ 947fd8a0c2Smacallan ROP_OSTP(GX_ROP_CLEAR, GX_ROP_INVERT), /* GXandReverse */ 957fd8a0c2Smacallan ROP_OSTP(GX_ROP_CLEAR, GX_ROP_SET), /* GXcopy */ 967fd8a0c2Smacallan ROP_OSTP(GX_ROP_NOOP, GX_ROP_CLEAR), /* GXandInverted */ 977fd8a0c2Smacallan ROP_OSTP(GX_ROP_NOOP, GX_ROP_NOOP), /* GXnoop */ 987fd8a0c2Smacallan ROP_OSTP(GX_ROP_NOOP, GX_ROP_INVERT), /* GXxor */ 997fd8a0c2Smacallan ROP_OSTP(GX_ROP_NOOP, GX_ROP_SET), /* GXor */ 1007fd8a0c2Smacallan ROP_OSTP(GX_ROP_INVERT, GX_ROP_CLEAR), /* GXnor */ 1017fd8a0c2Smacallan ROP_OSTP(GX_ROP_INVERT, GX_ROP_NOOP), /* GXequiv */ 1027fd8a0c2Smacallan ROP_OSTP(GX_ROP_INVERT, GX_ROP_INVERT), /* GXinvert */ 1037fd8a0c2Smacallan ROP_OSTP(GX_ROP_INVERT, GX_ROP_SET), /* GXorReverse */ 1047fd8a0c2Smacallan ROP_OSTP(GX_ROP_SET, GX_ROP_CLEAR), /* GXcopyInverted */ 1057fd8a0c2Smacallan ROP_OSTP(GX_ROP_SET, GX_ROP_NOOP), /* GXorInverted */ 1067fd8a0c2Smacallan ROP_OSTP(GX_ROP_SET, GX_ROP_INVERT), /* GXnand */ 1077fd8a0c2Smacallan ROP_OSTP(GX_ROP_SET, GX_ROP_SET), /* GXset */ 1087fd8a0c2Smacallan}; 1097fd8a0c2Smacallan 1107fd8a0c2Smacallan/* DGA stuff */ 1117fd8a0c2Smacallan 112a1fff668Smartinstatic Bool Cg6_OpenFramebuffer(ScrnInfoPtr pScrn, char **, unsigned char **mem, 113a1fff668Smartin int *, int *, int *); 1147fd8a0c2Smacallanstatic Bool Cg6_SetMode(ScrnInfoPtr, DGAModePtr); 1157fd8a0c2Smacallanstatic void Cg6_SetViewport(ScrnInfoPtr, int, int, int); 1167fd8a0c2Smacallanstatic int Cg6_GetViewport(ScrnInfoPtr); 1177fd8a0c2Smacallanstatic void Cg6_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); 1187fd8a0c2Smacallanstatic void Cg6_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); 1197fd8a0c2Smacallan 1207fd8a0c2Smacallanstatic void Cg6Sync(ScrnInfoPtr); 1217fd8a0c2Smacallan 1227fd8a0c2Smacallanstatic DGAFunctionRec Cg6_DGAFuncs = { 1237fd8a0c2Smacallan Cg6_OpenFramebuffer, 1247fd8a0c2Smacallan NULL, 1257fd8a0c2Smacallan Cg6_SetMode, 1267fd8a0c2Smacallan Cg6_SetViewport, 1277fd8a0c2Smacallan Cg6_GetViewport, 1287fd8a0c2Smacallan Cg6Sync, 1297fd8a0c2Smacallan Cg6_FillRect, 1307fd8a0c2Smacallan Cg6_BlitRect, 1317fd8a0c2Smacallan NULL 1327fd8a0c2Smacallan}; 1337fd8a0c2Smacallan 1347fd8a0c2Smacallan 1357fd8a0c2Smacallan/* 1367fd8a0c2Smacallan * wait until the engine is idle 1377fd8a0c2Smacallan * unclip since clipping also influences framebuffer accesses 1387fd8a0c2Smacallan */ 1397fd8a0c2Smacallanstatic void 1407fd8a0c2SmacallanCg6Sync(ScrnInfoPtr pScrn) 1417fd8a0c2Smacallan{ 1427fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 1437fd8a0c2Smacallan 1447fd8a0c2Smacallan while (pCg6->fbc->s & GX_INPROGRESS); 1457fd8a0c2Smacallan pCg6->fbc->clipminx = 0; 1467fd8a0c2Smacallan pCg6->fbc->clipmaxx = pCg6->width; 1477fd8a0c2Smacallan pCg6->fbc->clipminy = 0; 1487fd8a0c2Smacallan pCg6->fbc->clipmaxy = pCg6->maxheight; 1497fd8a0c2Smacallan} 1507fd8a0c2Smacallan 1517fd8a0c2Smacallan#define runDraw(pCg6) { volatile CARD32 rubbish = pCg6->fbc->draw; } 1527fd8a0c2Smacallan#define runBlit(pCg6) { volatile CARD32 rubbish = pCg6->fbc->blit; } 153f00f1d62Smacallan 154f00f1d62Smacallan/* 155f00f1d62Smacallan * XXX 156f00f1d62Smacallan * was GX_FULL, which apparently isn't enough on some (slower) CG6 like 157f00f1d62Smacallan * the one found on the SPARCstation LX mainboard 158f00f1d62Smacallan */ 159f00f1d62Smacallan#define waitReady(pCg6) while(pCg6->fbc->s & GX_INPROGRESS) 1607fd8a0c2Smacallan 1617fd8a0c2Smacallan/* 1627fd8a0c2Smacallan * restore clipping values set by the Xserver since we're messing with them in 1637fd8a0c2Smacallan * CPU-to-screen colour expansion 1647fd8a0c2Smacallan */ 1657fd8a0c2Smacallan 1667fd8a0c2Smacallanstatic void 1677fd8a0c2SmacallanunClip(Cg6Ptr pCg6) 1687fd8a0c2Smacallan{ 1697fd8a0c2Smacallan pCg6->fbc->clipminx = pCg6->clipxa; 1707fd8a0c2Smacallan pCg6->fbc->clipmaxx = pCg6->clipxe; 1717fd8a0c2Smacallan} 1727fd8a0c2Smacallan 17370ca4aa4Smacallanvoid 1747fd8a0c2SmacallanCg6InitEngine(Cg6Ptr pCg6) 1757fd8a0c2Smacallan{ 1767fd8a0c2Smacallan pCg6->clipxa = 0; 1777fd8a0c2Smacallan pCg6->clipxe = pCg6->width; 1787fd8a0c2Smacallan pCg6->fbc->clipminx = 0; 1797fd8a0c2Smacallan pCg6->fbc->clipmaxx = pCg6->width; 1807fd8a0c2Smacallan pCg6->fbc->clipminy = 0; 1817fd8a0c2Smacallan pCg6->fbc->clipmaxy = pCg6->maxheight; 1827fd8a0c2Smacallan 1837fd8a0c2Smacallan pCg6->fbc->mode = GX_BLIT_SRC | 1847fd8a0c2Smacallan GX_MODE_COLOR8 | 1857fd8a0c2Smacallan GX_DRAW_RENDER | 1867fd8a0c2Smacallan GX_BWRITE0_ENABLE | 1877fd8a0c2Smacallan GX_BWRITE1_DISABLE | 1887fd8a0c2Smacallan GX_BREAD_0 | 1897fd8a0c2Smacallan GX_BDISP_0; 1907fd8a0c2Smacallan 1917fd8a0c2Smacallan pCg6->fbc->fg = 0xff; 1927fd8a0c2Smacallan pCg6->fbc->bg = 0x00; 1937fd8a0c2Smacallan 1947fd8a0c2Smacallan /* we ignore the pixel mask anyway but for completeness... */ 1957fd8a0c2Smacallan pCg6->fbc->pixelm = ~0; 1967fd8a0c2Smacallan 1977fd8a0c2Smacallan pCg6->fbc->s = 0; 1987fd8a0c2Smacallan pCg6->fbc->clip = 0; 1997fd8a0c2Smacallan pCg6->fbc->offx = 0; 2007fd8a0c2Smacallan pCg6->fbc->offy = 0; 2017fd8a0c2Smacallan pCg6->fbc->incx = 0; 2027fd8a0c2Smacallan pCg6->fbc->incy = 0; 2037fd8a0c2Smacallan} 2047fd8a0c2Smacallan 2057fd8a0c2Smacallanstatic void 2067fd8a0c2SmacallanCg6SetupForScreenToScreenCopy( 2077fd8a0c2Smacallan ScrnInfoPtr pScrn, 2087fd8a0c2Smacallan int xdir, 2097fd8a0c2Smacallan int ydir, 2107fd8a0c2Smacallan int rop, 2117fd8a0c2Smacallan unsigned int planemask, 2127fd8a0c2Smacallan int TransparencyColour 2137fd8a0c2Smacallan) 2147fd8a0c2Smacallan{ 2157fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 2167fd8a0c2Smacallan 2177fd8a0c2Smacallan waitReady(pCg6); 2187fd8a0c2Smacallan unClip(pCg6); 2197fd8a0c2Smacallan 2207fd8a0c2Smacallan pCg6->fbc->mode = GX_BLIT_SRC | 2217fd8a0c2Smacallan GX_MODE_COLOR8 | 2227fd8a0c2Smacallan GX_DRAW_RENDER | 2237fd8a0c2Smacallan GX_BWRITE0_ENABLE | 2247fd8a0c2Smacallan GX_BWRITE1_DISABLE | 2257fd8a0c2Smacallan GX_BREAD_0 | 2267fd8a0c2Smacallan GX_BDISP_0; 2277fd8a0c2Smacallan 2287fd8a0c2Smacallan /* we probably don't need the following three */ 2297fd8a0c2Smacallan pCg6->fbc->fg = 0xff; 2307fd8a0c2Smacallan pCg6->fbc->bg = 0x00; 2317fd8a0c2Smacallan pCg6->fbc->s = 0; 2327fd8a0c2Smacallan 2337fd8a0c2Smacallan pCg6->fbc->alu = Cg6BlitROP[rop]; 2347fd8a0c2Smacallan pCg6->fbc->pm = planemask; 2357fd8a0c2Smacallan} 2367fd8a0c2Smacallan 2377fd8a0c2Smacallanstatic void 2387fd8a0c2SmacallanCg6SubsequentScreenToScreenCopy 2397fd8a0c2Smacallan( 2407fd8a0c2Smacallan ScrnInfoPtr pScrn, 2417fd8a0c2Smacallan int xSrc, 2427fd8a0c2Smacallan int ySrc, 2437fd8a0c2Smacallan int xDst, 2447fd8a0c2Smacallan int yDst, 2457fd8a0c2Smacallan int w, 2467fd8a0c2Smacallan int h 2477fd8a0c2Smacallan) 2487fd8a0c2Smacallan{ 2497fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 2507fd8a0c2Smacallan 2517fd8a0c2Smacallan waitReady(pCg6); 2527fd8a0c2Smacallan pCg6->fbc->x0 = xSrc; 2537fd8a0c2Smacallan pCg6->fbc->y0 = ySrc; 2547fd8a0c2Smacallan pCg6->fbc->x1 = xSrc + w - 1; 2557fd8a0c2Smacallan pCg6->fbc->y1 = ySrc + h - 1; 2567fd8a0c2Smacallan pCg6->fbc->x2 = xDst; 2577fd8a0c2Smacallan pCg6->fbc->y2 = yDst; 2587fd8a0c2Smacallan pCg6->fbc->x3 = xDst + w - 1; 2597fd8a0c2Smacallan pCg6->fbc->y3 = yDst + h - 1; 2607fd8a0c2Smacallan runBlit(pCg6); 2617fd8a0c2Smacallan} 2627fd8a0c2Smacallan 2637fd8a0c2Smacallanstatic void 2647fd8a0c2SmacallanCg6SetupForSolidFill 2657fd8a0c2Smacallan( 2667fd8a0c2Smacallan ScrnInfoPtr pScrn, 2677fd8a0c2Smacallan int colour, 2687fd8a0c2Smacallan int rop, 2697fd8a0c2Smacallan unsigned int planemask 2707fd8a0c2Smacallan) 2717fd8a0c2Smacallan{ 2727fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 2737fd8a0c2Smacallan CARD32 c2; 2747fd8a0c2Smacallan 2757fd8a0c2Smacallan waitReady(pCg6); 2767fd8a0c2Smacallan unClip(pCg6); 2777fd8a0c2Smacallan 2787fd8a0c2Smacallan pCg6->fbc->mode = GX_BLIT_SRC | 2797fd8a0c2Smacallan GX_MODE_COLOR8 | 2807fd8a0c2Smacallan GX_DRAW_RENDER | 2817fd8a0c2Smacallan GX_BWRITE0_ENABLE | 2827fd8a0c2Smacallan GX_BWRITE1_DISABLE | 2837fd8a0c2Smacallan GX_BREAD_0 | 2847fd8a0c2Smacallan GX_BDISP_0; 2857fd8a0c2Smacallan pCg6->fbc->fg = colour; 2867fd8a0c2Smacallan pCg6->fbc->s = 0; 2877fd8a0c2Smacallan pCg6->fbc->alu = Cg6DrawROP[rop]; 2887fd8a0c2Smacallan pCg6->fbc->pm = planemask; 2897fd8a0c2Smacallan} 2907fd8a0c2Smacallan 2917fd8a0c2Smacallanstatic void 2927fd8a0c2SmacallanCg6SubsequentSolidFillRect 2937fd8a0c2Smacallan( 2947fd8a0c2Smacallan ScrnInfoPtr pScrn, 2957fd8a0c2Smacallan int x, 2967fd8a0c2Smacallan int y, 2977fd8a0c2Smacallan int w, 2987fd8a0c2Smacallan int h 2997fd8a0c2Smacallan) 3007fd8a0c2Smacallan{ 3017fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 3027fd8a0c2Smacallan 3037fd8a0c2Smacallan waitReady(pCg6); 3047fd8a0c2Smacallan pCg6->fbc->arecty = y; 3057fd8a0c2Smacallan pCg6->fbc->arectx = x; 3067fd8a0c2Smacallan /* use the relative coordinate registers - saves two additions */ 3077fd8a0c2Smacallan pCg6->fbc->rrecty = h - 1; 3087fd8a0c2Smacallan pCg6->fbc->rrectx = w - 1; 3097fd8a0c2Smacallan runDraw(pCg6); 3107fd8a0c2Smacallan} 3117fd8a0c2Smacallan 312185b32eaSmacallan#ifdef HAVE_XAA_H 313185b32eaSmacallan 3147fd8a0c2Smacallanstatic void 3157fd8a0c2SmacallanCg6SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 3167fd8a0c2Smacallan int fg, int bg, 3177fd8a0c2Smacallan int rop, 3187fd8a0c2Smacallan unsigned int planemask) 3197fd8a0c2Smacallan{ 3207fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 3217fd8a0c2Smacallan 3227fd8a0c2Smacallan waitReady(pCg6); 3237fd8a0c2Smacallan pCg6->fbc->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1; 3247fd8a0c2Smacallan 3257fd8a0c2Smacallan if(bg == -1) { 3267fd8a0c2Smacallan /* transparent */ 3277fd8a0c2Smacallan pCg6->fbc->alu = Cg6StippleROP[rop] | GX_PATTERN_ONES; 3287fd8a0c2Smacallan pCg6->fbc->bg = 0xff; 3297fd8a0c2Smacallan } else { 3307fd8a0c2Smacallan /* draw background */ 3317fd8a0c2Smacallan pCg6->fbc->alu = Cg6OpaqueStippleROP[rop] | GX_PATTERN_ONES; 3327fd8a0c2Smacallan pCg6->fbc->bg = bg; 3337fd8a0c2Smacallan } 3347fd8a0c2Smacallan pCg6->fbc->fg = fg; 3357fd8a0c2Smacallan pCg6->fbc->incx = 32; 3367fd8a0c2Smacallan pCg6->fbc->incy = 0; 3377fd8a0c2Smacallan pCg6->fbc->s = 0; 3387fd8a0c2Smacallan pCg6->fbc->pm = planemask; 3397fd8a0c2Smacallan} 3407fd8a0c2Smacallan 3417fd8a0c2Smacallanstatic void 3427fd8a0c2SmacallanCg6SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 3437fd8a0c2Smacallan int x, int y, int w, int h, 3447fd8a0c2Smacallan int skipleft ) 3457fd8a0c2Smacallan{ 3467fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 3477fd8a0c2Smacallan 3487fd8a0c2Smacallan pCg6->scan_x = x; 3497fd8a0c2Smacallan pCg6->scan_xe = x + w - 1; 3507fd8a0c2Smacallan pCg6->scan_y = y; 3517fd8a0c2Smacallan 3527fd8a0c2Smacallan /* 3537fd8a0c2Smacallan * we need to clip the left and right margins of what we're going to draw or 3547fd8a0c2Smacallan * we'll end up with garbage left or right 3557fd8a0c2Smacallan */ 3567fd8a0c2Smacallan pCg6->fbc->clipminx = x + skipleft; 3577fd8a0c2Smacallan pCg6->fbc->clipmaxx = x + w - 1; 3587fd8a0c2Smacallan pCg6->words_in_scanline = ((w + 31) >> 5); 3597fd8a0c2Smacallan} 3607fd8a0c2Smacallan 3617fd8a0c2Smacallanstatic void 3627fd8a0c2SmacallanCg6SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 3637fd8a0c2Smacallan{ 3647fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 3657fd8a0c2Smacallan int i; 3667fd8a0c2Smacallan 3677fd8a0c2Smacallan /* 3687fd8a0c2Smacallan * the GX is WEIRD. if we tell it to draw n pixels it will fill the entire 3697fd8a0c2Smacallan * line with whatever we feed into the font register. When we write the next 3707fd8a0c2Smacallan * word it draws the entire line AGAIN. So we turn on clipping and pretend 3717fd8a0c2Smacallan * to write only 32 pixels... 3727fd8a0c2Smacallan */ 3737fd8a0c2Smacallan pCg6->fbc->x0 = pCg6->scan_x; 3747fd8a0c2Smacallan pCg6->fbc->x1 = pCg6->scan_x + 31; 3757fd8a0c2Smacallan pCg6->fbc->y0 = pCg6->scan_y; 3767fd8a0c2Smacallan for (i = 0; i < pCg6->words_in_scanline; i++) { 3777fd8a0c2Smacallan pCg6->fbc->font = pCg6->scanline[i]; 3787fd8a0c2Smacallan } 3797fd8a0c2Smacallan pCg6->scan_y++; 3807fd8a0c2Smacallan} 3817fd8a0c2Smacallan 3827fd8a0c2Smacallanstatic void 3837fd8a0c2SmacallanCg6SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 3847fd8a0c2Smacallan unsigned int planemask) 3857fd8a0c2Smacallan{ 3867fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 3877fd8a0c2Smacallan 3887fd8a0c2Smacallan waitReady(pCg6); 3897fd8a0c2Smacallan unClip(pCg6); 3907fd8a0c2Smacallan 3917fd8a0c2Smacallan pCg6->fbc->fg = color; 3927fd8a0c2Smacallan pCg6->fbc->mode = GX_BLIT_NOSRC; 3937fd8a0c2Smacallan pCg6->fbc->s = 0; 3947fd8a0c2Smacallan pCg6->fbc->alu = Cg6DrawROP[rop]; 3957fd8a0c2Smacallan pCg6->fbc->pm = planemask; 3967fd8a0c2Smacallan} 3977fd8a0c2Smacallan 3987fd8a0c2Smacallanstatic void 3997fd8a0c2SmacallanCg6SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 4007fd8a0c2Smacallan int y2, int flags) 4017fd8a0c2Smacallan{ 4027fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 4037fd8a0c2Smacallan 4047fd8a0c2Smacallan /* 4057fd8a0c2Smacallan * XXX we're blatantly ignoring the flags parameter which could tell us not 4067fd8a0c2Smacallan * to draw the last point. Xsun simply reads it from the framebuffer and 4077fd8a0c2Smacallan * puts it back after drawing the line but that would mean we have to wait 4087fd8a0c2Smacallan * until the line is actually drawn. On the other hand - line drawing is 4097fd8a0c2Smacallan * pretty fast so we won't lose too much speed 4107fd8a0c2Smacallan */ 4117fd8a0c2Smacallan waitReady(pCg6); 4127fd8a0c2Smacallan pCg6->fbc->aliney = y1; 4137fd8a0c2Smacallan pCg6->fbc->alinex = x1; 4147fd8a0c2Smacallan pCg6->fbc->aliney = y2; 4157fd8a0c2Smacallan pCg6->fbc->alinex = x2; 4167fd8a0c2Smacallan runDraw(pCg6); 4177fd8a0c2Smacallan} 4187fd8a0c2Smacallan 4197fd8a0c2Smacallanstatic void 4207fd8a0c2SmacallanCg6SetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right, 4217fd8a0c2Smacallan int bottom) 4227fd8a0c2Smacallan{ 4237fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 4247fd8a0c2Smacallan 4257fd8a0c2Smacallan pCg6->fbc->clipminx = pCg6->clipxa = left; 4267fd8a0c2Smacallan pCg6->fbc->clipminy = top; 4277fd8a0c2Smacallan pCg6->fbc->clipmaxx = pCg6->clipxe = right; 4287fd8a0c2Smacallan pCg6->fbc->clipmaxy = bottom; 4297fd8a0c2Smacallan} 4307fd8a0c2Smacallan 4317fd8a0c2Smacallanstatic void 4327fd8a0c2SmacallanCg6DisableClipping(ScrnInfoPtr pScrn) 4337fd8a0c2Smacallan{ 4347fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 4357fd8a0c2Smacallan 4367fd8a0c2Smacallan pCg6->fbc->clipminx = pCg6->clipxa = 0; 4377fd8a0c2Smacallan pCg6->fbc->clipminy = 0; 4387fd8a0c2Smacallan pCg6->fbc->clipmaxx = pCg6->clipxe = pCg6->width; 4397fd8a0c2Smacallan pCg6->fbc->clipmaxy = pCg6->maxheight; 4407fd8a0c2Smacallan} 4417fd8a0c2Smacallan 4427fd8a0c2Smacallanint 4437fd8a0c2SmacallanCG6AccelInit(ScrnInfoPtr pScrn) 4447fd8a0c2Smacallan{ 4457fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 4467fd8a0c2Smacallan XAAInfoRecPtr pXAAInfo = pCg6->pXAA; 4477fd8a0c2Smacallan 4487fd8a0c2Smacallan pXAAInfo->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 4497fd8a0c2Smacallan pXAAInfo->maxOffPixWidth = pCg6->width; 4507fd8a0c2Smacallan pXAAInfo->maxOffPixHeight = pCg6->maxheight; 4517fd8a0c2Smacallan 4527fd8a0c2Smacallan Cg6InitEngine(pCg6); 4537fd8a0c2Smacallan 4547fd8a0c2Smacallan /* wait until the engine is idle and remove clipping */ 4557fd8a0c2Smacallan pXAAInfo->Sync = Cg6Sync; 4567fd8a0c2Smacallan 4577fd8a0c2Smacallan /* clipping */ 4587fd8a0c2Smacallan pXAAInfo->SetClippingRectangle = Cg6SetClippingRectangle; 4597fd8a0c2Smacallan pXAAInfo->DisableClipping = Cg6DisableClipping; 4607fd8a0c2Smacallan pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 4617fd8a0c2Smacallan HARDWARE_CLIP_SOLID_FILL | 4627fd8a0c2Smacallan /*HARDWARE_CLIP_MONO_8x8_FILL | 4637fd8a0c2Smacallan HARDWARE_CLIP_COLOR_8x8_FILL |*/ 4647fd8a0c2Smacallan HARDWARE_CLIP_SOLID_LINE; 4657fd8a0c2Smacallan 4667fd8a0c2Smacallan /* Screen-to-screen copy */ 4677fd8a0c2Smacallan pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 4687fd8a0c2Smacallan pXAAInfo->SetupForScreenToScreenCopy = Cg6SetupForScreenToScreenCopy; 4697fd8a0c2Smacallan pXAAInfo->SubsequentScreenToScreenCopy = 4707fd8a0c2Smacallan Cg6SubsequentScreenToScreenCopy; 4717fd8a0c2Smacallan 4727fd8a0c2Smacallan /* Solid fills */ 4737fd8a0c2Smacallan pXAAInfo->SetupForSolidFill = Cg6SetupForSolidFill; 4747fd8a0c2Smacallan pXAAInfo->SubsequentSolidFillRect = Cg6SubsequentSolidFillRect; 4757fd8a0c2Smacallan 4767fd8a0c2Smacallan /* TODO: add pattern fills */ 4777fd8a0c2Smacallan 4787fd8a0c2Smacallan /* colour expansion */ 4797fd8a0c2Smacallan pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 4807fd8a0c2Smacallan LEFT_EDGE_CLIPPING|SCANLINE_PAD_DWORD; 4817fd8a0c2Smacallan pXAAInfo->NumScanlineColorExpandBuffers = 1; 4827fd8a0c2Smacallan pCg6->buffers[0] = (unsigned char *)pCg6->scanline; 4837fd8a0c2Smacallan pXAAInfo->ScanlineColorExpandBuffers = pCg6->buffers; 4847fd8a0c2Smacallan pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 4857fd8a0c2Smacallan Cg6SetupForCPUToScreenColorExpandFill; 4867fd8a0c2Smacallan pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 4877fd8a0c2Smacallan Cg6SubsequentScanlineCPUToScreenColorExpandFill; 4887fd8a0c2Smacallan pXAAInfo->SubsequentColorExpandScanline = 4897fd8a0c2Smacallan Cg6SubsequentColorExpandScanline; 4907fd8a0c2Smacallan 4917fd8a0c2Smacallan /* line drawing */ 4927fd8a0c2Smacallan pXAAInfo->SetupForSolidLine = Cg6SetupForSolidLine; 4937fd8a0c2Smacallan pXAAInfo->SubsequentSolidTwoPointLine = Cg6SubsequentSolidTwoPointLine; 4947fd8a0c2Smacallan pXAAInfo->SolidLineFlags = BIT_ORDER_IN_BYTE_MSBFIRST; 4957fd8a0c2Smacallan /* 4967fd8a0c2Smacallan * apparently the hardware can't do dashed lines, only lines with patterns 4977fd8a0c2Smacallan * which isn't useful 4987fd8a0c2Smacallan */ 4997fd8a0c2Smacallan 5007fd8a0c2Smacallan /* TODO: add host-to-vram colour blits */ 5017fd8a0c2Smacallan 5027fd8a0c2Smacallan return 0; 5037fd8a0c2Smacallan} 5047fd8a0c2Smacallan 505185b32eaSmacallan#endif /* HAVE_XAA_H */ 506185b32eaSmacallan 5077fd8a0c2SmacallanBool 5087fd8a0c2SmacallanCg6DGAInit(ScreenPtr pScreen) 5097fd8a0c2Smacallan{ 5107fd8a0c2Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 5117fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 5127fd8a0c2Smacallan DGAModePtr mode; 5137fd8a0c2Smacallan int result; 5147fd8a0c2Smacallan 5157fd8a0c2Smacallan mode = xnfcalloc(sizeof(DGAModeRec), 1); 5167fd8a0c2Smacallan if (mode == NULL) { 5177fd8a0c2Smacallan xf86Msg(X_WARNING, "%s: DGA setup failed, cannot allocate memory\n", 5187fd8a0c2Smacallan pCg6->psdp->device); 5197fd8a0c2Smacallan return FALSE; 5207fd8a0c2Smacallan } 5217fd8a0c2Smacallan 5227fd8a0c2Smacallan mode->mode = pScrn->modes; 5237fd8a0c2Smacallan mode->flags = DGA_PIXMAP_AVAILABLE | DGA_CONCURRENT_ACCESS; 5247fd8a0c2Smacallan if(!pCg6->NoAccel) { 5257fd8a0c2Smacallan mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; 5267fd8a0c2Smacallan } 5277fd8a0c2Smacallan 5287fd8a0c2Smacallan mode->imageWidth = mode->pixmapWidth = mode->viewportWidth = 5297fd8a0c2Smacallan pScrn->virtualX; 5307fd8a0c2Smacallan mode->imageHeight = mode->pixmapHeight = mode->viewportHeight = 5317fd8a0c2Smacallan pScrn->virtualY; 5327fd8a0c2Smacallan 5337fd8a0c2Smacallan mode->bytesPerScanline = mode->imageWidth; 5347fd8a0c2Smacallan 5357fd8a0c2Smacallan mode->byteOrder = pScrn->imageByteOrder; 5367fd8a0c2Smacallan mode->depth = 8; 5377fd8a0c2Smacallan mode->bitsPerPixel = 8; 5387fd8a0c2Smacallan mode->red_mask = pScrn->mask.red; 5397fd8a0c2Smacallan mode->green_mask = pScrn->mask.green; 5407fd8a0c2Smacallan mode->blue_mask = pScrn->mask.blue; 5417fd8a0c2Smacallan 5427fd8a0c2Smacallan mode->visualClass = PseudoColor; 5437fd8a0c2Smacallan mode->address = pCg6->fb; 5447fd8a0c2Smacallan 5457fd8a0c2Smacallan result = DGAInit(pScreen, &Cg6_DGAFuncs, mode, 1); 5467fd8a0c2Smacallan 5477fd8a0c2Smacallan if (result) { 5487fd8a0c2Smacallan xf86Msg(X_INFO, "%s: DGA initialized\n", 5497fd8a0c2Smacallan pCg6->psdp->device); 5501c90c60aSchristos return TRUE; 5517fd8a0c2Smacallan } else { 5527fd8a0c2Smacallan xf86Msg(X_WARNING, "%s: DGA setup failed\n", 5537fd8a0c2Smacallan pCg6->psdp->device); 5541c90c60aSchristos return FALSE; 5551c90c60aSchristos } 5567fd8a0c2Smacallan} 5577fd8a0c2Smacallan 5587fd8a0c2Smacallanstatic Bool 5597fd8a0c2SmacallanCg6_OpenFramebuffer(ScrnInfoPtr pScrn, char **name, 560a1fff668Smartin unsigned char **mem, 561a1fff668Smartin int *size, int *offset, 562a1fff668Smartin int *extra) 5637fd8a0c2Smacallan{ 5647fd8a0c2Smacallan Cg6Ptr pCg6 = GET_CG6_FROM_SCRN(pScrn); 5657fd8a0c2Smacallan 5667fd8a0c2Smacallan *name = pCg6->psdp->device; 5677fd8a0c2Smacallan 568a1fff668Smartin *mem = (unsigned char*)CG6_RAM_VOFF; 5697fd8a0c2Smacallan *size = pCg6->vidmem; 5707fd8a0c2Smacallan *offset = 0; 5717fd8a0c2Smacallan *extra = 0; 5727fd8a0c2Smacallan 5737fd8a0c2Smacallan return TRUE; 5747fd8a0c2Smacallan} 5757fd8a0c2Smacallan 5767fd8a0c2Smacallanstatic Bool 5777fd8a0c2SmacallanCg6_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) 5787fd8a0c2Smacallan{ 5797fd8a0c2Smacallan /* 5807fd8a0c2Smacallan * Nothing to do, we currently only support one mode 5817fd8a0c2Smacallan * and we are always in it. 5827fd8a0c2Smacallan */ 5837fd8a0c2Smacallan return TRUE; 5847fd8a0c2Smacallan} 5857fd8a0c2Smacallan 5867fd8a0c2Smacallanstatic void 5877fd8a0c2SmacallanCg6_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 5887fd8a0c2Smacallan{ 5897fd8a0c2Smacallan /* We don't support viewports, so... */ 5907fd8a0c2Smacallan} 5917fd8a0c2Smacallan 5927fd8a0c2Smacallanstatic int 5937fd8a0c2SmacallanCg6_GetViewport(ScrnInfoPtr pScrn) 5947fd8a0c2Smacallan{ 5957fd8a0c2Smacallan /* No viewports, none pending... */ 5967fd8a0c2Smacallan return 0; 5977fd8a0c2Smacallan} 5987fd8a0c2Smacallan 5997fd8a0c2Smacallanstatic void 6007fd8a0c2SmacallanCg6_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) 6017fd8a0c2Smacallan{ 6027fd8a0c2Smacallan 6037fd8a0c2Smacallan Cg6SetupForSolidFill(pScrn, color, GXset, 8); 6047fd8a0c2Smacallan Cg6SubsequentSolidFillRect(pScrn, x, y, w, h); 6057fd8a0c2Smacallan} 6067fd8a0c2Smacallan 6077fd8a0c2Smacallanstatic void 6087fd8a0c2SmacallanCg6_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, 6097fd8a0c2Smacallan int w, int h, int dstx, int dsty) 6107fd8a0c2Smacallan{ 6117fd8a0c2Smacallan 6127fd8a0c2Smacallan Cg6SetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, 8, 0); 6137fd8a0c2Smacallan Cg6SubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h); 6147fd8a0c2Smacallan} 615