nv_xaa.c revision bd304fc0
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 */ 109fc5a983dSmrg#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 179fc5a983dSmrgstatic void 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); 285fc5a983dSmrg 286fc5a983dSmrg if(pNv->DMAKickoffCallback) 287fc5a983dSmrg (*pNv->DMAKickoffCallback)(pScrn); 288fc5a983dSmrg 289fc5a983dSmrg while(READ_GET(pNv) != pNv->dmaPut); 290fc5a983dSmrg 291fc5a983dSmrg while(pNv->PGRAPH[0x0700/4]); 292fc5a983dSmrg} 293fc5a983dSmrg 294fc5a983dSmrgstatic void 295fc5a983dSmrgNVDMAKickoffCallback (ScrnInfoPtr pScrn) 296fc5a983dSmrg{ 297fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 298fc5a983dSmrg 299fc5a983dSmrg NVDmaKickoff(pNv); 300fc5a983dSmrg pNv->DMAKickoffCallback = NULL; 301fc5a983dSmrg} 302fc5a983dSmrg 303bd304fc0Smrg#ifdef HAVE_XAA_H 304fc5a983dSmrgstatic void 305fc5a983dSmrgNVSetupForScreenToScreenCopy( 306fc5a983dSmrg ScrnInfoPtr pScrn, 307fc5a983dSmrg int xdir, int ydir, 308fc5a983dSmrg int rop, 309fc5a983dSmrg unsigned planemask, 310fc5a983dSmrg int transparency_color 311fc5a983dSmrg) 312fc5a983dSmrg{ 313fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 314fc5a983dSmrg 315fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 316fc5a983dSmrg 317fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 318fc5a983dSmrg 319fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 320fc5a983dSmrg} 321fc5a983dSmrg 322fc5a983dSmrgstatic void 323fc5a983dSmrgNVSubsequentScreenToScreenCopy( 324fc5a983dSmrg ScrnInfoPtr pScrn, 325fc5a983dSmrg int x1, int y1, 326fc5a983dSmrg int x2, int y2, 327fc5a983dSmrg int w, int h 328fc5a983dSmrg) 329fc5a983dSmrg{ 330fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 331fc5a983dSmrg 332fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 3); 333fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | x1); 334fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | x2); 335fc5a983dSmrg NVDmaNext (pNv, (h << 16) | w); 336fc5a983dSmrg 337fc5a983dSmrg if((w * h) >= 512) 338fc5a983dSmrg NVDmaKickoff(pNv); 339fc5a983dSmrg} 340fc5a983dSmrg 341fc5a983dSmrgstatic void 342fc5a983dSmrgNVSetupForSolidFill( 343fc5a983dSmrg ScrnInfoPtr pScrn, 344fc5a983dSmrg int color, 345fc5a983dSmrg int rop, 346fc5a983dSmrg unsigned planemask 347fc5a983dSmrg) 348fc5a983dSmrg{ 349fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 350fc5a983dSmrg 351fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 352fc5a983dSmrg 353fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 354fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_COLOR, 1); 355fc5a983dSmrg NVDmaNext (pNv, color); 356fc5a983dSmrg 357fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 358fc5a983dSmrg} 359fc5a983dSmrg 360fc5a983dSmrgstatic void 361fc5a983dSmrgNVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 362fc5a983dSmrg{ 363fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 364fc5a983dSmrg 365fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); 366fc5a983dSmrg NVDmaNext (pNv, (x << 16) | y); 367fc5a983dSmrg NVDmaNext (pNv, (w << 16) | h); 368fc5a983dSmrg 369fc5a983dSmrg if((w * h) >= 512) 370fc5a983dSmrg NVDmaKickoff(pNv); 371fc5a983dSmrg} 372fc5a983dSmrg 373fc5a983dSmrgstatic void 374fc5a983dSmrgNVSetupForMono8x8PatternFill ( 375fc5a983dSmrg ScrnInfoPtr pScrn, 376fc5a983dSmrg int patternx, int patterny, 377fc5a983dSmrg int fg, int bg, 378fc5a983dSmrg int rop, 379fc5a983dSmrg unsigned planemask 380fc5a983dSmrg) 381fc5a983dSmrg{ 382fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 383fc5a983dSmrg 384fc5a983dSmrg planemask = ~0 << pNv->CurrentLayout.depth; 385fc5a983dSmrg 386fc5a983dSmrg fg |= planemask; 387fc5a983dSmrg if(bg == -1) bg = 0; 388fc5a983dSmrg else bg |= planemask; 389fc5a983dSmrg 390fc5a983dSmrg if (pNv->currentRop != (rop + 16)) { 391fc5a983dSmrg NVDmaStart(pNv, ROP_SET, 1); 392fc5a983dSmrg NVDmaNext (pNv, NVPatternROP[rop]); 393fc5a983dSmrg pNv->currentRop = rop + 16; 394fc5a983dSmrg } 395fc5a983dSmrg 396fc5a983dSmrg NVSetPattern(pScrn, bg, fg, patternx, patterny); 397fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_COLOR, 1); 398fc5a983dSmrg NVDmaNext (pNv, fg); 399fc5a983dSmrg 400fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 401fc5a983dSmrg} 402fc5a983dSmrg 403fc5a983dSmrgstatic void 404fc5a983dSmrgNVSubsequentMono8x8PatternFillRect( 405fc5a983dSmrg ScrnInfoPtr pScrn, 406fc5a983dSmrg int patternx, int patterny, 407fc5a983dSmrg int x, int y, 408fc5a983dSmrg int w, int h 409fc5a983dSmrg) 410fc5a983dSmrg{ 411fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 412fc5a983dSmrg 413fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); 414fc5a983dSmrg NVDmaNext (pNv, (x << 16) | y); 415fc5a983dSmrg NVDmaNext (pNv, (w << 16) | h); 416fc5a983dSmrg 417fc5a983dSmrg if((w * h) >= 512) 418fc5a983dSmrg NVDmaKickoff(pNv); 419fc5a983dSmrg} 420fc5a983dSmrg 421fc5a983dSmrgstatic CARD32 _bg_pixel; 422fc5a983dSmrgstatic CARD32 _fg_pixel; 423fc5a983dSmrgstatic Bool _transparent; 424fc5a983dSmrgstatic CARD32 _color_expand_dwords; 425fc5a983dSmrgstatic CARD32 _color_expand_offset; 426fc5a983dSmrgstatic int _remaining; 427fc5a983dSmrgstatic unsigned char *_storage_buffer[1]; 428fc5a983dSmrg 429fc5a983dSmrgstatic void 430fc5a983dSmrgNVSetupForScanlineCPUToScreenColorExpandFill ( 431fc5a983dSmrg ScrnInfoPtr pScrn, 432fc5a983dSmrg int fg, int bg, 433fc5a983dSmrg int rop, 434fc5a983dSmrg unsigned int planemask 435fc5a983dSmrg) 436fc5a983dSmrg{ 437fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 438fc5a983dSmrg 439fc5a983dSmrg CARD32 mask = ~0 << pNv->CurrentLayout.depth; 440fc5a983dSmrg 441fc5a983dSmrg planemask |= mask; 442fc5a983dSmrg _fg_pixel = fg | mask; 443fc5a983dSmrg 444fc5a983dSmrg if(bg == -1) { 445fc5a983dSmrg _transparent = TRUE; 446fc5a983dSmrg } else { 447fc5a983dSmrg _transparent = FALSE; 448fc5a983dSmrg _bg_pixel = bg | mask; 449fc5a983dSmrg } 450fc5a983dSmrg 451fc5a983dSmrg NVSetRopSolid (pScrn, rop, planemask); 452fc5a983dSmrg} 453fc5a983dSmrg 454fc5a983dSmrgstatic void 455fc5a983dSmrgNVSubsequentScanlineCPUToScreenColorExpandFill ( 456fc5a983dSmrg ScrnInfoPtr pScrn, 457fc5a983dSmrg int x, int y, 458fc5a983dSmrg int w, int h, 459fc5a983dSmrg int skipleft 460fc5a983dSmrg) 461fc5a983dSmrg{ 462fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 463fc5a983dSmrg int bw = (w + 31) & ~31; 464fc5a983dSmrg 465fc5a983dSmrg _color_expand_dwords = bw >> 5; 466fc5a983dSmrg _remaining = h; 467fc5a983dSmrg 468fc5a983dSmrg if(_transparent) { 469fc5a983dSmrg NVDmaStart(pNv, RECT_EXPAND_ONE_COLOR_CLIP, 5); 470fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); 471fc5a983dSmrg NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); 472fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 473fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 474fc5a983dSmrg NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); 475fc5a983dSmrg _color_expand_offset = RECT_EXPAND_ONE_COLOR_DATA(0); 476fc5a983dSmrg } else { 477fc5a983dSmrg NVDmaStart(pNv, RECT_EXPAND_TWO_COLOR_CLIP, 7); 478fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); 479fc5a983dSmrg NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); 480fc5a983dSmrg NVDmaNext (pNv, _bg_pixel); 481fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 482fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 483fc5a983dSmrg NVDmaNext (pNv, (h << 16) | bw); 484fc5a983dSmrg NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); 485fc5a983dSmrg _color_expand_offset = RECT_EXPAND_TWO_COLOR_DATA(0); 486fc5a983dSmrg } 487fc5a983dSmrg 488fc5a983dSmrg NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); 489fc5a983dSmrg _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; 490fc5a983dSmrg} 491fc5a983dSmrg 492fc5a983dSmrgstatic void 493fc5a983dSmrgNVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 494fc5a983dSmrg{ 495fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 496fc5a983dSmrg 497fc5a983dSmrg pNv->dmaCurrent += _color_expand_dwords; 498fc5a983dSmrg 499fc5a983dSmrg if(--_remaining) { 500fc5a983dSmrg NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); 501fc5a983dSmrg _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; 502fc5a983dSmrg } else { 503fc5a983dSmrg /* hardware bug workaround */ 504fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 1); 505fc5a983dSmrg NVDmaNext (pNv, 0); 506fc5a983dSmrg NVDmaKickoff(pNv); 507fc5a983dSmrg } 508fc5a983dSmrg} 509fc5a983dSmrg 510fc5a983dSmrgstatic void 511fc5a983dSmrgNVSetupForScanlineImageWrite( 512fc5a983dSmrg ScrnInfoPtr pScrn, int rop, 513fc5a983dSmrg unsigned int planemask, 514fc5a983dSmrg int trans_color, 515fc5a983dSmrg int bpp, int depth 516fc5a983dSmrg) 517fc5a983dSmrg{ 518fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 519fc5a983dSmrg 520fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 521fc5a983dSmrg 522fc5a983dSmrg NVSetRopSolid (pScrn, rop, planemask); 523fc5a983dSmrg} 524fc5a983dSmrg 525fc5a983dSmrgstatic CARD32 _image_size; 526fc5a983dSmrgstatic CARD32 _image_srcpoint; 527fc5a983dSmrgstatic CARD32 _image_dstpoint; 528fc5a983dSmrgstatic CARD32 _image_dstpitch; 529fc5a983dSmrg 530fc5a983dSmrgstatic void 531fc5a983dSmrgNVSubsequentScanlineImageWriteRect( 532fc5a983dSmrg ScrnInfoPtr pScrn, 533fc5a983dSmrg int x, int y, 534fc5a983dSmrg int w, int h, 535fc5a983dSmrg int skipleft 536fc5a983dSmrg) 537fc5a983dSmrg{ 538fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 539fc5a983dSmrg int Bpp = pNv->CurrentLayout.bitsPerPixel >> 3; 540fc5a983dSmrg int image_srcpitch; 541fc5a983dSmrg 542fc5a983dSmrg _image_size = (1 << 16) | (w - skipleft); 543fc5a983dSmrg _image_srcpoint = skipleft; 544fc5a983dSmrg _image_dstpoint = (y << 16) | (x + skipleft); 545fc5a983dSmrg _remaining = h; 546fc5a983dSmrg _image_dstpitch = pNv->CurrentLayout.displayWidth * Bpp; 547fc5a983dSmrg image_srcpitch = ((w * Bpp) + 63) & ~63; 548fc5a983dSmrg _storage_buffer[0] = pNv->FbStart + pNv->ScratchBufferStart; 549fc5a983dSmrg 550fc5a983dSmrg NVSync(pScrn); 551fc5a983dSmrg 552fc5a983dSmrg NVDmaStart(pNv, SURFACE_PITCH, 2); 553fc5a983dSmrg NVDmaNext (pNv, (_image_dstpitch << 16) | image_srcpitch); 554fc5a983dSmrg NVDmaNext (pNv, pNv->ScratchBufferStart); 555fc5a983dSmrg} 556fc5a983dSmrg 557fc5a983dSmrgstatic void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 558fc5a983dSmrg{ 559fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 560fc5a983dSmrg 561fc5a983dSmrg NVDmaStart(pNv, BLIT_POINT_SRC, 3); 562fc5a983dSmrg NVDmaNext (pNv, _image_srcpoint); 563fc5a983dSmrg NVDmaNext (pNv, _image_dstpoint); 564fc5a983dSmrg NVDmaNext (pNv, _image_size); 565fc5a983dSmrg NVDmaKickoff(pNv); 566fc5a983dSmrg 567fc5a983dSmrg if(--_remaining) { 568fc5a983dSmrg _image_dstpoint += (1 << 16); 569fc5a983dSmrg NVSync(pScrn); 570fc5a983dSmrg } else { 571fc5a983dSmrg NVDmaStart(pNv, SURFACE_PITCH, 2); 572fc5a983dSmrg NVDmaNext (pNv, _image_dstpitch | (_image_dstpitch << 16)); 573fc5a983dSmrg NVDmaNext (pNv, 0); 574fc5a983dSmrg } 575fc5a983dSmrg} 576fc5a983dSmrg 577fc5a983dSmrgstatic void 578fc5a983dSmrgNVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) 579fc5a983dSmrg{ 580fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 581fc5a983dSmrg 582fc5a983dSmrg planemask |= ~0 << pNv->CurrentLayout.depth; 583fc5a983dSmrg 584fc5a983dSmrg NVSetRopSolid(pScrn, rop, planemask); 585fc5a983dSmrg 586fc5a983dSmrg _fg_pixel = color; 587fc5a983dSmrg 588fc5a983dSmrg pNv->DMAKickoffCallback = NVDMAKickoffCallback; 589fc5a983dSmrg} 590fc5a983dSmrg 591fc5a983dSmrgstatic void 592fc5a983dSmrgNVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) 593fc5a983dSmrg{ 594fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 595fc5a983dSmrg 596fc5a983dSmrg NVDmaStart(pNv, LINE_COLOR, 1); 597fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 598fc5a983dSmrg NVDmaStart(pNv, LINE_LINES(0), 2); 599fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ( x & 0xffff)); 600fc5a983dSmrg if(dir == DEGREES_0) { 601fc5a983dSmrg NVDmaNext (pNv, (y << 16) | ((x + len) & 0xffff)); 602fc5a983dSmrg } else { 603fc5a983dSmrg NVDmaNext (pNv, ((y + len) << 16) | (x & 0xffff)); 604fc5a983dSmrg } 605fc5a983dSmrg} 606fc5a983dSmrg 607fc5a983dSmrgstatic void 608fc5a983dSmrgNVSubsequentSolidTwoPointLine( 609fc5a983dSmrg ScrnInfoPtr pScrn, 610fc5a983dSmrg int x1, int y1, 611fc5a983dSmrg int x2, int y2, 612fc5a983dSmrg int flags 613fc5a983dSmrg) 614fc5a983dSmrg{ 615fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 616fc5a983dSmrg Bool drawLast = !(flags & OMIT_LAST); 617fc5a983dSmrg 618fc5a983dSmrg NVDmaStart(pNv, LINE_COLOR, 1); 619fc5a983dSmrg NVDmaNext (pNv, _fg_pixel); 620fc5a983dSmrg NVDmaStart(pNv, LINE_LINES(0), drawLast ? 4 : 2); 621fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | (x1 & 0xffff)); 622fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); 623fc5a983dSmrg if(drawLast) { 624fc5a983dSmrg NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); 625fc5a983dSmrg NVDmaNext (pNv, ((y2 + 1) << 16) | (x2 & 0xffff)); 626fc5a983dSmrg } 627fc5a983dSmrg} 628fc5a983dSmrg 629fc5a983dSmrgstatic void 630fc5a983dSmrgNVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 631fc5a983dSmrg{ 632fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 633fc5a983dSmrg int h = y2 - y1 + 1; 634fc5a983dSmrg int w = x2 - x1 + 1; 635fc5a983dSmrg 636fc5a983dSmrg NVDmaStart(pNv, CLIP_POINT, 2); 637fc5a983dSmrg NVDmaNext (pNv, (y1 << 16) | x1); 638fc5a983dSmrg NVDmaNext (pNv, (h << 16) | w); 639fc5a983dSmrg} 640fc5a983dSmrg 641fc5a983dSmrgstatic void 642fc5a983dSmrgNVDisableClipping(ScrnInfoPtr pScrn) 643fc5a983dSmrg{ 644fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 645fc5a983dSmrg 646fc5a983dSmrg NVDmaStart(pNv, CLIP_POINT, 2); 647fc5a983dSmrg NVDmaNext (pNv, 0); 648fc5a983dSmrg NVDmaNext (pNv, 0x7FFF7FFF); 649fc5a983dSmrg} 650fc5a983dSmrg 651bd304fc0Smrg#endif 652fc5a983dSmrg 653fc5a983dSmrg/* Initialize XAA acceleration info */ 654fc5a983dSmrgBool 655fc5a983dSmrgNVAccelInit(ScreenPtr pScreen) 656fc5a983dSmrg{ 657bd304fc0Smrg#ifdef HAVE_XAA_H 658bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 659fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 660fc5a983dSmrg XAAInfoRecPtr accel; 661fc5a983dSmrg 662fc5a983dSmrg accel = pNv->AccelInfoRec = XAACreateInfoRec(); 663fc5a983dSmrg if(!accel) return FALSE; 664fc5a983dSmrg 665fc5a983dSmrg accel->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 666fc5a983dSmrg accel->Sync = NVSync; 667fc5a983dSmrg 668fc5a983dSmrg accel->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 669fc5a983dSmrg accel->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy; 670fc5a983dSmrg accel->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy; 671fc5a983dSmrg 672fc5a983dSmrg accel->SolidFillFlags = 0; 673fc5a983dSmrg accel->SetupForSolidFill = NVSetupForSolidFill; 674fc5a983dSmrg accel->SubsequentSolidFillRect = NVSubsequentSolidFillRect; 675fc5a983dSmrg 676fc5a983dSmrg accel->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN | 677fc5a983dSmrg HARDWARE_PATTERN_PROGRAMMED_BITS | 678fc5a983dSmrg NO_PLANEMASK; 679fc5a983dSmrg accel->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill; 680fc5a983dSmrg accel->SubsequentMono8x8PatternFillRect = NVSubsequentMono8x8PatternFillRect; 681fc5a983dSmrg 682fc5a983dSmrg accel->ScanlineCPUToScreenColorExpandFillFlags = 683fc5a983dSmrg BIT_ORDER_IN_BYTE_LSBFIRST | 684fc5a983dSmrg CPU_TRANSFER_PAD_DWORD | 685fc5a983dSmrg LEFT_EDGE_CLIPPING | 686fc5a983dSmrg LEFT_EDGE_CLIPPING_NEGATIVE_X; 687fc5a983dSmrg accel->NumScanlineColorExpandBuffers = 1; 688fc5a983dSmrg accel->SetupForScanlineCPUToScreenColorExpandFill = 689fc5a983dSmrg NVSetupForScanlineCPUToScreenColorExpandFill; 690fc5a983dSmrg accel->SubsequentScanlineCPUToScreenColorExpandFill = 691fc5a983dSmrg NVSubsequentScanlineCPUToScreenColorExpandFill; 692fc5a983dSmrg accel->SubsequentColorExpandScanline = 693fc5a983dSmrg NVSubsequentColorExpandScanline; 694fc5a983dSmrg accel->ScanlineColorExpandBuffers = _storage_buffer; 695fc5a983dSmrg 696fc5a983dSmrg accel->ScanlineImageWriteFlags = NO_GXCOPY | 697fc5a983dSmrg NO_TRANSPARENCY | 698fc5a983dSmrg LEFT_EDGE_CLIPPING | 699fc5a983dSmrg LEFT_EDGE_CLIPPING_NEGATIVE_X; 700fc5a983dSmrg accel->NumScanlineImageWriteBuffers = 1; 701fc5a983dSmrg accel->SetupForScanlineImageWrite = NVSetupForScanlineImageWrite; 702fc5a983dSmrg accel->SubsequentScanlineImageWriteRect = NVSubsequentScanlineImageWriteRect; 703fc5a983dSmrg accel->SubsequentImageWriteScanline = NVSubsequentImageWriteScanline; 704fc5a983dSmrg accel->ScanlineImageWriteBuffers = _storage_buffer; 705fc5a983dSmrg 706fc5a983dSmrg accel->SolidLineFlags = 0; 707fc5a983dSmrg accel->SetupForSolidLine = NVSetupForSolidLine; 708fc5a983dSmrg accel->SubsequentSolidHorVertLine = NVSubsequentSolidHorVertLine; 709fc5a983dSmrg accel->SubsequentSolidTwoPointLine = NVSubsequentSolidTwoPointLine; 710fc5a983dSmrg accel->SetClippingRectangle = NVSetClippingRectangle; 711fc5a983dSmrg accel->DisableClipping = NVDisableClipping; 712fc5a983dSmrg accel->ClippingFlags = HARDWARE_CLIP_SOLID_LINE; 713fc5a983dSmrg 714fc5a983dSmrg miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6); 715fc5a983dSmrg 716fc5a983dSmrg return (XAAInit(pScreen, accel)); 717bd304fc0Smrg#else 718bd304fc0Smrg return FALSE; 719bd304fc0Smrg#endif 720fc5a983dSmrg} 721