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