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" 3172320d7bSmrg#include "g80_exa.h" 32fc5a983dSmrg#include "g80_xaa.h" 33fc5a983dSmrg 34fc5a983dSmrgstatic void 35fc5a983dSmrgwaitMarker(ScreenPtr pScreen, int marker) 36fc5a983dSmrg{ 37bd304fc0Smrg G80Sync(xf86ScreenToScrn(pScreen)); 38fc5a983dSmrg} 39fc5a983dSmrg 40fc5a983dSmrgstatic Bool 41fc5a983dSmrgsetSrc(G80Ptr pNv, PixmapPtr pSrc) 42fc5a983dSmrg{ 43fc5a983dSmrg CARD32 depth; 44fc5a983dSmrg 45fc5a983dSmrg switch(pSrc->drawable.depth) { 46fc5a983dSmrg case 8: depth = 0x000000f3; break; 47fc5a983dSmrg case 15: depth = 0x000000f8; break; 48fc5a983dSmrg case 16: depth = 0x000000e8; break; 49fc5a983dSmrg case 24: depth = 0x000000e6; break; 50fc5a983dSmrg case 32: depth = 0x000000cf; break; 51fc5a983dSmrg default: return FALSE; 52fc5a983dSmrg } 53fc5a983dSmrg 54fc5a983dSmrg G80DmaStart(pNv, 0x230, 2); 55fc5a983dSmrg G80DmaNext (pNv, depth); 56fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 57fc5a983dSmrg G80DmaStart(pNv, 0x244, 5); 58fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapPitch(pSrc)); 59fc5a983dSmrg G80DmaNext (pNv, pSrc->drawable.width); 60fc5a983dSmrg G80DmaNext (pNv, pSrc->drawable.height); 61fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 62fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapOffset(pSrc)); 63fc5a983dSmrg 64fc5a983dSmrg return TRUE; 65fc5a983dSmrg} 66fc5a983dSmrg 67fc5a983dSmrgstatic Bool 68fc5a983dSmrgsetDst(G80Ptr pNv, PixmapPtr pDst) 69fc5a983dSmrg{ 70fc5a983dSmrg CARD32 depth, depth2; 71fc5a983dSmrg 72fc5a983dSmrg switch(pDst->drawable.depth) { 73fc5a983dSmrg case 8: depth = 0x000000f3; depth2 = 3; break; 74fc5a983dSmrg case 15: depth = 0x000000f8; depth2 = 1; break; 75fc5a983dSmrg case 16: depth = 0x000000e8; depth2 = 0; break; 76fc5a983dSmrg case 24: depth = 0x000000e6; depth2 = 2; break; 77fc5a983dSmrg case 32: depth = 0x000000cf; depth2 = 2; break; 78fc5a983dSmrg default: return FALSE; 79fc5a983dSmrg } 80fc5a983dSmrg 81fc5a983dSmrg G80DmaStart(pNv, 0x200, 2); 82fc5a983dSmrg G80DmaNext (pNv, depth); 83fc5a983dSmrg G80DmaNext (pNv, 0x00000001); 84fc5a983dSmrg G80DmaStart(pNv, 0x214, 5); 85fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapPitch(pDst)); 86fc5a983dSmrg G80DmaNext (pNv, pDst->drawable.width); 87fc5a983dSmrg G80DmaNext (pNv, pDst->drawable.height); 88fc5a983dSmrg G80DmaNext (pNv, 0x00000000); 89fc5a983dSmrg G80DmaNext (pNv, exaGetPixmapOffset(pDst)); 90fc5a983dSmrg G80DmaStart(pNv, 0x2e8, 1); 91fc5a983dSmrg G80DmaNext (pNv, depth2); 92fc5a983dSmrg G80DmaStart(pNv, 0x584, 1); 93fc5a983dSmrg G80DmaNext (pNv, depth); 94fc5a983dSmrg G80SetClip(pNv, 0, 0, pDst->drawable.width, pDst->drawable.height); 95fc5a983dSmrg 96fc5a983dSmrg return TRUE; 97fc5a983dSmrg} 98fc5a983dSmrg 99fc5a983dSmrg/* solid fills */ 100fc5a983dSmrg 101fc5a983dSmrgstatic Bool 102fc5a983dSmrgprepareSolid(PixmapPtr pPixmap, 103fc5a983dSmrg int alu, 104fc5a983dSmrg Pixel planemask, 105fc5a983dSmrg Pixel fg) 106fc5a983dSmrg{ 107bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 108fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 109fc5a983dSmrg 110fc5a983dSmrg if(pPixmap->drawable.depth > 24) return FALSE; 111fc5a983dSmrg if(!setDst(pNv, pPixmap)) return FALSE; 112fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 113f3561b8bSmrg G80DmaNext (pNv, 4); 114fc5a983dSmrg G80SetRopSolid(pNv, alu, planemask); 115fc5a983dSmrg G80DmaStart(pNv, 0x580, 1); 116fc5a983dSmrg G80DmaNext (pNv, 4); 117fc5a983dSmrg G80DmaStart(pNv, 0x588, 1); 118fc5a983dSmrg G80DmaNext (pNv, fg); 119fc5a983dSmrg 12063a93945Smrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 121fc5a983dSmrg return TRUE; 122fc5a983dSmrg} 123fc5a983dSmrg 124fc5a983dSmrgstatic void 125fc5a983dSmrgsolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 126fc5a983dSmrg{ 127bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 128fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 129fc5a983dSmrg 130fc5a983dSmrg G80DmaStart(pNv, 0x600, 4); 131fc5a983dSmrg G80DmaNext (pNv, x1); 132fc5a983dSmrg G80DmaNext (pNv, y1); 133fc5a983dSmrg G80DmaNext (pNv, x2); 134fc5a983dSmrg G80DmaNext (pNv, y2); 135fc5a983dSmrg 136fc5a983dSmrg if((x2 - x1) * (y2 - y1) >= 512) 137fc5a983dSmrg G80DmaKickoff(pNv); 138fc5a983dSmrg} 139fc5a983dSmrg 140fc5a983dSmrgstatic void 141fc5a983dSmrgdoneSolid(PixmapPtr pPixmap) 142fc5a983dSmrg{ 143fc5a983dSmrg} 144fc5a983dSmrg 145fc5a983dSmrg/* screen to screen copies */ 146fc5a983dSmrg 147fc5a983dSmrgstatic Bool 148fc5a983dSmrgprepareCopy(PixmapPtr pSrcPixmap, 149fc5a983dSmrg PixmapPtr pDstPixmap, 150fc5a983dSmrg int dx, 151fc5a983dSmrg int dy, 152fc5a983dSmrg int alu, 153fc5a983dSmrg Pixel planemask) 154fc5a983dSmrg{ 155bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 156fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 157fc5a983dSmrg 158fc5a983dSmrg if(!setSrc(pNv, pSrcPixmap)) return FALSE; 159fc5a983dSmrg if(!setDst(pNv, pDstPixmap)) return FALSE; 160fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 161fc5a983dSmrg if(alu == GXcopy && planemask == ~0) { 162fc5a983dSmrg G80DmaNext (pNv, 3); 163fc5a983dSmrg } else { 164f3561b8bSmrg G80DmaNext (pNv, 4); 165fc5a983dSmrg G80SetRopSolid(pNv, alu, planemask); 166fc5a983dSmrg } 16763a93945Smrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 168fc5a983dSmrg return TRUE; 169fc5a983dSmrg} 170fc5a983dSmrg 171fc5a983dSmrgstatic void 172fc5a983dSmrgcopy(PixmapPtr pDstPixmap, 173fc5a983dSmrg int srcX, 174fc5a983dSmrg int srcY, 175fc5a983dSmrg int dstX, 176fc5a983dSmrg int dstY, 177fc5a983dSmrg int width, 178fc5a983dSmrg int height) 179fc5a983dSmrg{ 180bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 181fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 182fc5a983dSmrg 183fc5a983dSmrg G80DmaStart(pNv, 0x110, 1); 184fc5a983dSmrg G80DmaNext (pNv, 0); 185fc5a983dSmrg G80DmaStart(pNv, 0x8b0, 12); 186fc5a983dSmrg G80DmaNext (pNv, dstX); 187fc5a983dSmrg G80DmaNext (pNv, dstY); 188fc5a983dSmrg G80DmaNext (pNv, width); 189fc5a983dSmrg G80DmaNext (pNv, height); 190fc5a983dSmrg G80DmaNext (pNv, 0); 191fc5a983dSmrg G80DmaNext (pNv, 1); 192fc5a983dSmrg G80DmaNext (pNv, 0); 193fc5a983dSmrg G80DmaNext (pNv, 1); 194fc5a983dSmrg G80DmaNext (pNv, 0); 195fc5a983dSmrg G80DmaNext (pNv, srcX); 196fc5a983dSmrg G80DmaNext (pNv, 0); 197fc5a983dSmrg G80DmaNext (pNv, srcY); 198fc5a983dSmrg 199fc5a983dSmrg if(width * height >= 512) 200fc5a983dSmrg G80DmaKickoff(pNv); 201fc5a983dSmrg} 202fc5a983dSmrg 203fc5a983dSmrgstatic void 204fc5a983dSmrgdoneCopy(PixmapPtr pDstPixmap) 205fc5a983dSmrg{ 206fc5a983dSmrg} 207fc5a983dSmrg 208fc5a983dSmrg/* composite */ 209fc5a983dSmrg 210fc5a983dSmrgstatic Bool 211fc5a983dSmrgcheckComposite(int op, 212fc5a983dSmrg PicturePtr pSrc, 213fc5a983dSmrg PicturePtr pMask, 214fc5a983dSmrg PicturePtr pDst) 215fc5a983dSmrg{ 216fc5a983dSmrg return FALSE; 217fc5a983dSmrg} 218fc5a983dSmrg 219fc5a983dSmrg/* upload to screen */ 220fc5a983dSmrg 221fc5a983dSmrgstatic Bool 222fc5a983dSmrgupload(PixmapPtr pDst, 223fc5a983dSmrg int x, 224fc5a983dSmrg int y, 225fc5a983dSmrg int w, 226fc5a983dSmrg int h, 227fc5a983dSmrg char *src, 228fc5a983dSmrg int src_pitch) 229fc5a983dSmrg{ 230bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 231fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 232fc5a983dSmrg const int Bpp = pDst->drawable.bitsPerPixel >> 3; 233fc5a983dSmrg int line_dwords = (w * Bpp + 3) / 4; 234fc5a983dSmrg const Bool kickoff = w * h >= 512; 235fc5a983dSmrg CARD32 depth; 236fc5a983dSmrg 237fc5a983dSmrg if(!setDst(pNv, pDst)) return FALSE; 238fc5a983dSmrg switch(pDst->drawable.depth) { 239fc5a983dSmrg case 8: depth = 0x000000f3; break; 240fc5a983dSmrg case 15: depth = 0x000000f8; break; 241fc5a983dSmrg case 16: depth = 0x000000e8; break; 242fc5a983dSmrg case 24: depth = 0x000000e6; break; 243fc5a983dSmrg case 32: depth = 0x000000cf; break; 244fc5a983dSmrg default: return FALSE; 245fc5a983dSmrg } 246fc5a983dSmrg 247fc5a983dSmrg G80SetClip(pNv, x, y, w, h); 248fc5a983dSmrg G80DmaStart(pNv, 0x2ac, 1); 249fc5a983dSmrg G80DmaNext (pNv, 3); 250fc5a983dSmrg G80DmaStart(pNv, 0x800, 2); 251fc5a983dSmrg G80DmaNext (pNv, 0); 252fc5a983dSmrg G80DmaNext (pNv, depth); 253fc5a983dSmrg G80DmaStart(pNv, 0x838, 10); 254fc5a983dSmrg G80DmaNext (pNv, (line_dwords * 4) / Bpp); 255fc5a983dSmrg G80DmaNext (pNv, h); 256fc5a983dSmrg G80DmaNext (pNv, 0); 257fc5a983dSmrg G80DmaNext (pNv, 1); 258fc5a983dSmrg G80DmaNext (pNv, 0); 259fc5a983dSmrg G80DmaNext (pNv, 1); 260fc5a983dSmrg G80DmaNext (pNv, 0); 261fc5a983dSmrg G80DmaNext (pNv, x); 262fc5a983dSmrg G80DmaNext (pNv, 0); 263fc5a983dSmrg G80DmaNext (pNv, y); 264fc5a983dSmrg 265fc5a983dSmrg while(h-- > 0) { 266fc5a983dSmrg int count = line_dwords; 267fc5a983dSmrg char *p = src; 268fc5a983dSmrg 269fc5a983dSmrg while(count) { 270fc5a983dSmrg int size = count > 1792 ? 1792 : count; 271fc5a983dSmrg 272fc5a983dSmrg G80DmaStart(pNv, 0x40000860, size); 273fc5a983dSmrg memcpy(&pNv->dmaBase[pNv->dmaCurrent], p, size * 4); 274fc5a983dSmrg 275fc5a983dSmrg p += size * Bpp; 276fc5a983dSmrg pNv->dmaCurrent += size; 277fc5a983dSmrg 278fc5a983dSmrg count -= size; 279fc5a983dSmrg } 280fc5a983dSmrg 281fc5a983dSmrg src += src_pitch; 282fc5a983dSmrg } 283fc5a983dSmrg 284fc5a983dSmrg if(kickoff) 285fc5a983dSmrg G80DmaKickoff(pNv); 286fc5a983dSmrg else 28763a93945Smrg pNv->DMAKickoffCallback = G80DMAKickoffCallback; 288fc5a983dSmrg 289fc5a983dSmrg return TRUE; 290fc5a983dSmrg} 291fc5a983dSmrg 292fc5a983dSmrg/******************************************************************************/ 293fc5a983dSmrg 294fc5a983dSmrgBool G80ExaInit(ScreenPtr pScreen, ScrnInfoPtr pScrn) 295fc5a983dSmrg{ 296fc5a983dSmrg G80Ptr pNv = G80PTR(pScrn); 297fc5a983dSmrg ExaDriverPtr exa; 298fc5a983dSmrg const int pitch = pScrn->displayWidth * (pScrn->bitsPerPixel / 8); 299fc5a983dSmrg 300fc5a983dSmrg exa = pNv->exa = exaDriverAlloc(); 301fc5a983dSmrg if(!exa) return FALSE; 302fc5a983dSmrg 303fc5a983dSmrg exa->exa_major = EXA_VERSION_MAJOR; 304fc5a983dSmrg exa->exa_minor = EXA_VERSION_MINOR; 305fc5a983dSmrg exa->memoryBase = pNv->mem; 306fc5a983dSmrg exa->offScreenBase = 0; 307fc5a983dSmrg exa->memorySize = pitch * pNv->offscreenHeight; 308fc5a983dSmrg exa->pixmapOffsetAlign = 256; 309fc5a983dSmrg exa->pixmapPitchAlign = 256; 310fc5a983dSmrg exa->flags = EXA_OFFSCREEN_PIXMAPS; 311fc5a983dSmrg exa->maxX = 8192; 312fc5a983dSmrg exa->maxY = 8192; 313fc5a983dSmrg 314fc5a983dSmrg /**** Rendering ops ****/ 315fc5a983dSmrg exa->PrepareSolid = prepareSolid; 316fc5a983dSmrg exa->Solid = solid; 317fc5a983dSmrg exa->DoneSolid = doneSolid; 318fc5a983dSmrg exa->PrepareCopy = prepareCopy; 319fc5a983dSmrg exa->Copy = copy; 320fc5a983dSmrg exa->DoneCopy = doneCopy; 321fc5a983dSmrg exa->CheckComposite = checkComposite; 322fc5a983dSmrg //exa->PrepareComposite = prepareComposite; 323fc5a983dSmrg //exa->Composite = composite; 324fc5a983dSmrg //exa->DoneComposite = doneComposite; 325fc5a983dSmrg exa->UploadToScreen = upload; 326fc5a983dSmrg 327fc5a983dSmrg exa->WaitMarker = waitMarker; 328fc5a983dSmrg 329fc5a983dSmrg return exaDriverInit(pScreen, exa); 330fc5a983dSmrg} 331