completed move_overlay() implementation.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9997 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen 2004-11-18 12:52:55 +00:00
parent 5d6e6b647c
commit 1e421b8672
4 changed files with 59 additions and 400 deletions

View File

@ -3,7 +3,7 @@
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
Other authors: Other authors:
Rudolf Cornelissen 4/2003-5/2004 Rudolf Cornelissen 4/2003-11/2004
*/ */
#define MODULE_BIT 0x20000000 #define MODULE_BIT 0x20000000
@ -85,8 +85,7 @@ void MOVE_CURSOR(uint16 x, uint16 y)
if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start)) if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
{ {
MOVE_DISPLAY(hds,vds); MOVE_DISPLAY(hds,vds);
//fixme: implement: nm_bes_move_overlay();
//move_overlay(hds,vds);
} }
/* put cursor in correct physical position */ /* put cursor in correct physical position */

View File

@ -4,7 +4,7 @@
Other authors: Other authors:
Mark Watson, Mark Watson,
Rudolf Cornelissen 10/2002-4/2004. Rudolf Cornelissen 10/2002-11/2004.
*/ */
#define MODULE_BIT 0x00800000 #define MODULE_BIT 0x00800000
@ -127,7 +127,7 @@ status_t INIT_ACCELERANT(int the_fd) {
status_t result; status_t result;
int cnt; //used for iteration through the overlay buffers int cnt; //used for iteration through the overlay buffers
if (1) { if (0) {
time_t now = time (NULL); time_t now = time (NULL);
// LOG not available from here to next LOG: NULL si // LOG not available from here to next LOG: NULL si
MSG(("INIT_ACCELERANT: %s", ctime (&now))); MSG(("INIT_ACCELERANT: %s", ctime (&now)));
@ -197,6 +197,9 @@ status_t INIT_ACCELERANT(int the_fd) {
/* make sure overlay unit is 'marked' as being free */ /* make sure overlay unit is 'marked' as being free */
si->overlay.myToken = NULL; si->overlay.myToken = NULL;
/* note that overlay is not in use (for nm_bes_move_overlay()) */
si->overlay.active = false;
/* bail out if something failed */ /* bail out if something failed */
if (result != B_OK) goto error1; if (result != B_OK) goto error1;

View File

@ -5,19 +5,6 @@
#include "nm_std.h" #include "nm_std.h"
//fixme: implementation of move_overlay() function in progress...
//fixme: probably best to add routine:status_t nm_bes_init(void);
typedef struct move_overlay_info move_overlay_info;
struct move_overlay_info
{
uint32 hcoordv; /* left and right edges of video output window */
uint32 vcoordv; /* top and bottom edges of video output window */
uint32 hsrcstv; /* horizontal source start in source buffer (clipping) */
uint32 hsrcendv; /* horizontal source end in source buffer (clipping) */
uint32 a1orgv; /* vertical source clipping via startadress of source buffer */
};
static void nm_bes_calc_move_overlay(move_overlay_info *moi); static void nm_bes_calc_move_overlay(move_overlay_info *moi);
static void nm_bes_program_move_overlay(move_overlay_info moi); static void nm_bes_program_move_overlay(move_overlay_info moi);
@ -42,6 +29,8 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
uint16 temp1, temp2; uint16 temp1, temp2;
/* visible screen window in virtual workspaces */ /* visible screen window in virtual workspaces */
uint16 crtc_hstart, crtc_vstart, crtc_hend, crtc_vend; uint16 crtc_hstart, crtc_vstart, crtc_hend, crtc_vend;
/* horizontal source start in source buffer (clipping) */
uint32 hsrcstv;
/* the BES does not respect virtual_workspaces, but adheres to CRTC /* the BES does not respect virtual_workspaces, but adheres to CRTC
* constraints only */ * constraints only */
@ -180,7 +169,7 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
* Note: The input bitmaps slopspace is automatically excluded from the calculations this way! */ * Note: The input bitmaps slopspace is automatically excluded from the calculations this way! */
/* Note also: /* Note also:
* Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */ * Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */
moi->hsrcstv = 0; hsrcstv = 0;
/* check for destination horizontal clipping at left side */ /* check for destination horizontal clipping at left side */
if (si->overlay.ow.h_start < crtc_hstart) if (si->overlay.ow.h_start < crtc_hstart)
{ {
@ -189,22 +178,22 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
if ((si->overlay.ow.h_start + si->overlay.ow.width - 1) < (crtc_hstart + 1)) if ((si->overlay.ow.h_start + si->overlay.ow.width - 1) < (crtc_hstart + 1))
{ {
/* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */ /* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */
moi->hsrcstv += (si->overlay.ow.width - 2); hsrcstv += (si->overlay.ow.width - 2);
} }
else else
{ {
/* increase 'first contributing pixel' with actual number of dest. clipping pixels */ /* increase 'first contributing pixel' with actual number of dest. clipping pixels */
moi->hsrcstv += (crtc_hstart - si->overlay.ow.h_start); hsrcstv += (crtc_hstart - si->overlay.ow.h_start);
} }
LOG(4,("Overlay: clipping left...\n")); LOG(4,("Overlay: clipping left...\n"));
/* The calculated value is based on scaling = 1x. So we now compensate for scaling. /* The calculated value is based on scaling = 1x. So we now compensate for scaling.
* Note that this also already takes care of aligning the value to the BES register! */ * Note that this also already takes care of aligning the value to the BES register! */
moi->hsrcstv *= (si->overlay.h_ifactor << 4); hsrcstv *= (si->overlay.h_ifactor << 4);
} }
/* take zoom into account */ /* take zoom into account */
moi->hsrcstv += ((uint32)si->overlay.my_ov.h_start) << 16; hsrcstv += ((uint32)si->overlay.my_ov.h_start) << 16;
LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", moi->hsrcstv / (float)65536)); LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", hsrcstv / (float)65536));
/* Setup horizontal source end: last (sub)pixel contributing to output picture */ /* Setup horizontal source end: last (sub)pixel contributing to output picture */
/* Note: /* Note:
@ -274,6 +263,7 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
/* increase source buffer origin with 'fixed value': /* increase source buffer origin with 'fixed value':
* (integer part of ('total height - 2' of dest. picture in pixels * inverse scaling factor)) * * (integer part of ('total height - 2' of dest. picture in pixels * inverse scaling factor)) *
* bytes per row source picture */ * bytes per row source picture */
//fixme: rounding down would be better than just chopping off the fractional part...
moi->a1orgv += moi->a1orgv +=
((((si->overlay.ow.height - 2) * (si->overlay.v_ifactor << 4)) >> 16) * ((((si->overlay.ow.height - 2) * (si->overlay.v_ifactor << 4)) >> 16) *
si->overlay.ob.bytes_per_row); si->overlay.ob.bytes_per_row);
@ -283,6 +273,7 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
/* increase source buffer origin with: /* increase source buffer origin with:
* (integer part of (number of destination picture clipping pixels * inverse scaling factor)) * * (integer part of (number of destination picture clipping pixels * inverse scaling factor)) *
* bytes per row source picture */ * bytes per row source picture */
//fixme: rounding down would be better than just chopping off the fractional part...
moi->a1orgv += moi->a1orgv +=
((((crtc_vstart - si->overlay.ow.v_start) * (si->overlay.v_ifactor << 4)) >> 16) * ((((crtc_vstart - si->overlay.ow.v_start) * (si->overlay.v_ifactor << 4)) >> 16) *
si->overlay.ob.bytes_per_row); si->overlay.ob.bytes_per_row);
@ -293,7 +284,7 @@ static void nm_bes_calc_move_overlay(move_overlay_info *moi)
moi->a1orgv += (si->overlay.my_ov.v_start * si->overlay.ob.bytes_per_row); moi->a1orgv += (si->overlay.my_ov.v_start * si->overlay.ob.bytes_per_row);
/* now include 'pixel precise' left clipping... /* now include 'pixel precise' left clipping...
* (subpixel precision is not supported by NeoMagic cards) */ * (subpixel precision is not supported by NeoMagic cards) */
moi->a1orgv += ((moi->hsrcstv >> 16) * 2); moi->a1orgv += ((hsrcstv >> 16) * 2);
/* we need to step in 4-byte (2 pixel) granularity due to the nature of yuy2 */ /* we need to step in 4-byte (2 pixel) granularity due to the nature of yuy2 */
moi->a1orgv &= ~0x03; moi->a1orgv &= ~0x03;
LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n", moi->a1orgv)); LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n", moi->a1orgv));
@ -388,9 +379,9 @@ static void nm_bes_program_move_overlay(move_overlay_info moi)
LOG(4,("Overlay: kerneldriver programs BES\n")); LOG(4,("Overlay: kerneldriver programs BES\n"));
/* setup BES info struct... */ /* setup BES info struct... */
// bi.moi = moi; bi.moi = moi;
bi.card_type = si->ps.card_type; bi.card_type = si->ps.card_type;
// bi.pgm_all = false; //maybe better to setup a seperate kerneldriver function.. bi.move_only = true;
/* ... and call kerneldriver to program the BES */ /* ... and call kerneldriver to program the BES */
bi.magic = NM_PRIVATE_DATA_MAGIC; bi.magic = NM_PRIVATE_DATA_MAGIC;
ioctl(fd, NM_PGM_BES, &bi, sizeof(bi)); ioctl(fd, NM_PGM_BES, &bi, sizeof(bi));
@ -417,10 +408,6 @@ status_t nm_configure_bes
/* bes setup data */ /* bes setup data */
nm_bes_data bi; nm_bes_data bi;
/* misc used variables */
uint16 temp1, temp2;
/* BES output coordinate system for virtual workspaces */
uint16 crtc_hstart, crtc_vstart, crtc_hend, crtc_vend;
/* inverse scaling factor, used for source positioning */ /* inverse scaling factor, used for source positioning */
uint32 ifactor; uint32 ifactor;
/* copy of overlay view which has checked valid values */ /* copy of overlay view which has checked valid values */
@ -446,132 +433,15 @@ status_t nm_configure_bes
LOG(6,("Overlay: inputbuffer view (zoom) left %d, top %d, width %d, height %d\n", LOG(6,("Overlay: inputbuffer view (zoom) left %d, top %d, width %d, height %d\n",
my_ov.h_start, my_ov.v_start, my_ov.width, my_ov.height)); my_ov.h_start, my_ov.v_start, my_ov.width, my_ov.height));
/* the BES does not respect virtual_workspaces, but adheres to CRTC /* save for nm_bes_calc_move_overlay() */
* constraints only */ si->overlay.ow = *ow;
crtc_hstart = si->dm.h_display_start; si->overlay.ob = *ob;
/* horizontal end is the first position beyond the displayed range on the CRTC */ si->overlay.my_ov = my_ov;
crtc_hend = crtc_hstart + si->dm.timing.h_display;
crtc_vstart = si->dm.v_display_start;
/* vertical end is the first position beyond the displayed range on the CRTC */
crtc_vend = crtc_vstart + si->dm.timing.v_display;
/**************************************** /********************************
*** setup all edges of output window *** *** setup horizontal scaling ***
****************************************/ ********************************/
/* setup left and right edges of output window */
bi.hcoordv = 0;
/* left edge coordinate of output window, must be inside desktop */
/* clipping on the left side */
if (ow->h_start < crtc_hstart)
{
temp1 = 0;
}
else
{
/* clipping on the right side */
if (ow->h_start >= (crtc_hend - 1))
{
/* width < 2 is not allowed */
temp1 = (crtc_hend - crtc_hstart - 2);
}
else
/* no clipping here */
{
temp1 = (ow->h_start - crtc_hstart);
}
}
bi.hcoordv |= temp1 << 16;
/* right edge coordinate of output window, must be inside desktop */
/* width < 2 is not allowed */
if (ow->width < 2)
{
temp2 = (temp1 + 1);
}
else
{
/* clipping on the right side */
if ((ow->h_start + ow->width - 1) > (crtc_hend - 1))
{
temp2 = (crtc_hend - crtc_hstart - 1);
}
else
{
/* clipping on the left side */
if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1))
{
/* width < 2 is not allowed */
temp2 = 1;
}
else
/* no clipping here */
{
temp2 = ((uint16)(ow->h_start + ow->width - crtc_hstart - 1));
}
}
}
bi.hcoordv |= temp2 << 0;
LOG(4,("Overlay: CRTC left-edge output %d, right-edge output %d\n",temp1, temp2));
/* setup top and bottom edges of output window */
bi.vcoordv = 0;
/* top edge coordinate of output window, must be inside desktop */
/* clipping on the top side */
if (ow->v_start < crtc_vstart)
{
temp1 = 0;
}
else
{
/* clipping on the bottom side */
if (ow->v_start >= (crtc_vend - 1))
{
/* height < 2 is not allowed */
temp1 = (crtc_vend - crtc_vstart - 2);
}
else
/* no clipping here */
{
temp1 = (ow->v_start - crtc_vstart);
}
}
bi.vcoordv |= temp1 << 16;
/* bottom edge coordinate of output window, must be inside desktop */
/* height < 2 is not allowed */
if (ow->height < 2)
{
temp2 = (temp1 + 1);
}
else
{
/* clipping on the bottom side */
if ((ow->v_start + ow->height - 1) > (crtc_vend - 1))
{
temp2 = (crtc_vend - crtc_vstart - 1);
}
else
{
/* clipping on the top side */
if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1))
{
/* height < 2 is not allowed */
temp2 = 1;
}
else
/* no clipping here */
{
temp2 = ((uint16)(ow->v_start + ow->height - crtc_vstart - 1));
}
}
}
bi.vcoordv |= temp2 << 0;
LOG(4,("Overlay: CRTC top-edge output %d, bottom-edge output %d\n",temp1, temp2));
/*********************************************
*** setup horizontal scaling and clipping ***
*********************************************/
LOG(6,("Overlay: total input picture width = %d, height = %d\n", LOG(6,("Overlay: total input picture width = %d, height = %d\n",
(ob->width - si->overlay.myBufInfo[offset].slopspace), ob->height)); (ob->width - si->overlay.myBufInfo[offset].slopspace), ob->height));
@ -583,6 +453,8 @@ status_t nm_configure_bes
/* correct factor to prevent most-right visible 'line' from distorting */ /* correct factor to prevent most-right visible 'line' from distorting */
ifactor -= 1; ifactor -= 1;
bi.hiscalv = ifactor; bi.hiscalv = ifactor;
/* save for nv_bes_calc_move_overlay() */
si->overlay.h_ifactor = ifactor;
LOG(4,("Overlay: horizontal scaling factor is %f\n", (float)4096 / ifactor)); LOG(4,("Overlay: horizontal scaling factor is %f\n", (float)4096 / ifactor));
/* check scaling factor (and modify if needed) to be within scaling limits */ /* check scaling factor (and modify if needed) to be within scaling limits */
@ -602,87 +474,9 @@ status_t nm_configure_bes
} }
/* do horizontal clipping... */ /******************************
/* Setup horizontal source start: first (sub)pixel contributing to output picture */ *** setup vertical scaling ***
/* Note: ******************************/
* The method is to calculate, based on 1:1 scaling, based on the output window.
* After this is done, include the scaling factor so you get a value based on the input bitmap.
* Then add the left starting position of the bitmap's view (zoom function) to get the final value needed.
* Note: The input bitmaps slopspace is automatically excluded from the calculations this way! */
/* Note also:
* Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */
bi.hsrcstv = 0;
/* check for destination horizontal clipping at left side */
if (ow->h_start < crtc_hstart)
{
/* check if entire destination picture is clipping left:
* (2 pixels will be clamped onscreen at least) */
if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1))
{
/* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */
bi.hsrcstv += (ow->width - 2);
}
else
{
/* increase 'first contributing pixel' with actual number of dest. clipping pixels */
bi.hsrcstv += (crtc_hstart - ow->h_start);
}
LOG(4,("Overlay: clipping left...\n"));
/* The calculated value is based on scaling = 1x. So we now compensate for scaling.
* Note that this also already takes care of aligning the value to the BES register! */
bi.hsrcstv *= (ifactor << 4);
}
/* take zoom into account */
bi.hsrcstv += ((uint32)my_ov.h_start) << 16;
LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", bi.hsrcstv / (float)65536));
/* Setup horizontal source end: last (sub)pixel contributing to output picture */
/* Note:
* The method is to calculate, based on 1:1 scaling, based on the output window.
* After this is done, include the scaling factor so you get a value based on the input bitmap.
* Then add the right ending position of the bitmap's view (zoom function) to get the final value needed. */
/* Note also:
* Even if the scaling factor is clamping we instruct the BES to use the correct source end pos.! */
bi.hsrcendv = 0;
/* check for destination horizontal clipping at right side */
if ((ow->h_start + ow->width - 1) > (crtc_hend - 1))
{
/* check if entire destination picture is clipping right:
* (2 pixels will be clamped onscreen at least) */
if (ow->h_start > (crtc_hend - 2))
{
/* increase 'number of clipping pixels' with 'fixed value': (total dest. width - 2) */
bi.hsrcendv += (ow->width - 2);
}
else
{
/* increase 'number of clipping pixels' with actual number of dest. clipping pixels */
bi.hsrcendv += ((ow->h_start + ow->width - 1) - (crtc_hend - 1));
}
LOG(4,("Overlay: clipping right...\n"));
/* The calculated value is based on scaling = 1x. So we now compensate for scaling.
* Note that this also already takes care of aligning the value to the BES register! */
bi.hsrcendv *= (ifactor << 4);
/* now subtract this value from the last used pixel in (zoomed) inputbuffer, aligned to BES */
bi.hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16) - bi.hsrcendv;
}
else
{
/* set last contributing pixel to last used pixel in (zoomed) inputbuffer, aligned to BES */
bi.hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16);
}
/* AND below required by hardware */
bi.hsrcendv &= 0x03ffffff;
LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", bi.hsrcendv / (float)65536));
/*******************************************
*** setup vertical scaling and clipping ***
*******************************************/
/* calculate inverse vertical scaling factor, taking zoom into account */ /* calculate inverse vertical scaling factor, taking zoom into account */
ifactor = ((((uint32)my_ov.height) << 12) / ow->height); ifactor = ((((uint32)my_ov.height) << 12) / ow->height);
@ -693,6 +487,8 @@ status_t nm_configure_bes
/* preserve ifactor for source positioning calculations later on */ /* preserve ifactor for source positioning calculations later on */
bi.viscalv = ifactor; bi.viscalv = ifactor;
/* save for nv_bes_calc_move_overlay() */
si->overlay.v_ifactor = ifactor;
/* check scaling factor (and modify if needed) to be within scaling limits */ /* check scaling factor (and modify if needed) to be within scaling limits */
/* the upscaling limit is 8.0 (see official Neomagic specsheets) */ /* the upscaling limit is 8.0 (see official Neomagic specsheets) */
@ -711,59 +507,10 @@ status_t nm_configure_bes
} }
/* do vertical clipping... */ /********************************************************************************
/* Setup vertical source start: first (sub)pixel contributing to output picture. *** setup all edges of output window, setup horizontal and vertical clipping ***
* Note: this exists of two parts: ********************************************************************************/
* 1. setup fractional part (sign is always 'positive'); nm_bes_calc_move_overlay(&(bi.moi));
* 2. setup relative base_adress, taking clipping on top (and zoom) into account.
* Both parts are done intertwined below. */
/* Note:
* The method is to calculate, based on 1:1 scaling, based on the output window.
* 'After' this is done, include the scaling factor so you get a value based on the input bitmap.
* Then add the top starting position of the bitmap's view (zoom function) to get the final value needed. */
/* Note also:
* Even if the scaling factor is clamping we instruct the BES to use the correct source start pos.! */
/* calculate relative base_adress and 'vertical weight fractional part' */
bi.weight = 0;
bi.a1orgv = (uint32)((vuint32 *)ob->buffer);
bi.a1orgv -= (uint32)((vuint32 *)si->framebuffer);
/* calculate origin adress */
LOG(4,("Overlay: topleft corner of input bitmap (cardRAM offset) $%08x\n",bi.a1orgv));
/* check for destination vertical clipping at top side */
if (ow->v_start < crtc_vstart)
{
/* check if entire destination picture is clipping at top:
* (2 pixels will be clamped onscreen at least) */
if ((ow->v_start + ow->height - 1) < (crtc_vstart + 1))
{
/* increase source buffer origin with 'fixed value':
* (integer part of ('total height - 2' of dest. picture in pixels * inverse scaling factor)) *
* bytes per row source picture */
bi.weight = (ow->height - 2) * (ifactor << 4);
bi.a1orgv += ((bi.weight >> 16) * ob->bytes_per_row);
}
else
{
/* increase source buffer origin with:
* (integer part of (number of destination picture clipping pixels * inverse scaling factor)) *
* bytes per row source picture */
bi.weight = (crtc_vstart - ow->v_start) * (ifactor << 4);
bi.a1orgv += ((bi.weight >> 16) * ob->bytes_per_row);
}
LOG(4,("Overlay: clipping at top...\n"));
}
/* take zoom into account */
bi.a1orgv += (my_ov.v_start * ob->bytes_per_row);
bi.weight += (((uint32)my_ov.v_start) << 16);
/* now include 'pixel precise' left clipping...
* (subpixel precision is not supported by NeoMagic cards) */
bi.a1orgv += ((bi.hsrcstv >> 16) * 2);
/* we need to step in 4-byte (2 pixel) granularity due to the nature of yuy2 */
bi.a1orgv &= ~0x03;
LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n",bi.a1orgv));
LOG(4,("Overlay: first vert. (sub)pixel of input bitmap contributing %f\n", bi.weight / (float)65536));
/***************************** /*****************************
@ -810,15 +557,7 @@ status_t nm_configure_bes
/* Make sure reprogramming the BES completes before the next retrace occurs, /* Make sure reprogramming the BES completes before the next retrace occurs,
* to prevent register-update glitches (double buffer feature). */ * to prevent register-update glitches (double buffer feature). */
//fixme... //fixme if needed...
// LOG(3,("Overlay: starting register programming beyond Vcount %d\n", CR1R(VCOUNT)));
/* Even at 1600x1200x90Hz, a single line still takes about 9uS to complete:
* this resolution will generate about 180Mhz pixelclock while we can do
* upto 360Mhz. So snooze about 4uS to prevent bus-congestion...
* Appr. 200 lines time will provide enough room even on a 100Mhz CPU if it's
* screen is set to the highest refreshrate/resolution possible. */
// while (CR1R(VCOUNT) > (si->dm.timing.v_total - 200)) snooze(4);
/************************************** /**************************************
@ -835,12 +574,12 @@ status_t nm_configure_bes
/* unlock card overlay sequencer registers (b5 = 1) */ /* unlock card overlay sequencer registers (b5 = 1) */
PCIGRPHW(GENLOCK, (PCIGRPHR(GENLOCK) | 0x20)); PCIGRPHW(GENLOCK, (PCIGRPHR(GENLOCK) | 0x20));
/* destination rectangle #1 (output window position and size) */ /* destination rectangle #1 (output window position and size) */
PCIGRPHW(HD1COORD1L, ((bi.hcoordv >> 16) & 0xff)); PCIGRPHW(HD1COORD1L, ((bi.moi.hcoordv >> 16) & 0xff));
PCIGRPHW(HD1COORD2L, (bi.hcoordv & 0xff)); PCIGRPHW(HD1COORD2L, (bi.moi.hcoordv & 0xff));
PCIGRPHW(HD1COORD21H, (((bi.hcoordv >> 4) & 0xf0) | ((bi.hcoordv >> 24) & 0x0f))); PCIGRPHW(HD1COORD21H, (((bi.moi.hcoordv >> 4) & 0xf0) | ((bi.moi.hcoordv >> 24) & 0x0f)));
PCIGRPHW(VD1COORD1L, ((bi.vcoordv >> 16) & 0xff)); PCIGRPHW(VD1COORD1L, ((bi.moi.vcoordv >> 16) & 0xff));
PCIGRPHW(VD1COORD2L, (bi.vcoordv & 0xff)); PCIGRPHW(VD1COORD2L, (bi.moi.vcoordv & 0xff));
PCIGRPHW(VD1COORD21H, (((bi.vcoordv >> 4) & 0xf0) | ((bi.vcoordv >> 24) & 0x0f))); PCIGRPHW(VD1COORD21H, (((bi.moi.vcoordv >> 4) & 0xf0) | ((bi.moi.vcoordv >> 24) & 0x0f)));
/* scaling */ /* scaling */
PCIGRPHW(XSCALEL, (bi.hiscalv & 0xff)); PCIGRPHW(XSCALEL, (bi.hiscalv & 0xff));
PCIGRPHW(XSCALEH, ((bi.hiscalv >> 8) & 0xff)); PCIGRPHW(XSCALEH, ((bi.hiscalv >> 8) & 0xff));
@ -850,7 +589,7 @@ status_t nm_configure_bes
/* (we don't program buffer #2 as it's unused.) */ /* (we don't program buffer #2 as it's unused.) */
if (si->ps.card_type < NM2200) if (si->ps.card_type < NM2200)
{ {
bi.a1orgv >>= 1; bi.moi.a1orgv >>= 1;
/* horizontal source end does not use subpixelprecision: granularity is 8 pixels */ /* horizontal source end does not use subpixelprecision: granularity is 8 pixels */
/* notes: /* notes:
* - correctly programming horizontal source end minimizes used bandwidth; * - correctly programming horizontal source end minimizes used bandwidth;
@ -860,7 +599,7 @@ status_t nm_configure_bes
- adding 1 to convert 'last used position' to 'number of used pixels'; - adding 1 to convert 'last used position' to 'number of used pixels';
- adding 7 to round-up to the nearest higher (or equal) valid register - adding 7 to round-up to the nearest higher (or equal) valid register
value (needed because of it's 8-pixel granularity). */ value (needed because of it's 8-pixel granularity). */
PCIGRPHW(0xbc, ((((bi.hsrcendv >> 16) + 9) >> 3) - 1)); PCIGRPHW(0xbc, ((((bi.moi.hsrcendv >> 16) + 9) >> 3) - 1));
} }
else else
{ {
@ -875,34 +614,17 @@ status_t nm_configure_bes
* - make absolutely sure the engine can fetch the last pixel needed from * - make absolutely sure the engine can fetch the last pixel needed from
* the sourcebitmap even if only to generate a tiny subpixel from it! * the sourcebitmap even if only to generate a tiny subpixel from it!
* (see remarks for < NM2200 cards regarding programming this register) */ * (see remarks for < NM2200 cards regarding programming this register) */
PCIGRPHW(0xbc, ((((bi.hsrcendv >> 16) + 17) >> 4) - 1)); PCIGRPHW(0xbc, ((((bi.moi.hsrcendv >> 16) + 17) >> 4) - 1));
} }
PCIGRPHW(BUF1ORGL, (bi.a1orgv & 0xff)); PCIGRPHW(BUF1ORGL, (bi.moi.a1orgv & 0xff));
PCIGRPHW(BUF1ORGM, ((bi.a1orgv >> 8) & 0xff)); PCIGRPHW(BUF1ORGM, ((bi.moi.a1orgv >> 8) & 0xff));
PCIGRPHW(BUF1ORGH, ((bi.a1orgv >> 16) & 0xff)); PCIGRPHW(BUF1ORGH, ((bi.moi.a1orgv >> 16) & 0xff));
/* ??? */ /* ??? */
PCIGRPHW(0xbd, 0x02); PCIGRPHW(0xbd, 0x02);
PCIGRPHW(0xbe, 0x00); PCIGRPHW(0xbe, 0x00);
/* b2 = 0: don't use horizontal mirroring (NM2160) */ /* b2 = 0: don't use horizontal mirroring (NM2160) */
/* other bits do ??? */ /* other bits do ??? */
PCIGRPHW(0xbf, 0x02); PCIGRPHW(0xbf, 0x02);
/* destination rectangle #2 (output window position and size) */
/*
{
uint16 left = 0;
uint16 right = 128;
uint16 top = 0;
uint16 bottom = 128;
PCISEQW(HD2COORD1L, (left & 0xff));
PCISEQW(HD2COORD2L, (right & 0xff));
PCISEQW(HD2COORD21H, (((right >> 4) & 0xf0) | ((left >> 8) & 0x0f)));
PCISEQW(VD2COORD1L, (top & 0xff));
PCISEQW(VD2COORD2L, (bottom & 0xff));
PCISEQW(VD2COORD21H, (((bottom >> 4) & 0xf0) | ((top >> 8) & 0x0f)));
}
*/
/* ??? */ /* ??? */
PCISEQW(0x1c, 0xfb); PCISEQW(0x1c, 0xfb);
PCISEQW(0x1d, 0x00); PCISEQW(0x1d, 0x00);
@ -953,14 +675,14 @@ status_t nm_configure_bes
bi.colkey_g = (ow->green.value & ow->green.mask); bi.colkey_g = (ow->green.value & ow->green.mask);
bi.colkey_b = (ow->blue.value & ow->blue.mask); bi.colkey_b = (ow->blue.value & ow->blue.mask);
bi.ob_width = ob->width; bi.ob_width = ob->width;
bi.move_only = false;
/* ... and call kerneldriver to program the BES */ /* ... and call kerneldriver to program the BES */
bi.magic = NM_PRIVATE_DATA_MAGIC; bi.magic = NM_PRIVATE_DATA_MAGIC;
ioctl(fd, NM_PGM_BES, &bi, sizeof(bi)); ioctl(fd, NM_PGM_BES, &bi, sizeof(bi));
} }
/* on a 500Mhz P3 CPU just logging a line costs 400uS (18-19 vcounts at 1024x768x60Hz)! /* note that overlay is in use (for nm_bes_move_overlay()) */
* programming the registers above actually costs 180uS here */ si->overlay.active = true;
// LOG(3,("Overlay: completed at Vcount %d\n", CR1R(VCOUNT)));
return B_OK; return B_OK;
} }
@ -981,5 +703,8 @@ status_t nm_release_bes()
ISASEQW(BESCTRL2, 0xa0); ISASEQW(BESCTRL2, 0xa0);
} }
/* note that overlay is not in use (for nm_bes_move_overlay()) */
si->overlay.active = false;
return B_OK; return B_OK;
} }

