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