diff options
Diffstat (limited to 'src/g80_exa.c')
-rw-r--r-- | src/g80_exa.c | 249 |
1 files changed, 238 insertions, 11 deletions
diff --git a/src/g80_exa.c b/src/g80_exa.c index 7f487ff..8113c1a 100644 --- a/src/g80_exa.c +++ b/src/g80_exa.c @@ -28,6 +28,7 @@ #include "g80_type.h" #include "g80_dma.h" +#include "g80_xaa.h" static void waitMarker(ScreenPtr pScreen, int marker) @@ -36,23 +37,112 @@ waitMarker(ScreenPtr pScreen, int marker) } static Bool +setSrc(G80Ptr pNv, PixmapPtr pSrc) +{ + CARD32 depth; + + switch(pSrc->drawable.depth) { + case 8: depth = 0x000000f3; break; + case 15: depth = 0x000000f8; break; + case 16: depth = 0x000000e8; break; + case 24: depth = 0x000000e6; break; + case 32: depth = 0x000000cf; break; + default: return FALSE; + } + + G80DmaStart(pNv, 0x230, 2); + G80DmaNext (pNv, depth); + G80DmaNext (pNv, 0x00000001); + G80DmaStart(pNv, 0x244, 5); + G80DmaNext (pNv, exaGetPixmapPitch(pSrc)); + G80DmaNext (pNv, pSrc->drawable.width); + G80DmaNext (pNv, pSrc->drawable.height); + G80DmaNext (pNv, 0x00000000); + G80DmaNext (pNv, exaGetPixmapOffset(pSrc)); + + return TRUE; +} + +static Bool +setDst(G80Ptr pNv, PixmapPtr pDst) +{ + CARD32 depth, depth2; + + switch(pDst->drawable.depth) { + case 8: depth = 0x000000f3; depth2 = 3; break; + case 15: depth = 0x000000f8; depth2 = 1; break; + case 16: depth = 0x000000e8; depth2 = 0; break; + case 24: depth = 0x000000e6; depth2 = 2; break; + case 32: depth = 0x000000cf; depth2 = 2; break; + default: return FALSE; + } + + G80DmaStart(pNv, 0x200, 2); + G80DmaNext (pNv, depth); + G80DmaNext (pNv, 0x00000001); + G80DmaStart(pNv, 0x214, 5); + G80DmaNext (pNv, exaGetPixmapPitch(pDst)); + G80DmaNext (pNv, pDst->drawable.width); + G80DmaNext (pNv, pDst->drawable.height); + G80DmaNext (pNv, 0x00000000); + G80DmaNext (pNv, exaGetPixmapOffset(pDst)); + G80DmaStart(pNv, 0x2e8, 1); + G80DmaNext (pNv, depth2); + G80DmaStart(pNv, 0x584, 1); + G80DmaNext (pNv, depth); + G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height); + + return TRUE; +} + +/* solid fills */ + +static Bool prepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) { - return FALSE; + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + G80Ptr pNv = G80PTR(pScrn); + + if(pPixmap->drawable.depth > 24) return FALSE; + if(!setDst(pNv, pPixmap)) return FALSE; + G80DmaStart(pNv, 0x2ac, 1); + G80DmaNext (pNv, 1); + G80SetRopSolid(pNv, alu, planemask); + G80DmaStart(pNv, 0x580, 1); + G80DmaNext (pNv, 4); + G80DmaStart(pNv, 0x588, 1); + G80DmaNext (pNv, fg); + + pNv->DMAKickoffCallback = G80DMAKickoffCallback; + return TRUE; } -static Bool -checkComposite(int op, - PicturePtr pSrcPicture, - PicturePtr pMaskPicture, - PicturePtr pDstPicture) +static void +solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) { - return FALSE; + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + G80Ptr pNv = G80PTR(pScrn); + + G80DmaStart(pNv, 0x600, 4); + G80DmaNext (pNv, x1); + G80DmaNext (pNv, y1); + G80DmaNext (pNv, x2); + G80DmaNext (pNv, y2); + + if((x2 - x1) * (y2 - y1) >= 512) + G80DmaKickoff(pNv); } +static void +doneSolid(PixmapPtr pPixmap) +{ +} + +/* screen to screen copies */ + static Bool prepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, @@ -61,9 +151,145 @@ prepareCopy(PixmapPtr pSrcPixmap, int alu, Pixel planemask) { + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + G80Ptr pNv = G80PTR(pScrn); + + if(!setSrc(pNv, pSrcPixmap)) return FALSE; + if(!setDst(pNv, pDstPixmap)) return FALSE; + G80DmaStart(pNv, 0x2ac, 1); + if(alu == GXcopy && planemask == ~0) { + G80DmaNext (pNv, 3); + } else { + G80DmaNext (pNv, 1); + G80SetRopSolid(pNv, alu, planemask); + } + pNv->DMAKickoffCallback = G80DMAKickoffCallback; + return TRUE; +} + +static void +copy(PixmapPtr pDstPixmap, + int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + G80Ptr pNv = G80PTR(pScrn); + + G80DmaStart(pNv, 0x110, 1); + G80DmaNext (pNv, 0); + G80DmaStart(pNv, 0x8b0, 12); + G80DmaNext (pNv, dstX); + G80DmaNext (pNv, dstY); + G80DmaNext (pNv, width); + G80DmaNext (pNv, height); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, 1); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, 1); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, srcX); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, srcY); + + if(width * height >= 512) + G80DmaKickoff(pNv); +} + +static void +doneCopy(PixmapPtr pDstPixmap) +{ +} + +/* composite */ + +static Bool +checkComposite(int op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst) +{ return FALSE; } +/* upload to screen */ + +static Bool +upload(PixmapPtr pDst, + int x, + int y, + int w, + int h, + char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + G80Ptr pNv = G80PTR(pScrn); + const int Bpp = pDst->drawable.bitsPerPixel >> 3; + int line_dwords = (w * Bpp + 3) / 4; + const Bool kickoff = w * h >= 512; + CARD32 depth; + + if(!setDst(pNv, pDst)) return FALSE; + switch(pDst->drawable.depth) { + case 8: depth = 0x000000f3; break; + case 15: depth = 0x000000f8; break; + case 16: depth = 0x000000e8; break; + case 24: depth = 0x000000e6; break; + case 32: depth = 0x000000cf; break; + default: return FALSE; + } + + G80SetClip(pNv, x, y, w, h); + G80DmaStart(pNv, 0x2ac, 1); + G80DmaNext (pNv, 3); + G80DmaStart(pNv, 0x800, 2); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, depth); + G80DmaStart(pNv, 0x838, 10); + G80DmaNext (pNv, (line_dwords * 4) / Bpp); + G80DmaNext (pNv, h); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, 1); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, 1); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, x); + G80DmaNext (pNv, 0); + G80DmaNext (pNv, y); + + while(h-- > 0) { + int count = line_dwords; + char *p = src; + + while(count) { + int size = count > 1792 ? 1792 : count; + + G80DmaStart(pNv, 0x40000860, size); + memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4); + + p += size * Bpp; + pNv->dmaCurrent += size; + + count -= size; + } + + src += src_pitch; + } + + if(kickoff) + G80DmaKickoff(pNv); + else + pNv->DMAKickoffCallback = G80DMAKickoffCallback; + + return TRUE; +} + +/******************************************************************************/ + Bool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn) { G80Ptr pNv = G80PTR(pScrn); @@ -86,15 +312,16 @@ Bool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn) /**** Rendering ops ****/ exa->PrepareSolid = prepareSolid; - //exa->Solid = solid; - //exa->DoneSolid = doneSolid; + exa->Solid = solid; + exa->DoneSolid = doneSolid; exa->PrepareCopy = prepareCopy; - //exa->Copy = copy; - //exa->DoneCopy = doneCopy; + exa->Copy = copy; + exa->DoneCopy = doneCopy; exa->CheckComposite = checkComposite; //exa->PrepareComposite = prepareComposite; //exa->Composite = composite; //exa->DoneComposite = doneComposite; + exa->UploadToScreen = upload; exa->WaitMarker = waitMarker; |