s3_accel.c revision bd35f0db
1340e3fbdSmrg/* 2340e3fbdSmrg * Copyright 2001 Ani Joshi <ajoshi@unixbox.com> 3340e3fbdSmrg * 4340e3fbdSmrg * XFree86 4.x driver for S3 chipsets 5340e3fbdSmrg * 6340e3fbdSmrg * 7340e3fbdSmrg * Permission to use, copy, modify, distribute, and sell this software and its 8340e3fbdSmrg * documentation for any purpose is hereby granted without fee, provided that 9340e3fbdSmrg * the above copyright notice appear in all copies and that both that copyright 10340e3fbdSmrg * notice and this permission notice appear in supporting documentation and 11340e3fbdSmrg * that the name of Ani Joshi not be used in advertising or 12340e3fbdSmrg * publicity pertaining to distribution of the software without specific, 13340e3fbdSmrg * written prior permission. Ani Joshi makes no representations 14340e3fbdSmrg * about the suitability of this software for any purpose. It is provided 15340e3fbdSmrg * "as-is" without express or implied warranty. 16340e3fbdSmrg * 17340e3fbdSmrg * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18340e3fbdSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19340e3fbdSmrg * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20340e3fbdSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21340e3fbdSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22340e3fbdSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23340e3fbdSmrg * PERFORMANCE OF THIS SOFTWARE. 24340e3fbdSmrg * 25340e3fbdSmrg * 26340e3fbdSmrg */ 27340e3fbdSmrg 28340e3fbdSmrg#ifdef HAVE_CONFIG_H 29340e3fbdSmrg#include "config.h" 30340e3fbdSmrg#endif 31340e3fbdSmrg 32340e3fbdSmrg#include "xf86.h" 33340e3fbdSmrg 34340e3fbdSmrg#include "miline.h" 35340e3fbdSmrg 36340e3fbdSmrg#include "s3.h" 37340e3fbdSmrg#include "s3_reg.h" 38340e3fbdSmrg 39340e3fbdSmrg 40340e3fbdSmrg#if 0 41340e3fbdSmrgstatic Bool NicePattern; 42340e3fbdSmrgstatic int DashPatternSize; 43340e3fbdSmrg#define MAX_LINE_PATTERN_LENGTH 512 44340e3fbdSmrg#define LINE_PATTERN_START ((MAX_LINE_PATTERN_LENGTH >> 5) - 1) 45340e3fbdSmrgstatic CARD32 DashPattern[MAX_LINE_PATTERN_LENGTH >> 5]; 46340e3fbdSmrg#endif 47340e3fbdSmrg 48340e3fbdSmrg 49340e3fbdSmrgstatic void S3Sync(ScrnInfoPtr pScrn) 50340e3fbdSmrg{ 51340e3fbdSmrg WaitIdle(); 52340e3fbdSmrg} 53340e3fbdSmrg 54340e3fbdSmrgstatic void S3SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 55340e3fbdSmrg unsigned int planemask) 56340e3fbdSmrg{ 57340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 58340e3fbdSmrg 59340e3fbdSmrg WaitQueue16_32(4,6); 60340e3fbdSmrg SET_PIX_CNTL(0); 61340e3fbdSmrg SET_FRGD_COLOR(color); 62340e3fbdSmrg SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]); 63340e3fbdSmrg SET_WRT_MASK(planemask); 64340e3fbdSmrg} 65340e3fbdSmrg 66340e3fbdSmrgstatic void S3SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, 67340e3fbdSmrg int w, int h) 68340e3fbdSmrg{ 69340e3fbdSmrg#ifdef S3_NEWMMIO 70340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 71340e3fbdSmrg#endif 72340e3fbdSmrg 73340e3fbdSmrg WaitQueue(5); 74340e3fbdSmrg SET_CURPT((short)x, (short)y); 75340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 76340e3fbdSmrg SET_CMD(CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA); 77340e3fbdSmrg} 78340e3fbdSmrg 79340e3fbdSmrg 80340e3fbdSmrgstatic void S3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, 81340e3fbdSmrg int ydir, int rop, 82340e3fbdSmrg unsigned int planemask, 83340e3fbdSmrg int trans_color) 84340e3fbdSmrg{ 85340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 86340e3fbdSmrg 87340e3fbdSmrg pS3->BltDir = CMD_BITBLT | DRAW | WRTDATA; 88340e3fbdSmrg 89340e3fbdSmrg if (xdir == 1) 90340e3fbdSmrg pS3->BltDir |= INC_X; 91340e3fbdSmrg if (ydir == 1) 92340e3fbdSmrg pS3->BltDir |= INC_Y; 93340e3fbdSmrg 94340e3fbdSmrg pS3->trans_color = trans_color; 95340e3fbdSmrg 96340e3fbdSmrg WaitQueue16_32(3,4); 97340e3fbdSmrg SET_PIX_CNTL(0); 98340e3fbdSmrg SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]); 99340e3fbdSmrg SET_WRT_MASK(planemask); 100340e3fbdSmrg} 101340e3fbdSmrg 102340e3fbdSmrg 103340e3fbdSmrgstatic void S3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 104340e3fbdSmrg int srcx, int srcy, 105340e3fbdSmrg int dstx, int dsty, 106340e3fbdSmrg int w, int h) 107340e3fbdSmrg{ 108340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 109340e3fbdSmrg 110340e3fbdSmrg w--; 111340e3fbdSmrg h--; 112340e3fbdSmrg 113340e3fbdSmrg if (!(pS3->BltDir & INC_Y)) { 114340e3fbdSmrg srcy += h; 115340e3fbdSmrg dsty += h; 116340e3fbdSmrg } 117340e3fbdSmrg 118340e3fbdSmrg if (!(pS3->BltDir & INC_X)) { 119340e3fbdSmrg srcx += w; 120340e3fbdSmrg dstx += w; 121340e3fbdSmrg } 122340e3fbdSmrg 123340e3fbdSmrg if (pS3->trans_color == -1) { 124340e3fbdSmrg WaitQueue(7); 125340e3fbdSmrg SET_CURPT((short)srcx, (short)srcy); 126340e3fbdSmrg SET_DESTSTP((short)dstx, (short)dsty); 127340e3fbdSmrg SET_AXIS_PCNT((short)w, (short)h); 128340e3fbdSmrg SET_CMD(pS3->BltDir); 129340e3fbdSmrg } else { 130340e3fbdSmrg WaitQueue16_32(2,3); 131340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH | 0x0100); 132340e3fbdSmrg SET_COLOR_CMP(pS3->trans_color); 133340e3fbdSmrg 134340e3fbdSmrg WaitQueue(8); 135340e3fbdSmrg SET_CURPT((short)srcx, (short)srcy); 136340e3fbdSmrg SET_DESTSTP((short)dstx, (short)dsty); 137340e3fbdSmrg SET_AXIS_PCNT((short)w, (short)h); 138340e3fbdSmrg SET_CMD(pS3->BltDir); 139340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH); 140340e3fbdSmrg } 141340e3fbdSmrg} 142340e3fbdSmrg 143bd35f0dbSahoka#if 0 144340e3fbdSmrgstatic void S3SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, 145340e3fbdSmrg int patx, int paty, 146340e3fbdSmrg int rop, unsigned int planemask, 147340e3fbdSmrg int trans_color) 148340e3fbdSmrg{ 149340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 150340e3fbdSmrg 151340e3fbdSmrg pS3->trans_color = trans_color; 152340e3fbdSmrg 153340e3fbdSmrg WaitQueue16_32(3,4); 154340e3fbdSmrg SET_PIX_CNTL(0); 155340e3fbdSmrg SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]); 156340e3fbdSmrg SET_WRT_MASK(planemask); 157340e3fbdSmrg} 158340e3fbdSmrg 159340e3fbdSmrgstatic void S3SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, 160340e3fbdSmrg int patx, int paty, 161340e3fbdSmrg int x, int y, 162340e3fbdSmrg int w, int h) 163340e3fbdSmrg{ 164340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 165340e3fbdSmrg 166340e3fbdSmrg if (pS3->trans_color == -1) { 167340e3fbdSmrg WaitQueue(7); 168340e3fbdSmrg SET_CURPT((short)patx, (short)paty); 169340e3fbdSmrg SET_DESTSTP((short)x, (short)y); 170340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 171340e3fbdSmrg SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA); 172340e3fbdSmrg } else { 173340e3fbdSmrg WaitQueue16_32(2,3); 174340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH | 0x0100); 175340e3fbdSmrg SET_COLOR_CMP(pS3->trans_color); 176340e3fbdSmrg 177340e3fbdSmrg WaitQueue(8); 178340e3fbdSmrg SET_CURPT((short)patx, (short)paty); 179340e3fbdSmrg SET_DESTSTP((short)x, (short)y); 180340e3fbdSmrg SET_AXIS_PCNT(w - 1, h - 1); 181340e3fbdSmrg SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA); 182340e3fbdSmrg SET_MULT_MISC(CMD_REG_WIDTH); 183340e3fbdSmrg } 184340e3fbdSmrg} 185bd35f0dbSahoka#endif 186340e3fbdSmrg 187340e3fbdSmrg#ifdef S3_NEWMMIO 188340e3fbdSmrgstatic void S3SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 189340e3fbdSmrg int fg, int bg, 190340e3fbdSmrg int rop, 191340e3fbdSmrg unsigned int planemask) 192340e3fbdSmrg{ 193340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 194340e3fbdSmrg 195340e3fbdSmrg WaitQueue16_32(3,4); 196340e3fbdSmrg if (bg == -1) { 197340e3fbdSmrg if (pS3->ColorExpandBug) { 198340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_XOR); 199340e3fbdSmrg SET_BKGD_COLOR(0); 200340e3fbdSmrg } else 201340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_DST); 202340e3fbdSmrg } else { 203340e3fbdSmrg SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | s3alu[rop]); 204340e3fbdSmrg SET_BKGD_COLOR(bg); 205340e3fbdSmrg } 206340e3fbdSmrg 207340e3fbdSmrg WaitQueue16_32(3,5); 208340e3fbdSmrg SET_FRGD_COLOR(fg); 209340e3fbdSmrg SET_WRT_MASK(planemask); 210340e3fbdSmrg SET_PIX_CNTL(MIXSEL_EXPPC); 211340e3fbdSmrg} 212340e3fbdSmrg 213340e3fbdSmrg 214340e3fbdSmrgstatic void S3SubsequentCPUToScreenColorExpandFill32(ScrnInfoPtr pScrn, 215340e3fbdSmrg int x, int y, 216340e3fbdSmrg int w, int h, 217340e3fbdSmrg int skipleft) 218340e3fbdSmrg{ 219340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 220340e3fbdSmrg 221340e3fbdSmrg WaitQueue(4); 222340e3fbdSmrg SET_CURPT((short)x, (short)y); 223340e3fbdSmrg SET_AXIS_PCNT((short)w-1, (short)h-1); 224340e3fbdSmrg 225340e3fbdSmrg WaitIdle(); 226340e3fbdSmrg SET_CMD(CMD_RECT | BYTSEQ | _32BIT | PCDATA | DRAW | 227340e3fbdSmrg PLANAR | INC_Y | INC_X | WRTDATA); 228340e3fbdSmrg} 229340e3fbdSmrg#endif 230340e3fbdSmrg 231340e3fbdSmrg#if 0 232340e3fbdSmrg#ifndef S3_NEWMMIO 233340e3fbdSmrg 234340e3fbdSmrgstatic void S3SetupForScanlineImageWriteNoMMIO(ScrnInfoPtr pScrn, int rop, 235340e3fbdSmrg unsigned int planemask, 236340e3fbdSmrg int trans_color, 237340e3fbdSmrg int bpp, int depth) 238340e3fbdSmrg{ 239340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 240340e3fbdSmrg 241340e3fbdSmrg WaitQueue16_32(3,4) 242340e3fbdSmrg SET_FRGD_MIX(FSS_PCDATA | s3alu[rop]); 243340e3fbdSmrg SET_WRT_MASK(planemask); 244340e3fbdSmrg SET_PIX_CNTL(0); 245340e3fbdSmrg} 246340e3fbdSmrg 247340e3fbdSmrgstatic void S3SubsequentScanlineImageWriteRectNoMMIO(ScrnInfoPtr pScrn, 248340e3fbdSmrg int x, int y, 249340e3fbdSmrg int w, int h, 250340e3fbdSmrg int skipleft) 251340e3fbdSmrg{ 252340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 253340e3fbdSmrg 254340e3fbdSmrg pS3->imageWidth = w; 255340e3fbdSmrg pS3->imageHeight = h; 256340e3fbdSmrg 257340e3fbdSmrg WaitQueue(5); 258340e3fbdSmrg SET_CURPT((short)x, (short)y); 259340e3fbdSmrg SET_AXIS_PCNT((short)w-1, (short)h-1); 260340e3fbdSmrg WaitIdle(); 261340e3fbdSmrg SET_CMD(CMD_RECT | BYTSEQ | _16BIT | INC_Y | INC_X | DRAW | 262340e3fbdSmrg PCDATA | WRTDATA); 263340e3fbdSmrg} 264340e3fbdSmrg 265340e3fbdSmrg 266340e3fbdSmrgstatic void S3SubsequentImageWriteScanlineNoMMIO(ScrnInfoPtr pScrn, 267340e3fbdSmrg int bufno) 268340e3fbdSmrg{ 269340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 270340e3fbdSmrg int i, j; 271340e3fbdSmrg int w, h; 272340e3fbdSmrg CARD16 *src = (CARD16 *)&pS3->imageBuffer; 273340e3fbdSmrg 274340e3fbdSmrg w = pS3->imageWidth * pS3->s3Bpp; 275340e3fbdSmrg h = pS3->imageHeight; 276340e3fbdSmrg 277340e3fbdSmrg for(j=0; j<h; j++) { 278340e3fbdSmrg for(i=0; i<(w & ~1); ) { 279340e3fbdSmrg /* XXX not for 32bpp */ 280340e3fbdSmrg SET_PIX_TRANS_W(ldw_u(src)); 281340e3fbdSmrg src++; 282340e3fbdSmrg i += 2; 283340e3fbdSmrg } 284340e3fbdSmrg } 285340e3fbdSmrg} 286340e3fbdSmrg 287340e3fbdSmrg#endif 288340e3fbdSmrg#endif 289340e3fbdSmrg 290340e3fbdSmrg 291340e3fbdSmrgstatic void S3SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 292340e3fbdSmrg unsigned int planemask) 293340e3fbdSmrg{ 294340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 295340e3fbdSmrg 296340e3fbdSmrg WaitQueue16_32(4,6); 297340e3fbdSmrg SET_PIX_CNTL(0); 298340e3fbdSmrg SET_FRGD_COLOR(color); 299340e3fbdSmrg SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]); 300340e3fbdSmrg SET_WRT_MASK(planemask); 301340e3fbdSmrg} 302340e3fbdSmrg 303340e3fbdSmrg 304340e3fbdSmrgstatic void S3SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, 305340e3fbdSmrg int x, int y, 306340e3fbdSmrg int major, int minor, 307340e3fbdSmrg int err, int len, int octant) 308340e3fbdSmrg{ 309340e3fbdSmrg#ifdef S3_NEWMMIO 310340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 311340e3fbdSmrg#endif 312340e3fbdSmrg unsigned short cmd; 313340e3fbdSmrg int error, e1, e2; 314340e3fbdSmrg 315340e3fbdSmrg error = minor + err; 316340e3fbdSmrg e1 = minor; /* was: major, wrong (twini@xfree86.org) */ 317340e3fbdSmrg e2 = minor - major; 318340e3fbdSmrg 319340e3fbdSmrg if (major) { 320340e3fbdSmrg cmd = CMD_LINE | DRAW | WRTDATA | LASTPIX; 321340e3fbdSmrg 322340e3fbdSmrg if (octant & YMAJOR) 323340e3fbdSmrg cmd |= YMAJAXIS; 324340e3fbdSmrg if (!(octant & XDECREASING)) 325340e3fbdSmrg cmd |= INC_X; 326340e3fbdSmrg if (!(octant & YDECREASING)) 327340e3fbdSmrg cmd |= INC_Y; 328340e3fbdSmrg 329340e3fbdSmrg WaitQueue(7); 330340e3fbdSmrg SET_CURPT((short)x, (short)y); 331340e3fbdSmrg SET_ERR_TERM((short)error); 332340e3fbdSmrg SET_DESTSTP((short)e2, (short)e1); 333340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len); 334340e3fbdSmrg SET_CMD(cmd); 335340e3fbdSmrg } else { 336340e3fbdSmrg WaitQueue(4); 337340e3fbdSmrg SET_CURPT((short)x, (short)y); 338340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len-1); 339340e3fbdSmrg SET_CMD(CMD_LINE | DRAW | LINETYPE | WRTDATA | VECDIR_270); 340340e3fbdSmrg } 341340e3fbdSmrg} 342340e3fbdSmrg 343340e3fbdSmrg 344340e3fbdSmrg 345340e3fbdSmrgstatic void S3SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, 346340e3fbdSmrg int x, int y, int len, int dir) 347340e3fbdSmrg{ 348340e3fbdSmrg if (dir == DEGREES_0) 349340e3fbdSmrg S3SubsequentSolidFillRect(pScrn, x, y, len, 1); 350340e3fbdSmrg else 351340e3fbdSmrg S3SubsequentSolidFillRect(pScrn, x, y, 1, len); 352340e3fbdSmrg} 353340e3fbdSmrg 354340e3fbdSmrg 355340e3fbdSmrg#if 0 356340e3fbdSmrg 357340e3fbdSmrgstatic void S3SetupForDashedLine(ScrnInfoPtr pScrn, 358340e3fbdSmrg int fg, int bg, 359340e3fbdSmrg int rop, unsigned int planemask, 360340e3fbdSmrg int len, unsigned char *pattern) 361340e3fbdSmrg{ 362340e3fbdSmrg#ifdef S3_NEWMMIO 363340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 364340e3fbdSmrg 365340e3fbdSmrg S3SetupForCPUToScreenColorExpandFill(pScrn, bg, fg, rop, planemask); 366340e3fbdSmrg#endif 367340e3fbdSmrg 368340e3fbdSmrg WaitQueue(4); 369340e3fbdSmrg 370340e3fbdSmrg NicePattern = FALSE; 371340e3fbdSmrg 372340e3fbdSmrg if (len <= 32) { 373340e3fbdSmrg register CARD32 scratch = DashPattern[LINE_PATTERN_START]; 374340e3fbdSmrg 375340e3fbdSmrg if (len & (len - 1)) { 376340e3fbdSmrg while (len < 16) { 377340e3fbdSmrg scratch |= (scratch >> len); 378340e3fbdSmrg len <<= 1; 379340e3fbdSmrg } 380340e3fbdSmrg scratch |= (scratch >> len); 381340e3fbdSmrg DashPattern[LINE_PATTERN_START] = scratch; 382340e3fbdSmrg } else { 383340e3fbdSmrg switch (len) { 384340e3fbdSmrg case 2: 385340e3fbdSmrg scratch |= scratch >> 2; 386340e3fbdSmrg case 4: 387340e3fbdSmrg scratch |= scratch >> 4; 388340e3fbdSmrg case 8: 389340e3fbdSmrg scratch |= scratch >> 8; 390340e3fbdSmrg case 16: 391340e3fbdSmrg scratch |= scratch >> 16; 392340e3fbdSmrg DashPattern[LINE_PATTERN_START] = scratch; 393340e3fbdSmrg case 32: 394340e3fbdSmrg NicePattern = TRUE; 395340e3fbdSmrg default: 396340e3fbdSmrg break; 397340e3fbdSmrg } 398340e3fbdSmrg } 399340e3fbdSmrg } 400340e3fbdSmrg 401340e3fbdSmrg DashPatternSize = len; 402340e3fbdSmrg} 403340e3fbdSmrg 404340e3fbdSmrg 405340e3fbdSmrgstatic void S3SubsequentDashedBresenhamLine32(ScrnInfoPtr pScrn, 406340e3fbdSmrg int x, int y, 407340e3fbdSmrg int absmaj, int absmin, 408340e3fbdSmrg int err, int len, 409340e3fbdSmrg int octant, int phase) 410340e3fbdSmrg{ 411340e3fbdSmrg#ifdef S3_NEWMMIO 412340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 413340e3fbdSmrg#endif 414340e3fbdSmrg register int count = (len + 31) >> 5; 415340e3fbdSmrg register CARD32 pattern; 416340e3fbdSmrg int error, e1, e2; 417340e3fbdSmrg 418340e3fbdSmrg error = absmin + err; 419340e3fbdSmrg e1 = absmaj; 420340e3fbdSmrg e2 = absmin - absmaj; 421340e3fbdSmrg 422340e3fbdSmrg if (err) { 423340e3fbdSmrg unsigned short cmd = _32BIT | PLANAR | WRTDATA | DRAW | 424340e3fbdSmrg PCDATA | LASTPIX | CMD_LINE; 425340e3fbdSmrg 426340e3fbdSmrg if (octant & YMAJOR) 427340e3fbdSmrg cmd |= YMAJAXIS; 428340e3fbdSmrg if (!(octant & XDECREASING)) 429340e3fbdSmrg cmd |= INC_X; 430340e3fbdSmrg if (!(octant & YDECREASING)) 431340e3fbdSmrg cmd |= INC_Y; 432340e3fbdSmrg 433340e3fbdSmrg WaitQueue(7); 434340e3fbdSmrg SET_CURPT((short)x, (short)y); 435340e3fbdSmrg SET_ERR_TERM((short)error); 436340e3fbdSmrg SET_DESTSTP((short)e2, (short)e1); 437340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len); 438340e3fbdSmrg SET_CMD(cmd); 439340e3fbdSmrg } else { 440340e3fbdSmrg if (octant & YMAJOR) { 441340e3fbdSmrg WaitQueue(4); 442340e3fbdSmrg SET_CURPT((short)x, (short)y); 443340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 444340e3fbdSmrg 445340e3fbdSmrg if (octant & YDECREASING) { 446340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 447340e3fbdSmrg CMD_LINE | LINETYPE | VECDIR_090); 448340e3fbdSmrg } else { 449340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 450340e3fbdSmrg CMD_LINE | LINETYPE | VECDIR_270); 451340e3fbdSmrg } 452340e3fbdSmrg } else { 453340e3fbdSmrg if (octant & XDECREASING) { 454340e3fbdSmrg WaitQueue(4); 455340e3fbdSmrg SET_CURPT((short)x, (short)y); 456340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 457340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 458340e3fbdSmrg PCDATA | CMD_LINE | LINETYPE | VECDIR_180); 459340e3fbdSmrg } else { 460340e3fbdSmrg WaitQueue(4); 461340e3fbdSmrg SET_CURPT((short)x, (short)y); 462340e3fbdSmrg SET_MAJ_AXIS_PCNT((short)len - 1); 463340e3fbdSmrg SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW | 464340e3fbdSmrg PCDATA | CMD_RECT | INC_Y | INC_X); 465340e3fbdSmrg } 466340e3fbdSmrg } 467340e3fbdSmrg } 468340e3fbdSmrg 469340e3fbdSmrg if (NicePattern) { 470340e3fbdSmrg#ifdef S3_NEWMMIO 471340e3fbdSmrg register CARD32 *dest = (CARD32*)&IMG_TRANS; 472340e3fbdSmrg#endif 473340e3fbdSmrg 474340e3fbdSmrg pattern = (phase) ? (DashPattern[LINE_PATTERN_START] << phase) | 475340e3fbdSmrg (DashPattern[LINE_PATTERN_START] >> (32 - phase)) : 476340e3fbdSmrg DashPattern[LINE_PATTERN_START]; 477340e3fbdSmrg 478340e3fbdSmrg#ifdef S3_NEWMMIO 479340e3fbdSmrg while (count & ~0x03) { 480340e3fbdSmrg dest[0] = dest[1] = dest[2] = dest[3] = pattern; 481340e3fbdSmrg dest += 4; 482340e3fbdSmrg count -= 4; 483340e3fbdSmrg } 484340e3fbdSmrg switch (count) { 485340e3fbdSmrg case 1: 486340e3fbdSmrg dest[0] = pattern; 487340e3fbdSmrg break; 488340e3fbdSmrg case 2: 489340e3fbdSmrg dest[0] = dest[1] = pattern; 490340e3fbdSmrg break; 491340e3fbdSmrg case 3: 492340e3fbdSmrg dest[0] = dest[1] = dest[2] = pattern; 493340e3fbdSmrg break; 494340e3fbdSmrg } 495340e3fbdSmrg#else 496340e3fbdSmrg 497340e3fbdSmrg while (count--) 498340e3fbdSmrg SET_PIX_TRANS_L(pattern); 499340e3fbdSmrg#endif 500340e3fbdSmrg } else if (DashPatternSize < 32) { 501340e3fbdSmrg register int offset = phase; 502340e3fbdSmrg 503340e3fbdSmrg while (count--) { 504340e3fbdSmrg SET_PIX_TRANS_L((DashPattern[LINE_PATTERN_START] << offset) | 505340e3fbdSmrg (DashPattern[LINE_PATTERN_START] >> 506340e3fbdSmrg (DashPatternSize - offset))); 507340e3fbdSmrg offset += 32; 508340e3fbdSmrg while (offset > DashPatternSize) 509340e3fbdSmrg offset -= DashPatternSize; 510340e3fbdSmrg } 511340e3fbdSmrg } else { 512340e3fbdSmrg int offset = phase; 513340e3fbdSmrg register unsigned char *srcp = (unsigned char *)(DashPattern) + 514340e3fbdSmrg (MAX_LINE_PATTERN_LENGTH >> 3) - 1; 515340e3fbdSmrg register CARD32 *scratch; 516340e3fbdSmrg int scratch2, shift; 517340e3fbdSmrg 518340e3fbdSmrg while (count--) { 519340e3fbdSmrg shift = DashPatternSize - offset; 520340e3fbdSmrg scratch = (CARD32*)(srcp - (offset >> 3) - 3); 521340e3fbdSmrg scratch2 = offset & 0x07; 522340e3fbdSmrg 523340e3fbdSmrg if (shift & ~31) { 524340e3fbdSmrg if (scratch2) { 525340e3fbdSmrg pattern = (*scratch << scratch2) | 526340e3fbdSmrg (*(scratch - 1) >> (32 - scratch2)); 527340e3fbdSmrg } else 528340e3fbdSmrg pattern = *scratch; 529340e3fbdSmrg } else { 530340e3fbdSmrg pattern = (*((CARD32*)(srcp - 3)) >> shift) | 531340e3fbdSmrg (*scratch << scratch2); 532340e3fbdSmrg } 533340e3fbdSmrg SET_PIX_TRANS_L(pattern); 534340e3fbdSmrg offset += 32; 535340e3fbdSmrg while (offset >= DashPatternSize) 536340e3fbdSmrg offset -= DashPatternSize; 537340e3fbdSmrg } 538340e3fbdSmrg } 539340e3fbdSmrg} 540340e3fbdSmrg 541340e3fbdSmrg#endif 542340e3fbdSmrg 543340e3fbdSmrg#ifdef S3_NEWMMIO 544340e3fbdSmrgBool S3AccelInitNewMMIO(ScreenPtr pScreen) 545340e3fbdSmrg#else 546340e3fbdSmrgBool S3AccelInitPIO(ScreenPtr pScreen) 547340e3fbdSmrg#endif 548340e3fbdSmrg{ 549340e3fbdSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 550340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 551340e3fbdSmrg XAAInfoRecPtr pXAA; 552340e3fbdSmrg 553340e3fbdSmrg if (pS3->Chipset == PCI_CHIP_968) 554340e3fbdSmrg pS3->ColorExpandBug = TRUE; 555340e3fbdSmrg else 556340e3fbdSmrg pS3->ColorExpandBug = FALSE; 557340e3fbdSmrg 558340e3fbdSmrg if (!(pXAA = XAACreateInfoRec())) 559340e3fbdSmrg return FALSE; 560340e3fbdSmrg 561340e3fbdSmrg pS3->pXAA = pXAA; 562340e3fbdSmrg 563340e3fbdSmrg pXAA->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS | 564340e3fbdSmrg LINEAR_FRAMEBUFFER); 565340e3fbdSmrg 566340e3fbdSmrg pXAA->Sync = S3Sync; 567340e3fbdSmrg 568340e3fbdSmrg pXAA->SetupForSolidFill = S3SetupForSolidFill; 569340e3fbdSmrg pXAA->SubsequentSolidFillRect = S3SubsequentSolidFillRect; 570340e3fbdSmrg 571340e3fbdSmrg pXAA->SetupForScreenToScreenCopy = S3SetupForScreenToScreenCopy; 572340e3fbdSmrg pXAA->SubsequentScreenToScreenCopy = S3SubsequentScreenToScreenCopy; 573bd35f0dbSahoka pXAA->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 574340e3fbdSmrg 575bd35f0dbSahoka#if 0 576bd35f0dbSahoka/* 577bd35f0dbSahoka 8x8 color pattern filling doesn't work properly after introducing 578bd35f0dbSahoka framebuffer manager initialization before XAA initialization. There 579bd35f0dbSahoka are problems with addressing a colour patterns from offscreen area. 580bd35f0dbSahoka*/ 581340e3fbdSmrg pXAA->SetupForColor8x8PatternFill = S3SetupForColor8x8PatternFill; 582340e3fbdSmrg pXAA->SubsequentColor8x8PatternFillRect = S3SubsequentColor8x8PatternFillRect; 583bd35f0dbSahoka pXAA->Color8x8PatternFillFlags = NO_TRANSPARENCY | 584bd35f0dbSahoka HARDWARE_PATTERN_SCREEN_ORIGIN | 585bd35f0dbSahoka BIT_ORDER_IN_BYTE_MSBFIRST; 586bd35f0dbSahoka 587bd35f0dbSahoka pXAA->CachePixelGranularity = 0; 588bd35f0dbSahoka#endif 589340e3fbdSmrg 590340e3fbdSmrg#ifdef S3_NEWMMIO 591340e3fbdSmrg pXAA->SetupForCPUToScreenColorExpandFill = 592340e3fbdSmrg S3SetupForCPUToScreenColorExpandFill; 593340e3fbdSmrg pXAA->SubsequentCPUToScreenColorExpandFill = 594340e3fbdSmrg S3SubsequentCPUToScreenColorExpandFill32; 595340e3fbdSmrg pXAA->ColorExpandBase = (void *) &IMG_TRANS; 596340e3fbdSmrg pXAA->ColorExpandRange = 0x8000; 597340e3fbdSmrg pXAA->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | 598340e3fbdSmrg BIT_ORDER_IN_BYTE_MSBFIRST | 599340e3fbdSmrg SCANLINE_PAD_DWORD; 600340e3fbdSmrg#endif 601340e3fbdSmrg 602340e3fbdSmrg#if 0 603340e3fbdSmrg#ifndef S3_NEWMMIO 604340e3fbdSmrg pXAA->ScanlineImageWriteFlags = NO_TRANSPARENCY; 605340e3fbdSmrg pXAA->SetupForScanlineImageWrite = 606340e3fbdSmrg S3SetupForScanlineImageWriteNoMMIO; 607340e3fbdSmrg pXAA->SubsequentScanlineImageWriteRect = 608340e3fbdSmrg S3SubsequentScanlineImageWriteRectNoMMIO; 609340e3fbdSmrg pXAA->SubsequentImageWriteScanline = 610340e3fbdSmrg S3SubsequentImageWriteScanlineNoMMIO; 611340e3fbdSmrg pXAA->NumScanlineImageWriteBuffers = 1; 612340e3fbdSmrg pXAA->ScanlineImageWriteBuffers = &pS3->imageBuffer; 613340e3fbdSmrg#endif 614340e3fbdSmrg#endif 615340e3fbdSmrg 616340e3fbdSmrg pXAA->SetupForSolidLine = S3SetupForSolidLine; 617340e3fbdSmrg pXAA->SubsequentSolidBresenhamLine = S3SubsequentSolidBresenhamLine; 618340e3fbdSmrg pXAA->SubsequentSolidHorVertLine = S3SubsequentSolidHorVertLine; 619340e3fbdSmrg pXAA->SolidBresenhamLineErrorTermBits = 12; 620340e3fbdSmrg#if 0 621340e3fbdSmrg /* kinda buggy... and its faster without it */ 622340e3fbdSmrg pXAA->SetupForDashedLine = S3SetupForDashedLine; 623340e3fbdSmrg pXAA->SubsequentDashedBresenhamLine = S3SubsequentDashedBresenhamLine32; 624340e3fbdSmrg pXAA->DashPatternMaxLength = MAX_LINE_PATTERN_LENGTH; 625340e3fbdSmrg#endif 626340e3fbdSmrg 627340e3fbdSmrg return XAAInit(pScreen, pXAA); 628340e3fbdSmrg} 629