rndr_gu2.c revision 71d7fec4
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/gfx/rndr_gu2.c,v 1.1 2002/12/10 15:12:27 alanh Exp $ */ 2/* 3 * $Workfile: rndr_gu2.c $ 4 * 5 * This file contains routines to program the 2D acceleration hardware for 6 * the second generation graphics unit. 7 * 8 * Basic rendering routines (common to all Geode processors): 9 * gfx_set_bpp 10 * gfx_set_solid_pattern 11 * gfx_set_mono_pattern 12 * gfx_set_color_pattern 13 * gfx_set_solid_source 14 * gfx_set_mono_source 15 * gfx_set_raster_operation 16 * gfx_pattern_fill 17 * gfx_color_pattern_fill 18 * gfx_screen_to_screen_blt 19 * gfx_screen_to_screen_xblt 20 * gfx_color_bitmap_to_screen_blt 21 * gfx_color_bitmap_to_screen_xblt 22 * gfx_mono_bitmap_to_screen_blt 23 * gfx_bresenham_line 24 * gfx_wait_until_idle 25 * 26 * Extended rendering routines for second generation functionality: 27 * gfx2_set_source_stride 28 * gfx2_set_destination_stride 29 * gfx2_set_pattern_origins 30 * gfx2_set_source_transparency 31 * gfx2_set_alpha_mode 32 * gfx2_set_alpha_value 33 * gfx2_pattern_fill 34 * gfx2_color_pattern_fill 35 * gfx2_screen_to_screen_blt 36 * gfx2_mono_expand_blt 37 * gfx2_color_bitmap_to_screen_blt 38 * gfx2_mono_bitmap_to_screen_blt 39 * gfx2_bresenham_line 40 * gfx2_sync_to_vblank 41 * 42 * NSC_LIC_ALTERNATIVE_PREAMBLE 43 * 44 * Revision 1.0 45 * 46 * National Semiconductor Alternative GPL-BSD License 47 * 48 * National Semiconductor Corporation licenses this software 49 * ("Software"): 50 * 51 * Durango 52 * 53 * under one of the two following licenses, depending on how the 54 * Software is received by the Licensee. 55 * 56 * If this Software is received as part of the Linux Framebuffer or 57 * other GPL licensed software, then the GPL license designated 58 * NSC_LIC_GPL applies to this Software; in all other circumstances 59 * then the BSD-style license designated NSC_LIC_BSD shall apply. 60 * 61 * END_NSC_LIC_ALTERNATIVE_PREAMBLE */ 62 63/* NSC_LIC_BSD 64 * 65 * National Semiconductor Corporation Open Source License for Durango 66 * 67 * (BSD License with Export Notice) 68 * 69 * Copyright (c) 1999-2001 70 * National Semiconductor Corporation. 71 * All rights reserved. 72 * 73 * Redistribution and use in source and binary forms, with or without 74 * modification, are permitted provided that the following conditions 75 * are met: 76 * 77 * * Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 80 * * Redistributions in binary form must reproduce the above 81 * copyright notice, this list of conditions and the following 82 * disclaimer in the documentation and/or other materials provided 83 * with the distribution. 84 * 85 * * Neither the name of the National Semiconductor Corporation nor 86 * the names of its contributors may be used to endorse or promote 87 * products derived from this software without specific prior 88 * written permission. 89 * 90 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 91 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 92 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 93 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 94 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 95 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 97 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 98 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 99 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 100 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 101 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 102 * OF SUCH DAMAGE. 103 * 104 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 105 * YOUR JURISDICTION. It is licensee's responsibility to comply with 106 * any export regulations applicable in licensee's jurisdiction. Under 107 * CURRENT (2001) U.S. export regulations this software 108 * is eligible for export from the U.S. and can be downloaded by or 109 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 110 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 111 * Syria, Sudan, Afghanistan and any other country to which the U.S. 112 * has embargoed goods and services. 113 * 114 * END_NSC_LIC_BSD */ 115 116/* NSC_LIC_GPL 117 * 118 * National Semiconductor Corporation Gnu General Public License for Durango 119 * 120 * (GPL License with Export Notice) 121 * 122 * Copyright (c) 1999-2001 123 * National Semiconductor Corporation. 124 * All rights reserved. 125 * 126 * Redistribution and use in source and binary forms, with or without 127 * modification, are permitted under the terms of the GNU General 128 * Public License as published by the Free Software Foundation; either 129 * version 2 of the License, or (at your option) any later version 130 * 131 * In addition to the terms of the GNU General Public License, neither 132 * the name of the National Semiconductor Corporation nor the names of 133 * its contributors may be used to endorse or promote products derived 134 * from this software without specific prior written permission. 135 * 136 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 137 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 138 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 139 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 140 * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY 141 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 142 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 143 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 144 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 145 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE, 146 * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY 147 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 148 * OF SUCH DAMAGE. See the GNU General Public License for more details. 149 * 150 * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF 151 * YOUR JURISDICTION. It is licensee's responsibility to comply with 152 * any export regulations applicable in licensee's jurisdiction. Under 153 * CURRENT (2001) U.S. export regulations this software 154 * is eligible for export from the U.S. and can be downloaded by or 155 * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed 156 * destinations which include Cuba, Iraq, Libya, North Korea, Iran, 157 * Syria, Sudan, Afghanistan and any other country to which the U.S. 158 * has embargoed goods and services. 159 * 160 * You should have received a copy of the GNU General Public License 161 * along with this file; if not, write to the Free Software Foundation, 162 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 163 * 164 * END_NSC_LIC_GPL */ 165 166void gu2_set_bpp(unsigned short bpp); 167void gu2_set_solid_pattern(unsigned long color); 168void gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 169 unsigned long data0, unsigned long data1, 170 unsigned char transparency); 171void gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 172 unsigned long data0, unsigned long data1, 173 unsigned long data2, unsigned long data3, 174 unsigned char transparency); 175void gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8); 176void gu2_set_solid_source(unsigned long color); 177void gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 178 unsigned short transparent); 179void gu2_set_pattern_flags(unsigned short flags); 180void gu2_set_raster_operation(unsigned char rop); 181void gu2_pattern_fill(unsigned short x, unsigned short y, 182 unsigned short width, unsigned short height); 183void gu2_color_pattern_fill(unsigned short x, unsigned short y, 184 unsigned short width, unsigned short height, 185 unsigned long *pattern); 186void gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 187 unsigned short dstx, unsigned short dsty, 188 unsigned short width, unsigned short height); 189void gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 190 unsigned short dstx, unsigned short dsty, 191 unsigned short width, unsigned short height, 192 unsigned long color); 193void gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 194 unsigned short dstx, unsigned short dsty, 195 unsigned short width, 196 unsigned short height, 197 unsigned char *data, long pitch); 198void gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 199 unsigned short dstx, unsigned short dsty, 200 unsigned short width, 201 unsigned short height, 202 unsigned char *data, long pitch, 203 unsigned long color); 204void gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 205 unsigned short dstx, unsigned short dsty, 206 unsigned short width, 207 unsigned short height, unsigned char *data, 208 short pitch); 209void gu2_text_blt(unsigned short dstx, unsigned short dsty, 210 unsigned short width, unsigned short height, 211 unsigned char *data); 212void gu2_bresenham_line(unsigned short x, unsigned short y, 213 unsigned short length, unsigned short initerr, 214 unsigned short axialerr, unsigned short diagerr, 215 unsigned short flags); 216void gu2_wait_until_idle(void); 217int gu2_test_blt_pending(void); 218 219/* SECOND GENERATION RENDERING ROUTINES */ 220 221void gu22_set_source_stride(unsigned short stride); 222void gu22_set_destination_stride(unsigned short stride); 223void gu22_set_pattern_origin(int x, int y); 224void gu22_set_source_transparency(unsigned long color, unsigned long mask); 225void gu22_set_alpha_mode(int mode); 226void gu22_set_alpha_value(unsigned char value); 227void gu22_pattern_fill(unsigned long dstoffset, unsigned short width, 228 unsigned short height); 229void gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width, 230 unsigned short height, unsigned long *pattern); 231void gu22_screen_to_screen_blt(unsigned long srcoffset, 232 unsigned long dstoffset, unsigned short width, 233 unsigned short height, int flags); 234void gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx, 235 unsigned short srcy, unsigned long dstoffset, 236 unsigned short width, unsigned short height, 237 int byte_packed); 238void gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 239 unsigned long dstoffset, 240 unsigned short width, 241 unsigned short height, 242 unsigned char *data, short pitch); 243void gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 244 unsigned long dstoffset, 245 unsigned short width, 246 unsigned short height, 247 unsigned char *data, short pitch); 248void gu22_text_blt(unsigned long dstoffset, unsigned short width, 249 unsigned short height, unsigned char *data); 250void gu22_bresenham_line(unsigned long dstoffset, unsigned short length, 251 unsigned short initerr, unsigned short axialerr, 252 unsigned short diagerr, unsigned short flags); 253void gu22_sync_to_vblank(void); 254void gu2_reset_pitch(unsigned short pitch); 255 256#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) 257#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) 258#define GU2_WAIT_HALF_EMPTY while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY)) 259 260/* PATTERN SWIZZLES */ 261 262#define WORD_SWIZZLE(x) (((x) << 16) | ((x) >> 16)) 263#define BYTE_SWIZZLE(x) (((x) << 24) | ((x) >> 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00)) 264 265/* GLOBAL VARIABLES USED BY THE RENDERING ROUTINES */ 266 267unsigned long gu2_bpp; 268unsigned long gu2_pitch = 1280; 269unsigned long gu2_src_pitch = 1280; 270unsigned long gu2_dst_pitch = 1280; 271unsigned long gu2_xshift = 1; 272unsigned long gu2_pattern_origin = 0; 273unsigned long gu2_rop32; 274unsigned long gu2_alpha32 = 0; 275unsigned long gu2_alpha_value = 0; 276unsigned long gu2_alpha_mode = 0; 277unsigned long gu2_alpha_active = 0; 278unsigned short gu2_alpha_blt_mode = 0; 279unsigned short gu2_alpha_vec_mode = 0; 280unsigned short gu2_blt_mode = 0; 281unsigned short gu2_vector_mode = 0; 282unsigned short gu2_bm_throttle = 0; 283unsigned short gu2_vm_throttle = 0; 284int gu2_current_line = 0; 285 286/*--------------------------------------------------------------------------- 287 * GFX_RESET_PITCH (PRIVATE ROUTINE - NOT PART OF API) 288 * 289 * This routine resets all pitches in the graphics engine to one value. 290 *--------------------------------------------------------------------------- 291 */ 292#if GFX_2DACCEL_DYNAMIC 293void 294gu2_reset_pitch(unsigned short pitch) 295#else 296void 297gfx_reset_pitch(unsigned short pitch) 298#endif 299{ 300 gu2_pitch = pitch; 301 gu2_dst_pitch = pitch; 302 gu2_src_pitch = pitch; 303} 304 305/*--------------------------------------------------------------------------- 306 * GFX_SET_BPP 307 * 308 * This routine sets the bits per pixel value in the graphics engine. 309 * It is also stored in the static variable "gu2_bpp" to use in the future 310 * calls to the rendering routines. That variable contains the hardware 311 * specific value to load into the MGP_RASTER_MODE register. 312 *--------------------------------------------------------------------------- 313 */ 314#if GFX_2DACCEL_DYNAMIC 315void 316gu2_set_bpp(unsigned short bpp) 317#else 318void 319gfx_set_bpp(unsigned short bpp) 320#endif 321{ 322 GFXbpp = bpp; 323 324 /* COVERT TO BPP/FORMAT VALUE */ 325 /* Save in global to combine with ROP later. */ 326 /* Could write register here and then use byte access for */ 327 /* the ROP, but would need to set other 24 bits to make */ 328 /* sure all are set to their appropriate values. */ 329 330 switch (bpp) { 331 case 8: 332 gu2_bpp = MGP_RM_BPPFMT_332; 333 gu2_xshift = 0; 334 break; 335 case 12: 336 gu2_bpp = MGP_RM_BPPFMT_4444; 337 gu2_xshift = 1; 338 break; 339 case 15: 340 gu2_bpp = MGP_RM_BPPFMT_1555; 341 gu2_xshift = 1; 342 break; 343 case 16: 344 gu2_bpp = MGP_RM_BPPFMT_565; 345 gu2_xshift = 1; 346 break; 347 case 32: 348 gu2_bpp = MGP_RM_BPPFMT_8888; 349 gu2_xshift = 2; 350 break; 351 } 352 353 /* SET INITIAL ROP BASED ONLY ON BPP */ 354 /* Needs to be set before loading any pattern or source colors. */ 355 /* We must wait for BUSY because these bits are not pipelined */ 356 /* in the hardware. */ 357 358 GU2_WAIT_BUSY; 359 WRITE_GP32(MGP_RASTER_MODE, gu2_bpp); 360} 361 362/* 363//--------------------------------------------------------------------------- 364// GFX_SET_SOLID_SOURCE 365// 366// This routine is used to specify a solid source color. For the Xfree96 367// display driver, the source color is used to specify a planemask and the 368// ROP is adjusted accordingly. 369//--------------------------------------------------------------------------- 370*/ 371#if GFX_2DACCEL_DYNAMIC 372void 373gu2_set_solid_source(unsigned long color) 374#else 375void 376gfx_set_solid_source(unsigned long color) 377#endif 378{ 379 /* CLEAR TRANSPARENCY FLAG */ 380 381 GFXsourceFlags = 0; 382 383 /* WRITE REGISTERS TO SPECIFY SOURCE COLOR */ 384 385 GU2_WAIT_PENDING; 386 WRITE_GP32(MGP_SRC_COLOR_FG, color); 387} 388 389/* 390//--------------------------------------------------------------------------- 391// GFX_SET_MONO_SOURCE 392// 393// This routine is used to specify the monochrome source colors. 394// It must be called *after* loading any pattern data (those routines 395// clear the source flags). 396//--------------------------------------------------------------------------- 397*/ 398#if GFX_2DACCEL_DYNAMIC 399void 400gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 401 unsigned short transparent) 402#else 403void 404gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor, 405 unsigned short transparent) 406#endif 407{ 408 /* SET TRANSPARENCY FLAG */ 409 410 GFXsourceFlags = transparent ? MGP_RM_SRC_TRANS : 0; 411 412 /* WRITE COLOR VALUES */ 413 414 GU2_WAIT_PENDING; 415 WRITE_GP32(MGP_SRC_COLOR_FG, fgcolor); 416 WRITE_GP32(MGP_SRC_COLOR_BG, bgcolor); 417} 418 419/* 420//--------------------------------------------------------------------------- 421// GFX_SET_SOLID_PATTERN 422// 423// This routine is used to specify a solid pattern color. It is called 424// before performing solid rectangle fills or more complicated BLTs that 425// use a solid pattern color. 426// 427// The driver should always call "gfx_load_raster_operation" after a call 428// to this routine to make sure that the pattern flags are set appropriately. 429//--------------------------------------------------------------------------- 430*/ 431#if GFX_2DACCEL_DYNAMIC 432void 433gu2_set_solid_pattern(unsigned long color) 434#else 435void 436gfx_set_solid_pattern(unsigned long color) 437#endif 438{ 439 /* CLEAR TRANSPARENCY FLAG */ 440 441 GFXsourceFlags = 0; 442 443 /* SET PATTERN FLAGS */ 444 445 GFXpatternFlags = 0; 446 447 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 448 449 GU2_WAIT_PENDING; 450 WRITE_GP32(MGP_RASTER_MODE, gu2_bpp); 451 WRITE_GP32(MGP_PAT_COLOR_0, color); 452} 453 454/* 455//--------------------------------------------------------------------------- 456// GFX_SET_MONO_PATTERN 457// 458// This routine is used to specify a monochrome pattern. 459//--------------------------------------------------------------------------- 460*/ 461#if GFX_2DACCEL_DYNAMIC 462void 463gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 464 unsigned long data0, unsigned long data1, 465 unsigned char transparent) 466#else 467void 468gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor, 469 unsigned long data0, unsigned long data1, 470 unsigned char transparent) 471#endif 472{ 473 /* CLEAR TRANSPARENCY FLAG */ 474 475 GFXsourceFlags = 0; 476 477 /* SET PATTERN FLAGS */ 478 479 if (transparent) 480 GFXpatternFlags = MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS; 481 else 482 GFXpatternFlags = MGP_RM_PAT_MONO; 483 484 /* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */ 485 486 GU2_WAIT_PENDING; 487 WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GFXpatternFlags); 488 WRITE_GP32(MGP_PAT_COLOR_0, bgcolor); 489 WRITE_GP32(MGP_PAT_COLOR_1, fgcolor); 490 WRITE_GP32(MGP_PAT_DATA_0, data0); 491 WRITE_GP32(MGP_PAT_DATA_1, data1); 492} 493 494/* 495//--------------------------------------------------------------------------- 496// GFX_SET_COLOR_PATTERN 497// 498// This routine is used to specify a color pattern. 499//--------------------------------------------------------------------------- 500*/ 501#if GFX_2DACCEL_DYNAMIC 502void 503gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 504 unsigned long data0, unsigned long data1, 505 unsigned long data2, unsigned long data3, 506 unsigned char transparent) 507#else 508void 509gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor, 510 unsigned long data0, unsigned long data1, 511 unsigned long data2, unsigned long data3, 512 unsigned char transparent) 513#endif 514{ 515 /* REMOVE */ 516} 517 518/* 519//--------------------------------------------------------------------------- 520// GFX_LOAD_COLOR_PATTERN_LINE 521// 522// This routine is used to load a single line of a 8x8 color pattern. 523//--------------------------------------------------------------------------- 524*/ 525#if GFX_2DACCEL_DYNAMIC 526void 527gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8) 528#else 529void 530gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8) 531#endif 532{ 533 unsigned long temp1, temp2, temp3, temp4; 534 535 /* CLEAR TRANSPARENCY FLAG */ 536 537 GFXsourceFlags = 0; 538 539 /* SET PATTERN FLAGS */ 540 541 GFXpatternFlags = MGP_RM_PAT_COLOR; 542 543 /* OVERRIDE THE RASTER MODE REGISTER */ 544 /* If the pattern format is set to anything but color */ 545 /* before loading the registers, some of the data will */ 546 /* be duplicated according to the current mode. */ 547 548 GU2_WAIT_PENDING; 549 WRITE_GP32(MGP_RASTER_MODE, 550 (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR); 551 552 /* LOAD THE PATTERN DATA */ 553 /* This routine is designed to work in tandem with gfx_pattern_fill. */ 554 /* It is used for cases when multiple BLTs with color pattern data */ 555 /* are desired on the same line. It would be inefficient to */ 556 /* repeatedly call gfx_color_pattern_fill for each single-line BLT. */ 557 /* So, we will simply replicate the pattern data across all available */ 558 /* lines such that the pattern y origin plays no part in the BLT. */ 559 560 /* 8 BPP */ 561 562 if (gu2_xshift == 0) { 563 pattern_8x8 += (y & 7) << 1; 564 temp1 = BYTE_SWIZZLE(pattern_8x8[0]); 565 temp2 = BYTE_SWIZZLE(pattern_8x8[1]); 566 WRITE_GP32(MGP_PAT_DATA_1, temp1); 567 WRITE_GP32(MGP_PAT_DATA_0, temp2); 568 WRITE_GP32(MGP_PAT_COLOR_1, temp1); 569 WRITE_GP32(MGP_PAT_COLOR_0, temp2); 570 571 GU2_WAIT_BUSY; 572 WRITE_GP32(MGP_PAT_COLOR_3, temp1); 573 WRITE_GP32(MGP_PAT_COLOR_2, temp2); 574 WRITE_GP32(MGP_PAT_COLOR_5, temp1); 575 WRITE_GP32(MGP_PAT_COLOR_4, temp2); 576 } else if (gu2_xshift == 1) { 577 pattern_8x8 += (y & 7) << 2; 578 temp1 = WORD_SWIZZLE(pattern_8x8[0]); 579 temp2 = WORD_SWIZZLE(pattern_8x8[1]); 580 temp3 = WORD_SWIZZLE(pattern_8x8[2]); 581 temp4 = WORD_SWIZZLE(pattern_8x8[3]); 582 583 WRITE_GP32(MGP_PAT_COLOR_1, temp1); 584 WRITE_GP32(MGP_PAT_COLOR_0, temp2); 585 WRITE_GP32(MGP_PAT_DATA_1, temp3); 586 WRITE_GP32(MGP_PAT_DATA_0, temp4); 587 588 GU2_WAIT_BUSY; 589 WRITE_GP32(MGP_PAT_COLOR_5, temp1); 590 WRITE_GP32(MGP_PAT_COLOR_4, temp2); 591 WRITE_GP32(MGP_PAT_COLOR_3, temp3); 592 WRITE_GP32(MGP_PAT_COLOR_2, temp4); 593 } else { 594 pattern_8x8 += (y & 7) << 3; 595 596 WRITE_GP32(MGP_PAT_COLOR_1, pattern_8x8[4]); 597 WRITE_GP32(MGP_PAT_COLOR_0, pattern_8x8[5]); 598 WRITE_GP32(MGP_PAT_DATA_1, pattern_8x8[6]); 599 WRITE_GP32(MGP_PAT_DATA_0, pattern_8x8[7]); 600 601 GU2_WAIT_BUSY; 602 WRITE_GP32(MGP_PAT_COLOR_5, pattern_8x8[0]); 603 WRITE_GP32(MGP_PAT_COLOR_4, pattern_8x8[1]); 604 WRITE_GP32(MGP_PAT_COLOR_3, pattern_8x8[2]); 605 WRITE_GP32(MGP_PAT_COLOR_2, pattern_8x8[3]); 606 } 607} 608 609/* 610//--------------------------------------------------------------------------- 611// GFX_SET_RASTER_OPERATION 612// 613// This routine loads the specified raster operation. It sets the pattern 614// flags appropriately. 615//--------------------------------------------------------------------------- 616*/ 617#if GFX_2DACCEL_DYNAMIC 618void 619gu2_set_raster_operation(unsigned char rop) 620#else 621void 622gfx_set_raster_operation(unsigned char rop) 623#endif 624{ 625 gu2_blt_mode = 0; 626 627 /* DISABLE ALPHA BLENDING */ 628 629 gu2_alpha_active = 0; 630 631 /* GENERATE 32-BIT VERSION OF ROP WITH PATTERN FLAGS */ 632 633 gu2_rop32 = (unsigned long)rop | GFXpatternFlags | gu2_bpp; 634 635 /* CHECK IF SOURCE FLAGS SHOULD BE MERGED */ 636 637 if ((rop & 0x33) ^ ((rop >> 2) & 0x33)) 638 gu2_rop32 |= GFXsourceFlags; 639 else 640 gu2_blt_mode = 0x40; 641 642 /* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */ 643 /* True if even bits (0:2:4:6) do not equal the corresponding */ 644 /* even bits (1:3:5:7). */ 645 646 if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) { 647 gu2_blt_mode |= MGP_BM_DST_REQ; 648 gu2_vector_mode = MGP_VM_DST_REQ; 649 } else { 650 gu2_vector_mode = 0; 651 } 652} 653 654/* 655//---------------------------------------------------------------------------- 656// GFX_PATTERN_FILL 657// 658// This routine is used to fill a rectangular region. The pattern must 659// be previously loaded using one of GFX_load_*_pattern routines. Also, the 660// raster operation must be previously specified using the 661// "GFX_load_raster_operation" routine. 662// 663// X screen X position (left) 664// Y screen Y position (top) 665// WIDTH width of rectangle, in pixels 666// HEIGHT height of rectangle, in scanlines 667//---------------------------------------------------------------------------- 668*/ 669#if GFX_2DACCEL_DYNAMIC 670void 671gu2_pattern_fill(unsigned short x, unsigned short y, 672 unsigned short width, unsigned short height) 673#else 674void 675gfx_pattern_fill(unsigned short x, unsigned short y, 676 unsigned short width, unsigned short height) 677#endif 678{ 679 unsigned long offset = 0, size; 680 681 size = (((unsigned long)width) << 16) | height; 682 683 /* CALCULATE STARTING OFFSET */ 684 685 offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift); 686 687 /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 688 689 if (GFXpatternFlags) { 690 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 691 692 offset |= ((unsigned long)(x & 7)) << 26; 693 offset |= ((unsigned long)(y & 7)) << 29; 694 } 695 696 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 697 /* Put off poll for as long as possible (do most calculations first). */ 698 699 GU2_WAIT_PENDING; 700 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 701 WRITE_GP32(MGP_DST_OFFSET, offset); 702 WRITE_GP32(MGP_WID_HEIGHT, size); 703 WRITE_GP32(MGP_STRIDE, gu2_pitch); 704 WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode); 705} 706 707/* 708//---------------------------------------------------------------------------- 709// GFX_COLOR_PATTERN_FILL 710// 711// This routine is used to render a rectangle using the current raster 712// operation and the specified color pattern. It allows an 8x8 color 713// pattern to be rendered without multiple calls to the gfx_set_color_pattern 714// and gfx_pattern_fill routines. 715// 716// X screen X position (left) 717// Y screen Y position (top) 718// WIDTH width of rectangle, in pixels 719// HEIGHT height of rectangle, in scanlines 720// *PATTERN pointer to 8x8 color pattern data 721//---------------------------------------------------------------------------- 722*/ 723#if GFX_2DACCEL_DYNAMIC 724void 725gu2_color_pattern_fill(unsigned short x, unsigned short y, 726 unsigned short width, unsigned short height, 727 unsigned long *pattern) 728#else 729void 730gfx_color_pattern_fill(unsigned short x, unsigned short y, 731 unsigned short width, unsigned short height, 732 unsigned long *pattern) 733#endif 734{ 735 /* CALL GFX2 ROUTINE TO AVOID DUPLICATION OF CODE */ 736 737 unsigned long offset = (unsigned long)y * gu2_pitch + 738 (((unsigned long)x) << gu2_xshift); 739 unsigned long origin = gu2_pattern_origin; 740 unsigned long pitch = gu2_dst_pitch; 741 742 gfx2_set_pattern_origin(x, y); 743 gfx2_set_destination_stride((unsigned short)gu2_pitch); 744 gfx2_color_pattern_fill(offset, width, height, pattern); 745 746 /* RESTORE GFX2 VALUES */ 747 748 gu2_pattern_origin = origin; 749 gu2_dst_pitch = pitch; 750} 751 752/* 753//---------------------------------------------------------------------------- 754// SCREEN TO SCREEN BLT 755// 756// This routine should be used to perform a screen to screen BLT when the 757// ROP does not require destination data. 758// 759// SRCX screen X position to copy from 760// SRCY screen Y position to copy from 761// DSTX screen X position to copy to 762// DSTY screen Y position to copy to 763// WIDTH width of rectangle, in pixels 764// HEIGHT height of rectangle, in scanlines 765//---------------------------------------------------------------------------- 766*/ 767#if GFX_2DACCEL_DYNAMIC 768void 769gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 770 unsigned short dstx, unsigned short dsty, 771 unsigned short width, unsigned short height) 772#else 773void 774gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy, 775 unsigned short dstx, unsigned short dsty, 776 unsigned short width, unsigned short height) 777#endif 778{ 779 unsigned long srcoffset, dstoffset, size; 780 unsigned short blt_mode; 781 782 size = (((unsigned long)width) << 16) | height; 783 784 /* CALCULATE THE DIRECTION OF THE BLT */ 785 786 blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; 787 if (dstx > srcx) { 788 blt_mode |= MGP_BM_NEG_XDIR; 789 srcx += width - 1; 790 dstx += width - 1; 791 } 792 if (dsty > srcy) { 793 blt_mode |= MGP_BM_NEG_YDIR; 794 srcy += height - 1; 795 dsty += height - 1; 796 } 797 798 /* CALCULATE STARTING OFFSETS */ 799 800 srcoffset = (unsigned long)srcy *gu2_pitch + 801 (((unsigned long)srcx) << gu2_xshift); 802 dstoffset = ((unsigned long)dsty * gu2_pitch + 803 (((unsigned long)dstx) << gu2_xshift)) & 0xFFFFFF; 804 805 /* MERGE PATTERN INFORMATION */ 806 /* This must be done after the x and y coordinates have been updated, */ 807 /* as the x and y pattern origins correspond to the first ROPed pixel. */ 808 809 if (GFXpatternFlags) { 810 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 811 812 dstoffset |= ((unsigned long)(dstx & 7)) << 26; 813 dstoffset |= ((unsigned long)(dsty & 7)) << 29; 814 } 815 816 /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */ 817 /* This is a quirk of the hardware. */ 818 819 if (blt_mode & MGP_BM_NEG_XDIR) { 820 srcoffset += (1 << gu2_xshift) - 1; 821 dstoffset += (1 << gu2_xshift) - 1; 822 } 823 824 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 825 /* Put off poll for as long as possible (do most calculations first). */ 826 827 GU2_WAIT_PENDING; 828 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 829 WRITE_GP32(MGP_SRC_OFFSET, srcoffset); 830 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 831 WRITE_GP32(MGP_WID_HEIGHT, size); 832 WRITE_GP32(MGP_STRIDE, gu2_pitch | (gu2_pitch << 16)); 833 WRITE_GP16(MGP_BLT_MODE, blt_mode); 834} 835 836/* 837//---------------------------------------------------------------------------- 838// SCREEN TO SCREEN TRANSPARENT BLT 839// 840// This routine should be used to perform a screen to screen BLT when a 841// specified color should by transparent. The only supported ROP is SRCCOPY. 842// 843// SRCX screen X position to copy from 844// SRCY screen Y position to copy from 845// DSTX screen X position to copy to 846// DSTY screen Y position to copy to 847// WIDTH width of rectangle, in pixels 848// HEIGHT height of rectangle, in scanlines 849// COLOR transparent color 850//---------------------------------------------------------------------------- 851*/ 852#if GFX_2DACCEL_DYNAMIC 853void 854gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 855 unsigned short dstx, unsigned short dsty, 856 unsigned short width, unsigned short height, 857 unsigned long color) 858#else 859void 860gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy, 861 unsigned short dstx, unsigned short dsty, 862 unsigned short width, unsigned short height, 863 unsigned long color) 864#endif 865{ 866 unsigned long rop32; 867 868 /* SAVE ORIGINAL RASTER MODE SETTINGS */ 869 870 rop32 = gu2_rop32; 871 872 /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ 873 /* Match GU1 implementation that only allows SRCCOPY for the ROP. */ 874 875 GU2_WAIT_PENDING; 876 WRITE_GP32(MGP_SRC_COLOR_FG, color); 877 WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF); 878 879 /* SET GLOBAL RASTER SETTINGS */ 880 /* This is needed, as the screen-to-screen BLT */ 881 /* routine will overwrite the raster mode register. */ 882 883 gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC; 884 885 /* CALL NORMAL SCREEN TO SCREEN BLT ROUTINE */ 886 887 gfx_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height); 888 889 /* RESTORE GLOBAL RASTER SETTINGS */ 890 891 gu2_rop32 = rop32; 892} 893 894/* 895//---------------------------------------------------------------------------- 896// COLOR BITMAP TO SCREEN BLT 897// 898// This routine transfers color bitmap data to the screen. 899// 900// SRCX X offset within source bitmap 901// SRCY Y offset within source bitmap 902// DSTX screen X position to render data 903// DSTY screen Y position to render data 904// WIDTH width of rectangle, in pixels 905// HEIGHT height of rectangle, in scanlines 906// *DATA pointer to bitmap data 907// PITCH pitch of bitmap data (bytes between scanlines) 908// 909// Transparency is handled by another routine. 910//---------------------------------------------------------------------------- 911*/ 912 913#if GFX_2DACCEL_DYNAMIC 914void 915gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 916 unsigned short dstx, unsigned short dsty, 917 unsigned short width, unsigned short height, 918 unsigned char *data, long pitch) 919#else 920void 921gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 922 unsigned short dstx, unsigned short dsty, 923 unsigned short width, unsigned short height, 924 unsigned char *data, long pitch) 925#endif 926{ 927 unsigned long dstoffset, srcoffset, size, bytes; 928 unsigned long offset, temp_offset; 929 unsigned long dword_bytes, bytes_extra; 930 unsigned short blt_mode; 931 932 blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; 933 size = (((unsigned long)width) << 16) | 1; 934 935 /* CALCULATE STARTING OFFSETS */ 936 937 offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift); 938 939 dstoffset = (unsigned long)dsty *gu2_pitch + 940 (((unsigned long)dstx) << gu2_xshift); 941 942 /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 943 944 if (GFXpatternFlags) { 945 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 946 947 dstoffset |= ((unsigned long)(dstx & 7)) << 26; 948 dstoffset |= ((unsigned long)(dsty & 7)) << 29; 949 } 950 951 bytes = width << gu2_xshift; 952 dword_bytes = bytes & ~0x3L; 953 bytes_extra = bytes & 0x3L; 954 955 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 956 /* Put off poll for as long as possible (do most calculations first). */ 957 /* The source offset is always 0 since we allow misaligned dword reads. */ 958 /* We must wait for BLT busy because the GP may be executing a screen */ 959 /* to screen BLT from the scratchpad area. */ 960 961 GU2_WAIT_BUSY; 962 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 963 WRITE_GP32(MGP_WID_HEIGHT, size); 964 WRITE_GP32(MGP_STRIDE, gu2_pitch); 965 966 /* WRITE DATA ONE LINE AT A TIME */ 967 /* For speed reasons, data is written to an offscreen scratch area and then */ 968 /* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */ 969 /* slightly more efficient in that we can queue up data while the GP is rendering */ 970 /* a line. */ 971 972 while (height--) { 973 temp_offset = offset; 974 srcoffset = gfx_gx2_scratch_base; 975 if (gu2_current_line) 976 srcoffset += 8192; 977 978 GU2_WAIT_PENDING; 979 WRITE_GP32(MGP_SRC_OFFSET, srcoffset); 980 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 981 dstoffset += gu2_pitch; 982 dstoffset += 0x20000000; 983 984 WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset); 985 if (bytes_extra) { 986 temp_offset += dword_bytes; 987 srcoffset += dword_bytes; 988 WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data, 989 temp_offset); 990 } 991 WRITE_GP16(MGP_BLT_MODE, blt_mode); 992 offset += pitch; 993 gu2_current_line = 1 - gu2_current_line; 994 } 995} 996 997/* 998//---------------------------------------------------------------------------- 999// COLOR BITMAP TO SCREEN TRANSPARENT BLT 1000// 1001// This routine transfers color bitmap data to the screen with transparency. 1002// The transparent color is specified. The only supported ROP is SRCCOPY, 1003// meaning that transparency cannot be applied if the ROP requires 1004// destination data (this is a hardware restriction). 1005// 1006// SRCX X offset within source bitmap 1007// SRCY Y offset within source bitmap 1008// DSTX screen X position to render data 1009// DSTY screen Y position to render data 1010// WIDTH width of rectangle, in pixels 1011// HEIGHT height of rectangle, in scanlines 1012// *DATA pointer to bitmap data 1013// PITCH pitch of bitmap data (bytes between scanlines) 1014// COLOR transparent color 1015//---------------------------------------------------------------------------- 1016*/ 1017#if GFX_2DACCEL_DYNAMIC 1018void 1019gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1020 unsigned short dstx, unsigned short dsty, 1021 unsigned short width, unsigned short height, 1022 unsigned char *data, long pitch, 1023 unsigned long color) 1024#else 1025void 1026gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy, 1027 unsigned short dstx, unsigned short dsty, 1028 unsigned short width, unsigned short height, 1029 unsigned char *data, long pitch, 1030 unsigned long color) 1031#endif 1032{ 1033 unsigned long rop32; 1034 1035 /* SAVE EXISTING RASTER MODE SETTINGS */ 1036 1037 rop32 = gu2_rop32; 1038 1039 /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ 1040 /* Match GU1 implementation that only allows SRCCOPY for the ROP. */ 1041 1042 GU2_WAIT_PENDING; 1043 WRITE_GP32(MGP_SRC_COLOR_FG, color); 1044 WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF); 1045 1046 /* SET GLOBAL RASTER SETTINGS */ 1047 /* This is needed, as the screen-to-screen BLT */ 1048 /* routine will overwrite the raster mode register. */ 1049 1050 gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC; 1051 1052 /* CALL NORMAL COLOR BITMAP TO SCREEN BLT ROUTINE */ 1053 1054 gfx_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height, 1055 data, pitch); 1056 1057 /* RESTORE RASTER SETTINGS */ 1058 1059 gu2_rop32 = rop32; 1060} 1061 1062/* 1063//---------------------------------------------------------------------------- 1064// MONOCHROME BITMAP TO SCREEN BLT 1065// 1066// This routine transfers monochrome bitmap data to the screen. 1067// 1068// SRCX X offset within source bitmap 1069// SRCY Y offset within source bitmap 1070// DSTX screen X position to render data 1071// DSTY screen Y position to render data 1072// WIDTH width of rectangle, in pixels 1073// HEIGHT height of rectangle, in scanlines 1074// *DATA pointer to bitmap data 1075// PITCH pitch of bitmap data (bytes between scanlines) 1076//---------------------------------------------------------------------------- 1077*/ 1078#if GFX_2DACCEL_DYNAMIC 1079void 1080gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1081 unsigned short dstx, unsigned short dsty, 1082 unsigned short width, unsigned short height, 1083 unsigned char *data, short pitch) 1084#else 1085void 1086gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 1087 unsigned short dstx, unsigned short dsty, 1088 unsigned short width, unsigned short height, 1089 unsigned char *data, short pitch) 1090#endif 1091{ 1092 unsigned long dstoffset, size, bytes; 1093 unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; 1094 unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 1095 unsigned long shift = 0; 1096 1097 size = (((unsigned long)width) << 16) | height; 1098 1099 /* CALCULATE STARTING OFFSETS */ 1100 1101 offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); 1102 1103 dstoffset = (unsigned long)dsty *gu2_pitch + 1104 (((unsigned long)dstx) << gu2_xshift); 1105 1106 /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 1107 1108 if (GFXpatternFlags) { 1109 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 1110 1111 dstoffset |= ((unsigned long)(dstx & 7)) << 26; 1112 dstoffset |= ((unsigned long)(dsty & 7)) << 29; 1113 } 1114 1115 bytes = ((srcx & 7) + width + 7) >> 3; 1116 fifo_lines = bytes >> 5; 1117 dwords_extra = (bytes & 0x0000001Cl) >> 2; 1118 bytes_extra = bytes & 0x00000003l; 1119 1120 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1121 /* Put off poll for as long as possible (do most calculations first). */ 1122 /* The source offset is always 0 since we allow misaligned dword reads. */ 1123 /* Need to wait for busy instead of pending, since hardware clears */ 1124 /* the host data FIFO at the beginning of a BLT. */ 1125 1126 GU2_WAIT_PENDING; 1127 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 1128 WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); 1129 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 1130 WRITE_GP32(MGP_WID_HEIGHT, size); 1131 WRITE_GP32(MGP_STRIDE, gu2_pitch); 1132 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | MGP_BM_SRC_MONO); 1133 1134 /* WAIT FOR BLT TO BE LATCHED */ 1135 1136 GU2_WAIT_PENDING; 1137 1138 /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ 1139 1140 while (height--) { 1141 temp_offset = offset; 1142 1143 /* WRITE ALL FULL FIFO LINES */ 1144 1145 for (i = 0; i < fifo_lines; i++) { 1146 GU2_WAIT_HALF_EMPTY; 1147 WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); 1148 temp_offset += 32; 1149 } 1150 1151 /* WRITE ALL FULL DWORDS */ 1152 1153 GU2_WAIT_HALF_EMPTY; 1154 if (dwords_extra) { 1155 WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, 1156 temp_offset, temp1); 1157 temp_offset += (dwords_extra << 2); 1158 } 1159 1160 /* WRITE REMAINING BYTES */ 1161 1162 shift = 0; 1163 if (bytes_extra) 1164 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 1165 temp_offset, temp1, temp2); 1166 1167 offset += pitch; 1168 } 1169} 1170 1171/*--------------------------------------------------------------------------- 1172 * GFX_TEXT_BLT 1173 * 1174 * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine 1175 * but assumes that source data is byte-packed. 1176 *--------------------------------------------------------------------------- 1177 */ 1178#if GFX_2DACCEL_DYNAMIC 1179void 1180gu2_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 1181 unsigned short height, unsigned char *data) 1182#else 1183void 1184gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width, 1185 unsigned short height, unsigned char *data) 1186#endif 1187{ 1188 unsigned long size, bytes; 1189 unsigned long dstoffset, temp1 = 0, temp2 = 0, temp_offset = 0; 1190 unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 1191 unsigned long shift; 1192 1193 size = (((unsigned long)width) << 16) | height; 1194 1195 dstoffset = (unsigned long)dsty *gu2_pitch + 1196 (((unsigned long)dstx) << gu2_xshift); 1197 1198 /* CHECK IF PATTERN ORIGINS NEED TO BE SET */ 1199 1200 if (GFXpatternFlags) { 1201 /* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */ 1202 1203 dstoffset |= ((unsigned long)(dstx & 7)) << 26; 1204 dstoffset |= ((unsigned long)(dsty & 7)) << 29; 1205 } 1206 1207 /* CALCULATE STARTING OFFSETS */ 1208 1209 bytes = ((width + 7) >> 3) * height; 1210 fifo_lines = bytes >> 5; 1211 dwords_extra = (bytes & 0x0000001Cl) >> 2; 1212 bytes_extra = bytes & 0x00000003l; 1213 1214 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1215 1216 GU2_WAIT_PENDING; 1217 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 1218 WRITE_GP32(MGP_SRC_OFFSET, 0); 1219 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 1220 WRITE_GP32(MGP_WID_HEIGHT, size); 1221 WRITE_GP32(MGP_STRIDE, gu2_pitch); 1222 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | MGP_BM_SRC_HOST | 1223 MGP_BM_SRC_BP_MONO); 1224 1225 /* WAIT FOR BLT TO BE LATCHED */ 1226 1227 GU2_WAIT_PENDING; 1228 1229 /* WRITE ALL FULL FIFO LINES */ 1230 1231 for (i = 0; i < fifo_lines; i++) { 1232 GU2_WAIT_HALF_EMPTY; 1233 WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); 1234 temp_offset += 32; 1235 } 1236 1237 /* WRITE ALL FULL DWORDS */ 1238 1239 if (dwords_extra || bytes_extra) { 1240 GU2_WAIT_HALF_EMPTY; 1241 if (dwords_extra) { 1242 WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, 1243 temp_offset, temp1); 1244 temp_offset += (dwords_extra << 2); 1245 } 1246 if (bytes_extra) { 1247 shift = 0; 1248 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 1249 temp_offset, temp1, temp2); 1250 } 1251 } 1252} 1253 1254/* 1255//---------------------------------------------------------------------------- 1256// BRESENHAM LINE 1257// 1258// This routine draws a vector using the specified Bresenham parameters. 1259// Currently this file does not support a routine that accepts the two 1260// endpoints of a vector and calculates the Bresenham parameters. If it 1261// ever does, this routine is still required for vectors that have been 1262// clipped. 1263// 1264// X screen X position to start vector 1265// Y screen Y position to start vector 1266// LENGTH length of the vector, in pixels 1267// INITERR Bresenham initial error term 1268// AXIALERR Bresenham axial error term 1269// DIAGERR Bresenham diagonal error term 1270// FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC 1271//---------------------------------------------------------------------------- 1272*/ 1273#if GFX_2DACCEL_DYNAMIC 1274void 1275gu2_bresenham_line(unsigned short x, unsigned short y, 1276 unsigned short length, unsigned short initerr, 1277 unsigned short axialerr, unsigned short diagerr, 1278 unsigned short flags) 1279#else 1280void 1281gfx_bresenham_line(unsigned short x, unsigned short y, 1282 unsigned short length, unsigned short initerr, 1283 unsigned short axialerr, unsigned short diagerr, 1284 unsigned short flags) 1285#endif 1286{ 1287 unsigned long offset; 1288 unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr; 1289 unsigned long data2 = (((unsigned long)length) << 16) | initerr; 1290 unsigned short vector_mode = gu2_vector_mode | flags; 1291 1292 /* CALCULATE STARTING OFFSET */ 1293 1294 offset = (unsigned long)y *gu2_pitch + (((unsigned long)x) << gu2_xshift); 1295 1296 /* CHECK NULL LENGTH */ 1297 1298 if (!length) 1299 return; 1300 1301 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1302 /* Put off poll for as long as possible (do most calculations first). */ 1303 1304 GU2_WAIT_PENDING; 1305 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 1306 WRITE_GP32(MGP_DST_OFFSET, offset); 1307 WRITE_GP32(MGP_VEC_ERR, data1); 1308 WRITE_GP32(MGP_VEC_LEN, data2); 1309 WRITE_GP32(MGP_STRIDE, gu2_pitch); 1310 WRITE_GP32(MGP_VECTOR_MODE, vector_mode); 1311} 1312 1313/*--------------------------------------------------------------------------- 1314 * GFX_WAIT_UNTIL_IDLE 1315 * 1316 * This routine waits until the graphics engine is idle. This is required 1317 * before allowing direct access to the frame buffer. 1318 *--------------------------------------------------------------------------- 1319 */ 1320#if GFX_2DACCEL_DYNAMIC 1321void 1322gu2_wait_until_idle(void) 1323#else 1324void 1325gfx_wait_until_idle(void) 1326#endif 1327{ 1328 while (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) ; 1329} 1330 1331/*--------------------------------------------------------------------------- 1332 * GFX_TEST_BLT_PENDING 1333 * 1334 * This routine returns 1 if a BLT is pending, meaning that a call to 1335 * perform a rendering operation would stall. Otherwise it returns 0. 1336 * It is used by Darwin during random testing to only start a BLT 1337 * operation when it knows the Durango routines won't spin on graphics 1338 * (so Darwin can continue to do frame buffer reads and writes). 1339 *--------------------------------------------------------------------------- 1340 */ 1341#if GFX_2DACCEL_DYNAMIC 1342int 1343gu2_test_blt_pending(void) 1344#else 1345int 1346gfx_test_blt_pending(void) 1347#endif 1348{ 1349 if (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) 1350 return (1); 1351 return (0); 1352} 1353 1354/*--------------------------------------------------------------------------- 1355 * NEW ROUTINES FOR REDCLOUD 1356 *--------------------------------------------------------------------------- 1357 */ 1358 1359/*--------------------------------------------------------------------------- 1360 * GFX2_SET_SOURCE_STRIDE 1361 * 1362 * This routine sets the stride to be used in successive screen to screen 1363 * BLTs (used by gfx2_screen_to_screen_blt and gfx2_mono_expand_blt). 1364 *--------------------------------------------------------------------------- 1365 */ 1366#if GFX_2DACCEL_DYNAMIC 1367void 1368gu22_set_source_stride(unsigned short stride) 1369#else 1370void 1371gfx2_set_source_stride(unsigned short stride) 1372#endif 1373{ 1374 /* SAVE STRIDE TO BE USED LATER */ 1375 1376 gu2_src_pitch = (unsigned long)stride; 1377} 1378 1379/*--------------------------------------------------------------------------- 1380 * GFX2_SET_DESTINATION_STRIDE 1381 * 1382 * This routine sets the stride used when rendering to the screen. 1383 *--------------------------------------------------------------------------- 1384 */ 1385#if GFX_2DACCEL_DYNAMIC 1386void 1387gu22_set_destination_stride(unsigned short stride) 1388#else 1389void 1390gfx2_set_destination_stride(unsigned short stride) 1391#endif 1392{ 1393 /* SAVE STRIDE TO BE USED LATER */ 1394 1395 gu2_dst_pitch = (unsigned long)stride; 1396} 1397 1398/*--------------------------------------------------------------------------- 1399 * GFX2_SET_PATTERN_ORIGIN 1400 * 1401 * This routine sets the origin within an 8x8 pattern. It is needed if 1402 * using a monochrome or color pattern (not used for a solid pattern). 1403 *--------------------------------------------------------------------------- 1404 */ 1405#if GFX_2DACCEL_DYNAMIC 1406void 1407gu22_set_pattern_origin(int x, int y) 1408#else 1409void 1410gfx2_set_pattern_origin(int x, int y) 1411#endif 1412{ 1413 /* STORE IN FORMAT THAT CAN BE COMBINED WITH THE DESTINATION OFFSET */ 1414 1415 gu2_pattern_origin = (((unsigned long)(x & 7)) << 26) | 1416 (((unsigned long)(y & 7)) << 29); 1417} 1418 1419/*--------------------------------------------------------------------------- 1420 * GFX2_SET_SOURCE_TRANSPARENCY 1421 * 1422 * This routine sets the source transparency color and mask to be used 1423 * in future rendering operations. If both the color and mask are set 1424 * to zero (normally completely transparent), those values indicate that 1425 * transparency should be disabled. 1426 *--------------------------------------------------------------------------- 1427 */ 1428#if GFX_2DACCEL_DYNAMIC 1429void 1430gu22_set_source_transparency(unsigned long color, unsigned long mask) 1431#else 1432void 1433gfx2_set_source_transparency(unsigned long color, unsigned long mask) 1434#endif 1435{ 1436 /* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */ 1437 1438 GU2_WAIT_PENDING; 1439 WRITE_GP32(MGP_SRC_COLOR_FG, color); 1440 WRITE_GP32(MGP_SRC_COLOR_BG, mask); 1441 1442 /* SET TRANSPARENCY FLAG */ 1443 1444 GFXsourceFlags = (color || mask) ? MGP_RM_SRC_TRANS : 0; 1445} 1446 1447/*--------------------------------------------------------------------------- 1448 * GFX2_SET_ALPHA_MODE 1449 * 1450 * This routine sets the alpha blending mode to be used in successive 1451 * rendering operations. 1452 *--------------------------------------------------------------------------- 1453 */ 1454#if GFX_2DACCEL_DYNAMIC 1455void 1456gu22_set_alpha_mode(int mode) 1457#else 1458void 1459gfx2_set_alpha_mode(int mode) 1460#endif 1461{ 1462 /* SAVE ALPHA MODE FOR LATER */ 1463 1464 gu2_alpha_mode = mode; 1465} 1466 1467/*--------------------------------------------------------------------------- 1468 * GFX2_SET_ALPHA_VALUE 1469 * 1470 * This routine sets the alpha value to be used with certain alpha blending 1471 * modes (ALPHA_MODE_BLEND). 1472 *--------------------------------------------------------------------------- 1473 */ 1474#if GFX_2DACCEL_DYNAMIC 1475void 1476gu22_set_alpha_value(unsigned char value) 1477#else 1478void 1479gfx2_set_alpha_value(unsigned char value) 1480#endif 1481{ 1482 /* SAVE ALPHA VALUE TO BE USED LATER */ 1483 1484 gu2_alpha_value = (unsigned long)value; 1485 1486 /* SET GLOBAL FLAG */ 1487 /* gfx2_* routines will use this flag to program alpha values */ 1488 /* appropriately. Normal gfx_* routines will always write */ 1489 /* the current ROP settings. In this way, the alpha mode */ 1490 /* affects only second generation routines. */ 1491 1492 gu2_alpha_active = 1; 1493 1494 switch (gu2_alpha_mode) { 1495 case ALPHA_MODE_BLEND: 1496 1497 /* GENERATE 32-BIT VERSION OF RASTER MODE REGISTER */ 1498 /* Pattern data is not involved in the operation. */ 1499 1500 gu2_alpha32 = gu2_alpha_value | gu2_bpp; 1501 1502 /* HANDLE SPECIAL CASES FOR ENDPOINTS */ 1503 /* The 8-bit hardware alpha value is always */ 1504 /* interpreted as a fraction. Consequently, there */ 1505 /* is no way to use values of 255 or 0 to exclude */ 1506 /* one of the inputs. */ 1507 1508 switch (gu2_alpha_value) { 1509 /* DESTINATION ONLY */ 1510 /* Operation is alpha * A, where A is destination */ 1511 /* and alpha is 1. */ 1512 1513 case 0: 1514 1515 gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 | 1516 MGP_RM_ALPHA_TIMES_A | 1517 MGP_RM_ALPHA_TO_RGB | MGP_RM_DEST_FROM_CHAN_A; 1518 break; 1519 1520 /* SOURCE ONLY */ 1521 /* Operation is alpha * A, where A is source and */ 1522 /* alpha is 1. */ 1523 1524 case 255: 1525 1526 gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 | 1527 MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_TIMES_A; 1528 break; 1529 1530 /* DEFAULT */ 1531 /* Operation is alpha * A + (1 - alpha) * B; */ 1532 /* A is source, B is destination and alpha is the */ 1533 /* programmed 8-bit value. */ 1534 1535 default: 1536 1537 gu2_alpha32 |= MGP_RM_SELECT_ALPHA_R | 1538 MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_A_PLUS_BETA_B; 1539 1540 } 1541 1542 /* CHECK IF SOURCE INFORMATION SHOULD BE MERGED */ 1543 /* Alpha value of 0 indicates destination only. */ 1544 1545 if (gu2_alpha_value != 0) 1546 gu2_alpha32 |= GFXsourceFlags; 1547 1548 /* SET FLAG FOR DESTINATION DATA IF NECESSARY */ 1549 /* Alpha value of 255 indicates no destination */ 1550 1551 if (gu2_alpha_value != 255) { 1552 gu2_alpha_blt_mode = MGP_BM_DST_REQ; 1553 gu2_alpha_vec_mode = MGP_VM_DST_REQ; 1554 } 1555 1556 break; 1557 } 1558} 1559 1560/*--------------------------------------------------------------------------- 1561 * GFX2_PATTERN_FILL 1562 * 1563 * This routine is similar to the gfx_pattern_fill routine, but allows the 1564 * use of an arbitrary destination stride. The rendering position is 1565 * also specified as an offset instead of an (x,y) position. 1566 *--------------------------------------------------------------------------- 1567 */ 1568#if GFX_2DACCEL_DYNAMIC 1569void 1570gu22_pattern_fill(unsigned long dstoffset, unsigned short width, 1571 unsigned short height) 1572#else 1573void 1574gfx2_pattern_fill(unsigned long dstoffset, unsigned short width, 1575 unsigned short height) 1576#endif 1577{ 1578 unsigned long size; 1579 1580 size = (((unsigned long)width) << 16) | height; 1581 1582 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1583 /* Put off poll for as long as possible (do most calculations first). */ 1584 1585 GU2_WAIT_PENDING; 1586 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 1587 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 1588 WRITE_GP32(MGP_WID_HEIGHT, size); 1589 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); 1590 WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1591 gu2_bm_throttle = 0; 1592 gu2_vm_throttle = 0; 1593} 1594 1595/*--------------------------------------------------------------------------- 1596 * GFX2_COLOR_PATTERN_FILL 1597 * 1598 * This routine is used to render a rectangle using the current raster 1599 * operation and the specified color pattern. It allows an 8x8 color 1600 * pattern to be rendered without multiple calls to the gfx_set_color_pattern 1601 * and gfx_pattern_fill routines. 1602 *--------------------------------------------------------------------------- 1603 */ 1604#if GFX_2DACCEL_DYNAMIC 1605void 1606gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width, 1607 unsigned short height, unsigned long *pattern) 1608#else 1609void 1610gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width, 1611 unsigned short height, unsigned long *pattern) 1612#endif 1613{ 1614 int pass; 1615 unsigned long lines, size, patxorigin, patoffset; 1616 1617 /* ONLY USE HW PATTERN ORIGIN FOR THE X DIRECTION */ 1618 /* Y direction handled by referencing proper location in pattern data. */ 1619 1620 patxorigin = (gu2_pattern_origin) & 0x1C000000; 1621 1622 /* OVERRIDE PATTERN FLAGS IN ROP TO FORCE COLOR PATTERN */ 1623 1624 GU2_WAIT_PENDING; 1625 WRITE_GP32(MGP_RASTER_MODE, 1626 (gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR); 1627 1628 /* ATTEMPT TO OPTIMIZE */ 1629 /* If possible, we can perform the pattern fill in only a few passes */ 1630 /* This is performed by multiplying the pitch by an appropriate amount. */ 1631 /* Consequently, if the multiplied pitch exceeds 16 bits, this */ 1632 /* optimization is impossible. */ 1633 1634 if ((gu2_dst_pitch << (gu2_xshift + 1)) <= 0xFFFF) { 1635 /* HANDLE VARIOUS COLOR DEPTHS DIFFERENTLY */ 1636 1637 switch (gu2_xshift) { 1638 case 0: /* 8 BPP */ 1639 1640 /* TWO PASSES FOR 8 BPP */ 1641 /* Render every other line per pass by doubling the pitch. */ 1642 1643 patoffset = (gu2_pattern_origin >> 28) & 0x0E; 1644 for (pass = 0; pass < 2; pass++) { 1645 /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ 1646 1647 GU2_WAIT_PENDING; 1648 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1649 lines = (height + 1 - pass) >> 1; 1650 if (!lines) 1651 break; 1652 size = (((unsigned long)width) << 16) | lines; 1653 WRITE_GP32(MGP_WID_HEIGHT, size); 1654 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 1); 1655 WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset])); 1656 WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1])); 1657 patoffset = (patoffset + 4) & 0x0E; 1658 WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset])); 1659 WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1])); 1660 patoffset = (patoffset + 4) & 0x0E; 1661 1662 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1663 /* Those registers are not pipelined. */ 1664 1665 GU2_WAIT_BUSY; 1666 WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset])); 1667 WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1])); 1668 patoffset = (patoffset + 4) & 0x0E; 1669 WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset])); 1670 WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1])); 1671 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1672 gu2_bm_throttle = 0; 1673 gu2_vm_throttle = 0; 1674 1675 /* ADJUST FOR NEXT PASS */ 1676 1677 dstoffset += gu2_dst_pitch; 1678 patoffset = (patoffset + 6) & 0x0E; 1679 } 1680 break; 1681 1682 case 1: /* 12, 15, OR 16 BPP */ 1683 1684 /* FOUR PASSES FOR 16 BPP */ 1685 /* Render every 4th line per pass by quadrupling the pitch. */ 1686 1687 patoffset = (gu2_pattern_origin >> 27) & 0x1C; 1688 for (pass = 0; pass < 4; pass++) { 1689 /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ 1690 1691 GU2_WAIT_PENDING; 1692 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1693 lines = (height + 3 - pass) >> 2; 1694 if (!lines) 1695 break; 1696 size = (((unsigned long)width) << 16) | lines; 1697 WRITE_GP32(MGP_WID_HEIGHT, size); 1698 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 2); 1699 WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset])); 1700 WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1])); 1701 WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2])); 1702 WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3])); 1703 patoffset = (patoffset + 16) & 0x1C; 1704 1705 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1706 /* Those registers are not pipelined. */ 1707 1708 GU2_WAIT_BUSY; 1709 WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset])); 1710 WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1])); 1711 WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2])); 1712 WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3])); 1713 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1714 gu2_bm_throttle = 0; 1715 gu2_vm_throttle = 0; 1716 1717 /* ADJUST FOR NEXT PASS */ 1718 1719 dstoffset += gu2_dst_pitch; 1720 patoffset = (patoffset + 20) & 0x1C; 1721 } 1722 break; 1723 1724 case 2: /* 32 BPP */ 1725 1726 /* EIGHT PASSES FOR 32 BPP */ 1727 /* Render every 8th line per pass by setting pitch * 8. */ 1728 1729 patoffset = (gu2_pattern_origin >> 26) & 0x38; 1730 for (pass = 0; pass < 8; pass++) { 1731 /* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */ 1732 1733 GU2_WAIT_PENDING; 1734 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1735 lines = (height + 7 - pass) >> 3; 1736 if (!lines) 1737 break; 1738 size = (((unsigned long)width) << 16) | lines; 1739 WRITE_GP32(MGP_WID_HEIGHT, size); 1740 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 3); 1741 WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]); 1742 WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]); 1743 WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]); 1744 WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]); 1745 1746 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1747 /* Those registers are not pipelined. */ 1748 1749 GU2_WAIT_BUSY; 1750 WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]); 1751 WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]); 1752 WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]); 1753 WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]); 1754 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1755 gu2_bm_throttle = 0; 1756 gu2_vm_throttle = 0; 1757 1758 /* ADJUST FOR NEXT PASS */ 1759 1760 dstoffset += gu2_dst_pitch; 1761 patoffset = (patoffset + 8) & 0x38; 1762 } 1763 break; 1764 } 1765 } 1766 1767 else { 1768 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); 1769 1770 switch (gu2_xshift) { 1771 case 0: /* 8 BPP - 4 LINES PER PASS */ 1772 1773 patoffset = (gu2_pattern_origin >> 28) & 0x0E; 1774 while (height) { 1775 lines = height > 4 ? 4 : height; 1776 1777 /* CAN WRITE SOME REGISTERS WHILE PENDING */ 1778 1779 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1780 WRITE_GP32(MGP_WID_HEIGHT, 1781 (((unsigned long)width) << 16) | lines); 1782 WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset])); 1783 WRITE_GP32(MGP_PAT_DATA_0, BYTE_SWIZZLE(pattern[patoffset + 1])); 1784 patoffset = (patoffset + 2) & 0x0E; 1785 WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset])); 1786 WRITE_GP32(MGP_PAT_COLOR_0, BYTE_SWIZZLE(pattern[patoffset + 1])); 1787 patoffset = (patoffset + 2) & 0x0E; 1788 1789 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1790 /* Those registers are not pipelined. */ 1791 1792 GU2_WAIT_BUSY; 1793 WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset])); 1794 WRITE_GP32(MGP_PAT_COLOR_2, BYTE_SWIZZLE(pattern[patoffset + 1])); 1795 patoffset = (patoffset + 2) & 0x0E; 1796 WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset])); 1797 WRITE_GP32(MGP_PAT_COLOR_4, BYTE_SWIZZLE(pattern[patoffset + 1])); 1798 patoffset = (patoffset + 2) & 0x0E; 1799 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1800 1801 /* ADJUST FOR NEXT PASS */ 1802 1803 dstoffset += gu2_dst_pitch << 2; 1804 height -= (unsigned short)lines; 1805 } 1806 break; 1807 1808 case 1: /* 12, 15 AND 16 BPP - 2 LINES PER PASS */ 1809 1810 patoffset = (gu2_pattern_origin >> 27) & 0x1C; 1811 while (height) { 1812 lines = height > 2 ? 2 : height; 1813 1814 /* CAN WRITE SOME REGISTERS WHILE PENDING */ 1815 1816 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1817 WRITE_GP32(MGP_WID_HEIGHT, 1818 (((unsigned long)width) << 16) | lines); 1819 WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset])); 1820 WRITE_GP32(MGP_PAT_COLOR_0, WORD_SWIZZLE(pattern[patoffset + 1])); 1821 WRITE_GP32(MGP_PAT_DATA_1, WORD_SWIZZLE(pattern[patoffset + 2])); 1822 WRITE_GP32(MGP_PAT_DATA_0, WORD_SWIZZLE(pattern[patoffset + 3])); 1823 patoffset = (patoffset + 4) & 0x1C; 1824 1825 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1826 /* Those registers are not pipelined. */ 1827 1828 GU2_WAIT_BUSY; 1829 WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset])); 1830 WRITE_GP32(MGP_PAT_COLOR_4, WORD_SWIZZLE(pattern[patoffset + 1])); 1831 WRITE_GP32(MGP_PAT_COLOR_3, WORD_SWIZZLE(pattern[patoffset + 2])); 1832 WRITE_GP32(MGP_PAT_COLOR_2, WORD_SWIZZLE(pattern[patoffset + 3])); 1833 patoffset = (patoffset + 4) & 0x1C; 1834 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1835 1836 /* ADJUST FOR NEXT PASS */ 1837 1838 dstoffset += gu2_dst_pitch << 1; 1839 height -= (unsigned short)lines; 1840 } 1841 break; 1842 1843 case 2: /* 32 BPP - 1 LINE PER PASS */ 1844 1845 patoffset = (gu2_pattern_origin >> 26) & 0x38; 1846 while (height) { 1847 /* CAN WRITE SOME REGISTERS WHILE PENDING */ 1848 1849 WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin); 1850 WRITE_GP32(MGP_WID_HEIGHT, (((unsigned long)width) << 16) | 1l); 1851 WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]); 1852 WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]); 1853 WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]); 1854 WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]); 1855 1856 /* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */ 1857 /* Those registers are not pipelined. */ 1858 1859 GU2_WAIT_BUSY; 1860 WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]); 1861 WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]); 1862 WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]); 1863 WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]); 1864 patoffset = (patoffset + 8) & 0x38; 1865 WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle); 1866 1867 /* ADJUST FOR NEXT PASS */ 1868 1869 dstoffset += gu2_dst_pitch; 1870 height--; 1871 } 1872 break; 1873 } 1874 1875 } 1876 1877} 1878 1879/*--------------------------------------------------------------------------- 1880 * GFX2_SCREEN_TO_SCREEN_BLT 1881 * 1882 * This routine is similar to the gfx_screen_to_screen_blt routine but 1883 * allows the use of arbitrary source and destination strides and alpha 1884 * blending. It also allows the use of an arbitrary ROP with transparency. 1885 *--------------------------------------------------------------------------- 1886 */ 1887#if GFX_2DACCEL_DYNAMIC 1888void 1889gu22_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset, 1890 unsigned short width, unsigned short height, 1891 int flags) 1892#else 1893void 1894gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset, 1895 unsigned short width, unsigned short height, 1896 int flags) 1897#endif 1898{ 1899 unsigned long size, xbytes; 1900 unsigned short blt_mode; 1901 1902 size = (((unsigned long)width) << 16) | height; 1903 1904 /* USE ALPHA SETTINGS, IF REQUESTED */ 1905 1906 if (gu2_alpha_active) 1907 blt_mode = gu2_alpha_blt_mode | MGP_BM_SRC_FB; 1908 1909 else 1910 blt_mode = gu2_blt_mode | MGP_BM_SRC_FB; 1911 1912 /* CALCULATE THE DIRECTION OF THE BLT */ 1913 /* Using offsets, so flags from the calling routine are needed. */ 1914 1915 if (flags & 1) { 1916 xbytes = (width - 1) << gu2_xshift; 1917 srcoffset += xbytes; 1918 dstoffset += xbytes; 1919 blt_mode |= MGP_BM_NEG_XDIR; 1920 } 1921 if (flags & 2) { 1922 srcoffset += (height - 1) * gu2_src_pitch; 1923 dstoffset += (height - 1) * gu2_dst_pitch; 1924 blt_mode |= MGP_BM_NEG_YDIR; 1925 } 1926 1927 /* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */ 1928 /* This is a quirk of the hardware. */ 1929 1930 if (blt_mode & MGP_BM_NEG_XDIR) { 1931 srcoffset += (1 << gu2_xshift) - 1; 1932 dstoffset += (1 << gu2_xshift) - 1; 1933 } 1934 1935 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1936 /* Put off poll for as long as possible (do most calculations first). */ 1937 1938 GU2_WAIT_PENDING; 1939 1940 if (gu2_alpha_active) { 1941 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 1942 } else { 1943 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 1944 } 1945 1946 WRITE_GP32(MGP_SRC_OFFSET, srcoffset); 1947 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 1948 WRITE_GP32(MGP_WID_HEIGHT, size); 1949 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16)); 1950 WRITE_GP16(MGP_BLT_MODE, blt_mode | gu2_bm_throttle); 1951 gu2_bm_throttle = 0; 1952 gu2_vm_throttle = 0; 1953} 1954 1955/*--------------------------------------------------------------------------- 1956 * GFX2_MONO_EXPAND_BLT 1957 * 1958 * This routine is similar to the gfx2_screen_to_screen_blt routine but 1959 * expands monochrome data stored in graphics memory. 1960 * WARNING: This routine assumes that the regions in graphics memory 1961 * will not overlap, and therefore does not check the BLT direction. 1962 *--------------------------------------------------------------------------- 1963 */ 1964#if GFX_2DACCEL_DYNAMIC 1965void 1966gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx, 1967 unsigned short srcy, unsigned long dstoffset, 1968 unsigned short width, unsigned short height, 1969 int byte_packed) 1970#else 1971void 1972gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx, 1973 unsigned short srcy, unsigned long dstoffset, 1974 unsigned short width, unsigned short height, 1975 int byte_packed) 1976#endif 1977{ 1978 unsigned long size, srcoffset; 1979 unsigned short blt_mode; 1980 1981 size = (((unsigned long)width) << 16) | height; 1982 1983 /* CALCULATE SOURCE OFFSET */ 1984 1985 srcoffset = srcbase + (unsigned long)srcy *gu2_src_pitch; 1986 1987 srcoffset += srcx >> 3; 1988 srcoffset |= ((unsigned long)srcx & 7) << 26; 1989 1990 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 1991 /* Put off poll for as long as possible (do most calculations first). */ 1992 1993 GU2_WAIT_PENDING; 1994 1995 if (gu2_alpha_active) { 1996 blt_mode = gu2_alpha_blt_mode; 1997 1998 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 1999 } else { 2000 blt_mode = gu2_blt_mode; 2001 2002 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 2003 } 2004 2005 if (byte_packed) 2006 blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_BP_MONO | gu2_bm_throttle; 2007 else 2008 blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_MONO | gu2_bm_throttle; 2009 2010 WRITE_GP32(MGP_SRC_OFFSET, srcoffset); 2011 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 2012 WRITE_GP32(MGP_WID_HEIGHT, size); 2013 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16)); 2014 WRITE_GP16(MGP_BLT_MODE, blt_mode); 2015 gu2_bm_throttle = 0; 2016 gu2_vm_throttle = 0; 2017} 2018 2019/*--------------------------------------------------------------------------- 2020 * GFX2_COLOR_BITMAP_TO_SCREEN_BLT 2021 * 2022 * This routine is similar to the gfx_color_bitmap_to_screen_blt routine 2023 * but allows the use of an arbitrary destination stride and alpha blending. 2024 * It also allows the use of an arbitrary ROP with transparency. 2025 *--------------------------------------------------------------------------- 2026 */ 2027#if GFX_2DACCEL_DYNAMIC 2028void 2029gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 2030 unsigned long dstoffset, unsigned short width, 2031 unsigned short height, unsigned char *data, 2032 short pitch) 2033#else 2034void 2035gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 2036 unsigned long dstoffset, unsigned short width, 2037 unsigned short height, unsigned char *data, 2038 short pitch) 2039#endif 2040{ 2041 unsigned long size, bytes; 2042 unsigned long offset, temp_offset; 2043 unsigned long srcoffset, dword_bytes, bytes_extra; 2044 unsigned short blt_mode; 2045 2046 size = (((unsigned long)width) << 16) | 1; 2047 2048 /* CALCULATE STARTING OFFSETS */ 2049 2050 offset = (unsigned long)srcy *pitch + ((unsigned long)srcx << gu2_xshift); 2051 2052 dstoffset |= gu2_pattern_origin; 2053 2054 bytes = width << gu2_xshift; 2055 dword_bytes = bytes & ~0x3L; 2056 bytes_extra = bytes & 0x3L; 2057 2058 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 2059 /* Put off poll for as long as possible (do most calculations first). */ 2060 /* The source offset is always 0 since we allow misaligned dword reads. */ 2061 /* We must wait for BLT busy because the GP may be executing a screen */ 2062 /* to screen BLT from the scratchpad area. */ 2063 2064 GU2_WAIT_BUSY; 2065 2066 if (gu2_alpha_active) { 2067 blt_mode = gu2_alpha_blt_mode; 2068 2069 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 2070 } else { 2071 blt_mode = gu2_blt_mode; 2072 2073 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 2074 } 2075 blt_mode |= MGP_BM_SRC_FB | gu2_bm_throttle; 2076 gu2_bm_throttle = 0; 2077 gu2_vm_throttle = 0; 2078 2079 WRITE_GP32(MGP_WID_HEIGHT, size); 2080 2081 /* WRITE DATA ONE LINE AT A TIME */ 2082 /* For speed reasons, data is written to an offscreen scratch area and then */ 2083 /* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */ 2084 /* slightly more efficient in that we can queue up data while the GP is rendering */ 2085 /* a line. */ 2086 2087 while (height--) { 2088 temp_offset = offset; 2089 srcoffset = gfx_gx2_scratch_base; 2090 if (gu2_current_line) 2091 srcoffset += 8192; 2092 2093 GU2_WAIT_PENDING; 2094 WRITE_GP32(MGP_SRC_OFFSET, srcoffset); 2095 WRITE_GP32(MGP_DST_OFFSET, dstoffset); 2096 dstoffset += gu2_dst_pitch; 2097 dstoffset += 0x20000000; 2098 2099 WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset); 2100 if (bytes_extra) { 2101 temp_offset += dword_bytes; 2102 srcoffset += dword_bytes; 2103 WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data, 2104 temp_offset); 2105 } 2106 WRITE_GP16(MGP_BLT_MODE, blt_mode); 2107 offset += pitch; 2108 gu2_current_line = 1 - gu2_current_line; 2109 } 2110} 2111 2112/*--------------------------------------------------------------------------- 2113 * GFX2_TEXT_BLT 2114 * 2115 * This routine is similar to the gfx2_mono_bitmap_to_screen_blt routine 2116 * but assumes that source data is byte-packed. 2117 *--------------------------------------------------------------------------- 2118 */ 2119#if GFX_2DACCEL_DYNAMIC 2120void 2121gu22_text_blt(unsigned long dstoffset, unsigned short width, 2122 unsigned short height, unsigned char *data) 2123#else 2124void 2125gfx2_text_blt(unsigned long dstoffset, unsigned short width, 2126 unsigned short height, unsigned char *data) 2127#endif 2128{ 2129 unsigned long size, bytes; 2130 unsigned long temp1 = 0, temp2 = 0, temp_offset = 0; 2131 unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 2132 unsigned long shift; 2133 unsigned short blt_mode; 2134 2135 size = (((unsigned long)width) << 16) | height; 2136 2137 /* CALCULATE STARTING OFFSETS */ 2138 2139 bytes = ((width + 7) >> 3) * height; 2140 fifo_lines = bytes >> 5; 2141 dwords_extra = (bytes & 0x0000001Cl) >> 2; 2142 bytes_extra = bytes & 0x00000003l; 2143 2144 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 2145 2146 GU2_WAIT_PENDING; 2147 2148 if (gu2_alpha_active) { 2149 blt_mode = gu2_alpha_blt_mode; 2150 2151 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 2152 } else { 2153 blt_mode = gu2_blt_mode; 2154 2155 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 2156 } 2157 2158 WRITE_GP32(MGP_SRC_OFFSET, 0); 2159 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 2160 WRITE_GP32(MGP_WID_HEIGHT, size); 2161 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); 2162 WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST | 2163 MGP_BM_SRC_BP_MONO | gu2_bm_throttle); 2164 gu2_bm_throttle = 0; 2165 gu2_vm_throttle = 0; 2166 2167 /* WAIT FOR BLT TO BE LATCHED */ 2168 2169 GU2_WAIT_PENDING; 2170 2171 /* WRITE ALL FULL FIFO LINES */ 2172 2173 for (i = 0; i < fifo_lines; i++) { 2174 GU2_WAIT_HALF_EMPTY; 2175 WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); 2176 temp_offset += 32; 2177 } 2178 2179 /* WRITE ALL FULL DWORDS */ 2180 2181 if (dwords_extra || bytes_extra) { 2182 GU2_WAIT_HALF_EMPTY; 2183 if (dwords_extra) { 2184 WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, 2185 temp_offset, temp1); 2186 temp_offset += (dwords_extra << 2); 2187 } 2188 if (bytes_extra) { 2189 shift = 0; 2190 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 2191 temp_offset, temp1, temp2); 2192 } 2193 } 2194} 2195 2196/*--------------------------------------------------------------------------- 2197 * GFX2_MONO_BITMAP_TO_SCREEN_BLT 2198 * 2199 * This routine is similar to the gfx_mono_bitmap_to_screen_blt routine 2200 * but allows the use of an arbitrary destination stride and alpha blending. 2201 *--------------------------------------------------------------------------- 2202 */ 2203#if GFX_2DACCEL_DYNAMIC 2204void 2205gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 2206 unsigned long dstoffset, unsigned short width, 2207 unsigned short height, unsigned char *data, 2208 short pitch) 2209#else 2210void 2211gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy, 2212 unsigned long dstoffset, unsigned short width, 2213 unsigned short height, unsigned char *data, 2214 short pitch) 2215#endif 2216{ 2217 unsigned long size, bytes; 2218 unsigned long offset, temp_offset, temp1 = 0, temp2 = 0; 2219 unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra; 2220 unsigned long shift = 0; 2221 unsigned short blt_mode; 2222 2223 size = (((unsigned long)width) << 16) | height; 2224 2225 /* CALCULATE STARTING OFFSETS */ 2226 2227 offset = (unsigned long)srcy *pitch + ((unsigned long)srcx >> 3); 2228 2229 bytes = ((srcx & 7) + width + 7) >> 3; 2230 fifo_lines = bytes >> 5; 2231 dwords_extra = (bytes & 0x0000001Cl) >> 2; 2232 bytes_extra = bytes & 0x00000003l; 2233 2234 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 2235 2236 GU2_WAIT_PENDING; 2237 2238 if (gu2_alpha_active) { 2239 blt_mode = gu2_alpha_blt_mode; 2240 2241 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 2242 } else { 2243 blt_mode = gu2_blt_mode; 2244 2245 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 2246 } 2247 2248 WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long)srcx & 7) << 26); 2249 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 2250 WRITE_GP32(MGP_WID_HEIGHT, size); 2251 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); 2252 WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST | 2253 MGP_BM_SRC_MONO | gu2_bm_throttle); 2254 gu2_bm_throttle = 0; 2255 gu2_vm_throttle = 0; 2256 2257 /* WAIT FOR BLT TO BE LATCHED */ 2258 2259 GU2_WAIT_PENDING; 2260 2261 /* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */ 2262 2263 while (height--) { 2264 temp_offset = offset; 2265 2266 /* WRITE ALL FULL FIFO LINES */ 2267 2268 for (i = 0; i < fifo_lines; i++) { 2269 GU2_WAIT_HALF_EMPTY; 2270 WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1); 2271 temp_offset += 32; 2272 } 2273 2274 /* WRITE ALL FULL DWORDS */ 2275 2276 GU2_WAIT_HALF_EMPTY; 2277 if (dwords_extra) 2278 WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data, 2279 temp_offset, temp1); 2280 temp_offset += (dwords_extra << 2); 2281 2282 /* WRITE REMAINING BYTES */ 2283 2284 shift = 0; 2285 if (bytes_extra) 2286 WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data, 2287 temp_offset, temp1, temp2); 2288 2289 offset += pitch; 2290 } 2291} 2292 2293/*--------------------------------------------------------------------------- 2294 * GFX2_BRESENHAM_LINE 2295 * 2296 * This routine is similar to the gfx_bresenam_line routine but allows 2297 * the use of an arbitrary destination stride. 2298 *--------------------------------------------------------------------------- 2299 */ 2300#if GFX_2DACCEL_DYNAMIC 2301void 2302gu22_bresenham_line(unsigned long dstoffset, 2303 unsigned short length, unsigned short initerr, 2304 unsigned short axialerr, unsigned short diagerr, 2305 unsigned short flags) 2306#else 2307void 2308gfx2_bresenham_line(unsigned long dstoffset, 2309 unsigned short length, unsigned short initerr, 2310 unsigned short axialerr, unsigned short diagerr, 2311 unsigned short flags) 2312#endif 2313{ 2314 unsigned long vector_mode = gu2_vector_mode | flags; 2315 unsigned long data1 = (((unsigned long)axialerr) << 16) | diagerr; 2316 unsigned long data2 = (((unsigned long)length) << 16) | initerr; 2317 2318 /* CHECK NULL LENGTH */ 2319 2320 if (!length) 2321 return; 2322 2323 /* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */ 2324 /* Put off poll for as long as possible (do most calculations first). */ 2325 2326 GU2_WAIT_PENDING; 2327 2328 if (gu2_alpha_active) { 2329 vector_mode = gu2_alpha_vec_mode | flags; 2330 2331 WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32); 2332 } else 2333 WRITE_GP32(MGP_RASTER_MODE, gu2_rop32); 2334 2335 WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin); 2336 WRITE_GP32(MGP_VEC_ERR, data1); 2337 WRITE_GP32(MGP_VEC_LEN, data2); 2338 WRITE_GP32(MGP_STRIDE, gu2_dst_pitch); 2339 WRITE_GP32(MGP_VECTOR_MODE, vector_mode | gu2_vm_throttle); 2340 gu2_bm_throttle = 0; 2341 gu2_vm_throttle = 0; 2342} 2343 2344/*--------------------------------------------------------------------------- 2345 * GFX2_SYNC_TO_VBLANK 2346 * 2347 * This routine sets a flag to synchronize the next rendering routine to 2348 * VBLANK. The flag is cleared by the rendering routine. 2349 *--------------------------------------------------------------------------- 2350 */ 2351#if GFX_2DACCEL_DYNAMIC 2352void 2353gu22_sync_to_vblank(void) 2354#else 2355void 2356gfx2_sync_to_vblank(void) 2357#endif 2358{ 2359 /* SET FLAGS TO THROTTLE NEXT RENDERING ROUTINE */ 2360 2361 gu2_bm_throttle = MGP_BM_THROTTLE; 2362 gu2_vm_throttle = MGP_VM_THROTTLE; 2363} 2364 2365/* END OF FILE */ 2366