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