nv_xaa.c revision 092d2b73
1fc5a983dSmrg/* 2fc5a983dSmrg * Copyright (c) 2003 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#ifdef HAVE_CONFIG_H 25fc5a983dSmrg#include "config.h" 26fc5a983dSmrg#endif 27fc5a983dSmrg 28fc5a983dSmrg#include "nv_include.h" 29bd304fc0Smrg#ifdef HAVE_XAA_H 30fc5a983dSmrg#include "xaalocal.h" 31bd304fc0Smrg#endif 32fc5a983dSmrg#include "miline.h" 33fc5a983dSmrg#include "nv_dma.h" 34fc5a983dSmrg 35fc5a983dSmrgstatic const int NVCopyROP[16] = 36fc5a983dSmrg{ 37fc5a983dSmrg 0x00, /* GXclear */ 38fc5a983dSmrg 0x88, /* GXand */ 39fc5a983dSmrg 0x44, /* GXandReverse */ 40fc5a983dSmrg 0xCC, /* GXcopy */ 41fc5a983dSmrg 0x22, /* GXandInverted */ 42fc5a983dSmrg 0xAA, /* GXnoop */ 43fc5a983dSmrg 0x66, /* GXxor */ 44fc5a983dSmrg 0xEE, /* GXor */ 45fc5a983dSmrg 0x11, /* GXnor */ 46fc5a983dSmrg 0x99, /* GXequiv */ 47fc5a983dSmrg 0x55, /* GXinvert*/ 48fc5a983dSmrg 0xDD, /* GXorReverse */ 49fc5a983dSmrg 0x33, /* GXcopyInverted */ 50fc5a983dSmrg 0xBB, /* GXorInverted */ 51fc5a983dSmrg 0x77, /* GXnand */ 52fc5a983dSmrg 0xFF /* GXset */ 53fc5a983dSmrg}; 54fc5a983dSmrg 55fc5a983dSmrgstatic const int NVCopyROP_PM[16] = 56fc5a983dSmrg{ 57fc5a983dSmrg 0x0A, /* GXclear */ 58fc5a983dSmrg 0x8A, /* GXand */ 59fc5a983dSmrg 0x4A, /* GXandReverse */ 60fc5a983dSmrg 0xCA, /* GXcopy */ 61fc5a983dSmrg 0x2A, /* GXandInverted */ 62fc5a983dSmrg 0xAA, /* GXnoop */ 63fc5a983dSmrg 0x6A, /* GXxor */ 64fc5a983dSmrg 0xEA, /* GXor */ 65fc5a983dSmrg 0x1A, /* GXnor */ 66fc5a983dSmrg 0x9A, /* GXequiv */ 67fc5a983dSmrg 0x5A, /* GXinvert*/ 68fc5a983dSmrg 0xDA, /* GXorReverse */ 69fc5a983dSmrg 0x3A, /* GXcopyInverted */ 70fc5a983dSmrg 0xBA, /* GXorInverted */ 71fc5a983dSmrg 0x7A, /* GXnand */ 72fc5a983dSmrg 0xFA /* GXset */ 73fc5a983dSmrg}; 74fc5a983dSmrg 75fc5a983dSmrgstatic const int NVPatternROP[16] = 76fc5a983dSmrg{ 77fc5a983dSmrg 0x00, 78fc5a983dSmrg 0xA0, 79fc5a983dSmrg 0x50, 80fc5a983dSmrg 0xF0, 81fc5a983dSmrg 0x0A, 82fc5a983dSmrg 0xAA, 83fc5a983dSmrg 0x5A, 84fc5a983dSmrg 0xFA, 85fc5a983dSmrg 0x05, 86fc5a983dSmrg 0xA5, 87fc5a983dSmrg 0x55, 88fc5a983dSmrg 0xF5, 89fc5a983dSmrg 0x0F, 90fc5a983dSmrg 0xAF, 91fc5a983dSmrg 0x5F, 92fc5a983dSmrg 0xFF 93fc5a983dSmrg}; 94fc5a983dSmrg 95fc5a983dSmrgvoid 96fc5a983dSmrgNVDmaKickoff(NVPtr pNv) 97fc5a983dSmrg{ 98fc5a983dSmrg if(pNv->dmaCurrent != pNv->dmaPut) { 99fc5a983dSmrg pNv->dmaPut = pNv->dmaCurrent; 100fc5a983dSmrg WRITE_PUT(pNv, pNv->dmaPut); 101fc5a983dSmrg } 102fc5a983dSmrg} 103fc5a983dSmrg 104fc5a983dSmrg 105fc5a983dSmrg/* There is a HW race condition with videoram command buffers. 106fc5a983dSmrg You can't jump to the location of your put offset. We write put 107fc5a983dSmrg at the jump offset + SKIPS dwords with noop padding in between 108fc5a983dSmrg to solve this problem */ 109092d2b73Smacallan#define SKIPS 8 110fc5a983dSmrg 111fc5a983dSmrgvoid 112fc5a983dSmrgNVDmaWait ( 113fc5a983dSmrg NVPtr pNv, 114fc5a983dSmrg int size 115fc5a983dSmrg){ 116fc5a983dSmrg int dmaGet; 117fc5a983dSmrg 118fc5a983dSmrg size++; 119fc5a983dSmrg 120fc5a983dSmrg while(pNv->dmaFree < size) { 121fc5a983dSmrg dmaGet = READ_GET(pNv); 122fc5a983dSmrg 123fc5a983dSmrg if(pNv->dmaPut >= dmaGet) { 124fc5a983dSmrg pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; 125fc5a983dSmrg if(pNv->dmaFree < size) { 126fc5a983dSmrg NVDmaNext(pNv, 0x20000000); 127fc5a983dSmrg if(dmaGet <= SKIPS) { 128fc5a983dSmrg if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */ 129fc5a983dSmrg WRITE_PUT(pNv, SKIPS + 1); 130fc5a983dSmrg do { dmaGet = READ_GET(pNv); } 131fc5a983dSmrg while(dmaGet <= SKIPS); 132fc5a983dSmrg } 133fc5a983dSmrg WRITE_PUT(pNv, SKIPS); 134fc5a983dSmrg pNv->dmaCurrent = pNv->dmaPut = SKIPS; 135fc5a983dSmrg pNv->dmaFree = dmaGet - (SKIPS + 1); 136fc5a983dSmrg } 137fc5a983dSmrg } else 138fc5a983dSmrg pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1; 139fc5a983dSmrg } 140fc5a983dSmrg} 141fc5a983dSmrg 142fc5a983dSmrgvoid 143fc5a983dSmrgNVWaitVSync(NVPtr pNv) 144fc5a983dSmrg{ 145fc5a983dSmrg NVDmaStart(pNv, 0x0000A12C, 1); 146fc5a983dSmrg NVDmaNext (pNv, 0); 147fc5a983dSmrg NVDmaStart(pNv, 0x0000A134, 1); 148fc5a983dSmrg NVDmaNext (pNv, pNv->CRTCnumber); 149fc5a983dSmrg NVDmaStart(pNv, 0x0000A100, 1); 150fc5a983dSmrg NVDmaNext (pNv, 0); 151fc5a983dSmrg NVDmaStart(pNv, 0x0000A130, 1); 152fc5a983dSmrg NVDmaNext (pNv, 0); 153fc5a983dSmrg} 154fc5a983dSmrg 155fc5a983dSmrg/* 156fc5a983dSmrg currentRop = 0-15 solid fill 157fc5a983dSmrg 16-31 8x8 pattern fill 158fc5a983dSmrg 32-47 solid fill with planemask 159fc5a983dSmrg*/ 160fc5a983dSmrg 161fc5a983dSmrgstatic void 162fc5a983dSmrgNVSetPattern( 163fc5a983dSmrg ScrnInfoPtr pScrn, 164fc5a983dSmrg CARD32 clr0, 165fc5a983dSmrg CARD32 clr1, 166fc5a983dSmrg CARD32 pat0, 167fc5a983dSmrg CARD32 pat1 168fc5a983dSmrg) 169fc5a983dSmrg{ 170fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 171fc5a983dSmrg 172fc5a983dSmrg NVDmaStart(pNv, PATTERN_COLOR_0, 4); 173fc5a983dSmrg NVDmaNext (pNv, clr0); 174fc5a983dSmrg NVDmaNext (pNv, clr1); 175fc5a983dSmrg NVDmaNext (pNv, pat0); 176fc5a983dSmrg NVDmaNext (pNv, pat1); 177fc5a983dSmrg} 178fc5a983dSmrg 17905c1003fSmacallanvoid 180fc5a983dSmrgNVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask) 181fc5a983dSmrg{ 182fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 183fc5a983dSmrg 184fc5a983dSmrg if(planemask != ~0) { 185fc5a983dSmrg NVSetPattern(pScrn, 0, planemask, ~0, ~0); 186fc5a983dSmrg if(pNv->currentRop != (rop + 32)) { 187fc5a983dSmrg NVDmaStart(pNv, ROP_SET, 1); 188fc5a983dSmrg NVDmaNext (pNv, NVCopyROP_PM[rop]); 189fc5a983dSmrg pNv->currentRop = rop + 32; 190fc5a983dSmrg } 191fc5a983dSmrg } else 192fc5a983dSmrg if (pNv->currentRop != rop) { 193fc5a983dSmrg if(pNv->currentRop >= 16) 194fc5a983dSmrg NVSetPattern(pScrn, ~0, ~0, ~0, ~0); 195fc5a983dSmrg NVDmaStart(pNv, ROP_SET, 1); 196fc5a983dSmrg NVDmaNext (pNv, NVCopyROP[rop]); 197fc5a983dSmrg pNv->currentRop = rop; 198fc5a983dSmrg } 199fc5a983dSmrg} 200fc5a983dSmrg 201fc5a983dSmrgvoid NVResetGraphics(ScrnInfoPtr pScrn) 202fc5a983dSmrg{ 203fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 204fc5a983dSmrg CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat; 205fc5a983dSmrg int pitch, i; 206fc5a983dSmrg 207fc5a983dSmrg if(pNv->NoAccel) return; 208fc5a983dSmrg 209fc5a983dSmrg pitch = pNv->CurrentLayout.displayWidth * 210fc5a983dSmrg (pNv->CurrentLayout.bitsPerPixel >> 3); 211fc5a983dSmrg 212fc5a983dSmrg pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]); 213fc5a983dSmrg 214fc5a983dSmrg for(i = 0; i < SKIPS; i++) 215fc5a983dSmrg pNv->dmaBase[i] = 0x00000000; 216fc5a983dSmrg 217fc5a983dSmrg pNv->dmaBase[0x0 + SKIPS] = 0x00040000; 218fc5a983dSmrg pNv->dmaBase[0x1 + SKIPS] = 0x80000010; 219fc5a983dSmrg pNv->dmaBase[0x2 + SKIPS] = 0x00042000; 220fc5a983dSmrg pNv->dmaBase[0x3 + SKIPS] = 0x80000011; 221fc5a983dSmrg pNv->dmaBase[0x4 + SKIPS] = 0x00044000; 222fc5a983dSmrg pNv->dmaBase[0x5 + SKIPS] = 0x80000012; 223fc5a983dSmrg pNv->dmaBase[0x6 + SKIPS] = 0x00046000; 224fc5a983dSmrg pNv->dmaBase[0x7 + SKIPS] = 0x80000013; 225fc5a983dSmrg pNv->dmaBase[0x8 + SKIPS] = 0x00048000; 226fc5a983dSmrg pNv->dmaBase[0x9 + SKIPS] = 0x80000014; 227fc5a983dSmrg pNv->dmaBase[0xA + SKIPS] = 0x0004A000; 228fc5a983dSmrg pNv->dmaBase[0xB + SKIPS] = 0x80000015; 229fc5a983dSmrg pNv->dmaBase[0xC + SKIPS] = 0x0004C000; 230fc5a983dSmrg pNv->dmaBase[0xD + SKIPS] = 0x80000016; 231fc5a983dSmrg pNv->dmaBase[0xE + SKIPS] = 0x0004E000; 232fc5a983dSmrg pNv->dmaBase[0xF + SKIPS] = 0x80000017; 233fc5a983dSmrg 234fc5a983dSmrg pNv->dmaPut = 0; 235fc5a983dSmrg pNv->dmaCurrent = 16 + SKIPS; 236fc5a983dSmrg pNv->dmaMax = 8191; 237fc5a983dSmrg pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; 238fc5a983dSmrg 239fc5a983dSmrg switch(pNv->CurrentLayout.depth) { 240fc5a983dSmrg case 24: 241fc5a983dSmrg surfaceFormat = SURFACE_FORMAT_DEPTH24; 242fc5a983dSmrg patternFormat = PATTERN_FORMAT_DEPTH24; 243fc5a983dSmrg rectFormat = RECT_FORMAT_DEPTH24; 244fc5a983dSmrg lineFormat = LINE_FORMAT_DEPTH24; 245fc5a983dSmrg break; 246fc5a983dSmrg case 16: 247fc5a983dSmrg case 15: 248fc5a983dSmrg surfaceFormat = SURFACE_FORMAT_DEPTH16; 249fc5a983dSmrg patternFormat = PATTERN_FORMAT_DEPTH16; 250fc5a983dSmrg rectFormat = RECT_FORMAT_DEPTH16; 251fc5a983dSmrg lineFormat = LINE_FORMAT_DEPTH16; 252fc5a983dSmrg break; 253fc5a983dSmrg default: 254fc5a983dSmrg surfaceFormat = SURFACE_FORMAT_DEPTH8; 255fc5a983dSmrg patternFormat = PATTERN_FORMAT_DEPTH8; 256fc5a983dSmrg rectFormat = RECT_FORMAT_DEPTH8; 257fc5a983dSmrg lineFormat = LINE_FORMAT_DEPTH8; 258fc5a983dSmrg break; 259fc5a983dSmrg } 260fc5a983dSmrg 261fc5a983dSmrg NVDmaStart(pNv, SURFACE_FORMAT, 4); 262fc5a983dSmrg NVDmaNext (pNv, surfaceFormat); 263fc5a983dSmrg NVDmaNext (pNv, pitch | (pitch << 16)); 264fc5a983dSmrg NVDmaNext (pNv, 0); 265fc5a983dSmrg NVDmaNext (pNv, 0); 266fc5a983dSmrg 267fc5a983dSmrg NVDmaStart(pNv, PATTERN_FORMAT, 1); 268fc5a983dSmrg NVDmaNext (pNv, patternFormat); 269fc5a983dSmrg 270fc5a983dSmrg NVDmaStart(pNv, RECT_FORMAT, 1); 271fc5a983dSmrg NVDmaNext (pNv, rectFormat); 272fc5a983dSmrg 273fc5a983dSmrg NVDmaStart(pNv, LINE_FORMAT, 1); 274fc5a983dSmrg NVDmaNext (pNv, lineFormat); 275fc5a983dSmrg 276fc5a983dSmrg pNv->currentRop = ~0; /* set to something invalid */ 277fc5a983dSmrg NVSetRopSolid(pScrn, GXcopy, ~0); 278fc5a983dSmrg 279fc5a983dSmrg NVDmaKickoff(pNv); 280fc5a983dSmrg} 281fc5a983dSmrg 282fc5a983dSmrgvoid NVSync(ScrnInfoPtr pScrn) 283fc5a983dSmrg{ 284fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 28505c1003fSmacallan int bail = 10000000; 28605c1003fSmacallan 287fc5a983dSmrg if(pNv->DMAKickoffCallback) 288fc5a983dSmrg (*pNv->DMAKickoffCallback)(pScrn); 289fc5a983dSmrg 29005c1003fSmacallan while((READ_GET(pNv) != pNv->dmaPut) && (bail > 0)) bail--; 29105c1003fSmacallan if (bail == 0) { 29205c1003fSmacallan xf86Msg(X_ERROR, "DMA drain timeout\n"); 29305c1003fSmacallan goto crap; 29405c1003fSmacallan } 29505c1003fSmacallan 29605c1003fSmacallan bail = 10000000; 29705c1003fSmacallan while((pNv->PGRAPH[0x0700/4]) && (bail > 0)) bail--; 29805c1003fSmacallan if (bail == 0) { 29905c1003fSmacallan xf86Msg(X_ERROR, "engine stalled\n"); 30005c1003fSmacallan goto crap; 30105c1003fSmacallan } 30205c1003fSmacallan return; 30305c1003fSmacallan 30405c1003fSmacallancrap: 30505c1003fSmacallan NVResetGraphics(pScrn); 306fc5a983dSmrg} 307fc5a983dSmrg 30805c1003fSmacallan void 309fc5a983dSmrgNVDMAKickoffCallback (ScrnInfoPtr pScrn) 310fc5a983dSmrg{ 311fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 312fc5a983dSmrg 313fc5a983dSmrg NVDmaKickoff(pNv); 314fc5a983dSmrg pNv->DMAKickoffCallback = NULL; 315fc5a983dSmrg} 316fc5a983dSmrg 317bd304fc0Smrg#ifdef HAVE_XAA_H 318fc5a983dSmrgstatic void 319fc5a983dSmrgNVSetupForScreenToScreenCopy( 320fc5a983dSmrg ScrnInfoPtr pScrn, 321fc5a983dSmrg int xdir, int ydir, 322fc5a983dSmrg int rop, 323fc5a983dSmrg unsigned planemask, 324fc5a983dSmrg int transparency_color 325fc5a983dSmrg) 326fc5a983dSmrg{ 327fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 328fc5a983dSmrg 329fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 330fc5a983dSmrg 331fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 332fc5a983dSmrg 333fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 334fc5a983dSmrg} 335fc5a983dSmrg 336fc5a983dSmrgstatic void 337fc5a983dSmrgNVSubsequentScreenToScreenCopy( 338fc5a983dSmrg ScrnInfoPtr pScrn, 339fc5a983dSmrg int x1, int y1, 340fc5a983dSmrg int x2, int y2, 341fc5a983dSmrg int w, int h 342fc5a983dSmrg) 343fc5a983dSmrg{ 344fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 345fc5a983dSmrg 346fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 3); 347fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | x1); 348fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | x2); 349fc5a983dSmrg NVDmaNext (pNv, (h << 16) | w); 350fc5a983dSmrg 351fc5a983dSmrg if((w * h) >= 512) 352fc5a983dSmrg NVDmaKickoff(pNv); 353fc5a983dSmrg} 354fc5a983dSmrg 355fc5a983dSmrgstatic void 356fc5a983dSmrgNVSetupForSolidFill( 357fc5a983dSmrg ScrnInfoPtr pScrn, 358fc5a983dSmrg int color, 359fc5a983dSmrg int rop, 360fc5a983dSmrg unsigned planemask 361fc5a983dSmrg) 362fc5a983dSmrg{ 363fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 364fc5a983dSmrg 365fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 366fc5a983dSmrg 367fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 368fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_COLOR, 1); 369fc5a983dSmrg NVDmaNext (pNv, color); 370fc5a983dSmrg 371fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 372fc5a983dSmrg} 373fc5a983dSmrg 374fc5a983dSmrgstatic void 375fc5a983dSmrgNVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 376fc5a983dSmrg{ 377fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 378fc5a983dSmrg 379fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); 380fc5a983dSmrg NVDmaNext (pNv, (x << 16) | y); 381fc5a983dSmrg NVDmaNext (pNv, (w << 16) | h); 382fc5a983dSmrg 383fc5a983dSmrg if((w * h) >= 512) 384fc5a983dSmrg NVDmaKickoff(pNv); 385fc5a983dSmrg} 386fc5a983dSmrg 387fc5a983dSmrgstatic void 388fc5a983dSmrgNVSetupForMono8x8PatternFill ( 389fc5a983dSmrg ScrnInfoPtr pScrn, 390fc5a983dSmrg int patternx, int patterny, 391fc5a983dSmrg int fg, int bg, 392fc5a983dSmrg int rop, 393fc5a983dSmrg unsigned planemask 394fc5a983dSmrg) 395fc5a983dSmrg{ 396fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 397fc5a983dSmrg 398fc5a983dSmrg planemask = ~0 << pNv->CurrentLayout.depth; 399fc5a983dSmrg 400fc5a983dSmrg fg |= planemask; 401fc5a983dSmrg if(bg == -1) bg = 0; 402fc5a983dSmrg else bg |= planemask; 403fc5a983dSmrg 404fc5a983dSmrg if (pNv->currentRop != (rop + 16)) { 405fc5a983dSmrg NVDmaStart(pNv, ROP_SET, 1); 406fc5a983dSmrg NVDmaNext (pNv, NVPatternROP[rop]); 407fc5a983dSmrg pNv->currentRop = rop + 16; 408fc5a983dSmrg } 409fc5a983dSmrg 410fc5a983dSmrg NVSetPattern(pScrn, bg, fg, patternx, patterny); 411fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_COLOR, 1); 412fc5a983dSmrg NVDmaNext (pNv, fg); 413fc5a983dSmrg 414fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 415fc5a983dSmrg} 416fc5a983dSmrg 417fc5a983dSmrgstatic void 418fc5a983dSmrgNVSubsequentMono8x8PatternFillRect( 419fc5a983dSmrg ScrnInfoPtr pScrn, 420fc5a983dSmrg int patternx, int patterny, 421fc5a983dSmrg int x, int y, 422fc5a983dSmrg int w, int h 423fc5a983dSmrg) 424fc5a983dSmrg{ 425fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 426fc5a983dSmrg 427fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); 428fc5a983dSmrg NVDmaNext (pNv, (x << 16) | y); 429fc5a983dSmrg NVDmaNext (pNv, (w << 16) | h); 430fc5a983dSmrg 431fc5a983dSmrg if((w * h) >= 512) 432fc5a983dSmrg NVDmaKickoff(pNv); 433fc5a983dSmrg} 434fc5a983dSmrg 435fc5a983dSmrgstatic CARD32 _bg_pixel; 436fc5a983dSmrgstatic CARD32 _fg_pixel; 437fc5a983dSmrgstatic Bool _transparent; 438fc5a983dSmrgstatic CARD32 _color_expand_dwords; 439fc5a983dSmrgstatic CARD32 _color_expand_offset; 440fc5a983dSmrgstatic int _remaining; 441fc5a983dSmrgstatic unsigned char *_storage_buffer[1]; 442fc5a983dSmrg 443fc5a983dSmrgstatic void 444fc5a983dSmrgNVSetupForScanlineCPUToScreenColorExpandFill ( 445fc5a983dSmrg ScrnInfoPtr pScrn, 446fc5a983dSmrg int fg, int bg, 447fc5a983dSmrg int rop, 448fc5a983dSmrg unsigned int planemask 449fc5a983dSmrg) 450fc5a983dSmrg{ 451fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 452fc5a983dSmrg 453fc5a983dSmrg CARD32 mask = ~0 << pNv->CurrentLayout.depth; 454fc5a983dSmrg 455fc5a983dSmrg planemask |= mask; 456fc5a983dSmrg _fg_pixel = fg | mask; 457fc5a983dSmrg 458fc5a983dSmrg if(bg == -1) { 459fc5a983dSmrg _transparent = TRUE; 460fc5a983dSmrg } else { 461fc5a983dSmrg _transparent = FALSE; 462fc5a983dSmrg _bg_pixel = bg | mask; 463fc5a983dSmrg } 464fc5a983dSmrg 465fc5a983dSmrg NVSetRopSolid (pScrn, rop, planemask); 466fc5a983dSmrg} 467fc5a983dSmrg 468fc5a983dSmrgstatic void 469fc5a983dSmrgNVSubsequentScanlineCPUToScreenColorExpandFill ( 470fc5a983dSmrg ScrnInfoPtr pScrn, 471fc5a983dSmrg int x, int y, 472fc5a983dSmrg int w, int h, 473fc5a983dSmrg int skipleft 474fc5a983dSmrg) 475fc5a983dSmrg{ 476fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 477fc5a983dSmrg int bw = (w + 31) & ~31; 478fc5a983dSmrg 479fc5a983dSmrg _color_expand_dwords = bw >> 5; 480fc5a983dSmrg _remaining = h; 481fc5a983dSmrg 482fc5a983dSmrg if(_transparent) { 483fc5a983dSmrg NVDmaStart(pNv, RECT_EXPAND_ONE_COLOR_CLIP, 5); 484fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); 485fc5a983dSmrg NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); 486fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 487fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 488fc5a983dSmrg NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); 489fc5a983dSmrg _color_expand_offset = RECT_EXPAND_ONE_COLOR_DATA(0); 490fc5a983dSmrg } else { 491fc5a983dSmrg NVDmaStart(pNv, RECT_EXPAND_TWO_COLOR_CLIP, 7); 492fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); 493fc5a983dSmrg NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); 494fc5a983dSmrg NVDmaNext (pNv, _bg_pixel); 495fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 496fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 497fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 498fc5a983dSmrg NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); 499fc5a983dSmrg _color_expand_offset = RECT_EXPAND_TWO_COLOR_DATA(0); 500fc5a983dSmrg } 501fc5a983dSmrg 502fc5a983dSmrg NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); 503fc5a983dSmrg _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; 504fc5a983dSmrg} 505fc5a983dSmrg 506fc5a983dSmrgstatic void 507fc5a983dSmrgNVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 508fc5a983dSmrg{ 509fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 510fc5a983dSmrg 511fc5a983dSmrg pNv->dmaCurrent += _color_expand_dwords; 512fc5a983dSmrg 513fc5a983dSmrg if(--_remaining) { 514fc5a983dSmrg NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); 515fc5a983dSmrg _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; 516fc5a983dSmrg } else { 517fc5a983dSmrg /* hardware bug workaround */ 518fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 1); 519fc5a983dSmrg NVDmaNext (pNv, 0); 520fc5a983dSmrg NVDmaKickoff(pNv); 521fc5a983dSmrg } 522fc5a983dSmrg} 523fc5a983dSmrg 524fc5a983dSmrgstatic void 525fc5a983dSmrgNVSetupForScanlineImageWrite( 526fc5a983dSmrg ScrnInfoPtr pScrn, int rop, 527fc5a983dSmrg unsigned int planemask, 528fc5a983dSmrg int trans_color, 529fc5a983dSmrg int bpp, int depth 530fc5a983dSmrg) 531fc5a983dSmrg{ 532fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 533fc5a983dSmrg 534fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 535fc5a983dSmrg 536fc5a983dSmrg NVSetRopSolid (pScrn, rop, planemask); 537fc5a983dSmrg} 538fc5a983dSmrg 539fc5a983dSmrgstatic CARD32 _image_size; 540fc5a983dSmrgstatic CARD32 _image_srcpoint; 541fc5a983dSmrgstatic CARD32 _image_dstpoint; 542fc5a983dSmrgstatic CARD32 _image_dstpitch; 543fc5a983dSmrg 544fc5a983dSmrgstatic void 545fc5a983dSmrgNVSubsequentScanlineImageWriteRect( 546fc5a983dSmrg ScrnInfoPtr pScrn, 547fc5a983dSmrg int x, int y, 548fc5a983dSmrg int w, int h, 549fc5a983dSmrg int skipleft 550fc5a983dSmrg) 551fc5a983dSmrg{ 552fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 553fc5a983dSmrg int Bpp = pNv->CurrentLayout.bitsPerPixel >> 3; 554fc5a983dSmrg int image_srcpitch; 555fc5a983dSmrg 556fc5a983dSmrg _image_size = (1 << 16) | (w - skipleft); 557fc5a983dSmrg _image_srcpoint = skipleft; 558fc5a983dSmrg _image_dstpoint = (y << 16) | (x + skipleft); 559fc5a983dSmrg _remaining = h; 560fc5a983dSmrg _image_dstpitch = pNv->CurrentLayout.displayWidth * Bpp; 561fc5a983dSmrg image_srcpitch = ((w * Bpp) + 63) & ~63; 562fc5a983dSmrg _storage_buffer[0] = pNv->FbStart + pNv->ScratchBufferStart; 563fc5a983dSmrg 564fc5a983dSmrg NVSync(pScrn); 565fc5a983dSmrg 566fc5a983dSmrg NVDmaStart(pNv, SURFACE_PITCH, 2); 567fc5a983dSmrg NVDmaNext (pNv, (_image_dstpitch << 16) | image_srcpitch); 568fc5a983dSmrg NVDmaNext (pNv, pNv->ScratchBufferStart); 569fc5a983dSmrg} 570fc5a983dSmrg 571fc5a983dSmrgstatic void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 572fc5a983dSmrg{ 573fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 574fc5a983dSmrg 575fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 3); 576fc5a983dSmrg NVDmaNext (pNv, _image_srcpoint); 577fc5a983dSmrg NVDmaNext (pNv, _image_dstpoint); 578fc5a983dSmrg NVDmaNext (pNv, _image_size); 579fc5a983dSmrg NVDmaKickoff(pNv); 580fc5a983dSmrg 581fc5a983dSmrg if(--_remaining) { 582fc5a983dSmrg _image_dstpoint += (1 << 16); 583fc5a983dSmrg NVSync(pScrn); 584fc5a983dSmrg } else { 585fc5a983dSmrg NVDmaStart(pNv, SURFACE_PITCH, 2); 586fc5a983dSmrg NVDmaNext (pNv, _image_dstpitch | (_image_dstpitch << 16)); 587fc5a983dSmrg NVDmaNext (pNv, 0); 588fc5a983dSmrg } 589fc5a983dSmrg} 590fc5a983dSmrg 591fc5a983dSmrgstatic void 592fc5a983dSmrgNVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) 593fc5a983dSmrg{ 594fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 595fc5a983dSmrg 596fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 597fc5a983dSmrg 598fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 599fc5a983dSmrg 600fc5a983dSmrg _fg_pixel = color; 601fc5a983dSmrg 602fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 603fc5a983dSmrg} 604fc5a983dSmrg 605fc5a983dSmrgstatic void 606fc5a983dSmrgNVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) 607fc5a983dSmrg{ 608fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 609fc5a983dSmrg 610fc5a983dSmrg NVDmaStart(pNv, LINE_COLOR, 1); 611fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 612fc5a983dSmrg NVDmaStart(pNv, LINE_LINES(0), 2); 613fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ( x & 0xffff)); 614fc5a983dSmrg if(dir == DEGREES_0) { 615fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + len) & 0xffff)); 616fc5a983dSmrg } else { 617fc5a983dSmrg NVDmaNext (pNv, ((y + len) << 16) | (x & 0xffff)); 618fc5a983dSmrg } 619fc5a983dSmrg} 620fc5a983dSmrg 621fc5a983dSmrgstatic void 622fc5a983dSmrgNVSubsequentSolidTwoPointLine( 623fc5a983dSmrg ScrnInfoPtr pScrn, 624fc5a983dSmrg int x1, int y1, 625fc5a983dSmrg int x2, int y2, 626fc5a983dSmrg int flags 627fc5a983dSmrg) 628fc5a983dSmrg{ 629fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 630fc5a983dSmrg Bool drawLast = !(flags & OMIT_LAST); 631fc5a983dSmrg 632fc5a983dSmrg NVDmaStart(pNv, LINE_COLOR, 1); 633fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 634fc5a983dSmrg NVDmaStart(pNv, LINE_LINES(0), drawLast ? 4 : 2); 635fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | (x1 & 0xffff)); 636fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); 637fc5a983dSmrg if(drawLast) { 638fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); 639fc5a983dSmrg NVDmaNext (pNv, ((y2 + 1) << 16) | (x2 & 0xffff)); 640fc5a983dSmrg } 641fc5a983dSmrg} 642fc5a983dSmrg 643fc5a983dSmrgstatic void 644fc5a983dSmrgNVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 645fc5a983dSmrg{ 646fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 647fc5a983dSmrg int h = y2 - y1 + 1; 648fc5a983dSmrg int w = x2 - x1 + 1; 649fc5a983dSmrg 650fc5a983dSmrg NVDmaStart(pNv, CLIP_POINT, 2); 651fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | x1); 652fc5a983dSmrg NVDmaNext (pNv, (h << 16) | w); 653fc5a983dSmrg} 654fc5a983dSmrg 655fc5a983dSmrgstatic void 656fc5a983dSmrgNVDisableClipping(ScrnInfoPtr pScrn) 657fc5a983dSmrg{ 658fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 659fc5a983dSmrg 660fc5a983dSmrg NVDmaStart(pNv, CLIP_POINT, 2); 661fc5a983dSmrg NVDmaNext (pNv, 0); 662fc5a983dSmrg NVDmaNext (pNv, 0x7FFF7FFF); 663fc5a983dSmrg} 664fc5a983dSmrg 665bd304fc0Smrg#endif 666fc5a983dSmrg 667fc5a983dSmrg/* Initialize XAA acceleration info */ 668fc5a983dSmrgBool 669fc5a983dSmrgNVAccelInit(ScreenPtr pScreen) 670fc5a983dSmrg{ 671bd304fc0Smrg#ifdef HAVE_XAA_H 672bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 673fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 674fc5a983dSmrg XAAInfoRecPtr accel; 675fc5a983dSmrg 676fc5a983dSmrg accel = pNv->AccelInfoRec = XAACreateInfoRec(); 677fc5a983dSmrg if(!accel) return FALSE; 678fc5a983dSmrg 679fc5a983dSmrg accel->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 680fc5a983dSmrg accel->Sync = NVSync; 681fc5a983dSmrg 682fc5a983dSmrg accel->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 683fc5a983dSmrg accel->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy; 684fc5a983dSmrg accel->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy; 685fc5a983dSmrg 686fc5a983dSmrg accel->SolidFillFlags = 0; 687fc5a983dSmrg accel->SetupForSolidFill = NVSetupForSolidFill; 688fc5a983dSmrg accel->SubsequentSolidFillRect = NVSubsequentSolidFillRect; 689fc5a983dSmrg 690fc5a983dSmrg accel->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN | 691fc5a983dSmrg HARDWARE_PATTERN_PROGRAMMED_BITS | 692fc5a983dSmrg NO_PLANEMASK; 693fc5a983dSmrg accel->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill; 694fc5a983dSmrg accel->SubsequentMono8x8PatternFillRect = NVSubsequentMono8x8PatternFillRect; 695fc5a983dSmrg 696fc5a983dSmrg accel->ScanlineCPUToScreenColorExpandFillFlags = 697fc5a983dSmrg BIT_ORDER_IN_BYTE_LSBFIRST | 698fc5a983dSmrg CPU_TRANSFER_PAD_DWORD | 699fc5a983dSmrg LEFT_EDGE_CLIPPING | 700fc5a983dSmrg LEFT_EDGE_CLIPPING_NEGATIVE_X; 701fc5a983dSmrg accel->NumScanlineColorExpandBuffers = 1; 702fc5a983dSmrg accel->SetupForScanlineCPUToScreenColorExpandFill = 703fc5a983dSmrg NVSetupForScanlineCPUToScreenColorExpandFill; 704fc5a983dSmrg accel->SubsequentScanlineCPUToScreenColorExpandFill = 705fc5a983dSmrg NVSubsequentScanlineCPUToScreenColorExpandFill; 706fc5a983dSmrg accel->SubsequentColorExpandScanline = 707fc5a983dSmrg NVSubsequentColorExpandScanline; 708fc5a983dSmrg accel->ScanlineColorExpandBuffers = _storage_buffer; 709fc5a983dSmrg 710fc5a983dSmrg accel->ScanlineImageWriteFlags = NO_GXCOPY | 711fc5a983dSmrg NO_TRANSPARENCY | 712fc5a983dSmrg LEFT_EDGE_CLIPPING | 713fc5a983dSmrg LEFT_EDGE_CLIPPING_NEGATIVE_X; 714fc5a983dSmrg accel->NumScanlineImageWriteBuffers = 1; 715fc5a983dSmrg accel->SetupForScanlineImageWrite = NVSetupForScanlineImageWrite; 716fc5a983dSmrg accel->SubsequentScanlineImageWriteRect = NVSubsequentScanlineImageWriteRect; 717fc5a983dSmrg accel->SubsequentImageWriteScanline = NVSubsequentImageWriteScanline; 718fc5a983dSmrg accel->ScanlineImageWriteBuffers = _storage_buffer; 719fc5a983dSmrg 720fc5a983dSmrg accel->SolidLineFlags = 0; 721fc5a983dSmrg accel->SetupForSolidLine = NVSetupForSolidLine; 722fc5a983dSmrg accel->SubsequentSolidHorVertLine = NVSubsequentSolidHorVertLine; 723fc5a983dSmrg accel->SubsequentSolidTwoPointLine = NVSubsequentSolidTwoPointLine; 724fc5a983dSmrg accel->SetClippingRectangle = NVSetClippingRectangle; 725fc5a983dSmrg accel->DisableClipping = NVDisableClipping; 726fc5a983dSmrg accel->ClippingFlags = HARDWARE_CLIP_SOLID_LINE; 727fc5a983dSmrg 728fc5a983dSmrg miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6); 729fc5a983dSmrg 730fc5a983dSmrg return (XAAInit(pScreen, accel)); 731bd304fc0Smrg#else 732bd304fc0Smrg return FALSE; 733bd304fc0Smrg#endif 734fc5a983dSmrg} 735