1 /* G200-G550 Back End Scaler functions */ 2 /* Written by Rudolf Cornelissen 05/2002-1/2004 */ 3 4 #define MODULE_BIT 0x00000200 5 6 #include "mga_std.h" 7 8 //fixme: implement: (used for virtual screens!) 9 //void move_overlay(uint16 hdisp_start, uint16 vdisp_start); 10 11 status_t gx00_configure_bes 12 (const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov, int offset) 13 { 14 /* yuy2 (4:2:2) colorspace calculations */ 15 /* Note: Some calculations will have to be modified for other colorspaces if they are incorporated. */ 16 17 /* Note: 18 * in BeOS R5.0.3 and DANO: 19 * 'ow->offset_xxx' is always 0, so not used; 20 * 'ow->width' and 'ow->height' are the output window size: does not change 21 * if window is clipping; 22 * 'ow->h_start' and 'ow->v_start' are the left-top position of the output 23 * window. These values can be negative: this means the window is clipping 24 * at the left or the top of the display, respectively. */ 25 26 /* 'ov' is the view in the source bitmap, so which part of the bitmap is actually 27 * displayed on screen. This is used for the 'hardware zoom' function. */ 28 29 /* calculated BES register values */ 30 uint32 hcoordv, vcoordv, hiscalv, hsrcstv, hsrcendv, hsrclstv, 31 viscalv, a1orgv, v1wghtv, v1srclstv, globctlv, ctlv; 32 /* misc used variables */ 33 uint16 temp1, temp2; 34 /* interval representation, used for scaling calculations */ 35 uint16 intrep, crtc_hstart, crtc_vstart, crtc_hend, crtc_vend; 36 /* inverse scaling factor, used for source positioning */ 37 uint32 ifactor; 38 /* used for vertical weight starting value */ 39 uint32 weight; 40 /* copy of overlay view which has checked valid values */ 41 overlay_view my_ov; 42 43 /* Slowdown the G200-G550 BES if the pixelclock is too high for it to cope. 44 * This will in fact half the horizontal resolution of the BES with high 45 * pixelclocks (by setting a BES hardware 'zoom' = 2x). 46 * If you want optimal output quality better make sure you set the refreshrate/resolution 47 * of your monitor not too high ... */ 48 uint16 acczoom = 1; 49 LOG(4,("Overlay: pixelclock is %dkHz, ", si->dm.timing.pixel_clock)); 50 if (si->dm.timing.pixel_clock > BESMAXSPEED) 51 { 52 /* BES running at half speed and resolution */ 53 /* This is how it works (BES slowing down): 54 * - Activate BES internal horizontal hardware scaling = 4x (in GLOBCTL below), 55 * - This also sets up BES only getting half the amount of pixels per line from 56 * the input picture buffer (in effect half-ing the BES pixelclock input speed). 57 * Now in order to get the picture back to original size, we need to also double 58 * the inverse horizontal scaling factor here (x4 /2 /2 = 1x again). 59 * Note that every other pixel is now doubled or interpolated, according to another 60 * GLOBCTL bit. */ 61 acczoom = 2; 62 LOG(4,("slowing down BES!\n")); 63 } 64 else 65 { 66 /* BES running at full speed and resolution */ 67 LOG(4,("BES is running at full speed\n")); 68 } 69 70 71 /************************************************************************************** 72 *** copy, check and limit if needed the user-specified view into the intput bitmap *** 73 **************************************************************************************/ 74 my_ov = *ov; 75 /* check for valid 'coordinates' */ 76 if (my_ov.width == 0) my_ov.width++; 77 if (my_ov.height == 0) my_ov.height++; 78 if (my_ov.h_start > ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1)) 79 my_ov.h_start = ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1); 80 if (((my_ov.h_start + my_ov.width) - 1) > ((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1)) 81 my_ov.width = ((((ob->width - si->overlay.myBufInfo[offset].slopspace) - 1) - my_ov.h_start) + 1); 82 if (my_ov.v_start > (ob->height - 1)) 83 my_ov.v_start = (ob->height - 1); 84 if (((my_ov.v_start + my_ov.height) - 1) > (ob->height - 1)) 85 my_ov.height = (((ob->height - 1) - my_ov.v_start) + 1); 86 87 LOG(6,("Overlay: inputbuffer view (zoom) left %d, top %d, width %d, height %d\n", 88 my_ov.h_start, my_ov.v_start, my_ov.width, my_ov.height)); 89 90 /* the BES does not respect virtual_workspaces, but adheres to CRTC 91 * constraints only */ 92 crtc_hstart = si->dm.h_display_start; 93 /* make dualhead switch mode with TVout enabled work while we're at it.. */ 94 if (si->switched_crtcs) 95 { 96 crtc_hstart += si->dm.timing.h_display; 97 } 98 /* horizontal end is the first position beyond the displayed range on the CRTC */ 99 crtc_hend = crtc_hstart + si->dm.timing.h_display; 100 crtc_vstart = si->dm.v_display_start; 101 /* vertical end is the first position beyond the displayed range on the CRTC */ 102 crtc_vend = crtc_vstart + si->dm.timing.v_display; 103 104 105 /**************************************** 106 *** setup all edges of output window *** 107 ****************************************/ 108 109 /* setup left and right edges of output window */ 110 hcoordv = 0; 111 /* left edge coordinate of output window, must be inside desktop */ 112 /* clipping on the left side */ 113 if (ow->h_start < crtc_hstart) 114 { 115 temp1 = 0; 116 } 117 else 118 { 119 /* clipping on the right side */ 120 if (ow->h_start >= (crtc_hend - 1)) 121 { 122 /* width < 2 is not allowed */ 123 temp1 = (crtc_hend - crtc_hstart - 2) & 0x7ff; 124 } 125 else 126 /* no clipping here */ 127 { 128 temp1 = (ow->h_start - crtc_hstart) & 0x7ff; 129 } 130 } 131 hcoordv |= temp1 << 16; 132 /* right edge coordinate of output window, must be inside desktop */ 133 /* width < 2 is not allowed */ 134 if (ow->width < 2) 135 { 136 temp2 = (temp1 + 1) & 0x7ff; 137 } 138 else 139 { 140 /* clipping on the right side */ 141 if ((ow->h_start + ow->width - 1) > (crtc_hend - 1)) 142 { 143 temp2 = (crtc_hend - crtc_hstart - 1) & 0x7ff; 144 } 145 else 146 { 147 /* clipping on the left side */ 148 if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1)) 149 { 150 /* width < 2 is not allowed */ 151 temp2 = 1; 152 } 153 else 154 /* no clipping here */ 155 { 156 temp2 = ((uint16)(ow->h_start + ow->width - crtc_hstart - 1)) & 0x7ff; 157 } 158 } 159 } 160 hcoordv |= temp2 << 0; 161 LOG(4,("Overlay: CRTC left-edge output %d, right-edge output %d\n",temp1, temp2)); 162 163 /* setup top and bottom edges of output window */ 164 vcoordv = 0; 165 /* top edge coordinate of output window, must be inside desktop */ 166 /* clipping on the top side */ 167 if (ow->v_start < crtc_vstart) 168 { 169 temp1 = 0; 170 } 171 else 172 { 173 /* clipping on the bottom side */ 174 if (ow->v_start >= (crtc_vend - 1)) 175 { 176 /* height < 2 is not allowed */ 177 temp1 = (crtc_vend - crtc_vstart - 2) & 0x7ff; 178 } 179 else 180 /* no clipping here */ 181 { 182 temp1 = (ow->v_start - crtc_vstart) & 0x7ff; 183 } 184 } 185 vcoordv |= temp1 << 16; 186 /* bottom edge coordinate of output window, must be inside desktop */ 187 /* height < 2 is not allowed */ 188 if (ow->height < 2) 189 { 190 temp2 = (temp1 + 1) & 0x7ff; 191 } 192 else 193 { 194 /* clipping on the bottom side */ 195 if ((ow->v_start + ow->height - 1) > (crtc_vend - 1)) 196 { 197 temp2 = (crtc_vend - crtc_vstart - 1) & 0x7ff; 198 } 199 else 200 { 201 /* clipping on the top side */ 202 if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1)) 203 { 204 /* height < 2 is not allowed */ 205 temp2 = 1; 206 } 207 else 208 /* no clipping here */ 209 { 210 temp2 = ((uint16)(ow->v_start + ow->height - crtc_vstart - 1)) & 0x7ff; 211 } 212 } 213 } 214 vcoordv |= temp2 << 0; 215 LOG(4,("Overlay: CRTC top-edge output %d, bottom-edge output %d\n",temp1, temp2)); 216 217 218 /********************************************* 219 *** setup horizontal scaling and clipping *** 220 *********************************************/ 221 222 LOG(6,("Overlay: total input picture width = %d, height = %d\n", 223 (ob->width - si->overlay.myBufInfo[offset].slopspace), ob->height)); 224 LOG(6,("Overlay: output picture width = %d, height = %d\n", ow->width, ow->height)); 225 226 /* do horizontal scaling... */ 227 /* determine interval representation value, taking zoom into account */ 228 if (ow->flags & B_OVERLAY_HORIZONTAL_FILTERING) 229 { 230 /* horizontal filtering is ON */ 231 if ((my_ov.width == ow->width) | (ow->width < 2)) 232 { 233 /* no horizontal scaling used, OR destination width < 2 */ 234 intrep = 0; 235 } 236 else 237 { 238 intrep = 1; 239 } 240 } 241 else 242 { 243 /* horizontal filtering is OFF */ 244 if ((ow->width < my_ov.width) & (ow->width >= 2)) 245 { 246 /* horizontal downscaling used AND destination width >= 2 */ 247 intrep = 1; 248 } 249 else 250 { 251 intrep = 0; 252 } 253 } 254 LOG(4,("Overlay: horizontal interval representation value is %d\n",intrep)); 255 256 /* calculate inverse horizontal scaling factor, taking zoom into account */ 257 /* standard scaling formula: */ 258 ifactor = (((uint32)(my_ov.width - intrep)) << 16) / (ow->width - intrep); 259 260 /* correct factor to prevent most-right visible 'line' from distorting */ 261 ifactor -= (1 << 2); 262 LOG(4,("Overlay: horizontal scaling factor is %f\n", (float)65536 / ifactor)); 263 264 /* compensate for accelerated 2x zoom (slowdown BES if pixelclock is too high) */ 265 hiscalv = ifactor * acczoom; 266 LOG(4,("Overlay: horizontal speed compensated factor is %f\n", (float)65536 / hiscalv)); 267 268 /* check scaling factor (and modify if needed) to be within scaling limits */ 269 if (((((uint32)my_ov.width) << 16) / 16384) > hiscalv) 270 { 271 /* (non-inverse) factor too large, set factor to max. valid value */ 272 hiscalv = ((((uint32)my_ov.width) << 16) / 16384); 273 LOG(4,("Overlay: horizontal scaling factor too large, clamping at %f\n", (float)65536 / hiscalv)); 274 } 275 if (hiscalv >= (32 << 16)) 276 { 277 /* (non-inverse) factor too small, set factor to min. valid value */ 278 hiscalv = 0x1ffffc; 279 LOG(4,("Overlay: horizontal scaling factor too small, clamping at %f\n", (float)65536 / hiscalv)); 280 } 281 /* AND below is required by hardware */ 282 hiscalv &= 0x001ffffc; 283 284 285 /* do horizontal clipping... */ 286 /* Setup horizontal source start: first (sub)pixel contributing to output picture */ 287 /* Note: 288 * The method is to calculate, based on 1:1 scaling, based on the output window. 289 * After this is done, include the scaling factor so you get a value based on the input bitmap. 290 * Then add the left starting position of the bitmap's view (zoom function) to get the final value needed. 291 * Note: The input bitmaps slopspace is automatically excluded from the calculations this way! */ 292 /* Note also: 293 * Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */ 294 hsrcstv = 0; 295 /* check for destination horizontal clipping at left side */ 296 if (ow->h_start < crtc_hstart) 297 { 298 /* check if entire destination picture is clipping left: 299 * (2 pixels will be clamped onscreen at least) */ 300 if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1)) 301 { 302 /* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */ 303 hsrcstv += (ow->width - 2); 304 } 305 else 306 { 307 /* increase 'first contributing pixel' with actual number of dest. clipping pixels */ 308 hsrcstv += (crtc_hstart - ow->h_start); 309 } 310 LOG(4,("Overlay: clipping left...\n")); 311 312 /* The calculated value is based on scaling = 1x. So we now compensate for scaling. 313 * Note that this also already takes care of aligning the value to the BES register! */ 314 hsrcstv *= ifactor; 315 } 316 /* take zoom into account */ 317 hsrcstv += ((uint32)my_ov.h_start) << 16; 318 /* AND below required by hardware */ 319 hsrcstv &= 0x03fffffc; 320 LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", hsrcstv / (float)65536)); 321 322 323 /* Setup horizontal source end: last (sub)pixel contributing to output picture */ 324 /* Note: 325 * The method is to calculate, based on 1:1 scaling, based on the output window. 326 * After this is done, include the scaling factor so you get a value based on the input bitmap. 327 * Then add the right ending position of the bitmap's view (zoom function) to get the final value needed. */ 328 /* Note also: 329 * Even if the scaling factor is clamping we instruct the BES to use the correct source end pos.! */ 330 331 hsrcendv = 0; 332 /* check for destination horizontal clipping at right side */ 333 if ((ow->h_start + ow->width - 1) > (crtc_hend - 1)) 334 { 335 /* check if entire destination picture is clipping right: 336 * (2 pixels will be clamped onscreen at least) */ 337 if (ow->h_start > (crtc_hend - 2)) 338 { 339 /* increase 'number of clipping pixels' with 'fixed value': (total dest. width - 2) */ 340 hsrcendv += (ow->width - 2); 341 } 342 else 343 { 344 /* increase 'number of clipping pixels' with actual number of dest. clipping pixels */ 345 hsrcendv += ((ow->h_start + ow->width - 1) - (crtc_hend - 1)); 346 } 347 LOG(4,("Overlay: clipping right...\n")); 348 349 /* The calculated value is based on scaling = 1x. So we now compensate for scaling. 350 * Note that this also already takes care of aligning the value to the BES register! */ 351 hsrcendv *= ifactor; 352 /* now subtract this value from the last used pixel in (zoomed) inputbuffer, aligned to BES */ 353 hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16) - hsrcendv; 354 } 355 else 356 { 357 /* set last contributing pixel to last used pixel in (zoomed) inputbuffer, aligned to BES */ 358 hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16); 359 } 360 /* AND below required by hardware */ 361 hsrcendv &= 0x03fffffc; 362 LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", hsrcendv / (float)65536)); 363 364 365 /* setup horizontal source last position excluding slopspace: 366 * this is the last pixel that will be used for calculating interpolated pixels */ 367 hsrclstv = ((ob->width - 1) - si->overlay.myBufInfo[offset].slopspace) << 16; 368 /* AND below required by hardware */ 369 hsrclstv &= 0x03ff0000; 370 371 372 /******************************************* 373 *** setup vertical scaling and clipping *** 374 *******************************************/ 375 376 /* do vertical scaling... */ 377 /* determine interval representation value, taking zoom into account */ 378 if (ow->flags & B_OVERLAY_VERTICAL_FILTERING) 379 { 380 /* vertical filtering is ON */ 381 if ((my_ov.height == ow->height) | (ow->height < 2)) 382 { 383 /* no vertical scaling used, OR destination height < 2 */ 384 intrep = 0; 385 } 386 else 387 { 388 intrep = 1; 389 } 390 } 391 else 392 { 393 /* vertical filtering is OFF */ 394 if ((ow->height < my_ov.height) & (ow->height >= 2)) 395 { 396 /* vertical downscaling used AND destination height >= 2 */ 397 intrep = 1; 398 } 399 else 400 { 401 intrep = 0; 402 } 403 } 404 LOG(4,("Overlay: vertical interval representation value is %d\n",intrep)); 405 406 /* calculate inverse vertical scaling factor, taking zoom into account */ 407 /* standard scaling formula: */ 408 ifactor = (((uint32)(my_ov.height - intrep)) << 16) / (ow->height - intrep); 409 410 /* correct factor to prevent lowest visible line from distorting */ 411 ifactor -= (1 << 2); 412 LOG(4,("Overlay: vertical scaling factor is %f\n", (float)65536 / ifactor)); 413 414 /* preserve ifactor for source positioning calculations later on */ 415 viscalv = ifactor; 416 417 /* check scaling factor (and modify if needed) to be within scaling limits */ 418 if (((((uint32)my_ov.height) << 16) / 16384) > viscalv) 419 { 420 /* (non-inverse) factor too large, set factor to max. valid value */ 421 viscalv = ((((uint32)my_ov.height) << 16) / 16384); 422 LOG(4,("Overlay: vertical scaling factor too large, clamping at %f\n", (float)65536 / viscalv)); 423 } 424 if (viscalv >= (32 << 16)) 425 { 426 /* (non-inverse) factor too small, set factor to min. valid value */ 427 viscalv = 0x1ffffc; 428 LOG(4,("Overlay: vertical scaling factor too small, clamping at %f\n", (float)65536 / viscalv)); 429 } 430 /* AND below is required by hardware */ 431 viscalv &= 0x001ffffc; 432 433 434 /* do vertical clipping... */ 435 /* Setup vertical source start: first (sub)pixel contributing to output picture. 436 * Note: this exists of two parts: 437 * 1. setup fractional part (sign is always 'positive'); 438 * 2. setup relative base_adress, taking clipping on top (and zoom) into account. 439 * Both parts are done intertwined below. */ 440 /* Note: 441 * The method is to calculate, based on 1:1 scaling, based on the output window. 442 * 'After' this is done, include the scaling factor so you get a value based on the input bitmap. 443 * Then add the top starting position of the bitmap's view (zoom function) to get the final value needed. */ 444 /* Note also: 445 * Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */ 446 447 /* calculate relative base_adress and 'vertical weight fractional part' */ 448 weight = 0; 449 a1orgv = (uint32)((vuint32 *)ob->buffer); 450 a1orgv -= (uint32)((vuint32 *)si->framebuffer); 451 /* calculate origin adress */ 452 LOG(4,("Overlay: topleft corner of input bitmap (cardRAM offset) $%08x\n",a1orgv)); 453 /* check for destination vertical clipping at top side */ 454 if (ow->v_start < crtc_vstart) 455 { 456 /* check if entire destination picture is clipping at top: 457 * (2 pixels will be clamped onscreen at least) */ 458 if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1)) 459 { 460 /* increase source buffer origin with 'fixed value': 461 * (integer part of ('total height - 2' of dest. picture in pixels * inverse scaling factor)) * 462 * bytes per row source picture */ 463 a1orgv += ((((ow->height - 2) * ifactor) >> 16) * ob->bytes_per_row); 464 weight = (ow->height - 2) * ifactor; 465 } 466 else 467 { 468 /* increase source buffer origin with: 469 * (integer part of (number of destination picture clipping pixels * inverse scaling factor)) * 470 * bytes per row source picture */ 471 a1orgv += ((((crtc_vstart - ow->v_start) * ifactor) >> 16) * ob->bytes_per_row); 472 weight = (crtc_vstart - ow->v_start) * ifactor; 473 } 474 LOG(4,("Overlay: clipping at top...\n")); 475 } 476 /* take zoom into account */ 477 a1orgv += (my_ov.v_start * ob->bytes_per_row); 478 weight += (((uint32)my_ov.v_start) << 16); 479 LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n",a1orgv)); 480 LOG(4,("Overlay: first vert. (sub)pixel of input bitmap contributing %f\n", weight / (float)65536)); 481 482 /* Note: 483 * Because all > G200 overlay units will ignore b0-3 of the calculated adress, 484 * we do not use the above way for horizontal source positioning. 485 * (G200 cards ignore b0-2.) 486 * If we did, 8 source-image pixel jumps (in 4:2:2 colorspace) will occur if the picture 487 * is shifted horizontally during left clipping on all > G200 cards, while G200 cards 488 * will have 4 source-image pixel jumps occuring. */ 489 490 /* AND below is required by G200-G550 hardware. > G200 cards can have max. 32Mb RAM on board 491 * (16Mb on G200 cards). Compatible setting used (between G200 and the rest), this has no 492 * downside consequences here. */ 493 /* Buffer A topleft corner of field 1 (origin)(field 1 contains our full frames) */ 494 a1orgv &= 0x01fffff0; 495 496 /* field 1 weight: AND below required by hardware, also make sure 'sign' is always 'positive' */ 497 v1wghtv = weight & 0x0000fffc; 498 499 500 /* setup field 1 (is our complete frame) vertical source last position. 501 * this is the last pixel that will be used for calculating interpolated pixels */ 502 v1srclstv = (ob->height - 1); 503 /* AND below required by hardware */ 504 v1srclstv &= 0x000003ff; 505 506 507 /***************************** 508 *** log color keying info *** 509 *****************************/ 510 511 LOG(6,("Overlay: key_red %d, key_green %d, key_blue %d, key_alpha %d\n", 512 ow->red.value, ow->green.value, ow->blue.value, ow->alpha.value)); 513 LOG(6,("Overlay: mask_red %d, mask_green %d, mask_blue %d, mask_alpha %d\n", 514 ow->red.mask, ow->green.mask, ow->blue.mask, ow->alpha.mask)); 515 516 517 /************************* 518 *** setup BES control *** 519 *************************/ 520 521 /* BES global control: setup functions */ 522 globctlv = 0; 523 524 /* slowdown BES if nessesary */ 525 if (acczoom == 1) 526 { 527 /* run at full speed and resolution */ 528 globctlv |= 0 << 0; 529 /* disable filtering for half speed interpolation */ 530 globctlv |= 0 << 1; 531 } 532 else 533 { 534 /* run at half speed and resolution */ 535 globctlv |= 1 << 0; 536 /* enable filtering for half speed interpolation */ 537 globctlv |= 1 << 1; 538 } 539 540 /* 4:2:0 specific setup: not needed here */ 541 globctlv |= 0 << 3; 542 /* BES testregister: keep zero */ 543 globctlv |= 0 << 4; 544 /* the following bits marked (> G200) *must* be zero on G200: */ 545 /* 4:2:0 specific setup: not needed here (> G200) */ 546 globctlv |= 0 << 5; 547 /* select yuy2 byte-order to B_YCbCr422 (> G200) */ 548 globctlv |= 0 << 6; 549 /* BES internal contrast and brighness controls are not used, disabled (> G200) */ 550 globctlv |= 0 << 7; 551 /* RGB specific setup: not needed here, so disabled (> G200) */ 552 globctlv |= 0 << 8; 553 globctlv |= 0 << 9; 554 /* 4:2:0 specific setup: not needed here (> G200) */ 555 globctlv |= 0 << 10; 556 /* Tell BES when to copy the new register values to the actual active registers. 557 * bits 16-27 (12 bits) are the CRTC vert. count value at which copying takes 558 * place. 559 * (This is the double buffering feature: programming must be completed *before* 560 * the CRTC vert count value set here!) */ 561 /* CRTC vert count for copying = $000, so during retrace, line 0. */ 562 globctlv |= 0x000 << 16; 563 564 /* BES control: enable scaler and setup functions */ 565 /* pre-reset all bits */ 566 ctlv = 0; 567 /* enable BES */ 568 ctlv |= 1 << 0; 569 /* we start displaying at an even startline (zero) in 'field 1' (no hardware de-interlacing is used) */ 570 ctlv |= 0 << 6; 571 /* we don't use field 2, so its startline is not important */ 572 ctlv |= 0 << 7; 573 574 LOG(6,("Overlay: ow->flags is $%08x\n",ow->flags)); 575 /* enable horizontal filtering on scaling if asked for: if we *are* actually scaling */ 576 if ((ow->flags & B_OVERLAY_HORIZONTAL_FILTERING) && (hiscalv != (0x01 << 16))) 577 { 578 ctlv |= 1 << 10; 579 LOG(6,("Overlay: using horizontal interpolation on scaling\n")); 580 } 581 else 582 { 583 ctlv |= 0 << 10; 584 LOG(6,("Overlay: using horizontal dropping or replication on scaling\n")); 585 } 586 /* enable vertical filtering on scaling if asked for: if we are *upscaling* only */ 587 if ((ow->flags & B_OVERLAY_VERTICAL_FILTERING) && (viscalv < (0x01 << 16))) 588 { 589 ctlv |= 1 << 11; 590 LOG(6,("Overlay: using vertical interpolation on scaling\n")); 591 } 592 else 593 { 594 ctlv |= 0 << 11; 595 LOG(6,("Overlay: using vertical dropping or replication on scaling\n")); 596 } 597 598 /* use actual calculated weight for horizontal interpolation */ 599 ctlv |= 0 << 12; 600 /* use horizontal chroma interpolation upsampling on BES input picture */ 601 ctlv |= 1 << 16; 602 /* select 4:2:2 BES input format */ 603 ctlv |= 0 << 17; 604 /* dithering is enabled */ 605 ctlv |= 1 << 18; 606 /* horizontal mirroring is not used */ 607 ctlv |= 0 << 19; 608 /* BES output should be in color */ 609 ctlv |= 0 << 20; 610 /* BES output blanking is disabled: we want a picture, no 'black box'! */ 611 ctlv |= 0 << 21; 612 /* we do software field select (field select is not used) */ 613 ctlv |= 0 << 24; 614 /* we always display field 1 in buffer A, this contains our full frames */ 615 /* select field 1 */ 616 ctlv |= 0 << 25; 617 /* select buffer A */ 618 ctlv |= 0 << 26; 619 620 621 /************************************* 622 *** sync to BES (Back End Scaler) *** 623 *************************************/ 624 625 /* Make sure reprogramming the BES completes before the next retrace occurs, 626 * to prevent register-update glitches (double buffer feature). */ 627 628 LOG(3,("Overlay: starting register programming beyond Vcount %d\n", CR1R(VCOUNT))); 629 /* Even at 1600x1200x90Hz, a single line still takes about 9uS to complete: 630 * this resolution will generate about 180Mhz pixelclock while we can do 631 * upto 360Mhz. So snooze about 4uS to prevent bus-congestion... 632 * Appr. 200 lines time will provide enough room even on a 100Mhz CPU if it's 633 * screen is set to the highest refreshrate/resolution possible. */ 634 while ((uint16)CR1R(VCOUNT) > (si->dm.timing.v_total - 200)) snooze(4); 635 636 637 /************************************** 638 *** actually program the registers *** 639 **************************************/ 640 641 BESW(HCOORD, hcoordv); 642 BESW(VCOORD, vcoordv); 643 BESW(HISCAL, hiscalv); 644 BESW(HSRCST, hsrcstv); 645 BESW(HSRCEND, hsrcendv); 646 BESW(HSRCLST, hsrclstv); 647 BESW(VISCAL, viscalv); 648 BESW(A1ORG, a1orgv); 649 BESW(V1WGHT, v1wghtv); 650 BESW(V1SRCLST, v1srclstv); 651 BESW(GLOBCTL, globctlv); 652 BESW(CTL, ctlv); 653 654 655 /************************** 656 *** setup color keying *** 657 **************************/ 658 659 /* setup colorkeying */ 660 DXIW(COLKEY, (ow->alpha.value & ow->alpha.mask)); 661 662 DXIW(COLKEY0RED, (ow->red.value & ow->red.mask)); 663 DXIW(COLKEY0GREEN, (ow->green.value & ow->green.mask)); 664 DXIW(COLKEY0BLUE, (ow->blue.value & ow->blue.mask)); 665 666 DXIW(COLMSK, ow->alpha.mask); 667 668 DXIW(COLMSK0RED, ow->red.mask); 669 DXIW(COLMSK0GREEN, ow->green.mask); 670 DXIW(COLMSK0BLUE, ow->blue.mask); 671 672 /* enable colorkeying */ 673 DXIW(KEYOPMODE,0x01); 674 675 676 /************************* 677 *** setup misc. stuff *** 678 *************************/ 679 680 /* setup brightness and contrast to be 'neutral' (this is not implemented on G200) */ 681 BESW(LUMACTL, 0x00000080); 682 683 /* setup source pitch including slopspace (in pixels); AND is required by hardware */ 684 BESW(PITCH, (ob->width & 0x00000fff)); 685 686 /* on a 500Mhz P3 CPU just logging a line costs 400uS (18-19 vcounts at 1024x768x60Hz)! 687 * programming the registers above actually costs 180uS here */ 688 LOG(3,("Overlay: completed at Vcount %d\n", CR1R(VCOUNT))); 689 690 return B_OK; 691 } 692 693 status_t gx00_release_bes() 694 { 695 /* setup BES control: disable scaler */ 696 BESW(CTL, 0x00000000); 697 698 return B_OK; 699 } 700