From ee2288b79d1cdb61f77a84d5d1e8487c07151554 Mon Sep 17 00:00:00 2001 From: shatty Date: Mon, 1 Dec 2003 06:37:07 +0000 Subject: [PATCH] openBeOS_Neomagic_V0.04_src git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5516 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../graphics/neomagic/DriverInterface.h | 25 +- headers/private/graphics/neomagic/nm_macros.h | 109 ++-- .../accelerants/neomagic/GetAccelerantHook.c | 10 +- src/add-ons/accelerants/neomagic/Overlay.c | 116 +--- .../accelerants/neomagic/engine/nm_bes.c | 546 ++++++++---------- .../accelerants/neomagic/engine/nm_crtc.c | 4 +- .../accelerants/neomagic/engine/nm_general.c | 14 +- src/add-ons/accelerants/neomagic/global.h | 1 + .../kernel/drivers/graphics/neomagic/driver.c | 119 ++++ .../drivers/graphics/neomagic/nm.settings | 4 +- 10 files changed, 478 insertions(+), 470 deletions(-) diff --git a/headers/private/graphics/neomagic/DriverInterface.h b/headers/private/graphics/neomagic/DriverInterface.h index 5d7fc76921..528e0bd480 100644 --- a/headers/private/graphics/neomagic/DriverInterface.h +++ b/headers/private/graphics/neomagic/DriverInterface.h @@ -63,7 +63,8 @@ enum { MN_DEVICE_NAME, MN_RUN_INTERRUPTS, MN_ISA_OUT, - MN_ISA_IN + MN_ISA_IN, + MN_PGM_BES }; /* max. number of overlay buffers */ @@ -231,6 +232,28 @@ typedef struct { uint16 data; /* The value read or written */ } mn_in_out_isa; +/* setup ISA BES registers for overlay on ISA cards */ +typedef struct { + uint32 magic; /* magic number to make sure the caller groks us */ + uint32 card_type; /* see card_type enum above */ + uint32 hcoordv; + uint32 vcoordv; + uint32 hiscalv; + uint32 viscalv; + uint32 hsrcstv; + uint32 hsrcendv; + uint32 hsrclstv; + uint32 a1orgv; + uint32 globctlv; + uint32 v1wghtv; + uint32 weight; + uint32 v1srclstv; + uint8 colkey_r; + uint8 colkey_g; + uint8 colkey_b; + uint16 ob_width; +} mn_bes_data; + /* Set some boolean condition (like enabling or disabling interrupts) */ typedef struct { uint32 magic; /* magic number to make sure the caller groks us */ diff --git a/headers/private/graphics/neomagic/nm_macros.h b/headers/private/graphics/neomagic/nm_macros.h index ee17753e84..5f41f42a8b 100644 --- a/headers/private/graphics/neomagic/nm_macros.h +++ b/headers/private/graphics/neomagic/nm_macros.h @@ -1,5 +1,6 @@ /* NM registers definitions and macros for access to */ +//old: /* PCI_config_space */ #define NMCFG_DEVID 0x00 #define NMCFG_DEVCTRL 0x04 @@ -24,8 +25,8 @@ #define NMCFG_AGP_IDENT 0xf0 // >= MIL2 #define NMCFG_AGP_STS 0xf4 // >= MIL2 #define NMCFG_AGP_CMD 0xf8 // >= MIL2 +//end old. -//new: /* neomagic ISA direct registers */ /* VGA standard registers: */ #define NMISA8_ATTRINDW 0x03c0 @@ -42,6 +43,14 @@ #define NMISA8_GRPHDAT 0x03cf #define NMISA16_GRPHIND 0x03ce +/* neomagic PCI direct registers */ +#define NM2PCI8_SEQIND 0x03c4 +#define NM2PCI8_SEQDAT 0x03c5 +#define NM2PCI16_SEQIND 0x03c4 +#define NM2PCI8_GRPHIND 0x03ce +#define NM2PCI8_GRPHDAT 0x03cf +#define NM2PCI16_GRPHIND 0x03ce + /* neomagic ISA GENERAL direct registers */ /* VGA standard registers: */ #define NMISA8_MISCW 0x03c2 @@ -86,6 +95,25 @@ #define NMSEQX_RESET 0x00 #define NMSEQX_CLKMODE 0x01 #define NMSEQX_MEMMODE 0x04 +/* NeoMagic BES registers: (> NM2070) (accessible via mapped I/O: >= NM2097) */ +#define NMSEQX_BESCTRL2 0x08 +#define NMSEQX_0x09 0x09 //?? +#define NMSEQX_0x0a 0x0a //?? +#define NMSEQX_BUF2ORGL 0x0c +#define NMSEQX_BUF2ORGM 0x0d +#define NMSEQX_BUF2ORGH 0x0e +#define NMSEQX_VSCOORD1L 0x14 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_VSCOORD2L 0x15 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_VSCOORD21H 0x16 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_HSCOORD1L 0x17 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_HSCOORD2L 0x18 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_HSCOORD21H 0x19 /* >= NM2200(?), so clipping done via buffer startadress instead */ +#define NMSEQX_BUF2PITCHL 0x1a +#define NMSEQX_BUF2PITCHH 0x1b +#define NMSEQX_0x1c 0x1c //?? +#define NMSEQX_0x1d 0x1d //?? +#define NMSEQX_0x1e 0x1e //?? +#define NMSEQX_0x1f 0x1f //?? /* neomagic ISA ATTRIBUTE indexed registers */ /* VGA standard registers: */ @@ -129,6 +157,31 @@ #define NMGRPHX_PLLC_NL 0x9b #define NMGRPHX_PLLC_NH 0x8f /* >= NM2200 */ #define NMGRPHX_PLLC_M 0x9f +/* NeoMagic BES registers: (> NM2070) (accessible via mapped I/O: >= NM2097) */ +#define NMGRPHX_BESCTRL1 0xb0 +#define NMGRPHX_HDCOORD21H 0xb1 +#define NMGRPHX_HDCOORD1L 0xb2 +#define NMGRPHX_HDCOORD2L 0xb3 +#define NMGRPHX_VDCOORD21H 0xb4 +#define NMGRPHX_VDCOORD1L 0xb5 +#define NMGRPHX_VDCOORD2L 0xb6 +#define NMGRPHX_BUF1ORGH 0xb7 +#define NMGRPHX_BUF1ORGM 0xb8 +#define NMGRPHX_BUF1ORGL 0xb9 +#define NMGRPHX_BUF1PITCHH 0xba +#define NMGRPHX_BUF1PITCHL 0xbb +#define NMGRPHX_0xbc 0xbc //?? +#define NMGRPHX_0xbd 0xbd //?? +#define NMGRPHX_0xbe 0xbe //?? +#define NMGRPHX_0xbf 0xbf //?? +#define NMGRPHX_XSCALEH 0xc0 +#define NMGRPHX_XSCALEL 0xc1 +#define NMGRPHX_YSCALEH 0xc2 +#define NMGRPHX_YSCALEL 0xc3 +#define NMGRPHX_BRIGHTNESS 0xc4 +#define NMGRPHX_COLKEY_R 0xc5 +#define NMGRPHX_COLKEY_G 0xc6 +#define NMGRPHX_COLKEY_B 0xc7 /* NeoMagic specific PCI cursor registers < NM2200 */ #define NMCR1_CURCTRL 0x0100 @@ -144,8 +197,8 @@ #define NMCR1_22CURBGCOLOR 0x100c #define NMCR1_22CURFGCOLOR 0x1010 #define NMCR1_22CURADDRESS 0x1014 -//end new. +//old: /* NM ACCeleration registers */ #define NMACC_DWGCTL 0x1C00 #define NMACC_MACCESS 0x1C04 @@ -189,56 +242,30 @@ #define NMACC_TEXORG4 0x2CB0 // >= G200 #define NMACC_SRCORG 0x2CB4 // >= G200 #define NMACC_DSTORG 0x2CB8 // >= G200 - -/*NM BES (Back End Scaler) registers (>= G200) */ -#define NMBES_A1ORG 0x3D00 -#define NMBES_A2ORG 0x3D04 -#define NMBES_B1ORG 0x3D08 -#define NMBES_B2ORG 0x3D0C -#define NMBES_A1CORG 0x3D10 -#define NMBES_A2CORG 0x3D14 -#define NMBES_B1CORG 0x3D18 -#define NMBES_B2CORG 0x3D1C -#define NMBES_CTL 0x3D20 -#define NMBES_PITCH 0x3D24 -#define NMBES_HCOORD 0x3D28 -#define NMBES_VCOORD 0x3D2C -#define NMBES_HISCAL 0x3D30 -#define NMBES_VISCAL 0x3D34 -#define NMBES_HSRCST 0x3D38 -#define NMBES_HSRCEND 0x3D3C -#define NMBES_LUMACTL 0x3D40 -#define NMBES_V1WGHT 0x3D48 -#define NMBES_V2WGHT 0x3D4C -#define NMBES_HSRCLST 0x3D50 -#define NMBES_V1SRCLST 0x3D54 -#define NMBES_V2SRCLST 0x3D58 -#define NMBES_A1C3ORG 0x3D60 -#define NMBES_A2C3ORG 0x3D64 -#define NMBES_B1C3ORG 0x3D68 -#define NMBES_B2C3ORG 0x3D6C -#define NMBES_GLOBCTL 0x3DC0 -#define NMBES_STATUS 0x3DC4 +//end old. /* Macros for convenient accesses to the NM chips */ +/* primary PCI register area */ #define NM_REG8(r_) ((vuint8 *)regs)[(r_)] +#define NM_REG16(r_) ((vuint16 *)regs)[(r_) >> 1] #define NM_REG32(r_) ((vuint32 *)regs)[(r_) >> 2] +/* secondary PCI register area */ +#define NM_2REG8(r_) ((vuint8 *)regs2)[(r_)] +#define NM_2REG16(r_) ((vuint16 *)regs2)[(r_) >> 1] +#define NM_2REG32(r_) ((vuint32 *)regs2)[(r_) >> 2] /* read and write to PCI config space */ #define CFGR(A) (mn_pci_access.offset=NMCFG_##A, ioctl(fd,MN_GET_PCI, &mn_pci_access,sizeof(mn_pci_access)), mn_pci_access.value) #define CFGW(A,B) (mn_pci_access.offset=NMCFG_##A, mn_pci_access.value = B, ioctl(fd,MN_SET_PCI,&mn_pci_access,sizeof(mn_pci_access))) +//old: /* read and write from the powergraphics registers */ #define ACCR(A) (NM_REG32(NMACC_##A)) #define ACCW(A,B) (NM_REG32(NMACC_##A)=B) #define ACCGO(A,B) (NM_REG32(NMACC_##A + 0x0100)=B) +//end old. -/* read and write from the backend scaler registers */ -#define BESR(A) (NM_REG32(NMBES_##A)) -#define BESW(A,B) (NM_REG32(NMBES_##A)=B) - -//new: /* read and write from first CRTC (mapped) */ #define CR1R(A) (NM_REG32(NMCR1_##A)) #define CR1W(A,B) (NM_REG32(NMCR1_##A) = (B)) @@ -257,10 +284,18 @@ #define ISAGRPHW(A,B)(ISAWW(GRPHIND, ((NMGRPHX_##A) | ((B) << 8)))) #define ISAGRPHR(A) (ISAWB(GRPHIND, (NMGRPHX_##A)), ISARB(GRPHDAT)) +/* read and write from PCI GRAPHICS indexed registers (>= NM2097) */ +#define PCIGRPHW(A,B)(NM_2REG16(NM2PCI16_GRPHIND) = ((NMGRPHX_##A) | ((B) << 8))) +#define PCIGRPHR(A) (NM_2REG8(NM2PCI8_GRPHIND) = (NMGRPHX_##A), NM_2REG8(NM2PCI8_GRPHDAT)) + /* read and write from ISA SEQUENCER indexed registers */ #define ISASEQW(A,B)(ISAWW(SEQIND, ((NMSEQX_##A) | ((B) << 8)))) #define ISASEQR(A) (ISAWB(SEQIND, (NMSEQX_##A)), ISARB(SEQDAT)) +/* read and write from PCI SEQUENCER indexed registers (>= NM2097) */ +#define PCISEQW(A,B)(NM_2REG16(NM2PCI16_SEQIND) = ((NMSEQX_##A) | ((B) << 8))) +#define PCISEQR(A) (NM_2REG8(NM2PCI8_SEQIND) = (NMSEQX_##A), NM_2REG8(NM2PCI8_SEQDAT)) + /* read and write from ISA ATTRIBUTE indexed registers */ /* define DUMMY to prevent compiler warnings */ #define static uint8 DUMMY; diff --git a/src/add-ons/accelerants/neomagic/GetAccelerantHook.c b/src/add-ons/accelerants/neomagic/GetAccelerantHook.c index c52135a4a5..071cb8c0b2 100644 --- a/src/add-ons/accelerants/neomagic/GetAccelerantHook.c +++ b/src/add-ons/accelerants/neomagic/GetAccelerantHook.c @@ -169,12 +169,12 @@ status_t check_overlay_capability(uint32 feature) break; } -// if (si->ps.card_type > NM2070) -// { + if (si->ps.card_type > NM2070) + { /* export video overlay functions */ -// LOG(4, ("Overlay: Exporting hook %s.\n", msg)); -// return B_OK; -// } + LOG(4, ("Overlay: Exporting hook %s.\n", msg)); + return B_OK; + } /* do not export video overlay functions */ LOG(4, ("Overlay: Not exporting hook %s.\n", msg)); diff --git a/src/add-ons/accelerants/neomagic/Overlay.c b/src/add-ons/accelerants/neomagic/Overlay.c index 2a6cb6335c..04768974ef 100644 --- a/src/add-ons/accelerants/neomagic/Overlay.c +++ b/src/add-ons/accelerants/neomagic/Overlay.c @@ -1,4 +1,4 @@ -/* Written by Rudolf Cornelissen 05-2002/03-2003 */ +/* Written by Rudolf Cornelissen 05-2002/06-2003 */ /* Note on 'missing features' in BeOS 5.0.3 and DANO: * BeOS needs to define more colorspaces! It would be nice if BeOS would support the FourCC 'definitions' @@ -10,12 +10,6 @@ #include "acc_std.h" /* define the supported overlay input colorspaces */ -/* Note: - * G200-G550 can all do YUV4:2:0 2-plane colorspace as well, - * G200 does not support RGB modes while > G200 do (but with limited scaling and without filtering), - * G200 does not support YUV4:2:0 3-plane mode while > G200 do. - * It would be nice to have the YUV4:2:0 2-plane mode implemented also later on, but the Be colorspace - * definitions (in GraphicsDefs.h, R5.0.3 and DANO5.1d0) do not include this one... */ static uint32 overlay_colorspaces [] = { (uint32)B_YCbCr422, (uint32)B_NO_COLOR_SPACE }; uint32 OVERLAY_COUNT(const display_mode *dm) @@ -46,7 +40,7 @@ const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm) return NULL; } - /* interlaced VGA is not supported by G200-G550 BES */ + /* assuming interlaced VGA is not supported */ if (dm->timing.flags && B_TIMING_INTERLACED) { return NULL; @@ -60,16 +54,12 @@ uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space) { LOG(4,("Overlay: supported_features: color_space $%08x\n",a_color_space)); - /* check what features (like the keying method) are supported on the current - * Desktop colorspace */ - //fixme? Or are we talking about the overlay input bitmap's colorspace? + /* check what features are supported for the current overlaybitmap colorspace */ switch (a_color_space) { default: - /* fixme: for now 'direct 32bit' desktop colorspace assumed */ return - ( B_OVERLAY_KEYING_USES_ALPHA | - B_OVERLAY_COLOR_KEY | + ( B_OVERLAY_COLOR_KEY | B_OVERLAY_HORIZONTAL_FILTERING | B_OVERLAY_VERTICAL_FILTERING ); } @@ -103,12 +93,7 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint switch (cs) { case B_YCbCr422: - /* check if slopspace is needed: compatible settings choosen for now: - * G200 can do with ~0x0003 while > G200 need ~x0007. - * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ - /* fixme: update needed for DVDmax support to adhere to CRTC2 constraints: - * case display_mode == B_RGB16: multiple = 32 - * case display_mode == B_RGB32: multiple = 16 */ + /* check if slopspace is needed: NeoMagic cards can do with ~x0007 */ if (width == (width & ~0x0007)) { si->overlay.myBuffer[offset].width = width; @@ -119,10 +104,9 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint } si->overlay.myBuffer[offset].bytes_per_row = 2 * si->overlay.myBuffer[offset].width; - /* check if the requested horizontal pitch is supported: - * G200 max. pitch is 4092 pixels, > G200 max pitch is 4088 pixels for this colorspace. - * Compatible check done, has no downside consequences here. */ - if (si->overlay.myBuffer[offset].width > 4088) + /* check if the requested horizontal pitch is supported */ + //fixme?... + if (si->overlay.myBuffer[offset].width > 2048) { LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n")); @@ -132,37 +116,6 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint return NULL; } break; - -// case 0xffff://fixme: which one(s)? - //fixme: 4:2:0 2-plane supported format, should be selected only if detected - /* check if slopspace is needed: compatible settings choosen for now: - * G200 can do with ~0x0007 while > G200 need ~x001f. - * Optimized settings for G200 could reduce CPU load a tiny little bit there... */ -/* if (width == (width & ~0x001f)) - { - si->overlay.myBuffer[offset].width = width; - } - else - { - si->overlay.myBuffer[offset].width = (width & ~0x001f) + 32; - } -*/ /* assuming Y-plane only bytes_per_row are requested here */ -/* si->overlay.myBuffer[offset].bytes_per_row = si->overlay.myBuffer[offset].width; -*/ - /* check if the requested horizontal pitch is supported: - * G200 max. pitch is 4088 pixels, > G200 max pitch is 4064 pixels for this colorspace. - * Compatible check done, has no real downside consequences here. */ -/* if (si->overlay.myBuffer[offset].width > 4064) - { - LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n"); -*/ - /* release the shared benaphore */ -/* RELEASE_BEN(si->overlay.lock) - - return NULL; - } - break; -*/ default: /* unsupported colorspace! */ LOG(4,("Overlay: Sorry, colorspace $%08x not supported, aborted\n",cs)); @@ -235,16 +188,6 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint si->overlay.myBuffer[offset].bytes_per_row * si->overlay.myBuffer[offset].height; /* calculate virtual memory adress that would be needed for a new bitmap */ - /* NOTE to app programmers: - * For testing app behaviour regarding workspace switches or screen prefs changes to settings - * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with - * a low amount of RAM. Or you can set in the file nm.settings for example: - * memory 8 #8Mb RAM on card - * and reboot (this simulates 8Mb RAM on the card). - * - * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to - * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ - adress = (((uint32)((uint8*)si->framebuffer)) + (si->ps.memory_size * 1024)); for (cnt = 0; cnt <= offset; cnt++) { @@ -329,16 +272,6 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint si->overlay.myBuffer[offset].buffer = (void *) adress; /* calculate physical memory adress (for dma use) */ - /* NOTE to app programmers: - * For testing app behaviour regarding workspace switches or screen prefs changes to settings - * that do not have enough cardRAM left for allocation of overlay bitmaps, you need a card with - * a low amount of RAM. Or you can set in the file nm.settings for example: - * memory 8 #8Mb RAM on card - * and reboot (this simulates 8Mb RAM on the card). - * - * If you switch now to settings: 1600x1200x32bit (single head) the app needs to fallback to - * bitmap output or maybe single buffered overlay output if small bitmaps are used. */ - adress = (((uint32)((uint8*)si->framebuffer_pci)) + (si->ps.memory_size * 1024)); for (cnt = 0; cnt <= offset; cnt++) { @@ -438,17 +371,11 @@ status_t GET_OVERLAY_CONSTRAINTS switch (ob->space) { case B_YCbCr422: - /* G200 can work with 3, > G200 need 7. Compatible setting returned for now. + /* NeoMagic cards can work with 7. * Note: this has to be in sync with the slopspace setup during buffer allocation.. */ + //fixme: >= NM2200 use 16 instead of 8??? oc->view.width_alignment = 7; break; - -// case 0xffff://fixme: which one(s)? (4:2:0 supported formats. Not yet used...) - /* G200 can work with 7, > G200 need 31. Compatible setting returned for now. - * Note: this has to be in sync with the slopspace setup during buffer allocation.. */ -/* oc->view.width_alignment = 31; - break; -*/ default: /* we should not be here, but set the worst-case value just to be safe anyway */ oc->view.width_alignment = 31; @@ -468,6 +395,7 @@ status_t GET_OVERLAY_CONSTRAINTS oc->window.height_alignment = 0; oc->window.width.min = 2; /* G200-G550 can output upto and including 2048 pixels in width */ + //fixme... if (dm->virtual_width > 2048) { oc->window.width.max = 2048; @@ -478,6 +406,7 @@ status_t GET_OVERLAY_CONSTRAINTS } oc->window.height.min = 2; /* G200-G550 can output upto and including 2048 pixels in height */ + //fixme... if (dm->virtual_height > 2048) { oc->window.height.max = 2048; @@ -487,21 +416,12 @@ status_t GET_OVERLAY_CONSTRAINTS oc->window.height.max = dm->virtual_height; } - /* G200-G550 scaling restrictions */ - /* Adjust horizontal restrictions if pixelclock is above BES max. speed! */ - /* Note: If RGB32 is implemented no scaling is supported! */ - if (si->dm.timing.pixel_clock > BESMAXSPEED) - { - oc->h_scale.min = (1 * 2) / (32 - (1 / (float)16384)); - oc->h_scale.max = (16384 * 2)/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); - } - else - { - oc->h_scale.min = 1 / (32 - (1 / (float)16384)); - oc->h_scale.max = 16384/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); - } - oc->v_scale.min = 1 / (32 - (1 / (float)16384)); - oc->v_scale.max = 16384/(float)ob->height; + /* NeoMagic scaling restrictions */ + /* Note: NM BES does not support downscaling! */ + oc->h_scale.min = 1.0; + oc->h_scale.max = 1024/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); + oc->v_scale.min = 1.0; + oc->v_scale.max = 1024/(float)ob->height; return B_OK; } diff --git a/src/add-ons/accelerants/neomagic/engine/nm_bes.c b/src/add-ons/accelerants/neomagic/engine/nm_bes.c index ea7264fa71..a75dcbcdcb 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_bes.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_bes.c @@ -1,5 +1,5 @@ -/* G200-G550 Back End Scaler functions */ -/* Written by Rudolf Cornelissen 05/2002-04/2003 */ +/* NeoMagic Back End Scaler functions */ +/* Written by Rudolf Cornelissen 05/2002-06/2003 */ #define MODULE_BIT 0x00000200 @@ -26,47 +26,17 @@ status_t mn_configure_bes /* 'ov' is the view in the source bitmap, so which part of the bitmap is actually * displayed on screen. This is used for the 'hardware zoom' function. */ - /* calculated BES register values */ - uint32 hcoordv, vcoordv, hiscalv, hsrcstv, hsrcendv, hsrclstv, - viscalv, a1orgv, v1wghtv, v1srclstv, globctlv, ctlv; + /* bes setup data */ + mn_bes_data bi; /* misc used variables */ uint16 temp1, temp2; - /* interval representation, used for scaling calculations */ - uint16 intrep, crtc_hstart, crtc_vstart, crtc_hend, crtc_vend; + /* BES output coordinate system for virtual workspaces */ + uint16 crtc_hstart, crtc_vstart, crtc_hend, crtc_vend; /* inverse scaling factor, used for source positioning */ uint32 ifactor; - /* used for vertical weight starting value */ - uint32 weight; /* copy of overlay view which has checked valid values */ overlay_view my_ov; - /* Slowdown the G200-G550 BES if the pixelclock is too high for it to cope. - * This will in fact half the horizontal resolution of the BES with high - * pixelclocks (by setting a BES hardware 'zoom' = 2x). - * If you want optimal output quality better make sure you set the refreshrate/resolution - * of your monitor not too high ... */ - uint16 acczoom = 1; - LOG(4,("Overlay: pixelclock is %dkHz, ", si->dm.timing.pixel_clock)); - if (si->dm.timing.pixel_clock > BESMAXSPEED) - { - /* BES running at half speed and resolution */ - /* This is how it works (BES slowing down): - * - Activate BES internal horizontal hardware scaling = 4x (in GLOBCTL below), - * - This also sets up BES only getting half the amount of pixels per line from - * the input picture buffer (in effect half-ing the BES pixelclock input speed). - * Now in order to get the picture back to original size, we need to also double - * the inverse horizontal scaling factor here (x4 /2 /2 = 1x again). - * Note that every other pixel is now doubled or interpolated, according to another - * GLOBCTL bit. */ - acczoom = 2; - LOG(4,("slowing down BES!\n")); - } - else - { - /* BES running at full speed and resolution */ - LOG(4,("BES is running at full speed\n")); - } - /************************************************************************************** *** copy, check and limit if needed the user-specified view into the intput bitmap *** @@ -102,7 +72,7 @@ status_t mn_configure_bes ****************************************/ /* setup left and right edges of output window */ - hcoordv = 0; + bi.hcoordv = 0; /* left edge coordinate of output window, must be inside desktop */ /* clipping on the left side */ if (ow->h_start < crtc_hstart) @@ -115,27 +85,27 @@ status_t mn_configure_bes if (ow->h_start >= (crtc_hend - 1)) { /* width < 2 is not allowed */ - temp1 = (crtc_hend - crtc_hstart - 2) & 0x7ff; + temp1 = (crtc_hend - crtc_hstart - 2); } else /* no clipping here */ { - temp1 = (ow->h_start - crtc_hstart) & 0x7ff; + temp1 = (ow->h_start - crtc_hstart); } } - hcoordv |= temp1 << 16; + 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) & 0x7ff; + 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) & 0x7ff; + temp2 = (crtc_hend - crtc_hstart - 1); } else { @@ -148,15 +118,15 @@ status_t mn_configure_bes else /* no clipping here */ { - temp2 = ((uint16)(ow->h_start + ow->width - crtc_hstart - 1)) & 0x7ff; + temp2 = ((uint16)(ow->h_start + ow->width - crtc_hstart - 1)); } } } - hcoordv |= temp2 << 0; + 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 */ - vcoordv = 0; + bi.vcoordv = 0; /* top edge coordinate of output window, must be inside desktop */ /* clipping on the top side */ if (ow->v_start < crtc_vstart) @@ -169,27 +139,27 @@ status_t mn_configure_bes if (ow->v_start >= (crtc_vend - 1)) { /* height < 2 is not allowed */ - temp1 = (crtc_vend - crtc_vstart - 2) & 0x7ff; + temp1 = (crtc_vend - crtc_vstart - 2); } else /* no clipping here */ { - temp1 = (ow->v_start - crtc_vstart) & 0x7ff; + temp1 = (ow->v_start - crtc_vstart); } } - vcoordv |= temp1 << 16; + 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) & 0x7ff; + 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) & 0x7ff; + temp2 = (crtc_vend - crtc_vstart - 1); } else { @@ -202,11 +172,11 @@ status_t mn_configure_bes else /* no clipping here */ { - temp2 = ((uint16)(ow->v_start + ow->height - crtc_vstart - 1)) & 0x7ff; + temp2 = ((uint16)(ow->v_start + ow->height - crtc_vstart - 1)); } } } - vcoordv |= temp2 << 0; + bi.vcoordv |= temp2 << 0; LOG(4,("Overlay: CRTC top-edge output %d, bottom-edge output %d\n",temp1, temp2)); @@ -218,63 +188,28 @@ status_t mn_configure_bes (ob->width - si->overlay.myBufInfo[offset].slopspace), ob->height)); LOG(6,("Overlay: output picture width = %d, height = %d\n", ow->width, ow->height)); - /* do horizontal scaling... */ - /* determine interval representation value, taking zoom into account */ - if (ow->flags & B_OVERLAY_HORIZONTAL_FILTERING) - { - /* horizontal filtering is ON */ - if ((my_ov.width == ow->width) | (ow->width < 2)) - { - /* no horizontal scaling used, OR destination width < 2 */ - intrep = 0; - } - else - { - intrep = 1; - } - } - else - { - /* horizontal filtering is OFF */ - if ((ow->width < my_ov.width) & (ow->width >= 2)) - { - /* horizontal downscaling used AND destination width >= 2 */ - intrep = 1; - } - else - { - intrep = 0; - } - } - LOG(4,("Overlay: horizontal interval representation value is %d\n",intrep)); - /* calculate inverse horizontal scaling factor, taking zoom into account */ - /* standard scaling formula: */ - ifactor = (((uint32)(my_ov.width - intrep)) << 16) / (ow->width - intrep); + ifactor = ((((uint32)my_ov.width) << 12) / ow->width); /* correct factor to prevent most-right visible 'line' from distorting */ - ifactor -= (1 << 2); - LOG(4,("Overlay: horizontal scaling factor is %f\n", (float)65536 / ifactor)); - - /* compensate for accelerated 2x zoom (slowdown BES if pixelclock is too high) */ - hiscalv = ifactor * acczoom; - LOG(4,("Overlay: horizontal speed compensated factor is %f\n", (float)65536 / hiscalv)); + ifactor -= 1; + bi.hiscalv = 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 */ - if (((((uint32)my_ov.width) << 16) / 16384) > hiscalv) + if (((((uint32)my_ov.width) << 12) / 1024) > bi.hiscalv) { /* (non-inverse) factor too large, set factor to max. valid value */ - hiscalv = ((((uint32)my_ov.width) << 16) / 16384); - LOG(4,("Overlay: horizontal scaling factor too large, clamping at %f\n", (float)65536 / hiscalv)); + bi.hiscalv = ((((uint32)my_ov.width) << 12) / 1024); + LOG(4,("Overlay: horizontal scaling factor too large, clamping at %f\n", (float)4096 / bi.hiscalv)); } - if (hiscalv >= (32 << 16)) + /* horizontal downscaling cannot be done by NM BES hardware */ + if (bi.hiscalv > (1 << 12)) { /* (non-inverse) factor too small, set factor to min. valid value */ - hiscalv = 0x1ffffc; - LOG(4,("Overlay: horizontal scaling factor too small, clamping at %f\n", (float)65536 / hiscalv)); + bi.hiscalv = 0x1000; + LOG(4,("Overlay: horizontal scaling factor too small, clamping at %f\n", (float)4096 / bi.hiscalv)); } - /* AND below is required by hardware */ - hiscalv &= 0x001ffffc; /* do horizontal clipping... */ @@ -286,7 +221,7 @@ status_t mn_configure_bes * 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.! */ - hsrcstv = 0; + bi.hsrcstv = 0; /* check for destination horizontal clipping at left side */ if (ow->h_start < crtc_hstart) { @@ -295,24 +230,24 @@ status_t mn_configure_bes if ((ow->h_start + ow->width - 1) < (crtc_hstart + 1)) { /* increase 'first contributing pixel' with 'fixed value': (total dest. width - 2) */ - hsrcstv += (ow->width - 2); + bi.hsrcstv += (ow->width - 2); } else { /* increase 'first contributing pixel' with actual number of dest. clipping pixels */ - hsrcstv += (crtc_hstart - ow->h_start); + 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! */ - hsrcstv *= ifactor; + bi.hsrcstv *= (ifactor << 4); } /* take zoom into account */ - hsrcstv += ((uint32)my_ov.h_start) << 16; + bi.hsrcstv += ((uint32)my_ov.h_start) << 16; /* AND below required by hardware */ - hsrcstv &= 0x03fffffc; - LOG(4,("Overlay: first hor. (sub)pixel of input bitmap contributing %f\n", hsrcstv / (float)65536)); + bi.hsrcstv &= 0x03fffffc; + 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 */ @@ -323,7 +258,7 @@ status_t mn_configure_bes /* Note also: * Even if the scaling factor is clamping we instruct the BES to use the correct source end pos.! */ - hsrcendv = 0; + bi.hsrcendv = 0; /* check for destination horizontal clipping at right side */ if ((ow->h_start + ow->width - 1) > (crtc_hend - 1)) { @@ -332,98 +267,66 @@ status_t mn_configure_bes if (ow->h_start > (crtc_hend - 2)) { /* increase 'number of clipping pixels' with 'fixed value': (total dest. width - 2) */ - hsrcendv += (ow->width - 2); + bi.hsrcendv += (ow->width - 2); } else { /* increase 'number of clipping pixels' with actual number of dest. clipping pixels */ - hsrcendv += ((ow->h_start + ow->width - 1) - (crtc_hend - 1)); + 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! */ - hsrcendv *= ifactor; + bi.hsrcendv *= (ifactor << 4); /* now subtract this value from the last used pixel in (zoomed) inputbuffer, aligned to BES */ - hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16) - hsrcendv; + 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 */ - hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16); + bi.hsrcendv = (((uint32)((my_ov.h_start + my_ov.width) - 1)) << 16); } /* AND below required by hardware */ - hsrcendv &= 0x03fffffc; - LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", hsrcendv / (float)65536)); + bi.hsrcendv &= 0x03fffffc; + LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", bi.hsrcendv / (float)65536)); /* setup horizontal source last position excluding slopspace: * this is the last pixel that will be used for calculating interpolated pixels */ - hsrclstv = ((ob->width - 1) - si->overlay.myBufInfo[offset].slopspace) << 16; + bi.hsrclstv = ((ob->width - 1) - si->overlay.myBufInfo[offset].slopspace) << 16; /* AND below required by hardware */ - hsrclstv &= 0x03ff0000; + bi.hsrclstv &= 0x03ff0000; /******************************************* *** setup vertical scaling and clipping *** *******************************************/ - /* do vertical scaling... */ - /* determine interval representation value, taking zoom into account */ - if (ow->flags & B_OVERLAY_VERTICAL_FILTERING) - { - /* vertical filtering is ON */ - if ((my_ov.height == ow->height) | (ow->height < 2)) - { - /* no vertical scaling used, OR destination height < 2 */ - intrep = 0; - } - else - { - intrep = 1; - } - } - else - { - /* vertical filtering is OFF */ - if ((ow->height < my_ov.height) & (ow->height >= 2)) - { - /* vertical downscaling used AND destination height >= 2 */ - intrep = 1; - } - else - { - intrep = 0; - } - } - LOG(4,("Overlay: vertical interval representation value is %d\n",intrep)); - /* calculate inverse vertical scaling factor, taking zoom into account */ - /* standard scaling formula: */ - ifactor = (((uint32)(my_ov.height - intrep)) << 16) / (ow->height - intrep); + ifactor = ((((uint32)my_ov.height) << 12) / ow->height); /* correct factor to prevent lowest visible line from distorting */ - ifactor -= (1 << 2); - LOG(4,("Overlay: vertical scaling factor is %f\n", (float)65536 / ifactor)); + ifactor -= 1; + LOG(4,("Overlay: vertical scaling factor is %f\n", (float)4096 / ifactor)); /* preserve ifactor for source positioning calculations later on */ - viscalv = ifactor; + bi.viscalv = ifactor; /* check scaling factor (and modify if needed) to be within scaling limits */ - if (((((uint32)my_ov.height) << 16) / 16384) > viscalv) + if (((((uint32)my_ov.height) << 12) / 1024) > bi.viscalv) { /* (non-inverse) factor too large, set factor to max. valid value */ - viscalv = ((((uint32)my_ov.height) << 16) / 16384); - LOG(4,("Overlay: vertical scaling factor too large, clamping at %f\n", (float)65536 / viscalv)); + bi.viscalv = ((((uint32)my_ov.height) << 12) / 1024); + LOG(4,("Overlay: vertical scaling factor too large, clamping at %f\n", (float)4096 / bi.viscalv)); } - if (viscalv >= (32 << 16)) + /* vertical downscaling cannot be done by NM BES hardware */ + if (bi.viscalv > (1 << 12)) { /* (non-inverse) factor too small, set factor to min. valid value */ - viscalv = 0x1ffffc; - LOG(4,("Overlay: vertical scaling factor too small, clamping at %f\n", (float)65536 / viscalv)); + bi.viscalv = 0x1000; + LOG(4,("Overlay: vertical scaling factor too small, clamping at %f\n", (float)4096 / bi.viscalv)); } - /* AND below is required by hardware */ - viscalv &= 0x001ffffc; /* do vertical clipping... */ @@ -440,11 +343,11 @@ status_t mn_configure_bes * 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' */ - weight = 0; - a1orgv = (uint32)((vuint32 *)ob->buffer); - a1orgv -= (uint32)((vuint32 *)si->framebuffer); + 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",a1orgv)); + 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) { @@ -455,48 +358,38 @@ status_t mn_configure_bes /* 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 */ - a1orgv += ((((ow->height - 2) * ifactor) >> 16) * ob->bytes_per_row); - weight = (ow->height - 2) * ifactor; + 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 */ - a1orgv += ((((crtc_vstart - ow->v_start) * ifactor) >> 16) * ob->bytes_per_row); - weight = (crtc_vstart - ow->v_start) * ifactor; + 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 */ - a1orgv += (my_ov.v_start * ob->bytes_per_row); - weight += (((uint32)my_ov.v_start) << 16); - LOG(4,("Overlay: 'contributing part of buffer' origin is (cardRAM offset) $%08x\n",a1orgv)); - LOG(4,("Overlay: first vert. (sub)pixel of input bitmap contributing %f\n", weight / (float)65536)); + bi.a1orgv += (my_ov.v_start * ob->bytes_per_row); + bi.weight += (((uint32)my_ov.v_start) << 16); + 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)); - /* Note: - * Because all > G200 overlay units will ignore b0-3 of the calculated adress, - * we do not use the above way for horizontal source positioning. - * (G200 cards ignore b0-2.) - * If we did, 8 source-image pixel jumps (in 4:2:2 colorspace) will occur if the picture - * is shifted horizontally during left clipping on all > G200 cards, while G200 cards - * will have 4 source-image pixel jumps occuring. */ - - /* AND below is required by G200-G550 hardware. > G200 cards can have max. 32Mb RAM on board - * (16Mb on G200 cards). Compatible setting used (between G200 and the rest), this has no - * downside consequences here. */ + /* AND below is required by NM hardware. */ /* Buffer A topleft corner of field 1 (origin)(field 1 contains our full frames) */ - a1orgv &= 0x01fffff0; + bi.a1orgv &= 0x00fffff0; /* field 1 weight: AND below required by hardware, also make sure 'sign' is always 'positive' */ - v1wghtv = weight & 0x0000fffc; + bi.v1wghtv = bi.weight & 0x0000fffc; /* setup field 1 (is our complete frame) vertical source last position. * this is the last pixel that will be used for calculating interpolated pixels */ - v1srclstv = (ob->height - 1); + bi.v1srclstv = (ob->height - 1); /* AND below required by hardware */ - v1srclstv &= 0x000003ff; + bi.v1srclstv &= 0x000003ff; /***************************** @@ -514,103 +407,26 @@ status_t mn_configure_bes *************************/ /* BES global control: setup functions */ - globctlv = 0; + bi.globctlv = 0; - /* slowdown BES if nessesary */ - if (acczoom == 1) - { - /* run at full speed and resolution */ - globctlv |= 0 << 0; - /* disable filtering for half speed interpolation */ - globctlv |= 0 << 1; - } - else - { - /* run at half speed and resolution */ - globctlv |= 1 << 0; - /* enable filtering for half speed interpolation */ - globctlv |= 1 << 1; - } - - /* 4:2:0 specific setup: not needed here */ - globctlv |= 0 << 3; - /* BES testregister: keep zero */ - globctlv |= 0 << 4; - /* the following bits marked (> G200) *must* be zero on G200: */ - /* 4:2:0 specific setup: not needed here (> G200) */ - globctlv |= 0 << 5; - /* select yuy2 byte-order to B_YCbCr422 (> G200) */ - globctlv |= 0 << 6; - /* BES internal contrast and brighness controls are not used, disabled (> G200) */ - globctlv |= 0 << 7; - /* RGB specific setup: not needed here, so disabled (> G200) */ - globctlv |= 0 << 8; - globctlv |= 0 << 9; - /* 4:2:0 specific setup: not needed here (> G200) */ - globctlv |= 0 << 10; - /* Tell BES when to copy the new register values to the actual active registers. - * bits 16-27 (12 bits) are the CRTC vert. count value at which copying takes - * place. - * (This is the double buffering feature: programming must be completed *before* - * the CRTC vert count value set here!) */ - /* CRTC vert count for copying = $000, so during retrace, line 0. */ - globctlv |= 0x000 << 16; - - /* BES control: enable scaler and setup functions */ - /* pre-reset all bits */ - ctlv = 0; /* enable BES */ - ctlv |= 1 << 0; - /* we start displaying at an even startline (zero) in 'field 1' (no hardware de-interlacing is used) */ - ctlv |= 0 << 6; - /* we don't use field 2, so its startline is not important */ - ctlv |= 0 << 7; + bi.globctlv |= 1 << 0; + /* enable colorkeying */ + bi.globctlv |= 1 << 1; + /* b3 = 1: distorts right-half of overlay output. Keeping it zero. */ + /* colorspace is YV12, I420 or YUY2 (no RV15 or RV16) */ + bi.globctlv |= 0 << 5; - LOG(6,("Overlay: ow->flags is $%08x\n",ow->flags)); - /* enable horizontal filtering on scaling if asked for: if we *are* actually scaling */ - if ((ow->flags & B_OVERLAY_HORIZONTAL_FILTERING) && (hiscalv != (0x01 << 16))) - { - ctlv |= 1 << 10; - LOG(6,("Overlay: using horizontal interpolation on scaling\n")); - } - else - { - ctlv |= 0 << 10; - LOG(6,("Overlay: using horizontal dropping or replication on scaling\n")); - } - /* enable vertical filtering on scaling if asked for: if we are *upscaling* only */ - if ((ow->flags & B_OVERLAY_VERTICAL_FILTERING) && (viscalv < (0x01 << 16))) - { - ctlv |= 1 << 11; - LOG(6,("Overlay: using vertical interpolation on scaling\n")); - } - else - { - ctlv |= 0 << 11; - LOG(6,("Overlay: using vertical dropping or replication on scaling\n")); - } + /* enable auto-alternating hardware buffers if alternating buffers is enabled (NM2160) */ + bi.globctlv |= 1 << 8; + /* ??? */ + bi.globctlv |= 1 << 13; + /* display one buffer (no alternating buffers) (NM2160: no effect) */ + bi.globctlv |= 0 << 14; + /* display frame (no field) (NM2160: no effect) */ + bi.globctlv |= 0 << 15; - /* use actual calculated weight for horizontal interpolation */ - ctlv |= 0 << 12; - /* use horizontal chroma interpolation upsampling on BES input picture */ - ctlv |= 1 << 16; - /* select 4:2:2 BES input format */ - ctlv |= 0 << 17; - /* dithering is enabled */ - ctlv |= 1 << 18; - /* horizontal mirroring is not used */ - ctlv |= 0 << 19; - /* BES output should be in color */ - ctlv |= 0 << 20; - /* BES output blanking is disabled: we want a picture, no 'black box'! */ - ctlv |= 0 << 21; - /* we do software field select (field select is not used) */ - ctlv |= 0 << 24; - /* we always display field 1 in buffer A, this contains our full frames */ - /* select field 1 */ - ctlv |= 0 << 25; - /* select buffer A */ - ctlv |= 0 << 26; + /* BTW: horizontal and vertical filtering are always turned on in NM hardware. */ /************************************* @@ -620,6 +436,8 @@ status_t mn_configure_bes /* Make sure reprogramming the BES completes before the next retrace occurs, * to prevent register-update glitches (double buffer feature). */ + //fixme... + // 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 @@ -632,51 +450,132 @@ status_t mn_configure_bes /************************************** *** actually program the registers *** **************************************/ + + if (si->ps.card_type >= NM2097) + { + /* PCI card */ + LOG(4,("Overlay: accelerant is programming BES\n")); + /* unlock card overlay sequencer registers */ + PCIGRPHW(GENLOCK, 0x20); + /* destination rectangle */ + PCIGRPHW(HDCOORD1L, ((bi.hcoordv >> 16) & 0xff)); + PCIGRPHW(HDCOORD2L, (bi.hcoordv & 0xff)); + PCIGRPHW(HDCOORD21H, (((bi.hcoordv >> 4) & 0xf0) | ((bi.hcoordv >> 24) & 0x0f))); + PCIGRPHW(VDCOORD1L, ((bi.vcoordv >> 16) & 0xff)); + PCIGRPHW(VDCOORD2L, (bi.vcoordv & 0xff)); + PCIGRPHW(VDCOORD21H, (((bi.vcoordv >> 4) & 0xf0) | ((bi.vcoordv >> 24) & 0x0f))); + /* scaling */ + PCIGRPHW(XSCALEL, (bi.hiscalv & 0xff)); + PCIGRPHW(XSCALEH, ((bi.hiscalv >> 8) & 0xff)); + PCIGRPHW(YSCALEL, (bi.viscalv & 0xff)); + PCIGRPHW(YSCALEH, ((bi.viscalv >> 8) & 0xff)); + /* inputbuffer #1 origin */ + /* (we don't program buffer #2 as it's unused.) */ + /* first 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; + /* now setup buffer startadress and horizontal source end (minimizes used bandwidth) */ + if (si->ps.card_type < NM2200) + { + bi.a1orgv >>= 1; + /* horizontal source end does not use subpixelprecision: granularity is 8 pixels */ + PCIGRPHW(0xbc, (((((bi.hsrcendv >> 16) + 7) & ~8) / 8) - 1)); + } + else + { + /* horizontal source end does not use subpixelprecision: granularity is 16 pixels */ + //fixme? divide by 16 instead of 8 (if >= NM2200 owners report trouble then use 8!) + //fixme? check if overlaybuffer width should also have granularity of 16 now! + PCIGRPHW(0xbc, (((((bi.hsrcendv >> 16) + 15) & ~16) / 16) - 1)); + } + PCIGRPHW(BUF1ORGL, (bi.a1orgv & 0xff)); + PCIGRPHW(BUF1ORGM, ((bi.a1orgv >> 8) & 0xff)); + PCIGRPHW(BUF1ORGH, ((bi.a1orgv >> 16) & 0xff)); + /* b2 = 0: don't use horizontal mirroring (NM2160) */ + /* other bits do ??? */ + PCIGRPHW(0xbf, 0x02); + /* ??? */ + PCIGRPHW(0xbd, 0x02); + PCIGRPHW(0xbe, 0x00); + /* (subpixel precise) source rect clipping is not supported on NeoMagic cards; + * so we do 'pixel precise' left clipping via modification of buffer + * startadress above instead. + * (pixel precise top clipping is also done this way..) */ + //fixme: checkout real pixel precise clipping on NM2200 and later cards!!! /* - BESW(HCOORD, hcoordv); - BESW(VCOORD, vcoordv); - BESW(HISCAL, hiscalv); - BESW(HSRCST, hsrcstv); - BESW(HSRCEND, hsrcendv); - BESW(HSRCLST, hsrclstv); - BESW(VISCAL, viscalv); - BESW(A1ORG, a1orgv); - BESW(V1WGHT, v1wghtv); - BESW(V1SRCLST, v1srclstv); - BESW(GLOBCTL, globctlv); - BESW(CTL, ctlv); + { + uint16 left = 0; + uint16 right = 128; + uint16 top = 0; + uint16 bottom = 128; + + left = (bi.hsrcstv >> 16); + right = (bi.hsrclstv >> 16); + top = (bi.weight >> 16); + bottom = (bi.v1srclstv >> 16); + + PCISEQW(HSCOORD1L, (left & 0xff)); + PCISEQW(HSCOORD2L, (right & 0xff)); + PCISEQW(HSCOORD21H, (((right >> 4) & 0xf0) | ((left >> 8) & 0x0f))); + PCISEQW(VSCOORD1L, (top & 0xff)); + PCISEQW(VSCOORD2L, (bottom & 0xff)); + PCISEQW(VSCOORD21H, (((bottom >> 4) & 0xf0) | ((top >> 8) & 0x0f))); + } */ - - /************************** - *** setup color keying *** - **************************/ - - /* setup colorkeying */ -/* DXIW(COLKEY, (ow->alpha.value & ow->alpha.mask)); - - DXIW(COLKEY0RED, (ow->red.value & ow->red.mask)); - DXIW(COLKEY0GREEN, (ow->green.value & ow->green.mask)); - DXIW(COLKEY0BLUE, (ow->blue.value & ow->blue.mask)); - - DXIW(COLMSK, ow->alpha.mask); - - DXIW(COLMSK0RED, ow->red.mask); - DXIW(COLMSK0GREEN, ow->green.mask); - DXIW(COLMSK0BLUE, ow->blue.mask); -*/ - /* enable colorkeying */ -// DXIW(KEYOPMODE,0x01); + /* ??? */ + PCISEQW(0x1c, 0xfb); + PCISEQW(0x1d, 0x00); + PCISEQW(0x1e, 0xe2); + PCISEQW(0x1f, 0x02); + /* b1 = 0: disable alternating hardware buffers (NM2160) */ + /* other bits do ??? */ + PCISEQW(0x09, 0x11); + /* ??? */ + PCISEQW(0x0a, 0x00); + /* global BES control */ + PCIGRPHW(BESCTRL1, (bi.globctlv & 0xff)); + PCISEQW(BESCTRL2, ((bi.globctlv >> 8) & 0xff)); - /************************* - *** setup misc. stuff *** - *************************/ + /************************** + *** setup color keying *** + **************************/ - /* setup brightness and contrast to be 'neutral' (this is not implemented on G200) */ -// BESW(LUMACTL, 0x00000080); + PCIGRPHW(COLKEY_R, (ow->red.value & ow->red.mask)); + PCIGRPHW(COLKEY_G, (ow->green.value & ow->green.mask)); + PCIGRPHW(COLKEY_B, (ow->blue.value & ow->blue.mask)); - /* setup source pitch including slopspace (in pixels); AND is required by hardware */ -// BESW(PITCH, (ob->width & 0x00000fff)); + + /************************* + *** setup misc. stuff *** + *************************/ + + /* setup brightness to be 'neutral' (two's complement number) */ + PCIGRPHW(BRIGHTNESS, 0x00); + + /* setup inputbuffer #1 pitch including slopspace (in pixels) */ + /* (we don't program the pitch for inputbuffer #2 as it's unused.) */ + PCIGRPHW(BUF1PITCHL, (ob->width & 0xff)); + PCIGRPHW(BUF1PITCHH, ((ob->width >> 8) & 0xff)); + } + else + { + /* ISA card. Speed required, so: + * program entire sequence in kerneldriver in one context switch! */ + LOG(4,("Overlay: kerneldriver programs BES\n")); + + /* complete BES info struct... */ + bi.card_type = si->ps.card_type; + bi.colkey_r = (ow->red.value & ow->red.mask); + bi.colkey_g = (ow->green.value & ow->green.mask); + bi.colkey_b = (ow->blue.value & ow->blue.mask); + bi.ob_width = ob->width; + /* ... and call kerneldriver to program the BES */ + bi.magic = MN_PRIVATE_DATA_MAGIC; + ioctl(fd, MN_PGM_BES, &bi, sizeof(bi)); + } /* on a 500Mhz P3 CPU just logging a line costs 400uS (18-19 vcounts at 1024x768x60Hz)! * programming the registers above actually costs 180uS here */ @@ -688,7 +587,18 @@ status_t mn_configure_bes status_t mn_release_bes() { /* setup BES control: disable scaler */ -// BESW(CTL, 0x00000000); + if (si->ps.card_type >= NM2097) + { + /* PCI card */ + PCIGRPHW(BESCTRL1, 0x02); + PCISEQW(BESCTRL2, 0xa0); + } + else + { + /* ISA card */ + ISAGRPHW(BESCTRL1, 0x02); + ISASEQW(BESCTRL2, 0xa0); + } return B_OK; } diff --git a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c index c469c2e0ce..806682313e 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c @@ -650,7 +650,7 @@ status_t mn_crtc_cursor_define(uint8* andMask,uint8* xorMask) } //test.. only valid for ps.card_type = NM2070; LOG(4,("POWERUP: Detected MagicGraph 128 (NM2070)\n")); break; - case 0x000210c8: //NM2090 + case 0x000210c8: //NM2090 ISA si->ps.card_type = NM2090; LOG(4,("POWERUP: Detected MagicGraph 128V (NM2090)\n")); break; - case 0x000310c8: //NM2093 + case 0x000310c8: //NM2093 ISA si->ps.card_type = NM2093; LOG(4,("POWERUP: Detected MagicGraph 128ZV (NM2093)\n")); break; @@ -167,10 +167,10 @@ status_t nm_general_powerup() ISAWB(MISCW, temp); /* unlock cards GRAPHICS registers (any other value than 0x26 should lock it again) */ - ISAGRPHW(GRPHXLOCK,0x26); + ISAGRPHW(GRPHXLOCK, 0x26); - /* unlock shadow registers */ -// ISAGRPHW(GENLOCK,0x00);//0x01?? + /* unlock cards CRTC registers */ + ISAGRPHW(GENLOCK, 0x00); /* initialize the shared_info struct */ set_specs(); diff --git a/src/add-ons/accelerants/neomagic/global.h b/src/add-ons/accelerants/neomagic/global.h index 1220ce7797..c431d95d04 100644 --- a/src/add-ons/accelerants/neomagic/global.h +++ b/src/add-ons/accelerants/neomagic/global.h @@ -9,3 +9,4 @@ extern int accelerantIsClone; extern mn_get_set_pci mn_pci_access; extern mn_in_out_isa mn_isa_access; +extern mn_bes_data mn_bes_access; diff --git a/src/add-ons/kernel/drivers/graphics/neomagic/driver.c b/src/add-ons/kernel/drivers/graphics/neomagic/driver.c index 99a7fd5826..2e34dd4d5a 100644 --- a/src/add-ons/kernel/drivers/graphics/neomagic/driver.c +++ b/src/add-ons/kernel/drivers/graphics/neomagic/driver.c @@ -33,6 +33,8 @@ #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) #define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) +#define KISAGRPHW(A,B)(isa_bus->write_io_16(NMISA16_GRPHIND, ((NMGRPHX_##A) | ((B) << 8)))) +#define KISASEQW(A,B)(isa_bus->write_io_16(NMISA16_SEQIND, ((NMSEQX_##A) | ((B) << 8)))) #define MAX_DEVICES 8 @@ -77,6 +79,7 @@ static status_t map_device(device_info *di); static void unmap_device(device_info *di); static void probe_devices(void); static int32 mn_interrupt(void *data); +void drv_program_bes_ISA(mn_bes_data *bes); static DeviceData *pd; static pci_module_info *pci_bus; @@ -884,6 +887,122 @@ control_hook (void* dev, uint32 msg, void *buf, size_t len) { result = B_OK; } } break; + case MN_PGM_BES: { + mn_bes_data *bes_isa = (mn_bes_data *)buf; + if (bes_isa->magic == MN_PRIVATE_DATA_MAGIC) { + drv_program_bes_ISA(bes_isa); + result = B_OK; + } + } break; } return result; } + +void drv_program_bes_ISA(mn_bes_data *bes) +{ + /* ISA card */ + /* unlock card overlay sequencer registers */ + KISAGRPHW(GENLOCK, 0x20); + /* destination rectangle */ + KISAGRPHW(HDCOORD1L, ((bes->hcoordv >> 16) & 0xff)); + KISAGRPHW(HDCOORD2L, (bes->hcoordv & 0xff)); + KISAGRPHW(HDCOORD21H, (((bes->hcoordv >> 4) & 0xf0) | ((bes->hcoordv >> 24) & 0x0f))); + KISAGRPHW(VDCOORD1L, ((bes->vcoordv >> 16) & 0xff)); + KISAGRPHW(VDCOORD2L, (bes->vcoordv & 0xff)); + KISAGRPHW(VDCOORD21H, (((bes->vcoordv >> 4) & 0xf0) | ((bes->vcoordv >> 24) & 0x0f))); + /* scaling */ + KISAGRPHW(XSCALEL, (bes->hiscalv & 0xff)); + KISAGRPHW(XSCALEH, ((bes->hiscalv >> 8) & 0xff)); + KISAGRPHW(YSCALEL, (bes->viscalv & 0xff)); + KISAGRPHW(YSCALEH, ((bes->viscalv >> 8) & 0xff)); + /* inputbuffer #1 origin */ + /* (we don't program buffer #2 as it's unused.) */ + /* first include 'pixel precise' left clipping... + * (subpixel precision is not supported by NeoMagic cards) */ + bes->a1orgv += ((bes->hsrcstv >> 16) * 2); + /* we need to step in 4-byte (2 pixel) granularity due to the nature of yuy2 */ + bes->a1orgv &= ~0x03; + /* now setup buffer startadress and horizontal source end (minimizes used bandwidth) */ + if (bes->card_type < NM2200) + { + bes->a1orgv >>= 1; + /* horizontal source end does not use subpixelprecision: granularity is 8 pixels */ + KISAGRPHW(0xbc, (((((bes->hsrcendv >> 16) + 7) & ~8) / 8) - 1)); + } + else + { + /* horizontal source end does not use subpixelprecision: granularity is 16 pixels */ + //fixme? divide by 16 instead of 8 (if >= NM2200 owners report trouble then use 8!) + //fixme? check if overlaybuffer width should also have granularity of 16 now! + KISAGRPHW(0xbc, (((((bes->hsrcendv >> 16) + 15) & ~16) / 16) - 1)); + } + KISAGRPHW(BUF1ORGL, (bes->a1orgv & 0xff)); + KISAGRPHW(BUF1ORGM, ((bes->a1orgv >> 8) & 0xff)); + KISAGRPHW(BUF1ORGH, ((bes->a1orgv >> 16) & 0xff)); + /* b2 = 0: don't use horizontal mirroring (NM2160) */ + /* other bits do ??? */ + KISAGRPHW(0xbf, 0x02); + /* ??? */ + KISAGRPHW(0xbd, 0x02); + KISAGRPHW(0xbe, 0x00); + /* (subpixel precise) source rect clipping is not supported on NeoMagic cards; + * so we do 'pixel precise' left clipping via modification of buffer + * startadress above instead. + * (pixel precise top clipping is also done this way..) */ + //fixme: checkout real pixel precise clipping on NM2200 and later cards!!! +/* + { + uint16 left = 0; + uint16 right = 128; + uint16 top = 0; + uint16 bottom = 128; + + left = (bes->hsrcstv >> 16); + right = (bes->hsrclstv >> 16); + top = (bes->weight >> 16); + bottom = (bes->v1srclstv >> 16); + + KISASEQW(HSCOORD1L, (left & 0xff)); + KISASEQW(HSCOORD2L, (right & 0xff)); + KISASEQW(HSCOORD21H, (((right >> 4) & 0xf0) | ((left >> 8) & 0x0f))); + KISASEQW(VSCOORD1L, (top & 0xff)); + KISASEQW(VSCOORD2L, (bottom & 0xff)); + KISASEQW(VSCOORD21H, (((bottom >> 4) & 0xf0) | ((top >> 8) & 0x0f))); + } +*/ + /* ??? */ + KISASEQW(0x1c, 0xfb); + KISASEQW(0x1d, 0x00); + KISASEQW(0x1e, 0xe2); + KISASEQW(0x1f, 0x02); + /* b1 = 0: disable alternating hardware buffers (NM2160) */ + /* other bits do ??? */ + KISASEQW(0x09, 0x11); + /* ??? */ + KISASEQW(0x0a, 0x00); + /* global BES control */ + KISAGRPHW(BESCTRL1, (bes->globctlv & 0xff)); + KISASEQW(BESCTRL2, ((bes->globctlv >> 8) & 0xff)); + + + /************************** + *** setup color keying *** + **************************/ + + KISAGRPHW(COLKEY_R, bes->colkey_r); + KISAGRPHW(COLKEY_G, bes->colkey_g); + KISAGRPHW(COLKEY_B, bes->colkey_b); + + + /************************* + *** setup misc. stuff *** + *************************/ + + /* setup brightness to be 'neutral' (two's complement number) */ + KISAGRPHW(BRIGHTNESS, 0x00); + + /* setup inputbuffer #1 pitch including slopspace (in pixels) */ + /* (we don't program the pitch for inputbuffer #2 as it's unused.) */ + KISAGRPHW(BUF1PITCHL, (bes->ob_width & 0xff)); + KISAGRPHW(BUF1PITCHH, ((bes->ob_width >> 8) & 0xff)); +} diff --git a/src/add-ons/kernel/drivers/graphics/neomagic/nm.settings b/src/add-ons/kernel/drivers/graphics/neomagic/nm.settings index f8e75aeeb0..9c9f0334f0 100644 --- a/src/add-ons/kernel/drivers/graphics/neomagic/nm.settings +++ b/src/add-ons/kernel/drivers/graphics/neomagic/nm.settings @@ -8,7 +8,7 @@ # accelerant "nm.accelerant" # nm.accelerant parameters -usebios false # not used currently +usebios false # if true rely on bios to coldstart the card instead of driver #memory 2048 # in Kb, override builtin memory size detection hardcursor true # if true use on-chip cursor capabilities #logmask 0x00000000 # nothing logged, except errors, is default @@ -16,6 +16,6 @@ hardcursor true # if true use on-chip cursor capabilities #logmask 0x80000000 # log following mask #logmask 0x08000604 # log overlay use in full #logmask 0xffffffff # log everything -dumprom false # dump bios rom in ~/nm.rom: not yet working +dumprom false # dump bios rom in ~/nm.rom #--------- that's all. \ No newline at end of file