pm3_accel.c revision d038a282
1/* 2 * Copyright 2000-2001 by Sven Luther <luther@dpt-info.u-strasbg.fr>. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Sven Luther not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Sven Luther makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * SVEN LUTHER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL SVEN LUTHER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Authors: Sven Luther, <luther@dpt-info.u-strasbg.fr> 23 * Alan Hourihane, <alanh@fairlite.demon.co.uk> 24 * 25 * this work is sponsored by Appian Graphics. 26 * 27 * Permedia 3 accelerated options. 28 */ 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif 33 34#include <X11/Xarch.h> 35#include "xf86.h" 36#include "xf86_OSproc.h" 37 38#include "xf86Pci.h" 39 40#include "miline.h" 41 42#include "fb.h" 43 44#include "glint_regs.h" 45#include "pm3_regs.h" 46#include "glint.h" 47 48#define DEBUG 0 49 50#if DEBUG 51# define TRACE_ENTER(str) ErrorF("pm3_accel: " str " %d\n",pScrn->scrnIndex) 52# define TRACE_EXIT(str) ErrorF("pm3_accel: " str " done\n") 53# define TRACE(str) ErrorF("pm3_accel trace: " str "\n") 54#else 55# define TRACE_ENTER(str) 56# define TRACE_EXIT(str) 57# define TRACE(str) 58#endif 59 60#ifdef HAVE_XAA_H 61#include "xaalocal.h" /* For replacements */ 62#endif 63 64#ifdef HAVE_XAA_H 65 66/* Clipping */ 67static void Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y, 68 int w, int h); 69static void Permedia3DisableClipping(ScrnInfoPtr pScrn); 70/* ScreenToScreenCopy */ 71static void Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 72 int x1, int y1, int x2, 73 int y2, int w, int h); 74static void Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 75 int xdir, int ydir, int rop, 76 unsigned int planemask, 77 int transparency_color); 78/* SolidFill */ 79static void Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, 80 int rop, unsigned int planemask); 81static void Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, 82 int y, int w, int h); 83static void Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x, 84 int y, int w, int h); 85/* 8x8 Mono Pattern Fills */ 86static void Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 87 int patternx, int patterny, int fg, int bg, 88 int rop, unsigned int planemask); 89static void Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 90 int x_offset, int y_offset, int x, int y, 91 int w, int h); 92static void Permedia3SetupForScanlineCPUToScreenColorExpandFill( 93 ScrnInfoPtr pScrn, 94 int fg, int bg, int rop, 95 unsigned int planemask); 96static void Permedia3SubsequentScanlineCPUToScreenColorExpandFill( 97 ScrnInfoPtr pScrn, int x, 98 int y, int w, int h, int skipleft); 99static void Permedia3SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 100static void Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 101 unsigned int planemask, int trans_color, 102 int bpp, int depth); 103static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, 104 int x, int y, int w, int h, int skipleft); 105static void Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno); 106static void Permedia3RestoreAccelState(ScrnInfoPtr pScrn); 107static void Permedia3WritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, 108 unsigned char *src, int srcwidth, int rop, 109 unsigned int planemask, int transparency_color, 110 int bpp, int depth); 111static void Permedia3WriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, 112 unsigned char *src, int srcwidth, int skipleft, 113 int fg, int bg, int rop,unsigned int planemask); 114#endif /* HAVE_XAA_H */ 115 116void 117Permedia3InitializeEngine(ScrnInfoPtr pScrn) 118{ 119 GLINTPtr pGlint = GLINTPTR(pScrn); 120 int colorformat = 0; 121 122 /* Initialize the Accelerator Engine to defaults */ 123 TRACE_ENTER("Permedia3InitializeEngine"); 124 125 if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { 126 GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); 127 } 128 if (pGlint->MultiAperture) { 129 ErrorF("pm3_accel: SVEN : multiAperture set\n"); 130 /* Only write the following register to the first PM3 */ 131 GLINT_SLOW_WRITE_REG(1, BroadcastMask); 132 GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership); 133 134 /* Only write the following register to the second PM3 */ 135 GLINT_SLOW_WRITE_REG(2, BroadcastMask); 136 GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership); 137 138 /* Make sure the rest of the register writes go to both PM3's */ 139 GLINT_SLOW_WRITE_REG(3, BroadcastMask); 140 } 141 142 /* Disable LocalBuffer. Fixes stripes problems when 143 * doing screen-to-screen copies */ 144 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadMode); 145 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBDestReadEnables); 146 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBSourceReadMode); 147 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LBWriteMode); 148 149 /* Host out PreInit */ 150 /* Set filter mode to enable sync tag & data output */ 151 GLINT_SLOW_WRITE_REG(0x400, FilterMode); 152 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); 153 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3DeltaMode); 154 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); 155 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); 156 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode); 157 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); 158 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3GIDMode); 159 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); 160 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); 161 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); 162 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCoordMode); 163 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode0); 164 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureIndexMode1); 165 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode); 166 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3LUTMode); 167 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureFilterMode); 168 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureCompositeMode); 169 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3TextureApplicationMode); 170 GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode1); 171 GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode1); 172 GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeColorMode0); 173 GLINT_SLOW_WRITE_REG(0, PM3TextureCompositeAlphaMode0); 174 175 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); 176 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ChromaTestMode); 177 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); 178 /* Not done in P3Lib ??? */ 179 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); 180 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaTestMode); 181 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode); 182 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendColorMode); 183 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3AlphaBlendAlphaMode); 184 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); 185 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); 186 187 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); 188 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); 189 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PM3Window); 190 191 GLINT_SLOW_WRITE_REG(0, PM3Config2D); 192 193 GLINT_SLOW_WRITE_REG(0xffffffff, PM3SpanColorMask); 194 195 GLINT_SLOW_WRITE_REG(0, PM3XBias); 196 GLINT_SLOW_WRITE_REG(0, PM3YBias); 197 198 GLINT_SLOW_WRITE_REG(0, PM3DeltaControl); 199 200 GLINT_SLOW_WRITE_REG(0xffffffff, BitMaskPattern); 201 202 /* ScissorStippleUnit Initialization (is it needed ?) */ 203 pGlint->ClippingOn = FALSE; 204 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); 205 /* We never use Screen Scissor ... 206 GLINT_SLOW_WRITE_REG( 207 (pScrn->virtualX&0xffff)|((pScrn->virtualY&0xffff)<<16), 208 ScreenSize); 209 GLINT_SLOW_WRITE_REG( 210 (0&0xffff)|((0&0xffff)<<16), 211 WindowOrigin); 212 */ 213 214 /* StencilDepthUnit Initialization */ 215 GLINT_SLOW_WRITE_REG(0, PM3Window); 216 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); 217 GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); 218 GLINT_SLOW_WRITE_REG(0, StencilData); 219 220 /* FBReadUnit Initialization */ 221 TRACE("Permedia3InitializeEngine : only syncs upto now"); 222 GLINT_SLOW_WRITE_REG( 223 PM3FBDestReadEnables_E(0xff) | 224 PM3FBDestReadEnables_R(0xff) | 225 PM3FBDestReadEnables_ReferenceAlpha(0xff), 226 PM3FBDestReadEnables); 227 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr0); 228 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset0); 229 GLINT_SLOW_WRITE_REG( 230 PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), 231 PM3FBDestReadBufferWidth0); 232 /* 233 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr1); 234 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset1); 235 GLINT_SLOW_WRITE_REG( 236 PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), 237 PM3FBDestReadBufferWidth1); 238 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr2); 239 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset2); 240 GLINT_SLOW_WRITE_REG( 241 PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), 242 PM3FBDestReadBufferWidth2); 243 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferAddr3); 244 GLINT_SLOW_WRITE_REG(0, PM3FBDestReadBufferOffset3); 245 GLINT_SLOW_WRITE_REG( 246 PM3FBDestReadBufferWidth_Width(pScrn->displayWidth), 247 PM3FBDestReadBufferWidth3); 248 */ 249 GLINT_SLOW_WRITE_REG( 250 PM3FBDestReadMode_ReadEnable | 251 /* Not needed, since FBDestRead is the same as FBWrite. 252 PM3FBDestReadMode_Blocking | 253 */ 254 PM3FBDestReadMode_Enable0, 255 PM3FBDestReadMode); 256 TRACE("Permedia3InitializeEngine : DestRead"); 257 GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferAddr); 258 GLINT_SLOW_WRITE_REG(0, PM3FBSourceReadBufferOffset); 259 GLINT_SLOW_WRITE_REG( 260 PM3FBSourceReadBufferWidth_Width(pScrn->displayWidth), 261 PM3FBSourceReadBufferWidth); 262 GLINT_SLOW_WRITE_REG( 263 PM3FBSourceReadMode_Blocking | 264 PM3FBSourceReadMode_ReadEnable, 265 PM3FBSourceReadMode); 266 TRACE("Permedia3InitializeEngine : SourceRead"); 267 switch (pScrn->bitsPerPixel) { 268 case 8: 269 pGlint->PM3_PixelSize = 2; 270#if X_BYTE_ORDER == X_BIG_ENDIAN 271 pGlint->RasterizerSwap = 3<<15; /* Swap host data */ 272#endif 273 break; 274 case 16: 275 pGlint->PM3_PixelSize = 1; 276#if X_BYTE_ORDER == X_BIG_ENDIAN 277 pGlint->RasterizerSwap = 2<<15; /* Swap host data */ 278#endif 279 break; 280 case 32: 281 pGlint->PM3_PixelSize = 0; 282 break; 283 } 284 GLINT_SLOW_WRITE_REG(pGlint->PM3_PixelSize, PixelSize); 285#if X_BYTE_ORDER == X_BIG_ENDIAN 286 GLINT_SLOW_WRITE_REG(1 | pGlint->RasterizerSwap, RasterizerMode); 287#endif 288 TRACE("Permedia3InitializeEngine : PixelSize"); 289 290 /* LogicalOpUnit Initialization */ 291 GLINT_SLOW_WRITE_REG(0xffffffff, PM3_OTHERWRITEMASK); 292 293 /* FBWriteUnit Initialization */ 294 GLINT_SLOW_WRITE_REG( 295 PM3FBWriteMode_WriteEnable| 296 PM3FBWriteMode_OpaqueSpan| 297 PM3FBWriteMode_Enable0, 298 PM3FBWriteMode); 299 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr0); 300 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset0); 301 GLINT_SLOW_WRITE_REG( 302 PM3FBWriteBufferWidth_Width(pScrn->displayWidth), 303 PM3FBWriteBufferWidth0); 304 /* 305 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr1); 306 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset1); 307 GLINT_SLOW_WRITE_REG( 308 PM3FBWriteBufferWidth_Width(pScrn->displayWidth), 309 PM3FBWriteBufferWidth1); 310 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr2); 311 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset2); 312 GLINT_SLOW_WRITE_REG( 313 PM3FBWriteBufferWidth_Width(pScrn->displayWidth), 314 PM3FBWriteBufferWidth2); 315 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferAddr3); 316 GLINT_SLOW_WRITE_REG(0, PM3FBWriteBufferOffset3); 317 GLINT_SLOW_WRITE_REG( 318 PM3FBWriteBufferWidth_Width(pScrn->displayWidth), 319 PM3FBWriteBufferWidth3); 320 */ 321 TRACE("Permedia3InitializeEngine : FBWrite"); 322 /* SizeOfframebuffer */ 323 GLINT_SLOW_WRITE_REG( 324 pScrn->displayWidth * 325 (8 * pGlint->FbMapSize / (pScrn->bitsPerPixel * pScrn->displayWidth) 326 >4095?4095: 8 * pGlint->FbMapSize / 327 (pScrn->bitsPerPixel * pScrn->displayWidth)), 328 PM3SizeOfFramebuffer); 329 GLINT_SLOW_WRITE_REG(0xffffffff, PM3_WRITEMASK); 330 TRACE("Permedia3InitializeEngine : FBHardwareWriteMask & SizeOfFramebuffer"); 331 /* Color Format */ 332 switch (pScrn->depth) { 333 case 8: 334 colorformat = 4; 335 break; 336 case 15: 337 colorformat = 2; 338 break; 339 case 16: 340 colorformat = 3; 341 break; 342 case 24: 343 case 32: 344 colorformat = 0; 345 break; 346 } 347 GLINT_SLOW_WRITE_REG(UNIT_DISABLE| 348 ((colorformat&0xf)<<2)|(1<<10), 349 DitherMode); 350 351 /* Other stuff */ 352 pGlint->startxdom = 0; 353 pGlint->startxsub = 0; 354 pGlint->starty = 0; 355 pGlint->count = 0; 356 pGlint->dy = 1<<16; 357 pGlint->dxdom = 0; 358 pGlint->x = 0; 359 pGlint->y = 0; 360 pGlint->h = 0; 361 pGlint->w = 0; 362 pGlint->ROP = 0xFF; 363 GLINT_SLOW_WRITE_REG(0, dXDom); 364 GLINT_SLOW_WRITE_REG(0, dXSub); 365 GLINT_SLOW_WRITE_REG(1<<16, dY); 366 GLINT_SLOW_WRITE_REG(0, StartXDom); 367 GLINT_SLOW_WRITE_REG(0, StartXSub); 368 GLINT_SLOW_WRITE_REG(0, StartY); 369 GLINT_SLOW_WRITE_REG(0, GLINTCount); 370#ifdef HAVE_XAA_H 371 if (*pGlint->AccelInfoRec->Sync != NULL) 372 (*pGlint->AccelInfoRec->Sync)(pScrn); 373#endif 374 TRACE_EXIT("Permedia3InitializeEngine"); 375} 376 377Bool 378Permedia3AccelInit(ScreenPtr pScreen) 379{ 380#ifdef HAVE_XAA_H 381 XAAInfoRecPtr infoPtr; 382 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 383 GLINTPtr pGlint = GLINTPTR(pScrn); 384 385 pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); 386 if (!infoPtr) return FALSE; 387 388 /* Generic accel engine flags */ 389 infoPtr->Flags = PIXMAP_CACHE | 390 OFFSCREEN_PIXMAPS | 391 LINEAR_FRAMEBUFFER; 392 393 /* Synchronization of the accel engine */ 394 if (pGlint->MultiAperture) 395 infoPtr->Sync = DualPermedia3Sync; 396 else 397 infoPtr->Sync = Permedia3Sync; 398 399 Permedia3InitializeEngine(pScrn); 400 401 /* Clipping Setup */ 402 infoPtr->ClippingFlags = 0; 403 infoPtr->SetClippingRectangle = Permedia3SetClippingRectangle; 404 infoPtr->DisableClipping = Permedia3DisableClipping; 405 406 /* ScreenToScreenCopy */ 407 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 408 infoPtr->SetupForScreenToScreenCopy = 409 Permedia3SetupForScreenToScreenCopy; 410 infoPtr->SubsequentScreenToScreenCopy = 411 Permedia3SubsequentScreenToScreenCopy; 412 413 /* SolidFill */ 414 infoPtr->SolidFillFlags = 0; 415 infoPtr->SetupForSolidFill = Permedia3SetupForFillRectSolid; 416 infoPtr->SubsequentSolidFillRect = Permedia3SubsequentFillRectSolid; 417 418 /* 8x8 Mono Pattern Fills */ 419 infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 420 HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 421 HARDWARE_PATTERN_SCREEN_ORIGIN | 422 BIT_ORDER_IN_BYTE_LSBFIRST; 423 infoPtr->SetupForMono8x8PatternFill = 424 Permedia3SetupForMono8x8PatternFill; 425 infoPtr->SubsequentMono8x8PatternFillRect = 426 Permedia3SubsequentMono8x8PatternFillRect; 427 428 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = 429 LEFT_EDGE_CLIPPING | 430 LEFT_EDGE_CLIPPING_NEGATIVE_X | 431 BIT_ORDER_IN_BYTE_LSBFIRST | 432 CPU_TRANSFER_PAD_DWORD; 433 434 infoPtr->NumScanlineColorExpandBuffers = 1; 435 pGlint->ScratchBuffer = malloc(((pScrn->virtualX + 62) / 32 * 4) + (pScrn->virtualX * pScrn->bitsPerPixel / 8)); 436 infoPtr->ScanlineColorExpandBuffers = 437 pGlint->XAAScanlineColorExpandBuffers; 438 pGlint->XAAScanlineColorExpandBuffers[0] = 439 pGlint->IOBase + OutputFIFO + 4; 440 441 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 442 Permedia3SetupForScanlineCPUToScreenColorExpandFill; 443 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 444 Permedia3SubsequentScanlineCPUToScreenColorExpandFill; 445 infoPtr->SubsequentColorExpandScanline = 446 Permedia3SubsequentColorExpandScanline; 447 448 infoPtr->ScanlineImageWriteFlags = NO_GXCOPY | 449 LEFT_EDGE_CLIPPING | 450 LEFT_EDGE_CLIPPING_NEGATIVE_X | 451 BIT_ORDER_IN_BYTE_LSBFIRST | 452 CPU_TRANSFER_PAD_DWORD; 453 infoPtr->NumScanlineImageWriteBuffers = 1; 454 infoPtr->ScanlineImageWriteBuffers = 455 pGlint->XAAScanlineColorExpandBuffers; 456 infoPtr->SetupForScanlineImageWrite = 457 Permedia3SetupForScanlineImageWrite; 458 infoPtr->SubsequentScanlineImageWriteRect = 459 Permedia3SubsequentScanlineImageWriteRect; 460 infoPtr->SubsequentImageWriteScanline = 461 Permedia3SubsequentImageWriteScanline; 462 463 infoPtr->WriteBitmap = Permedia3WriteBitmap; 464 infoPtr->WriteBitmapFlags = 0; 465 466 infoPtr->WritePixmap = Permedia3WritePixmap; 467 infoPtr->WritePixmapFlags = 0; 468 469 { 470 Bool shared_accel = FALSE; 471 int i; 472 473 for(i = 0; i < pScrn->numEntities; i++) { 474 if(xf86IsEntityShared(pScrn->entityList[i])) 475 shared_accel = TRUE; 476 } 477 if(shared_accel == TRUE) 478 infoPtr->RestoreAccelState = Permedia3RestoreAccelState; 479 } 480 481 Permedia3EnableOffscreen(pScreen); 482 483 return(XAAInit(pScreen, infoPtr)); 484#else 485 return FALSE; 486#endif 487} 488 489void 490Permedia3EnableOffscreen (ScreenPtr pScreen) 491{ 492 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 493 GLINTPtr pGlint = GLINTPTR(pScrn); 494 BoxRec AvailFBArea; 495 496 /* Available Framebuffer Area for XAA. */ 497 AvailFBArea.x1 = 0; 498 AvailFBArea.y1 = 0; 499 AvailFBArea.x2 = pScrn->displayWidth; 500 /* X coords are short's so we have to do this to make sure we dont wrap*/ 501 AvailFBArea.y2 = ((pGlint->FbMapSize > 16384*1024) ? 16384*1024 : 502 pGlint->FbMapSize) / (pScrn->displayWidth * 503 pScrn->bitsPerPixel / 8); 504 505 /* Permedia3 has a maximum 4096x4096 framebuffer */ 506 if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095; 507 508 xf86InitFBManager(pScreen, &AvailFBArea); 509} 510 511 512#define CHECKCLIPPING \ 513{ \ 514 if (pGlint->ClippingOn) { \ 515 pGlint->ClippingOn = FALSE; \ 516 GLINT_WAIT(1); \ 517 GLINT_WRITE_REG(0, ScissorMode); \ 518 } \ 519} 520 521void 522Permedia3Sync(ScrnInfoPtr pScrn) 523{ 524 GLINTPtr pGlint = GLINTPTR(pScrn); 525 526 CHECKCLIPPING; 527 528 while (GLINT_READ_REG(DMACount) != 0); 529 GLINT_WAIT(2); 530 GLINT_WRITE_REG(0x400, FilterMode); 531 GLINT_WRITE_REG(0, GlintSync); 532 do { 533 while(GLINT_READ_REG(OutFIFOWords) == 0); 534 } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); 535} 536 537#ifdef HAVE_XAA_H 538void 539DualPermedia3Sync( 540 ScrnInfoPtr pScrn 541){ 542 GLINTPtr pGlint = GLINTPTR(pScrn); 543 544 CHECKCLIPPING; 545 546 while (GLINT_READ_REG(DMACount) != 0); 547 GLINT_WAIT(3); 548 GLINT_WRITE_REG(3, BroadcastMask); /* hack! this shouldn't need to be reloaded */ 549 GLINT_WRITE_REG(0x400, FilterMode); 550 GLINT_WRITE_REG(0, GlintSync); 551 552 /* Read 1st PM3 until Sync Tag shows */ 553 ACCESSCHIP1(); 554 do { 555 while(GLINT_READ_REG(OutFIFOWords) == 0); 556 } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); 557 558 ACCESSCHIP2(); 559 /* Read 2nd PM3 until Sync Tag shows */ 560 do { 561 while(GLINT_READ_REG(OutFIFOWords) == 0); 562 } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); 563 564 ACCESSCHIP1(); 565} 566 567static void 568Permedia3SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) 569{ 570 GLINTPtr pGlint = GLINTPTR(pScrn); 571 GLINT_WAIT(3); 572 GLINT_WRITE_REG(((y1&0x0fff)<<16)|(x1&0x0fff), ScissorMinXY); 573 GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMaxXY); 574 GLINT_WRITE_REG(1, ScissorMode); 575 pGlint->ClippingOn = TRUE; 576} 577static void 578Permedia3DisableClipping(ScrnInfoPtr pScrn) 579{ 580 GLINTPtr pGlint = GLINTPTR(pScrn); 581 CHECKCLIPPING; 582} 583 584/* ScreenToScreenCopy definition */ 585static void 586Permedia3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 587 int xdir, int ydir, int rop, 588 unsigned int planemask, int transparency_color) 589{ 590 GLINTPtr pGlint = GLINTPTR(pScrn); 591 TRACE_ENTER("Permedia3SetupForScreenToScreenCopy"); 592 593 pGlint->PM3_Render2D = 594 PM3Render2D_SpanOperation | 595 PM3Render2D_Operation_Normal; 596 597 pGlint->ClippingOn = TRUE; 598 599 pGlint->PM3_Config2D = 600 PM3Config2D_UserScissorEnable | 601 PM3Config2D_ForegroundROPEnable | 602 PM3Config2D_ForegroundROP(rop) | 603 PM3Config2D_FBWriteEnable; 604 605 if (xdir == 1) pGlint->PM3_Render2D |= PM3Render2D_XPositive; 606 if (ydir == 1) pGlint->PM3_Render2D |= PM3Render2D_YPositive; 607 608 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXnoop)&&(rop!=GXinvert)) { 609 pGlint->PM3_Render2D |= PM3Render2D_FBSourceReadEnable; 610 pGlint->PM3_Config2D |= PM3Config2D_Blocking; 611 } 612 613 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 614 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 615 616 GLINT_WAIT(2); 617 PM3_PLANEMASK(planemask); 618 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 619 620 TRACE_EXIT("Permedia3SetupForScreenToScreenCopy"); 621} 622static void 623Permedia3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 624 int x2, int y2, int w, int h) 625{ 626 GLINTPtr pGlint = GLINTPTR(pScrn); 627 /* Spans needs to be 32 bit aligned. */ 628 int x_align = x1 & 0x1f; 629 TRACE_ENTER("Permedia3SubsequentScreenToScreenCopy"); 630 GLINT_WAIT(5); 631 GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMinXY); 632 GLINT_WRITE_REG((((y2+h)&0x0fff)<<16)|((x2+w)&0x0fff), ScissorMaxXY); 633 GLINT_WRITE_REG( 634 PM3RectanglePosition_XOffset(x2-x_align) | 635 PM3RectanglePosition_YOffset(y2), 636 PM3RectanglePosition); 637 GLINT_WRITE_REG( 638 PM3FBSourceReadBufferOffset_XOffset(x1-x2)| 639 PM3FBSourceReadBufferOffset_YOffset(y1-y2), 640 PM3FBSourceReadBufferOffset); 641 GLINT_WRITE_REG(pGlint->PM3_Render2D | 642 PM3Render2D_Width(w+x_align)| 643 PM3Render2D_Height(h), 644 PM3Render2D); 645 TRACE_EXIT("Permedia3SubsequentScreenToScreenCopy"); 646} 647 648/* Solid Fills */ 649static void 650Permedia3SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, 651 int rop, unsigned int planemask) 652{ 653 GLINTPtr pGlint = GLINTPTR(pScrn); 654 TRACE_ENTER("Permedia3SetupForFillRectSolid"); 655 /* Prepare Common Render2D & Config2D data */ 656 pGlint->PM3_Render2D = 657 PM3Render2D_XPositive | 658 PM3Render2D_YPositive | 659 PM3Render2D_Operation_Normal; 660 pGlint->PM3_Config2D = 661 PM3Config2D_UseConstantSource | 662 PM3Config2D_ForegroundROPEnable | 663 PM3Config2D_ForegroundROP(rop) | 664 PM3Config2D_FBWriteEnable; 665 GLINT_WAIT(3); 666 REPLICATE(color); 667 /* We can't do block fills properly at 32bpp, so we can stick the chip 668 * into 16bpp and double the width and xcoord, but it seems that at 669 * extremely high resolutions (above 1600) it doesn't fill. 670 * so, we fall back to the slower span filling method. 671 */ 672 if ((rop == GXcopy) && (pScrn->bitsPerPixel == 32) && 673 (pScrn->displayWidth <= 1600)) { 674 pGlint->AccelInfoRec->SubsequentSolidFillRect = 675 Permedia3SubsequentFillRectSolid32bpp; 676 if (pGlint->PM3_UsingSGRAM) { 677 GLINT_WRITE_REG(color, PM3FBBlockColor); 678 } else { 679 pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; 680 GLINT_WRITE_REG(color, PM3ForegroundColor); 681 } 682 } else { 683 pGlint->AccelInfoRec->SubsequentSolidFillRect = 684 Permedia3SubsequentFillRectSolid; 685 /* Can't do block fills at 8bpp either */ 686 if ((rop == GXcopy) && (pScrn->bitsPerPixel == 16)) { 687 if (pGlint->PM3_UsingSGRAM) { 688 GLINT_WRITE_REG(color, PM3FBBlockColor); 689 } else { 690 pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; 691 GLINT_WRITE_REG(color, PM3ForegroundColor); 692 } 693 } else { 694 pGlint->PM3_Render2D |= PM3Render2D_SpanOperation; 695 GLINT_WRITE_REG(color, PM3ForegroundColor); 696 } 697 } 698 PM3_PLANEMASK(planemask); 699 if (((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 700 || ((planemask != 0xffffffff) && !(pGlint->PM3_UsingSGRAM))) 701 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 702 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 703 TRACE_EXIT("Permedia3SetupForFillRectSolid"); 704} 705 706static void 707Permedia3SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) 708{ 709 GLINTPtr pGlint = GLINTPTR(pScrn); 710 TRACE_ENTER("Permedia3SubsequentFillRectSolid"); 711 712 GLINT_WAIT(2); 713 GLINT_WRITE_REG( 714 PM3RectanglePosition_XOffset(x) | 715 PM3RectanglePosition_YOffset(y), 716 PM3RectanglePosition); 717 GLINT_WRITE_REG(pGlint->PM3_Render2D | 718 PM3Render2D_Width(w) | PM3Render2D_Height(h), 719 PM3Render2D); 720 721 TRACE_EXIT("Permedia3SubsequentFillRectSolid"); 722} 723 724static void 725Permedia3SubsequentFillRectSolid32bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h) 726{ 727 GLINTPtr pGlint = GLINTPTR(pScrn); 728 TRACE_ENTER("Permedia3SubsequentFillRectSolid32bpp"); 729 730 GLINT_WAIT(6); 731 732 /* Put the chip into 16bpp mode */ 733 GLINT_WRITE_REG(1, PixelSize); 734 /* Now double the displayWidth */ 735 GLINT_WRITE_REG( 736 PM3FBWriteBufferWidth_Width(pScrn->displayWidth<<1), 737 PM3FBWriteBufferWidth0); 738 739 /* and double the x,w coords */ 740 GLINT_WRITE_REG( 741 PM3RectanglePosition_XOffset(x<<1) | 742 PM3RectanglePosition_YOffset(y), 743 PM3RectanglePosition); 744 GLINT_WRITE_REG(pGlint->PM3_Render2D | 745 PM3Render2D_Width(w<<1) | PM3Render2D_Height(h), 746 PM3Render2D); 747 748 /* Now fixup */ 749 GLINT_WRITE_REG( 750 PM3FBWriteBufferWidth_Width(pScrn->displayWidth), 751 PM3FBWriteBufferWidth0); 752 GLINT_WRITE_REG(0, PixelSize); 753 TRACE_EXIT("Permedia3SubsequentFillRectSolid32bpp"); 754} 755 756/* 8x8 Mono Pattern Fills */ 757static void 758Permedia3SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 759 int patternx, int patterny, 760 int fg, int bg, int rop, 761 unsigned int planemask) 762{ 763 GLINTPtr pGlint = GLINTPTR(pScrn); 764 TRACE_ENTER("Permedia3SetupForMono8x8PatternFill"); 765 REPLICATE(fg); 766 pGlint->PM3_Render2D = 767 PM3Render2D_AreaStippleEnable | 768 PM3Render2D_SpanOperation | 769 PM3Render2D_XPositive | 770 PM3Render2D_YPositive | 771 PM3Render2D_Operation_Normal; 772 pGlint->PM3_Config2D = 773 PM3Config2D_UseConstantSource | 774 PM3Config2D_ForegroundROPEnable | 775 PM3Config2D_ForegroundROP(rop) | 776 PM3Config2D_FBWriteEnable; 777 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 778 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 779 pGlint->PM3_AreaStippleMode = 1; 780/* Mirror stipple pattern horizontally */ 781#if X_BYTE_ORDER == X_BIG_ENDIAN 782 pGlint->PM3_AreaStippleMode |= (1<<18); 783#endif 784 pGlint->PM3_AreaStippleMode |= (2<<1); 785 pGlint->PM3_AreaStippleMode |= (2<<4); 786 if (bg != -1) { 787 REPLICATE(bg); 788 pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; 789 pGlint->PM3_AreaStippleMode |= 1<<20; 790 GLINT_WAIT(12); 791 GLINT_WRITE_REG(bg, BackgroundColor); 792 } 793 else GLINT_WAIT(11); 794 GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0); 795 GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1); 796 GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2); 797 GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3); 798 GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4); 799 GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5); 800 GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6); 801 GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7); 802 GLINT_WRITE_REG(fg, PM3ForegroundColor); 803 PM3_PLANEMASK(planemask); 804 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 805 TRACE_EXIT("Permedia3SetupForMono8x8PatternFill"); 806} 807static void 808Permedia3SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 809 int x_offset, int y_offset, 810 int x, int y, int w, int h) 811{ 812 GLINTPtr pGlint = GLINTPTR(pScrn); 813 TRACE_ENTER("Permedia3SubsequentMono8x8PatternFillRect"); 814 GLINT_WAIT(3); 815 GLINT_WRITE_REG( 816 PM3RectanglePosition_XOffset(x) | 817 PM3RectanglePosition_YOffset(y), 818 PM3RectanglePosition); 819 GLINT_WRITE_REG( 820 (x_offset&0x7)<<7 | (y_offset&0x7)<<12 | 821 pGlint->PM3_AreaStippleMode, 822 AreaStippleMode); 823 GLINT_WRITE_REG(pGlint->PM3_Render2D | 824 PM3Render2D_Width(w) | PM3Render2D_Height(h), 825 PM3Render2D); 826 TRACE_EXIT("Permedia3SubsequentMono8x8PatternFillRect"); 827} 828 829static void 830Permedia3SetupForScanlineCPUToScreenColorExpandFill( 831 ScrnInfoPtr pScrn, 832 int fg, int bg, 833 int rop, 834 unsigned int planemask 835){ 836 GLINTPtr pGlint = GLINTPTR(pScrn); 837 838 REPLICATE(fg); 839 pGlint->PM3_Render2D = 840 PM3Render2D_SpanOperation | 841 PM3Render2D_XPositive | 842 PM3Render2D_YPositive | 843 PM3Render2D_Operation_SyncOnBitMask; 844 pGlint->PM3_Config2D = 845 PM3Config2D_UserScissorEnable | 846 PM3Config2D_UseConstantSource | 847 PM3Config2D_ForegroundROPEnable | 848 PM3Config2D_ForegroundROP(rop) | 849 PM3Config2D_FBWriteEnable; 850 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 851 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 852 if (bg != -1) { 853 REPLICATE(bg); 854 pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; 855 GLINT_WAIT(4); 856 GLINT_WRITE_REG(bg, BackgroundColor); 857 } 858 else GLINT_WAIT(3); 859 GLINT_WRITE_REG(fg, PM3ForegroundColor); 860 PM3_PLANEMASK(planemask); 861 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 862} 863 864static void 865Permedia3SubsequentScanlineCPUToScreenColorExpandFill( 866 ScrnInfoPtr pScrn, 867 int x, int y, int w, int h, 868 int skipleft 869){ 870 GLINTPtr pGlint = GLINTPTR(pScrn); 871 872 TRACE_ENTER("Permedia2SubsequentScanlineCPUToScreenColorExpandFill"); 873 874 pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ 875 876 pGlint->cpucount = h; 877 878 GLINT_WAIT(5); 879 GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); 880 GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); 881 GLINT_WRITE_REG( 882 PM3RectanglePosition_XOffset(x) | 883 PM3RectanglePosition_YOffset(y), 884 PM3RectanglePosition); 885 GLINT_WRITE_REG(pGlint->PM3_Render2D | 886 PM3Render2D_Width(w) | PM3Render2D_Height(h), 887 PM3Render2D); 888 889#if defined(__alpha__) 890 if (0) /* force Alpha to use indirect always */ 891#else 892 if ((pGlint->dwords*h) < pGlint->FIFOSize) 893#endif 894 { 895 /* Turn on direct for less than 120 dword colour expansion */ 896 pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; 897 pGlint->ScanlineDirect = 1; 898 GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); 899 GLINT_WAIT(pGlint->dwords*h); 900 } else { 901 /* Use indirect for anything else */ 902 pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; 903 pGlint->ScanlineDirect = 0; 904 } 905 906 pGlint->cpucount--; 907} 908 909static void 910Permedia3SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 911{ 912 GLINTPtr pGlint = GLINTPTR(pScrn); 913 CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; 914 int dwords = pGlint->dwords; 915 916 if (!pGlint->ScanlineDirect) { 917 while(dwords >= pGlint->FIFOSize) { 918 GLINT_WAIT(pGlint->FIFOSize); 919 GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); 920 GLINT_MoveDWORDS( 921 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 922 (CARD32*)srcp, pGlint->FIFOSize - 1); 923 dwords -= pGlint->FIFOSize - 1; 924 srcp += pGlint->FIFOSize - 1; 925 } 926 if(dwords) { 927 GLINT_WAIT(dwords + 1); 928 GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); 929 GLINT_MoveDWORDS( 930 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 931 (CARD32*)srcp, dwords); 932 } 933 } 934} 935 936/* Images Writes */ 937static void Permedia3SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 938 unsigned int planemask, int trans_color, int bpp, int depth) 939{ 940 GLINTPtr pGlint = GLINTPTR(pScrn); 941 TRACE_ENTER("Permedia3SetupForScanlineImageWrite"); 942 pGlint->PM3_Render2D = 943 PM3Render2D_SpanOperation | 944 PM3Render2D_XPositive | 945 PM3Render2D_YPositive | 946 PM3Render2D_Operation_SyncOnHostData; 947 pGlint->PM3_Config2D = 948 PM3Config2D_UserScissorEnable | 949 PM3Config2D_ForegroundROPEnable | 950 PM3Config2D_ForegroundROP(rop) | 951 PM3Config2D_FBWriteEnable; 952 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 953 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 954 GLINT_WAIT(2); 955 PM3_PLANEMASK(planemask); 956 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 957 TRACE_EXIT("Permedia3SetupForScanlineImageWrite"); 958} 959 960static void Permedia3SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, 961 int x, int y, int w, int h, int skipleft) 962{ 963 GLINTPtr pGlint = GLINTPTR(pScrn); 964 TRACE_ENTER("Permedia3SubsequentScanlineImageWrite"); 965 pGlint->dwords = (((w * pScrn->bitsPerPixel) + 3) >> 2); /* per scanline */ 966 967 pGlint->cpucount = h; 968 GLINT_WAIT(5); 969 GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); 970 GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); 971 GLINT_WRITE_REG( 972 PM3RectanglePosition_XOffset(x) | 973 PM3RectanglePosition_YOffset(y), 974 PM3RectanglePosition); 975 GLINT_WRITE_REG(pGlint->PM3_Render2D | 976 PM3Render2D_Width(w) | PM3Render2D_Height(h), 977 PM3Render2D); 978 979#if defined(__alpha__) 980 if (0) /* force Alpha to use indirect always */ 981#else 982 if (pGlint->dwords < pGlint->FIFOSize) 983#endif 984 { 985 /* Turn on direct for less than 120 dword colour expansion */ 986 pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; 987 pGlint->ScanlineDirect = 1; 988 GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | (0x15<<4) | 0x05, 989 OutputFIFO); 990 GLINT_WAIT(pGlint->dwords); 991 } else { 992 /* Use indirect for anything else */ 993 pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; 994 pGlint->ScanlineDirect = 0; 995 } 996 997 pGlint->cpucount--; 998 TRACE_EXIT("Permedia3SubsequentScanlineImageWrite"); 999} 1000 1001static void 1002Permedia3SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 1003{ 1004 GLINTPtr pGlint = GLINTPTR(pScrn); 1005 int dwords = pGlint->dwords; 1006 1007 if (pGlint->ScanlineDirect) { 1008 if (pGlint->cpucount--) 1009 GLINT_WAIT(dwords); 1010 return; 1011 } else { 1012 while(dwords >= pGlint->FIFOSize) { 1013 GLINT_WAIT(pGlint->FIFOSize); 1014 GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 1015 0x05, OutputFIFO); 1016 GLINT_MoveDWORDS( 1017 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1018 (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno], 1019 pGlint->FIFOSize - 1); 1020 dwords -= pGlint->FIFOSize - 1; 1021 } 1022 if(dwords) { 1023 GLINT_WAIT(dwords + 1); 1024 GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | 1025 0x05, OutputFIFO); 1026 GLINT_MoveDWORDS( 1027 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1028 (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno], 1029 dwords); 1030 } 1031 } 1032} 1033 1034static void 1035Permedia3RestoreAccelState(ScrnInfoPtr pScrn) 1036{ 1037 GLINTPtr pGlint = GLINTPTR(pScrn); 1038 if ((IS_J2000) && (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) { 1039 GLINT_SLOW_WRITE_REG(pGlint->MultiIndex, BroadcastMask); 1040 } 1041 Permedia3Sync(pScrn); 1042} 1043 1044static void 1045Permedia3WritePixmap( 1046 ScrnInfoPtr pScrn, 1047 int x, int y, int w, int h, 1048 unsigned char *src, 1049 int srcwidth, 1050 int rop, 1051 unsigned int planemask, 1052 int trans, 1053 int bpp, int depth 1054) 1055{ 1056 int dwords; 1057 int count; 1058 int skipleft = (long)src & 0x03L; 1059 int Bpp = bpp >> 3; 1060 CARD32 *srcp; 1061 GLINTPtr pGlint = GLINTPTR(pScrn); 1062 TRACE_ENTER("Permedia3WritePixmap"); 1063 1064 if (skipleft) { 1065 /* Skipleft is either 1066 * - 0, 1, 2 or 3 in 8 bpp 1067 * - 0 or 1 in 16 bpp 1068 * - 0 in 32 bpp 1069 */ 1070 skipleft /= Bpp; 1071 1072 x -= skipleft; 1073 w += skipleft; 1074 1075 src = (unsigned char*)((long)src & ~0x03L); 1076 } 1077 1078 pGlint->PM3_Render2D = 1079 PM3Render2D_SpanOperation | 1080 PM3Render2D_XPositive | 1081 PM3Render2D_YPositive | 1082 PM3Render2D_Operation_SyncOnHostData; 1083 pGlint->PM3_Config2D = 1084 PM3Config2D_UserScissorEnable | 1085 PM3Config2D_ForegroundROPEnable | 1086 PM3Config2D_ForegroundROP(rop) | 1087 PM3Config2D_FBWriteEnable; 1088 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 1089 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 1090 GLINT_WAIT(6); 1091 PM3_PLANEMASK(planemask); 1092 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 1093 GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); 1094 GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); 1095 GLINT_WRITE_REG( 1096 PM3RectanglePosition_XOffset(x) | 1097 PM3RectanglePosition_YOffset(y), 1098 PM3RectanglePosition); 1099 GLINT_WRITE_REG(pGlint->PM3_Render2D | 1100 PM3Render2D_Width(w) | PM3Render2D_Height(h), 1101 PM3Render2D); 1102 /* width of the stuff to copy in 32 bit words */ 1103 dwords = ((w * Bpp) + 3) >> 2; 1104 1105 while(h--) { 1106 count = dwords; 1107 srcp = (CARD32*)src; 1108 while(count >= pGlint->FIFOSize) { 1109 GLINT_WAIT(pGlint->FIFOSize); 1110 /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ 1111 GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 1112 0x05, OutputFIFO); 1113 GLINT_MoveDWORDS( 1114 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1115 (CARD32*)srcp, pGlint->FIFOSize - 1); 1116 count -= pGlint->FIFOSize - 1; 1117 srcp += pGlint->FIFOSize - 1; 1118 } 1119 if(count) { 1120 GLINT_WAIT(count + 1); 1121 /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ 1122 GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | 1123 0x05, OutputFIFO); 1124 GLINT_MoveDWORDS( 1125 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1126 (CARD32*)srcp, count); 1127 } 1128 src += srcwidth; 1129 } 1130 1131 Permedia3DisableClipping(pScrn); 1132 Permedia3Sync(pScrn); 1133} 1134 1135static void 1136Permedia3WriteBitmap(ScrnInfoPtr pScrn, 1137 int x, int y, int w, int h, 1138 unsigned char *src, 1139 int srcwidth, int skipleft, 1140 int fg, int bg, int rop, 1141 unsigned int planemask 1142) 1143{ 1144 int dwords; 1145 GLINTPtr pGlint = GLINTPTR(pScrn); 1146 int count; 1147 CARD32 *srcp; 1148 TRACE_ENTER("Permedia3WriteBitmap"); 1149 1150 w += skipleft; 1151 x -= skipleft; 1152 dwords = (w + 31) >>5; 1153 1154 REPLICATE(fg); 1155 pGlint->PM3_Render2D = 1156 PM3Render2D_SpanOperation | 1157 PM3Render2D_XPositive | 1158 PM3Render2D_YPositive | 1159 PM3Render2D_Operation_SyncOnBitMask; 1160 pGlint->PM3_Config2D = 1161 PM3Config2D_UserScissorEnable | 1162 PM3Config2D_UseConstantSource | 1163 PM3Config2D_ForegroundROPEnable | 1164 PM3Config2D_ForegroundROP(rop) | 1165 PM3Config2D_FBWriteEnable; 1166 if ((rop!=GXclear)&&(rop!=GXset)&&(rop!=GXcopy)&&(rop!=GXcopyInverted)) 1167 pGlint->PM3_Config2D |= PM3Config2D_FBDestReadEnable; 1168 if (bg != -1) { 1169 REPLICATE(bg); 1170 pGlint->PM3_Config2D |= PM3Config2D_OpaqueSpan; 1171 GLINT_WAIT(8); 1172 GLINT_WRITE_REG(bg, BackgroundColor); 1173 } 1174 else GLINT_WAIT(7); 1175 GLINT_WRITE_REG(fg, PM3ForegroundColor); 1176 PM3_PLANEMASK(planemask); 1177 GLINT_WRITE_REG(pGlint->PM3_Config2D, PM3Config2D); 1178 GLINT_WRITE_REG(((y&0x0fff)<<16)|((x+skipleft)&0x0fff), ScissorMinXY); 1179 GLINT_WRITE_REG((((y+h)&0x0fff)<<16)|((x+w)&0x0fff), ScissorMaxXY); 1180 GLINT_WRITE_REG( 1181 PM3RectanglePosition_XOffset(x) | 1182 PM3RectanglePosition_YOffset(y), 1183 PM3RectanglePosition); 1184 GLINT_WRITE_REG(pGlint->PM3_Render2D | 1185 PM3Render2D_Width(w) | PM3Render2D_Height(h), 1186 PM3Render2D); 1187 1188 while(h--) { 1189 count = dwords; 1190 srcp = (CARD32*)src; 1191 while(count >= pGlint->FIFOSize) { 1192 GLINT_WAIT(pGlint->FIFOSize); 1193 GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 1194 0x0D, OutputFIFO); 1195 GLINT_MoveDWORDS( 1196 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1197 (CARD32*)srcp, pGlint->FIFOSize - 1); 1198 count -= pGlint->FIFOSize - 1; 1199 srcp += pGlint->FIFOSize - 1; 1200 } 1201 if(count) { 1202 GLINT_WAIT(count + 1); 1203 GLINT_WRITE_REG(((count - 1) << 16) | 0x0D, OutputFIFO); 1204 GLINT_MoveDWORDS( 1205 (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 1206 (CARD32*)srcp, count); 1207 } 1208 src += srcwidth; 1209 } 1210 1211 Permedia3DisableClipping(pScrn); 1212 Permedia3Sync(pScrn); 1213} 1214#endif 1215