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