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