View File

@ -47,7 +47,7 @@ status_t nm_general_powerup()
{ {
status_t status; status_t status;
LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.10 running.\n")); LOG(1,("POWERUP: Haiku-OS Neomagic Accelerant 0.11 running.\n"));
/* detect card type and power it up */ /* detect card type and power it up */
switch(CFGR(DEVID)) switch(CFGR(DEVID))
@ -202,75 +202,7 @@ static status_t nmxxxx_general_powerup()
/* setup sequencer clocking mode */ /* setup sequencer clocking mode */
ISASEQW(CLKMODE, 0x21); ISASEQW(CLKMODE, 0x21);
/* G100 SGRAM and SDRAM use external pix and dac refs, do *not* activate internals! //fixme: setup coldstart capability...
* (this would create electrical shortcuts,
* resulting in extra chip heat and distortions visible on screen */
/* set voltage reference - using DAC reference block partly */
// DXIW(VREFCTRL,0x03);
/* wait for 100ms for voltage reference to stabilize */
delay(100000);
/* power up the SYSPLL */
// CFGW(OPTION,CFGR(OPTION)|0x20);
/* power up the PIXPLL */
// DXIW(PIXCLKCTRL,0x08);
/* disable pixelclock oscillations before switching on CLUT */
// DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) | 0x04));
/* disable 15bit mode CLUT-overlay function */
// DXIW(GENCTRL, DXIR(GENCTRL & 0xfd));
/* CRTC2->MAFC, 8-bit DAC, CLUT enabled, enable DAC */
// DXIW(MISCCTRL,0x1b);
// snooze(250);
/* re-enable pixelclock oscillations */
// DXIW(PIXCLKCTRL, (DXIR(PIXCLKCTRL) & 0xfb));
/*make sure card is in powergraphics mode*/
// VGAW_I(CRTCEXT,3,0x80);
/*set the system clocks to powergraphics speed*/
// LOG(2,("INIT: Setting system PLL to powergraphics speeds\n"));
// g100_dac_set_sys_pll();
/* 'official' RAM initialisation */
// LOG(2,("INIT: RAM init\n"));
/* disable plane write mask (needed for SDRAM): actual change needed to get it sent to RAM */
// ACCW(PLNWT,0x00000000);
// ACCW(PLNWT,0xffffffff);
/* program memory control waitstates */
// ACCW(MCTLWTST,si->ps.mctlwtst_reg);
/* set memory configuration including:
* - no split framebuffer.
* - Mark says b14 (G200) should be done also though not defined for G100 in spec,
* - b3 v3_mem_type was included by Mark for memconfig setup: but looks like not defined */
// CFGW(OPTION,(CFGR(OPTION)&0xFFFF8FFF) | ((si->ps.v3_mem_type & 0x04) << 10));
/* set memory buffer type:
* - Mark says: if((v3_mem_type & 0x03) == 0x03) then do not or-in bits in option2;
* but looks like v3_mem_type b1 is not defined,
* - Mark also says: place v3_mem_type b1 in option2 bit13 (if not 0x03) but b13 = reserved. */
// CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFCFFF)|((si->ps.v3_mem_type & 0x01) << 12));
/* set RAM read tap delay */
// CFGW(OPTION2,(CFGR(OPTION2)&0xFFFFFFF0) | ((si->ps.v3_mem_type & 0xf0) >> 4));
/* wait 200uS minimum */
// snooze(250);
/* reset memory (MACCESS is a write only register!) */
// ACCW(MACCESS, 0x00000000);
/* select JEDEC reset method */
// ACCW(MACCESS, 0x00004000);
/* perform actual RAM reset */
// ACCW(MACCESS, 0x0000c000);
// snooze(250);
/* start memory refresh */
// CFGW(OPTION,(CFGR(OPTION)&0xffe07fff) | (si->ps.option_reg & 0x001f8000));
/* set memory control waitstate again AFTER the RAM reset */
// ACCW(MCTLWTST,si->ps.mctlwtst_reg);
/* end 'official' RAM initialisation. */
/* Bus parameters: enable retries, use advanced read */
// CFGW(OPTION,(CFGR(OPTION)|(1<<22)|(0<<29)));
/*enable writing to crtc registers*/
// VGAW_I(CRTC,0x11,0);
/* turn on display */ /* turn on display */
nm_crtc_dpms(true, true, true); nm_crtc_dpms(true, true, true);