g80_exa.c revision fc5a983d
1fc5a983dSmrg/* 2fc5a983dSmrg * Copyright (c) 2007 NVIDIA, Corporation 3fc5a983dSmrg * 4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5fc5a983dSmrg * copy of this software and associated documentation files (the 6fc5a983dSmrg * "Software"), to deal in the Software without restriction, including 7fc5a983dSmrg * without limitation the rights to use, copy, modify, merge, publish, 8fc5a983dSmrg * distribute, sublicense, and/or sell copies of the Software, and to 9fc5a983dSmrg * permit persons to whom the Software is furnished to do so, subject to 10fc5a983dSmrg * the following conditions: 11fc5a983dSmrg * 12fc5a983dSmrg * The above copyright notice and this permission notice shall be included 13fc5a983dSmrg * in all copies or substantial portions of the Software. 14fc5a983dSmrg * 15fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16fc5a983dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17fc5a983dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18fc5a983dSmrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19fc5a983dSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20fc5a983dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21fc5a983dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22fc5a983dSmrg */ 23fc5a983dSmrg 24fc5a983dSmrg 25fc5a983dSmrg#ifdef HAVE_CONFIG_H 26fc5a983dSmrg#include "config.h" 27fc5a983dSmrg#endif 28fc5a983dSmrg 29fc5a983dSmrg#include "g80_type.h" 30fc5a983dSmrg#include "g80_dma.h" 31fc5a983dSmrg#include "g80_xaa.h" 32fc5a983dSmrg 33fc5a983dSmrgstatic void 34fc5a983dSmrgwaitMarker(ScreenPtr pScreen, int marker) 35fc5a983dSmrg{ 36fc5a983dSmrg G80Sync(xf86Screens[pScreen->myNum]); 37fc5a983dSmrg} 38fc5a983dSmrg 39fc5a983dSmrgstatic Bool 40fc5a983dSmrgsetSrc(G80Ptr pNv, PixmapPtr pSrc) 41fc5a983dSmrg{ 42fc5a983dSmrg CARD32 depth; 43fc5a983dSmrg 44fc5a983dSmrg switch(pSrc->drawable.depth) { 45fc5a983dSmrg case 8: depth = 0x000000f3; break; 46fc5a983dSmrg case 15: depth = 0x000000f8; break; 47fc5a983dSmrg case 16: depth = 0x000000e8; break; 48fc5a983dSmrg case 24: depth = 0x000000e6; break; 49fc5a983dSmrg case 32: depth = 0x000000cf; break; 50fc5a983dSmrg default: return FALSE; 51fc5a983dSmrg } 52fc5a983dSmrg 53fc5a983dSmrg G80DmaStart(pNv, 0x230, 2); 54fc5a983dSmrg G80DmaNext (pNv, depth); 55fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 56fc5a983dSmrg G80DmaStart(pNv, 0x244, 5); 57fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapPitch(pSrc)); 58fc5a983dSmrg G80DmaNext (pNv, pSrc->drawable.width); 59fc5a983dSmrg G80DmaNext (pNv, pSrc->drawable.height); 60fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 61fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapOffset(pSrc)); 62fc5a983dSmrg 63fc5a983dSmrg return TRUE; 64fc5a983dSmrg} 65fc5a983dSmrg 66fc5a983dSmrgstatic Bool 67fc5a983dSmrgsetDst(G80Ptr pNv, PixmapPtr pDst) 68fc5a983dSmrg{ 69fc5a983dSmrg CARD32 depth, depth2; 70fc5a983dSmrg 71fc5a983dSmrg switch(pDst->drawable.depth) { 72fc5a983dSmrg case 8: depth = 0x000000f3; depth2 = 3; break; 73fc5a983dSmrg case 15: depth = 0x000000f8; depth2 = 1; break; 74fc5a983dSmrg case 16: depth = 0x000000e8; depth2 = 0; break; 75fc5a983dSmrg case 24: depth = 0x000000e6; depth2 = 2; break; 76fc5a983dSmrg case 32: depth = 0x000000cf; depth2 = 2; break; 77fc5a983dSmrg default: return FALSE; 78fc5a983dSmrg } 79fc5a983dSmrg 80fc5a983dSmrg G80DmaStart(pNv, 0x200, 2); 81fc5a983dSmrg G80DmaNext (pNv, depth); 82fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 83fc5a983dSmrg G80DmaStart(pNv, 0x214, 5); 84fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapPitch(pDst)); 85fc5a983dSmrg G80DmaNext (pNv, pDst->drawable.width); 86fc5a983dSmrg G80DmaNext (pNv, pDst->drawable.height); 87fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 88fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapOffset(pDst)); 89fc5a983dSmrg G80DmaStart(pNv, 0x2e8, 1); 90fc5a983dSmrg G80DmaNext (pNv, depth2); 91fc5a983dSmrg G80DmaStart(pNv, 0x584, 1); 92fc5a983dSmrg G80DmaNext (pNv, depth); 93fc5a983dSmrg G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height); 94fc5a983dSmrg 95fc5a983dSmrg return TRUE; 96fc5a983dSmrg} 97fc5a983dSmrg 98fc5a983dSmrg/* solid fills */ 99fc5a983dSmrg 100fc5a983dSmrgstatic Bool 101fc5a983dSmrgprepareSolid(PixmapPtr pPixmap, 102fc5a983dSmrg int alu, 103fc5a983dSmrg Pixel planemask, 104fc5a983dSmrg Pixel fg) 105fc5a983dSmrg{ 106fc5a983dSmrg ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 107fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 108fc5a983dSmrg 109fc5a983dSmrg if(pPixmap->drawable.depth > 24) return FALSE; 110fc5a983dSmrg if(!setDst(pNv, pPixmap)) return FALSE; 111fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 112fc5a983dSmrg G80DmaNext (pNv, 1); 113fc5a983dSmrg G80SetRopSolid(pNv, alu, planemask); 114fc5a983dSmrg G80DmaStart(pNv, 0x580, 1); 115fc5a983dSmrg G80DmaNext (pNv, 4); 116fc5a983dSmrg G80DmaStart(pNv, 0x588, 1); 117fc5a983dSmrg G80DmaNext (pNv, fg); 118fc5a983dSmrg 119fc5a983dSmrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 120fc5a983dSmrg return TRUE; 121fc5a983dSmrg} 122fc5a983dSmrg 123fc5a983dSmrgstatic void 124fc5a983dSmrgsolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 125fc5a983dSmrg{ 126fc5a983dSmrg ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 127fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 128fc5a983dSmrg 129fc5a983dSmrg G80DmaStart(pNv, 0x600, 4); 130fc5a983dSmrg G80DmaNext (pNv, x1); 131fc5a983dSmrg G80DmaNext (pNv, y1); 132fc5a983dSmrg G80DmaNext (pNv, x2); 133fc5a983dSmrg G80DmaNext (pNv, y2); 134fc5a983dSmrg 135fc5a983dSmrg if((x2 - x1) * (y2 - y1) >= 512) 136fc5a983dSmrg G80DmaKickoff(pNv); 137fc5a983dSmrg} 138fc5a983dSmrg 139fc5a983dSmrgstatic void 140fc5a983dSmrgdoneSolid(PixmapPtr pPixmap) 141fc5a983dSmrg{ 142fc5a983dSmrg} 143fc5a983dSmrg 144fc5a983dSmrg/* screen to screen copies */ 145fc5a983dSmrg 146fc5a983dSmrgstatic Bool 147fc5a983dSmrgprepareCopy(PixmapPtr pSrcPixmap, 148fc5a983dSmrg PixmapPtr pDstPixmap, 149fc5a983dSmrg int dx, 150fc5a983dSmrg int dy, 151fc5a983dSmrg int alu, 152fc5a983dSmrg Pixel planemask) 153fc5a983dSmrg{ 154fc5a983dSmrg ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 155fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 156fc5a983dSmrg 157fc5a983dSmrg if(!setSrc(pNv, pSrcPixmap)) return FALSE; 158fc5a983dSmrg if(!setDst(pNv, pDstPixmap)) return FALSE; 159fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 160fc5a983dSmrg if(alu == GXcopy && planemask == ~0) { 161fc5a983dSmrg G80DmaNext (pNv, 3); 162fc5a983dSmrg } else { 163fc5a983dSmrg G80DmaNext (pNv, 1); 164fc5a983dSmrg G80SetRopSolid(pNv, alu, planemask); 165fc5a983dSmrg } 166fc5a983dSmrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 167fc5a983dSmrg return TRUE; 168fc5a983dSmrg} 169fc5a983dSmrg 170fc5a983dSmrgstatic void 171fc5a983dSmrgcopy(PixmapPtr pDstPixmap, 172fc5a983dSmrg int srcX, 173fc5a983dSmrg int srcY, 174fc5a983dSmrg int dstX, 175fc5a983dSmrg int dstY, 176fc5a983dSmrg int width, 177fc5a983dSmrg int height) 178fc5a983dSmrg{ 179fc5a983dSmrg ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 180fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 181fc5a983dSmrg 182fc5a983dSmrg G80DmaStart(pNv, 0x110, 1); 183fc5a983dSmrg G80DmaNext (pNv, 0); 184fc5a983dSmrg G80DmaStart(pNv, 0x8b0, 12); 185fc5a983dSmrg G80DmaNext (pNv, dstX); 186fc5a983dSmrg G80DmaNext (pNv, dstY); 187fc5a983dSmrg G80DmaNext (pNv, width); 188fc5a983dSmrg G80DmaNext (pNv, height); 189fc5a983dSmrg G80DmaNext (pNv, 0); 190fc5a983dSmrg G80DmaNext (pNv, 1); 191fc5a983dSmrg G80DmaNext (pNv, 0); 192fc5a983dSmrg G80DmaNext (pNv, 1); 193fc5a983dSmrg G80DmaNext (pNv, 0); 194fc5a983dSmrg G80DmaNext (pNv, srcX); 195fc5a983dSmrg G80DmaNext (pNv, 0); 196fc5a983dSmrg G80DmaNext (pNv, srcY); 197fc5a983dSmrg 198fc5a983dSmrg if(width * height >= 512) 199fc5a983dSmrg G80DmaKickoff(pNv); 200fc5a983dSmrg} 201fc5a983dSmrg 202fc5a983dSmrgstatic void 203fc5a983dSmrgdoneCopy(PixmapPtr pDstPixmap) 204fc5a983dSmrg{ 205fc5a983dSmrg} 206fc5a983dSmrg 207fc5a983dSmrg/* composite */ 208fc5a983dSmrg 209fc5a983dSmrgstatic Bool 210fc5a983dSmrgcheckComposite(int op, 211fc5a983dSmrg PicturePtr pSrc, 212fc5a983dSmrg PicturePtr pMask, 213fc5a983dSmrg PicturePtr pDst) 214fc5a983dSmrg{ 215fc5a983dSmrg return FALSE; 216fc5a983dSmrg} 217fc5a983dSmrg 218fc5a983dSmrg/* upload to screen */ 219fc5a983dSmrg 220fc5a983dSmrgstatic Bool 221fc5a983dSmrgupload(PixmapPtr pDst, 222fc5a983dSmrg int x, 223fc5a983dSmrg int y, 224fc5a983dSmrg int w, 225fc5a983dSmrg int h, 226fc5a983dSmrg char *src, 227fc5a983dSmrg int src_pitch) 228fc5a983dSmrg{ 229fc5a983dSmrg ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 230fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 231fc5a983dSmrg const int Bpp = pDst->drawable.bitsPerPixel >> 3; 232fc5a983dSmrg int line_dwords = (w * Bpp + 3) / 4; 233fc5a983dSmrg const Bool kickoff = w * h >= 512; 234fc5a983dSmrg CARD32 depth; 235fc5a983dSmrg 236fc5a983dSmrg if(!setDst(pNv, pDst)) return FALSE; 237fc5a983dSmrg switch(pDst->drawable.depth) { 238fc5a983dSmrg case 8: depth = 0x000000f3; break; 239fc5a983dSmrg case 15: depth = 0x000000f8; break; 240fc5a983dSmrg case 16: depth = 0x000000e8; break; 241fc5a983dSmrg case 24: depth = 0x000000e6; break; 242fc5a983dSmrg case 32: depth = 0x000000cf; break; 243fc5a983dSmrg default: return FALSE; 244fc5a983dSmrg } 245fc5a983dSmrg 246fc5a983dSmrg G80SetClip(pNv, x, y, w, h); 247fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 248fc5a983dSmrg G80DmaNext (pNv, 3); 249fc5a983dSmrg G80DmaStart(pNv, 0x800, 2); 250fc5a983dSmrg G80DmaNext (pNv, 0); 251fc5a983dSmrg G80DmaNext (pNv, depth); 252fc5a983dSmrg G80DmaStart(pNv, 0x838, 10); 253fc5a983dSmrg G80DmaNext (pNv, (line_dwords * 4) / Bpp); 254fc5a983dSmrg G80DmaNext (pNv, h); 255fc5a983dSmrg G80DmaNext (pNv, 0); 256fc5a983dSmrg G80DmaNext (pNv, 1); 257fc5a983dSmrg G80DmaNext (pNv, 0); 258fc5a983dSmrg G80DmaNext (pNv, 1); 259fc5a983dSmrg G80DmaNext (pNv, 0); 260fc5a983dSmrg G80DmaNext (pNv, x); 261fc5a983dSmrg G80DmaNext (pNv, 0); 262fc5a983dSmrg G80DmaNext (pNv, y); 263fc5a983dSmrg 264fc5a983dSmrg while(h-- > 0) { 265fc5a983dSmrg int count = line_dwords; 266fc5a983dSmrg char *p = src; 267fc5a983dSmrg 268fc5a983dSmrg while(count) { 269fc5a983dSmrg int size = count > 1792 ? 1792 : count; 270fc5a983dSmrg 271fc5a983dSmrg G80DmaStart(pNv, 0x40000860, size); 272fc5a983dSmrg memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4); 273fc5a983dSmrg 274fc5a983dSmrg p += size * Bpp; 275fc5a983dSmrg pNv->dmaCurrent += size; 276fc5a983dSmrg 277fc5a983dSmrg count -= size; 278fc5a983dSmrg } 279fc5a983dSmrg 280fc5a983dSmrg src += src_pitch; 281fc5a983dSmrg } 282fc5a983dSmrg 283fc5a983dSmrg if(kickoff) 284fc5a983dSmrg G80DmaKickoff(pNv); 285fc5a983dSmrg else 286fc5a983dSmrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 287fc5a983dSmrg 288fc5a983dSmrg return TRUE; 289fc5a983dSmrg} 290fc5a983dSmrg 291fc5a983dSmrg/******************************************************************************/ 292fc5a983dSmrg 293fc5a983dSmrgBool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn) 294fc5a983dSmrg{ 295fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 296fc5a983dSmrg ExaDriverPtr exa; 297fc5a983dSmrg const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); 298fc5a983dSmrg 299fc5a983dSmrg exa = pNv->exa = exaDriverAlloc(); 300fc5a983dSmrg if(!exa) return FALSE; 301fc5a983dSmrg 302fc5a983dSmrg exa->exa_major = EXA_VERSION_MAJOR; 303fc5a983dSmrg exa->exa_minor = EXA_VERSION_MINOR; 304fc5a983dSmrg exa->memoryBase = pNv->mem; 305fc5a983dSmrg exa->offScreenBase = 0; 306fc5a983dSmrg exa->memorySize = pitch * pNv->offscreenHeight; 307fc5a983dSmrg exa->pixmapOffsetAlign = 256; 308fc5a983dSmrg exa->pixmapPitchAlign = 256; 309fc5a983dSmrg exa->flags = EXA_OFFSCREEN_PIXMAPS; 310fc5a983dSmrg exa->maxX = 8192; 311fc5a983dSmrg exa->maxY = 8192; 312fc5a983dSmrg 313fc5a983dSmrg /**** Rendering ops ****/ 314fc5a983dSmrg exa->PrepareSolid = prepareSolid; 315fc5a983dSmrg exa->Solid = solid; 316fc5a983dSmrg exa->DoneSolid = doneSolid; 317fc5a983dSmrg exa->PrepareCopy = prepareCopy; 318fc5a983dSmrg exa->Copy = copy; 319fc5a983dSmrg exa->DoneCopy = doneCopy; 320fc5a983dSmrg exa->CheckComposite = checkComposite; 321fc5a983dSmrg //exa->PrepareComposite = prepareComposite; 322fc5a983dSmrg //exa->Composite = composite; 323fc5a983dSmrg //exa->DoneComposite = doneComposite; 324fc5a983dSmrg exa->UploadToScreen = upload; 325fc5a983dSmrg 326fc5a983dSmrg exa->WaitMarker = waitMarker; 327fc5a983dSmrg 328fc5a983dSmrg return exaDriverInit(pScreen, exa); 329fc5a983dSmrg} 330