ffb_accel.c revision d4df137b
1/* 2 * Acceleration for the Creator and Creator3D framebuffer. 3 * 4 * Copyright (C) 1998,1999,2000 Jakub Jelinek (jakub@redhat.com) 5 * Copyright (C) 1998 Michal Rehacek (majkl@iname.com) 6 * Copyright (C) 1999,2000 David S. Miller (davem@redhat.com) 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * JAKUB JELINEK, MICHAL REHACEK, OR DAVID MILLER BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 * USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 */ 27 28#ifdef HAVE_CONFIG_H 29#include "config.h" 30#endif 31 32#include "ffb.h" 33#include "ffb_fifo.h" 34#include "ffb_rcache.h" 35#include "ffb_loops.h" 36#include "ffb_regs.h" 37 38#include "scrnintstr.h" 39#include "pixmapstr.h" 40#include "regionstr.h" 41#include "mistruct.h" 42#include "miline.h" 43#include "fb.h" 44 45#ifdef HAVE_XAA_H 46/* VISmoveImage.s */ 47extern void VISmoveImageRL(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind); 48extern void VISmoveImageLR(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind); 49 50 51void 52CreatorVtChange (ScreenPtr pScreen, int enter) 53{ 54 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 55 FFBPtr pFfb = GET_FFB_FROM_SCRN (pScrn); 56 ffb_fbcPtr ffb = pFfb->regs; 57 58 pFfb->rp_active = 1; 59 FFBWait(pFfb, ffb); 60 pFfb->fifo_cache = -1; 61 pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | 62 FFB_FBC_RB_A | FFB_FBC_SB_BOTH| FFB_FBC_XE_OFF | 63 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_MASK); 64 pFfb->ppc_cache = (FFB_PPC_FW_DISABLE | 65 FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | 66 FFB_PPC_XS_CONST | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST| 67 FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE); 68 69 pFfb->pmask_cache = ~0; 70 pFfb->rop_cache = FFB_ROP_EDIT_BIT; 71 pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 72 pFfb->fg_cache = pFfb->bg_cache = 0; 73 pFfb->fontw_cache = 32; 74 pFfb->fontinc_cache = (1 << 16) | 0; 75 pFfb->laststipple = NULL; 76 FFBFifo(pFfb, 9); 77 ffb->fbc = pFfb->fbc_cache; 78 ffb->ppc = pFfb->ppc_cache; 79 ffb->pmask = pFfb->pmask_cache; 80 ffb->rop = pFfb->rop_cache; 81 ffb->drawop = pFfb->drawop_cache; 82 ffb->fg = pFfb->fg_cache; 83 ffb->bg = pFfb->bg_cache; 84 ffb->fontw = pFfb->fontw_cache; 85 ffb->fontinc = pFfb->fontinc_cache; 86 pFfb->rp_active = 1; 87 FFBWait(pFfb, ffb); 88 89 /* Fixup the FBC/PPC caches to deal with actually using 90 * a WID for every ROP. 91 */ 92 pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | 93 FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON | 94 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON); 95 pFfb->ppc_cache &= ~FFB_PPC_XS_MASK; 96 pFfb->ppc_cache |= FFB_PPC_XS_WID; 97 pFfb->wid_cache = (enter ? pFfb->wid : 0xff); 98 FFBFifo(pFfb, 11); 99 ffb->fbc = pFfb->fbc_cache; 100 ffb->ppc = FFB_PPC_XS_WID; 101 ffb->wid = pFfb->wid_cache; 102 ffb->xpmask = 0xff; 103 ffb->xclip = FFB_XCLIP_TEST_ALWAYS; 104 ffb->cmp = 0x80808080; 105 ffb->matchab = 0x80808080; 106 ffb->magnab = 0x80808080; 107 ffb->blendc = (FFB_BLENDC_FORCE_ONE | 108 FFB_BLENDC_DF_ONE_M_A | 109 FFB_BLENDC_SF_A); 110 ffb->blendc1 = 0; 111 ffb->blendc2 = 0; 112 pFfb->rp_active = 1; 113 FFBWait(pFfb, ffb); 114 115 if (enter) { 116 pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 117 118 FFBFifo(pFfb, 5); 119 ffb->drawop = pFfb->drawop_cache; 120 FFB_WRITE64(&ffb->by, 0, 0); 121 FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width); 122 pFfb->rp_active = 1; 123 FFBWait(pFfb, ffb); 124 125 SET_SYNC_FLAG(pFfb->pXAAInfo); 126 } 127} 128 129#ifdef DEBUG_FFB 130FILE *FDEBUG_FD = NULL; 131#endif 132 133static CARD32 FFBAlphaTextureFormats[2] = { PICT_a8, 0 }; 134static CARD32 FFBTextureFormats[2] = { PICT_a8b8g8r8, 0 }; 135static CARD32 FFBTextureDstFormats[3] = { PICT_a8b8g8r8, PICT_x8b8g8r8, 0 }; 136 137static Bool FFB_SetupForCPUToScreenAlphaTexture( 138 ScrnInfoPtr pScrn, 139 int op, 140 CARD16 red, 141 CARD16 green, 142 CARD16 blue, 143 CARD16 alpha, 144 CARD32 maskFormat, 145 CARD32 dstFormat, 146 CARD8 *alphaPtr, 147 int alphaPitch, 148 int width, 149 int height, 150 int flags 151) 152{ 153 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 154 155 FFBLOG(("FFB_SetupForCPUToScreenAlphaTexture: " 156 "argb[%04x:%04x:%04x:%04x] alpha[T(%x):P(%d)] " 157 "wh[%d:%d] flgs[%x]\n", 158 alpha, red, green, blue, 159 maskFormat, alphaPitch, 160 width, height, flags)); 161 162 FFB_SetupTextureAttrs(pFfb); 163 164 pFfb->xaa_tex = (unsigned char *) alphaPtr; 165 pFfb->xaa_tex_pitch = alphaPitch; 166 pFfb->xaa_tex_width = width; 167 pFfb->xaa_tex_height = height; 168 pFfb->xaa_tex_color = (/*((alpha >> 8) << 24) |*/ 169 ((blue >> 8) << 16) | 170 ((green >> 8) << 8) | 171 ((red >> 8) << 0)); 172 return TRUE; 173} 174 175static void FFB_SubsequentCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, 176 int dstx, int dsty, 177 int srcx, int srcy, 178 int width, int height) 179{ 180 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 181 unsigned char *dst_base, *alpha_base, *sfb32; 182 unsigned int pixel_base; 183 int psz_shift = 2; 184 185 FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: " 186 "dst[%d:%d] src[%d:%d] wh[%d:%d]\n", 187 dstx, dsty, srcx, srcy, width, height)); 188 189 sfb32 = (unsigned char *) pFfb->sfb32; 190 dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift); 191 alpha_base = pFfb->xaa_tex; 192 alpha_base += srcx; 193 if (srcy) 194 alpha_base += (srcy * pFfb->xaa_tex_pitch); 195 pixel_base = pFfb->xaa_tex_color; 196 while (height--) { 197 unsigned int *dst = (unsigned int *) dst_base; 198 unsigned char *alpha = alpha_base; 199 int w = width; 200 201 while (w--) { 202 (*dst) = (((unsigned int)*alpha << 24) | pixel_base); 203 dst++; 204 alpha++; 205 } 206 dst_base += (2048 << psz_shift); 207 alpha_base += pFfb->xaa_tex_pitch; 208 } 209} 210 211 212static Bool FFB_SetupForCPUToScreenTexture( 213 ScrnInfoPtr pScrn, 214 int op, 215 CARD32 srcFormat, 216 CARD32 dstFormat, 217 CARD8 *texPtr, 218 int texPitch, 219 int width, 220 int height, 221 int flags 222) 223{ 224 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 225 226 FFBLOG(("FFB_SetupForCPUToScreenTexture: " 227 "TEX[T(%x):P(%d)] " 228 "wh[%d:%d] flgs[%x]\n", 229 srcFormat, texPitch, 230 width, height, flags)); 231 232 FFB_SetupTextureAttrs(pFfb); 233 234 pFfb->xaa_tex = (unsigned char *) texPtr; 235 pFfb->xaa_tex_pitch = texPitch; 236 pFfb->xaa_tex_width = width; 237 pFfb->xaa_tex_height = height; 238 239 return TRUE; 240} 241 242static void FFB_SubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, 243 int dstx, int dsty, 244 int srcx, int srcy, 245 int width, int height) 246{ 247 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 248 unsigned char *dst_base, *sfb32; 249 unsigned int *tex_base; 250 int psz_shift = 2; 251 252 FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: " 253 "dst[%d:%d] src[%d:%d] wh[%d:%d]\n", 254 dstx, dsty, srcx, srcy, width, height)); 255 256 sfb32 = (unsigned char *) pFfb->sfb32; 257 dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift); 258 tex_base = (unsigned int *) pFfb->xaa_tex; 259 tex_base += srcx; 260 if (srcy) 261 tex_base += (srcy * pFfb->xaa_tex_pitch); 262 while (height--) { 263 unsigned int *dst = (unsigned int *) dst_base; 264 unsigned int *tex = tex_base; 265 int w = width; 266 while (w--) { 267 (*dst) = *tex; 268 269 dst++; 270 tex++; 271 } 272 dst_base += (2048 << psz_shift); 273 tex_base += pFfb->xaa_tex_pitch; 274 } 275} 276 277static void FFB_WritePixmap(ScrnInfoPtr pScrn, 278 int x, int y, int w, int h, 279 unsigned char *src, 280 int srcwidth, 281 int rop, 282 unsigned int planemask, 283 int trans, int bpp, int depth) 284{ 285 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 286 unsigned char *dst, *sfb32; 287 int psz_shift = 2; 288 ffb_fbcPtr ffb = pFfb->regs; 289 290 FFBLOG(("FFB_WritePixmap: " 291 "x[%d] y[%d] w[%d] h[%d] srcw[%d] rop[%d] pmask[%x] " 292 "trans[%d] bpp[%d] depth[%d]\n", 293 x, y, w, h, srcwidth, rop, planemask, 294 trans, bpp, depth)); 295 296 FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop); 297 FFBWait(pFfb, ffb); 298 299 sfb32 = (unsigned char *) pFfb->sfb32; 300 dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 301 VISmoveImageLR(src, dst, w << psz_shift, h, 302 srcwidth, (2048 << psz_shift)); 303} 304 305static void FFB_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 306 int pat_word1, int pat_word2, 307 int fg, int bg, int rop, 308 unsigned int planemask) 309{ 310 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 311 ffb_fbcPtr ffb = pFfb->regs; 312 unsigned int ppc, ppc_mask, fbc; 313 int i; 314 315 FFBLOG(("FFB_SetupForMono8x8PatternFill: " 316 "pat[%08x:%08x] fg[%x] bg[%x] rop[%d] pmask[%x]\n", 317 pat_word1, pat_word2, 318 fg, bg, rop, planemask)); 319 320 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_ENABLE | FFB_PPC_CS_CONST; 321 if (bg < 0) 322 ppc |= FFB_PPC_TBE_TRANSPARENT; 323 else 324 ppc |= FFB_PPC_TBE_OPAQUE; 325 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | 326 FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK; 327 fbc = pFfb->fbc; 328 rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8); 329 330 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, rop, 331 FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid); 332 if (bg >= 0) 333 FFB_WRITE_BG(pFfb, ffb, bg); 334 335 FFBFifo(pFfb, 32); 336 for (i = 0; i < 32; i += 2) { 337 CARD32 val1, val2; 338 int shift = (24 - ((i % 4) * 8)); 339 340 if ((i % 8) < 4) { 341 val1 = (pat_word1 >> shift) & 0xff; 342 val2 = (pat_word1 >> (shift + 8)) & 0xff; 343 } else { 344 val1 = (pat_word2 >> shift) & 0xff; 345 val2 = (pat_word2 >> (shift + 8)) & 0xff; 346 } 347 val1 |= (val1 << 8) | (val1 << 16) | (val1 << 24); 348 val2 |= (val2 << 8) | (val2 << 16) | (val2 << 24); 349 FFB_WRITE64(&ffb->pattern[i], val1, val2); 350 } 351 pFfb->rp_active = 1; 352} 353 354static void FFB_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 355 int pat_word1, int pat_word2, 356 int x, int y, int w, int h) 357{ 358 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 359 ffb_fbcPtr ffb = pFfb->regs; 360 361 FFBLOG(("FFB_SubsequentMono8x8PatternFillRect: " 362 "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h)); 363 364 FFBFifo(pFfb, 4); 365 FFB_WRITE64(&ffb->by, y, x); 366 FFB_WRITE64_2(&ffb->bh, h, w); 367} 368 369static void FFB_SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 370 int fg, int bg, 371 int rop, 372 unsigned int planemask) 373{ 374 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 375 ffb_fbcPtr ffb = pFfb->regs; 376 unsigned int ppc, ppc_mask, fbc; 377 378 FFBLOG(("FFB_SetupForScanlineCPUToScreenColorExpandFill: " 379 "fg[%x] bg[%x] rop[%d] pmask[%x]\n", 380 fg, bg, rop, planemask)); 381 382 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST; 383 if (bg < 0) 384 ppc |= FFB_PPC_TBE_TRANSPARENT; 385 else 386 ppc |= FFB_PPC_TBE_OPAQUE; 387 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | 388 FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK; 389 fbc = pFfb->fbc; 390 rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8); 391 392 if ((pFfb->ppc_cache & ppc_mask) != ppc || 393 pFfb->fg_cache != fg || 394 pFfb->fbc_cache != fbc || 395 pFfb->rop_cache != rop || 396 pFfb->pmask_cache != planemask || 397 pFfb->fontinc_cache != ((0<<16) | 32) || 398 (bg >= 0 && pFfb->bg_cache != bg)) { 399 pFfb->ppc_cache &= ~ppc_mask; 400 pFfb->ppc_cache |= ppc; 401 pFfb->fg_cache = fg; 402 pFfb->fbc_cache = fbc; 403 pFfb->rop_cache = rop; 404 pFfb->pmask_cache = planemask; 405 pFfb->fontinc_cache = ((0<<16) | 32); 406 if (bg >= 0) 407 pFfb->bg_cache = bg; 408 FFBFifo(pFfb, (bg >= 0 ? 7 : 6)); 409 ffb->ppc = ppc; 410 ffb->fg = fg; 411 ffb->fbc = fbc; 412 ffb->rop = rop; 413 ffb->pmask = planemask; 414 ffb->fontinc = ((0 << 16) | 32); 415 if(bg >= 0) 416 ffb->bg = bg; 417 } 418 pFfb->rp_active = 1; 419} 420 421static void FFB_SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 422 int x, int y, int w, int h, 423 int skipleft) 424{ 425 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 426 FFBLOG(("FFB_SubsequentCPUToScreenColorExpandFill: " 427 "x[%d] y[%d] w[%d] h[%d] skipleft[%d]\n", 428 x, y, w, h, skipleft)); 429 430 pFfb->xaa_scanline_x = x; 431 pFfb->xaa_scanline_y = y; 432 pFfb->xaa_scanline_w = w; 433} 434 435static void FFB_SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 436{ 437 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 438 ffb_fbcPtr ffb = pFfb->regs; 439 CARD32 *bits = (CARD32 *) pFfb->xaa_scanline_buffers[bufno]; 440 int w; 441 442 FFBFifo(pFfb, 1); 443 ffb->fontxy = ((pFfb->xaa_scanline_y << 16) | pFfb->xaa_scanline_x); 444 445 w = pFfb->xaa_scanline_w; 446 if (w >= 32) { 447 FFB_WRITE_FONTW(pFfb, ffb, 32); 448 FFBFifo(pFfb, (w / 32)); 449 do { 450 ffb->font = *bits++; 451 w -= 32; 452 } while (w >= 32); 453 } 454 if (w > 0) { 455 FFB_WRITE_FONTW(pFfb, ffb, w); 456 FFBFifo(pFfb, 1); 457 ffb->font = *bits++; 458 } 459 460 pFfb->xaa_scanline_y++; 461} 462 463static void FFB_SetupForDashedLine(ScrnInfoPtr pScrn, 464 int fg, int bg, int rop, 465 unsigned int planemask, 466 int length, unsigned char *pattern) 467{ 468 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 469 CARD32 *pat_ptr = (CARD32 *)pattern; 470 unsigned int ppc, ppc_mask, fbc; 471 472 FFBLOG(("FFB_SetupForDashedLine: " 473 "fg[%x] bg[%x] rop[%d] pmask[%x] patlen[%d] pat[%x]\n", 474 fg, bg, rop, planemask, length, *pat_ptr)); 475 476 pFfb->planemask = planemask; 477 pFfb->xaa_rop = rop; 478 pFfb->xaa_linepat = 479 (*pat_ptr << FFB_LPAT_PATTERN_SHIFT) | 480 (1 << FFB_LPAT_SCALEVAL_SHIFT) | 481 ((length & 0xf) << FFB_LPAT_PATLEN_SHIFT); 482 483 fbc = pFfb->fbc; 484 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 485 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 486 487 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 488 (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8), 489 FFB_DRAWOP_BRLINEOPEN, fg, fbc, pFfb->wid); 490 pFfb->rp_active = 1; 491} 492 493static void FFB_SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 494 int x1, int y1, 495 int x2, int y2, 496 int flags, int phase) 497{ 498 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 499 ffb_fbcPtr ffb = pFfb->regs; 500 unsigned int linepat = pFfb->xaa_linepat; 501 unsigned int drawop; 502 503 FFBLOG(("FFB_SubsequentDashedTwoPointLine: " 504 "x1[%d] y1[%d] x2[%d] y2[%d] flgs[%x] phase[%d]\n", 505 x1, y2, x2, y2, flags, phase)); 506 507 linepat |= (phase & 0xf) << FFB_LPAT_PATPTR_SHIFT; 508 509 drawop = (flags & OMIT_LAST) ? 510 FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP; 511 FFB_WRITE_DRAWOP(pFfb, ffb, drawop); 512 513 if (pFfb->has_brline_bug) { 514 FFBFifo(pFfb, 6); 515 ffb->ppc = 0; 516 } else 517 FFBFifo(pFfb, 5); 518 ffb->lpat = linepat; 519 FFB_WRITE64(&ffb->by, y1, x1); 520 FFB_WRITE64_2(&ffb->bh, y2, x2); 521} 522 523static void FFB_SetupForSolidLine(ScrnInfoPtr pScrn, 524 int color, int rop, unsigned int planemask) 525{ 526 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 527 ffb_fbcPtr ffb = pFfb->regs; 528 unsigned int ppc, ppc_mask, fbc; 529 FFBLOG(("FFB_SetupForSolidLine: " 530 "color[%d] rop[%d] pmask[%x]\n", 531 color, rop, planemask)); 532 533 pFfb->planemask = planemask; 534 pFfb->xaa_rop = rop; 535 536 fbc = pFfb->fbc; 537 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 538 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 539 540 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 541 (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8), 542 FFB_DRAWOP_BRLINEOPEN, color, fbc, pFfb->wid); 543 FFBFifo(pFfb, 1); 544 ffb->lpat = 0; 545 pFfb->rp_active = 1; 546} 547 548static void FFB_SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, 549 int x1, int y1, 550 int x2, int y2, 551 int flags) 552{ 553 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 554 ffb_fbcPtr ffb = pFfb->regs; 555 int drawop; 556 557 FFBLOG(("FFB_SubsequentSolidTwoPointLine: " 558 "x1[%d] y1[%d] x2[%d] y2[%d] flags[%d]\n", 559 x1, y1, x2, y2, flags)); 560 561 drawop = (flags & OMIT_LAST) ? 562 FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP; 563 FFB_WRITE_DRAWOP(pFfb, ffb, drawop); 564 565 if (pFfb->has_brline_bug) { 566 FFBFifo(pFfb, 5); 567 ffb->ppc = 0; 568 } else 569 FFBFifo(pFfb, 4); 570 FFB_WRITE64(&ffb->by, y1, x1); 571 FFB_WRITE64_2(&ffb->bh, y2, x2); 572} 573 574void FFB_SetupForSolidFill(ScrnInfoPtr pScrn, 575 int color, int rop, unsigned int planemask) 576{ 577 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 578 unsigned int ppc, ppc_mask, fbc; 579 580 FFBLOG(("FFB_SetupForSolidFill: " 581 "color[%d] rop[%d] pmask[%u]\n", 582 color, rop, planemask)); 583 584 pFfb->planemask = planemask; 585 pFfb->xaa_rop = rop; 586 587 fbc = pFfb->fbc; 588 if (pFfb->ffb_res == ffb_res_high) 589 fbc |= FFB_FBC_WB_B; 590 ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 591 ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 592 593 FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 594 (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8), 595 FFB_DRAWOP_RECTANGLE, color, fbc, pFfb->wid); 596 pFfb->rp_active = 1; 597} 598 599void FFB_SubsequentSolidFillRect(ScrnInfoPtr pScrn, 600 int x, int y, 601 int w, int h) 602{ 603 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 604 ffb_fbcPtr ffb = pFfb->regs; 605 606 FFBLOG(("FFB_SubsequentSolidFillRect: " 607 "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h)); 608 609 FFBFifo(pFfb, 4); 610 FFB_WRITE64(&ffb->by, y, x); 611 FFB_WRITE64_2(&ffb->bh, h, w); 612} 613 614static void FFB_ScreenToScreenBitBlt(ScrnInfoPtr pScrn, 615 int nbox, 616 DDXPointPtr pptSrc, 617 BoxPtr pbox, 618 int xdir, int ydir, 619 int rop, unsigned int planemask) 620{ 621 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 622 ffb_fbcPtr ffb = pFfb->regs; 623 int use_vscroll; 624 625 FFBLOG(("FFB_ScreenToScreenBitBlt: " 626 "nbox[%d] xdir[%d] ydir[%d] rop[%d] pmask[%x]\n", 627 nbox, xdir, ydir, rop, planemask)); 628 629 use_vscroll = 0; 630 if (!pFfb->disable_vscroll && 631 rop == GXcopy) { 632 int i; 633 634 for (i = 0; i < nbox; i++) 635 if (pptSrc[i].x != pbox[i].x1 || 636 pptSrc[i].y == pbox[i].y1) 637 break; 638 if (i == nbox) { 639 /* If/When double buffer extension is re-enabled 640 * check buffers here. 641 */ 642 use_vscroll = 1; 643 } 644 } 645 if (use_vscroll) { 646 FFB_ATTR_VSCROLL_XAA(pFfb, planemask); 647 while (nbox--) { 648 FFBFifo(pFfb, 7); 649 ffb->drawop = FFB_DRAWOP_VSCROLL; 650 FFB_WRITE64(&ffb->by, pptSrc->y, pptSrc->x); 651 FFB_WRITE64_2(&ffb->dy, pbox->y1, pbox->x1); 652 FFB_WRITE64_3(&ffb->bh, (pbox->y2 - pbox->y1), 653 (pbox->x2 - pbox->x1)); 654 655 pbox++; 656 pptSrc++; 657 } 658 pFfb->rp_active = 1; 659 SET_SYNC_FLAG(pFfb->pXAAInfo); 660 } else { 661 unsigned char *sfb32 = (unsigned char *) pFfb->sfb32; 662 int psz_shift = 2; 663 664 FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop); 665 if (pFfb->use_blkread_prefetch) { 666 unsigned int bit; 667 668 if (xdir < 0) 669 bit = FFB_MER_EDRA; 670 else 671 bit = FFB_MER_EIRA; 672 FFBFifo(pFfb, 1); 673 ffb->mer = bit; 674 pFfb->rp_active = 1; 675 } 676 FFBWait(pFfb, ffb); 677 678 while (nbox--) { 679 unsigned char *src, *dst; 680 int x1, y1, x2, y2; 681 int width, height; 682 int sdkind; 683 684 x1 = pptSrc->x; 685 y1 = pptSrc->y; 686 x2 = pbox->x1; 687 y2 = pbox->y1; 688 width = (pbox->x2 - pbox->x1); 689 height = (pbox->y2 - pbox->y1); 690 691 src = sfb32 + (y1 * (2048 << psz_shift)) 692 + (x1 << psz_shift); 693 dst = sfb32 + (y2 * (2048 << psz_shift)) 694 + (x2 << psz_shift); 695 sdkind = (2048 << psz_shift); 696 697 if (ydir < 0) { 698 src += ((height - 1) * (2048 << psz_shift)); 699 dst += ((height - 1) * (2048 << psz_shift)); 700 sdkind = -sdkind; 701 } 702 width <<= psz_shift; 703 if (xdir < 0) 704 VISmoveImageRL(src, dst, width, height, 705 sdkind, sdkind); 706 else 707 VISmoveImageLR(src, dst, width, height, 708 sdkind, sdkind); 709 pbox++; 710 pptSrc++; 711 } 712 if (pFfb->use_blkread_prefetch) { 713 FFBFifo(pFfb, 1); 714 ffb->mer = FFB_MER_DRA; 715 pFfb->rp_active = 1; 716 FFBWait(pFfb, ffb); 717 } 718 } 719} 720 721void FFB_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 722 int xdir, int ydir, int rop, 723 unsigned int planemask, 724 int trans_color) 725{ 726 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 727 ffb_fbcPtr ffb = pFfb->regs; 728 FFBLOG(("FFB_SetupForScreenToScreenCopy: " 729 "xdir[%d] ydir[%d] rop[%d] pmask[%x] tcolor[%d]\n", 730 xdir, ydir, rop, planemask, trans_color)); 731 732 pFfb->planemask = planemask; 733 pFfb->xaa_xdir = xdir; 734 pFfb->xaa_ydir = ydir; 735 pFfb->xaa_rop = rop; 736 FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop); 737 FFBWait(pFfb, ffb); 738} 739 740void FFB_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 741 int x1, int y1, 742 int x2, int y2, 743 int width, int height) 744{ 745 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 746 unsigned char *src, *dst, *sfb32; 747 int psz_shift = 2; 748 int sdkind; 749 750 FFBLOG(("FFB_SubsequentScreenToScreenCopy: " 751 "x1[%d] y1[%d] x2[%d] y2[%u] w[%d] h[%d]\n", 752 x1, y1, x2, y2, width, height)); 753 754 sfb32 = (unsigned char *) pFfb->sfb32; 755 src = sfb32 + (y1 * (2048 << psz_shift)) + (x1 << psz_shift); 756 dst = sfb32 + (y2 * (2048 << psz_shift)) + (x2 << psz_shift); 757 sdkind = (2048 << psz_shift); 758 759 if (pFfb->xaa_ydir < 0) { 760 src += ((height - 1) * (2048 << psz_shift)); 761 dst += ((height - 1) * (2048 << psz_shift)); 762 sdkind = -sdkind; 763 } 764 765 width <<= psz_shift; 766 if (pFfb->xaa_xdir < 0) 767 VISmoveImageRL(src, dst, width, height, sdkind, sdkind); 768 else 769 VISmoveImageLR(src, dst, width, height, sdkind, sdkind); 770} 771 772static void FFB_Sync(ScrnInfoPtr pScrn) 773{ 774 FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 775 ffb_fbcPtr ffb = pFfb->regs; 776 777 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 778 FFBWait(pFfb, ffb); 779} 780 781#endif 782 783Bool FFBAccelInit(ScreenPtr pScreen, FFBPtr pFfb) 784{ 785#ifdef HAVE_XAA_H 786 XAAInfoRecPtr infoRec; 787 ffb_fbcPtr ffb = pFfb->regs; 788 789 pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 790 FFB_FBC_WE_FORCEON | 791 FFB_FBC_SB_BOTH | 792 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 793 FFB_FBC_RGBE_MASK | 794 FFB_FBC_XE_ON); 795 pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE); 796 if (pFfb->wid == (unsigned int) -1) 797 return FALSE; 798 799 pFfb->pXAAInfo = infoRec = XAACreateInfoRec(); 800 if (!infoRec) { 801 FFBWidFree(pFfb, pFfb->wid); 802 return FALSE; 803 } 804 805 pFfb->xaa_scanline_buffers[0] = malloc(2048 * 4); 806 if (!pFfb->xaa_scanline_buffers[0]) { 807 XAADestroyInfoRec(infoRec); 808 return FALSE; 809 } 810 811 pFfb->xaa_scanline_buffers[1] = malloc(2048 * 4); 812 if (!pFfb->xaa_scanline_buffers[1]) { 813 free(pFfb->xaa_scanline_buffers[0]); 814 XAADestroyInfoRec(infoRec); 815 return FALSE; 816 } 817 818 infoRec->Sync = FFB_Sync; 819 820 /* Use VIS and VSCROLL for screen to screen copies. */ 821 infoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 822 infoRec->SetupForScreenToScreenCopy = 823 FFB_SetupForScreenToScreenCopy; 824 infoRec->SubsequentScreenToScreenCopy = 825 FFB_SubsequentScreenToScreenCopy; 826 827 /* In order to optimize VSCROLL and prefetching properly we 828 * have to use our own mid-layer routine. 829 */ 830 infoRec->ScreenToScreenBitBltFlags = NO_TRANSPARENCY; 831 infoRec->ScreenToScreenBitBlt = 832 FFB_ScreenToScreenBitBlt; 833 834 infoRec->SolidFillFlags = 0; 835 infoRec->SetupForSolidFill = 836 FFB_SetupForSolidFill; 837 infoRec->SubsequentSolidFillRect = 838 FFB_SubsequentSolidFillRect; 839 840 infoRec->SolidLineFlags = 0; 841 infoRec->SetupForSolidLine = 842 FFB_SetupForSolidLine; 843 infoRec->SubsequentSolidTwoPointLine = 844 FFB_SubsequentSolidTwoPointLine; 845 miSetZeroLineBias(pScreen, OCTANT3 | OCTANT4 | OCTANT6 | OCTANT1); 846 847 infoRec->DashedLineFlags = (TRANSPARENCY_ONLY | 848 LINE_PATTERN_LSBFIRST_LSBJUSTIFIED); 849 infoRec->DashPatternMaxLength = 16; 850 infoRec->SetupForDashedLine = 851 FFB_SetupForDashedLine; 852 infoRec->SubsequentDashedTwoPointLine = 853 FFB_SubsequentDashedTwoPointLine; 854 855 /* We cannot use the non-scanline color expansion mechanism on FFB 856 * for two reasons: 857 * 858 * 1) A render pass can only render 32-pixels wide on FFB, XAA expects 859 * that arbitrary widths are possible per render pass. 860 * 861 * 2) The FFB accelerator FIFO is only 100 or so words deep, and 862 * XAA gives no way to limit the number of words it writes into 863 * the ColorExpandBase register per rendering pass. 864 */ 865 infoRec->ScanlineColorExpandBuffers = pFfb->xaa_scanline_buffers; 866 infoRec->NumScanlineColorExpandBuffers = 2; 867 infoRec->ScanlineCPUToScreenColorExpandFillFlags = 868 CPU_TRANSFER_PAD_DWORD | 869 SCANLINE_PAD_DWORD | 870 CPU_TRANSFER_BASE_FIXED | 871 BIT_ORDER_IN_BYTE_LSBFIRST; 872 infoRec->SetupForScanlineCPUToScreenColorExpandFill = 873 FFB_SetupForScanlineCPUToScreenColorExpandFill; 874 infoRec->SubsequentScanlineCPUToScreenColorExpandFill = 875 FFB_SubsequentScanlineCPUToScreenColorExpandFill; 876 infoRec->SubsequentColorExpandScanline = 877 FFB_SubsequentColorExpandScanline; 878 879 infoRec->Mono8x8PatternFillFlags = 880 HARDWARE_PATTERN_PROGRAMMED_BITS | 881 HARDWARE_PATTERN_SCREEN_ORIGIN | 882 BIT_ORDER_IN_BYTE_LSBFIRST; 883 infoRec->SetupForMono8x8PatternFill = 884 FFB_SetupForMono8x8PatternFill; 885 infoRec->SubsequentMono8x8PatternFillRect = 886 FFB_SubsequentMono8x8PatternFillRect; 887 888 /* Use VIS for pixmap writes. */ 889 infoRec->WritePixmap = FFB_WritePixmap; 890 891 /* RENDER optimizations. */ 892 infoRec->CPUToScreenAlphaTextureFlags = 893 XAA_RENDER_NO_TILE | 894 XAA_RENDER_NO_SRC_ALPHA; 895 infoRec->CPUToScreenAlphaTextureFormats = FFBAlphaTextureFormats; 896 infoRec->CPUToScreenAlphaTextureDstFormats = FFBTextureDstFormats; 897 infoRec->SetupForCPUToScreenAlphaTexture2 = 898 FFB_SetupForCPUToScreenAlphaTexture; 899 infoRec->SubsequentCPUToScreenAlphaTexture = 900 FFB_SubsequentCPUToScreenAlphaTexture; 901 902 infoRec->CPUToScreenTextureFlags = 903 XAA_RENDER_NO_TILE | 904 XAA_RENDER_NO_SRC_ALPHA; 905 infoRec->CPUToScreenTextureFormats = FFBTextureFormats; 906 infoRec->CPUToScreenTextureDstFormats = FFBTextureDstFormats; 907 infoRec->SetupForCPUToScreenTexture2 = 908 FFB_SetupForCPUToScreenTexture; 909 infoRec->SubsequentCPUToScreenTexture = 910 FFB_SubsequentCPUToScreenTexture; 911 912 pFfb->fifo_cache = 0; 913 914 FFB_DEBUG_init(); 915 FDEBUG((FDEBUG_FD, 916 "FFB: cfg0(%08x) cfg1(%08x) cfg2(%08x) cfg3(%08x) ppcfg(%08x)\n", 917 ffb->fbcfg0, ffb->fbcfg1, ffb->fbcfg2, ffb->fbcfg3, ffb->ppcfg)); 918 919 FFB_HardwareSetup(pFfb); 920 921 pFfb->ppc_cache = (FFB_PPC_FW_DISABLE | 922 FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | 923 FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST | 924 FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE); 925 pFfb->wid_cache = pFfb->wid; 926 pFfb->pmask_cache = ~0; 927 pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8)); 928 pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 929 pFfb->fg_cache = pFfb->bg_cache = 0; 930 pFfb->fontw_cache = 32; 931 pFfb->fontinc_cache = (1 << 16) | 0; 932 pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 933 FFB_FBC_WE_FORCEON | 934 FFB_FBC_SB_BOTH | 935 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 936 FFB_FBC_RGBE_OFF | 937 FFB_FBC_XE_ON); 938 pFfb->laststipple = NULL; 939 940 /* We will now clear the screen: we'll draw a rectangle covering all the 941 * viewscreen, using a 'blackness' ROP. 942 */ 943 FFBFifo(pFfb, 22); 944 ffb->fbc = pFfb->fbc_cache; 945 ffb->ppc = pFfb->ppc_cache; 946 ffb->wid = pFfb->wid_cache; 947 ffb->xpmask = 0xff; 948 ffb->pmask = pFfb->pmask_cache; 949 ffb->rop = pFfb->rop_cache; 950 ffb->drawop = pFfb->drawop_cache; 951 ffb->fg = pFfb->fg_cache; 952 ffb->bg = pFfb->bg_cache; 953 ffb->fontw = pFfb->fontw_cache; 954 ffb->fontinc = pFfb->fontinc_cache; 955 ffb->xclip = FFB_XCLIP_TEST_ALWAYS; 956 ffb->cmp = 0x80808080; 957 ffb->matchab = 0x80808080; 958 ffb->magnab = 0x80808080; 959 ffb->blendc = (FFB_BLENDC_FORCE_ONE | 960 FFB_BLENDC_DF_ONE_M_A | 961 FFB_BLENDC_SF_A); 962 ffb->blendc1 = 0; 963 ffb->blendc2 = 0; 964 FFB_WRITE64(&ffb->by, 0, 0); 965 FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width); 966 pFfb->rp_active = 1; 967 FFBWait(pFfb, ffb); 968 969 FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 970 FFBWait(pFfb, ffb); 971 972 if (!XAAInit(pScreen, infoRec)) { 973 XAADestroyInfoRec(infoRec); 974 free(pFfb->xaa_scanline_buffers[0]); 975 free(pFfb->xaa_scanline_buffers[1]); 976 pFfb->pXAAInfo = NULL; 977 FFBWidFree(pFfb, pFfb->wid); 978 return FALSE; 979 } 980 /* Success */ 981 return TRUE; 982#else 983 return FALSE; 984#endif 985} 986