diff --git a/headers/private/graphics/nvidia/nv_macros.h b/headers/private/graphics/nvidia/nv_macros.h index 1ef52b8e26..387bcf1f32 100644 --- a/headers/private/graphics/nvidia/nv_macros.h +++ b/headers/private/graphics/nvidia/nv_macros.h @@ -96,9 +96,13 @@ regBase+0x00680000, 0x00003000); pNv->riva.PCRTC0 = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag, regBase+0x00600000, 0x00003000); + +Set interrupt enable. +chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01; */ /* Nvidia PCI direct registers */ +#define NV32_PWRUPCTRL 0x00000200 #define NV8_MISCW 0x000c03c2 #define NV8_MISCR 0x000c03cc #define NV8_SEQIND 0x000c03c4 @@ -220,65 +224,43 @@ #define NVGRPHX_MODE 0x05 #define NVGRPHX_MISC 0x06 #define NVGRPHX_BITMASK 0x08 + +/* Nvidia BES (Back End Scaler) registers (>= NV10) */ +#define NVBES_NV10_BUFSEL 0x00008700 +#define NVBES_NV10_GENCTRL 0x00008704 +#define NVBES_NV10_COLKEY 0x00008b00 +/* buffer 0 */ +#define NVBES_NV10_0BUFADR 0x00008900 +#define NVBES_NV10_0MEMMASK 0x00008908 +#define NVBES_NV10_0BRICON 0x00008910 +#define NVBES_NV10_0SAT 0x00008918 +#define NVBES_NV10_0WHAT 0x00008920 +#define NVBES_NV10_0SRCSIZE 0x00008928 +#define NVBES_NV10_0SRCREF 0x00008930 +#define NVBES_NV10_0ISCALH 0x00008938 +#define NVBES_NV10_0ISCALV 0x00008940 +#define NVBES_NV10_0DSTREF 0x00008948 +#define NVBES_NV10_0DSTSIZE 0x00008950 +#define NVBES_NV10_0SRCPTCH 0x00008958 +/* buffer 1 */ +#define NVBES_NV10_1BUFADR 0x00008904 +#define NVBES_NV10_1MEMMASK 0x0000890c +#define NVBES_NV10_1BRICON 0x00008914 +#define NVBES_NV10_1SAT 0x0000891c +#define NVBES_NV10_1WHAT 0x00008924 +#define NVBES_NV10_1SRCSIZE 0x0000892c +#define NVBES_NV10_1SRCREF 0x00008934 +#define NVBES_NV10_1ISCALH 0x0000893c +#define NVBES_NV10_1ISCALV 0x00008944 +#define NVBES_NV10_1DSTREF 0x0000894c +#define NVBES_NV10_1DSTSIZE 0x00008954 +#define NVBES_NV10_1SRCPTCH 0x0000895c +/* + chip->PMC[0x00008140/4] = 0; + chip->PMC[0x00001588/4] = 0; +*/ //end new. -/* (D)AC (X) (I)ndexed registers (>= G100) */ -#define NVDXI_VREFCTRL 0x18 -#define NVDXI_MULCTRL 0x19 -#define NVDXI_PIXCLKCTRL 0x1A -#define NVDXI_GENCTRL 0x1D -#define NVDXI_MISCCTRL 0x1E -#define NVDXI_PANELMODE 0x1F -#define NVDXI_MAFCDEL 0x20 -#define NVDXI_GENIOCTRL 0x2A -#define NVDXI_GENIODATA 0x2B -#define NVDXI_SYSPLLM 0x2C -#define NVDXI_SYSPLLN 0x2D -#define NVDXI_SYSPLLP 0x2E -#define NVDXI_SYSPLLSTAT 0x2F -#define NVDXI_ZOOMCTRL 0x38 -#define NVDXI_SENSETEST 0x3A -#define NVDXI_CRCREML 0x3C -#define NVDXI_CRCREMH 0x3D -#define NVDXI_CRCBITSEL 0x3E -#define NVDXI_COLMSK 0x40 -#define NVDXI_COLKEY 0x42 -#define NVDXI_PIXPLLAM 0x44 -#define NVDXI_PIXPLLAN 0x45 -#define NVDXI_PIXPLLAP 0x46 -#define NVDXI_PIXPLLBM 0x48 -#define NVDXI_PIXPLLBN 0x49 -#define NVDXI_PIXPLLBP 0x4A -#define NVDXI_PIXPLLCM 0x4C -#define NVDXI_PIXPLLCN 0x4D -#define NVDXI_PIXPLLCP 0x4E -#define NVDXI_PIXPLLSTAT 0x4F -#define NVDXI_CURCOLEXT 0x60 /*sequential from CURCOL3->15, RGB*/ - -/* (D)AC (X) (I)ndexed registers (>= G200) */ -#define NVDXI_KEYOPMODE 0x51 -#define NVDXI_COLMSK0RED 0x52 -#define NVDXI_COLMSK0GREEN 0x53 -#define NVDXI_COLMSK0BLUE 0x54 -#define NVDXI_COLKEY0RED 0x55 -#define NVDXI_COLKEY0GREEN 0x56 -#define NVDXI_COLKEY0BLUE 0x57 - -/* (D)AC (X) (I)ndexed registers (>= G450) */ -#define NVDXI_TVO_IDX 0x87 -#define NVDXI_TVO_DATA 0x88 -#define NVDXI_OUTPUTCONN 0x8A -#define NVDXI_SYNCCTRL 0x8B -#define NVDXI_VIDPLLSTAT 0x8C -#define NVDXI_VIDPLLP 0x8D -#define NVDXI_VIDPLLM 0x8E -#define NVDXI_VIDPLLN 0x8F -#define NVDXI_PWRCTRL 0xA0 -#define NVDXI_PANMODE 0xA2 - -/* NV 1st CRTC registers */ -#define NVCR1_VCOUNT 0x1E20 - /* NV 2nd CRTC registers (>= G400) */ #define NVCR2_CTL 0x3C10 #define NVCR2_HPARAM 0x3C14 @@ -337,36 +319,6 @@ #define NVACC_SRCORG 0x2CB4 // >= G200 #define NVACC_DSTORG 0x2CB8 // >= G200 -/*NV BES (Back End Scaler) registers (>= G200) */ -#define NVBES_A1ORG 0x3D00 -#define NVBES_A2ORG 0x3D04 -#define NVBES_B1ORG 0x3D08 -#define NVBES_B2ORG 0x3D0C -#define NVBES_A1CORG 0x3D10 -#define NVBES_A2CORG 0x3D14 -#define NVBES_B1CORG 0x3D18 -#define NVBES_B2CORG 0x3D1C -#define NVBES_CTL 0x3D20 -#define NVBES_PITCH 0x3D24 -#define NVBES_HCOORD 0x3D28 -#define NVBES_VCOORD 0x3D2C -#define NVBES_HISCAL 0x3D30 -#define NVBES_VISCAL 0x3D34 -#define NVBES_HSRCST 0x3D38 -#define NVBES_HSRCEND 0x3D3C -#define NVBES_LUMACTL 0x3D40 -#define NVBES_V1WGHT 0x3D48 -#define NVBES_V2WGHT 0x3D4C -#define NVBES_HSRCLST 0x3D50 -#define NVBES_V1SRCLST 0x3D54 -#define NVBES_V2SRCLST 0x3D58 -#define NVBES_A1C3ORG 0x3D60 -#define NVBES_A2C3ORG 0x3D64 -#define NVBES_B1C3ORG 0x3D68 -#define NVBES_B2C3ORG 0x3D6C -#define NVBES_GLOBCTL 0x3DC0 -#define NVBES_STATUS 0x3DC4 - /*MAVEN registers (<= G400) */ #define NVMAV_PGM 0x3E #define NVMAV_PIXPLLM 0x80 @@ -440,38 +392,11 @@ #define DACW(A,B) (NV_REG32(NVDAC_##A)=B) #define DAC2R(A) (NV_REG32(NVDAC2_##A)) #define DAC2W(A,B) (NV_REG32(NVDAC2_##A)=B) -//end new. - -/* read and write from the dac index register */ -#define DXIR(A) (DACW(PALWTADD,NVDXI_##A),DACR(X_DATAREG)) -#define DXIW(A,B) (DACW(PALWTADD,NVDXI_##A),DACW(X_DATAREG,B)) - -/* read and write from the vga registers */ -#define VGAR(A) (NV_REG8(NVVGA_##A)) -#define VGAW(A,B) (NV_REG8(NVVGA_##A)=B) - -/* read and write from the indexed vga registers */ -#define VGAR_I(A,B) (VGAW(A##_I,B),VGAR(A##_D)) -#define VGAW_I(A,B,C) (VGAW(A##_I,B),VGAW(A##_D,C)) - -/* read and write from the powergraphics registers */ -#define ACCR(A) (NV_REG32(NVACC_##A)) -#define ACCW(A,B) (NV_REG32(NVACC_##A)=B) -#define ACCGO(A,B) (NV_REG32(NVACC_##A + 0x0100)=B) /* read and write from the backend scaler registers */ #define BESR(A) (NV_REG32(NVBES_##A)) #define BESW(A,B) (NV_REG32(NVBES_##A)=B) -/* read and write from first CRTC */ -#define CR1R(A) (NV_REG32(NVCR1_##A)) -#define CR1W(A,B) (NV_REG32(NVCR1_##A)=B) - -/* read and write from second CRTC */ -#define CR2R(A) (NV_REG32(NVCR2_##A)) -#define CR2W(A,B) (NV_REG32(NVCR2_##A)=B) - -//new: /* read and write from CRTC indexed registers */ #define CRTCW(A,B)(NV_REG16(NV16_CRTCIND) = ((NVCRTCX_##A) | ((B) << 8))) #define CRTCR(A) (NV_REG8(NV8_CRTCIND) = (NVCRTCX_##A), NV_REG8(NV8_CRTCDAT)) @@ -484,7 +409,7 @@ #define SEQW(A,B)(NV_REG16(NV16_SEQIND) = ((NVSEQX_##A) | ((B) << 8))) #define SEQR(A) (NV_REG8(NV8_SEQIND) = (NVSEQX_##A), NV_REG8(NV8_SEQDAT)) -/* read and write from PCI GRAPHICS indexed registers (>= NM2097) */ +/* read and write from PCI GRAPHICS indexed registers */ #define GRPHW(A,B)(NV_REG16(NV16_GRPHIND) = ((NVGRPHX_##A) | ((B) << 8))) #define GRPHR(A) (NV_REG8(NV8_GRPHIND) = (NVGRPHX_##A), NV_REG8(NV8_GRPHDAT)) //end new. @@ -494,3 +419,12 @@ #define MAVW(A,B) (i2c_maven_write(NVMAV_##A ,B)) #define MAVRW(A) (i2c_maven_read (NVMAV_##A )|(i2c_maven_read(NVMAV_##A +1)<<8)) #define MAVWW(A,B) (i2c_maven_write(NVMAV_##A ,B &0xFF),i2c_maven_write(NVMAV_##A +1,B >>8)) + +/* read and write from the powergraphics registers */ +#define ACCR(A) (NV_REG32(NVACC_##A)) +#define ACCW(A,B) (NV_REG32(NVACC_##A)=B) +#define ACCGO(A,B) (NV_REG32(NVACC_##A + 0x0100)=B) + +/* read and write from second CRTC */ +#define CR2R(A) (NV_REG32(NVCR2_##A)) +#define CR2W(A,B) (NV_REG32(NVCR2_##A)=B) diff --git a/src/add-ons/accelerants/nvidia/GetAccelerantHook.c b/src/add-ons/accelerants/nvidia/GetAccelerantHook.c index 5173fb6f86..238b9f42ae 100644 --- a/src/add-ons/accelerants/nvidia/GetAccelerantHook.c +++ b/src/add-ons/accelerants/nvidia/GetAccelerantHook.c @@ -4,7 +4,7 @@ Other authors: Mark Watson, - Rudolf Cornelissen 10/2002-4/2003 + Rudolf Cornelissen 10/2002-8/2003 */ #define MODULE_BIT 0x08000000 @@ -170,8 +170,8 @@ status_t check_overlay_capability(uint32 feature) break; } -//temp disabled: - if (si->ps.card_type > G550) + /* fixme: setup NV4 overlay also... */ + if (si->ps.card_arch > NV04A) { /* export video overlay functions */ LOG(4, ("Overlay: Exporting hook %s.\n", msg)); diff --git a/src/add-ons/accelerants/nvidia/Overlay.c b/src/add-ons/accelerants/nvidia/Overlay.c index ebbffedf2c..dcfeab5640 100644 --- a/src/add-ons/accelerants/nvidia/Overlay.c +++ b/src/add-ons/accelerants/nvidia/Overlay.c @@ -1,4 +1,4 @@ -/* Written by Rudolf Cornelissen 05-2002/03-2003 */ +/* Written by Rudolf Cornelissen 05-2002/08-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,11 +10,7 @@ #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 +/* 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 }; @@ -46,7 +42,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,13 +56,10 @@ 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 | @@ -103,25 +96,21 @@ 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 */ - if (width == (width & ~0x0007)) + /* check if slopspace is needed: GeForce need ~0x001f. */ + /* fixme: + * update needed for GF DVDmax support to adhere to CRTC2 constraints?? */ + if (width == (width & ~0x001f)) { si->overlay.myBuffer[offset].width = width; } else { - si->overlay.myBuffer[offset].width = (width & ~0x0007) + 8; + si->overlay.myBuffer[offset].width = (width & ~0x001f) + 0x0020; } 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. */ + /* check if the requested horizontal pitch is supported: */ + //fixme: tune for GF... if (si->overlay.myBuffer[offset].width > 4088) { LOG(4,("Overlay: Sorry, requested buffer pitch not supported, aborted\n")); @@ -132,37 +121,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)); @@ -329,16 +287,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 nv.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 * 1024)); for (cnt = 0; cnt <= offset; cnt++) { @@ -438,17 +386,10 @@ status_t GET_OVERLAY_CONSTRAINTS switch (ob->space) { case B_YCbCr422: - /* G200 can work with 3, > G200 need 7. Compatible setting returned for now. + /* GeForce need 31. * Note: this has to be in sync with the slopspace setup during buffer allocation.. */ - oc->view.width_alignment = 7; + oc->view.width_alignment = 31; 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; @@ -467,40 +408,30 @@ status_t GET_OVERLAY_CONSTRAINTS oc->window.width_alignment = 0; oc->window.height_alignment = 0; oc->window.width.min = 2; - /* G200-G550 can output upto and including 2048 pixels in width */ - if (dm->virtual_width > 2048) + /* GeForce cards can output upto and including 2046 pixels in width */ + if (dm->virtual_width > 2046) { - oc->window.width.max = 2048; + oc->window.width.max = 2046; } else { oc->window.width.max = dm->virtual_width; } oc->window.height.min = 2; - /* G200-G550 can output upto and including 2048 pixels in height */ - if (dm->virtual_height > 2048) + /* GeForce cards can output upto and including 2046 pixels in height */ + if (dm->virtual_height > 2046) { - oc->window.height.max = 2048; + oc->window.height.max = 2046; } else { 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)); + /* GeForce scaling restrictions */ + oc->h_scale.min = 0.125; + oc->h_scale.max = 16384/(float)(ob->width - si->overlay.myBufInfo[offset].slopspace); + oc->v_scale.min = 0.125; oc->v_scale.max = 16384/(float)ob->height; return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_bes.c b/src/add-ons/accelerants/nvidia/engine/nv_bes.c index b2d75766fe..961967b08b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_bes.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_bes.c @@ -1,5 +1,5 @@ -/* G200-G550 Back End Scaler functions */ -/* Written by Rudolf Cornelissen 05/2002-04/2003 */ +/* Nvidia GeForce Back End Scaler functions */ +/* Written by Rudolf Cornelissen 05/2002-08/2003 */ #define MODULE_BIT 0x00000200 @@ -12,7 +12,6 @@ status_t nv_configure_bes (const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov, int offset) { /* yuy2 (4:2:2) colorspace calculations */ - /* Note: Some calculations will have to be modified for other colorspaces if they are incorporated. */ /* Note: * in BeOS R5.0.3 and DANO: @@ -27,46 +26,16 @@ status_t nv_configure_bes * 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; + uint32 hcoordv, vcoordv, hiscalv, hsrcstv, viscalv, a1orgv, v1srcstv; /* misc used variables */ uint16 temp1, temp2; /* interval representation, used for scaling calculations */ uint16 intrep, 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 *** @@ -259,12 +228,9 @@ status_t nv_configure_bes /* correct factor to prevent most-right visible 'line' from distorting */ ifactor -= (1 << 2); + hiscalv = ifactor; 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)); - /* check scaling factor (and modify if needed) to be within scaling limits */ if (((((uint32)my_ov.width) << 16) / 16384) > hiscalv) { @@ -272,10 +238,10 @@ status_t nv_configure_bes hiscalv = ((((uint32)my_ov.width) << 16) / 16384); LOG(4,("Overlay: horizontal scaling factor too large, clamping at %f\n", (float)65536 / hiscalv)); } - if (hiscalv >= (32 << 16)) + if (hiscalv > (8 << 16)) { /* (non-inverse) factor too small, set factor to min. valid value */ - hiscalv = 0x1ffffc; + hiscalv = (8 << 16); LOG(4,("Overlay: horizontal scaling factor too small, clamping at %f\n", (float)65536 / hiscalv)); } /* AND below is required by hardware */ @@ -320,55 +286,6 @@ status_t nv_configure_bes 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 */ - /* 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.! */ - - 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) */ - 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)); - } - 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; - /* 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; - } - 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); - } - /* AND below required by hardware */ - hsrcendv &= 0x03fffffc; - LOG(4,("Overlay: last horizontal (sub)pixel of input bitmap contributing %f\n", 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; - /* AND below required by hardware */ - hsrclstv &= 0x03ff0000; - - /******************************************* *** setup vertical scaling and clipping *** *******************************************/ @@ -421,10 +338,10 @@ status_t nv_configure_bes viscalv = ((((uint32)my_ov.height) << 16) / 16384); LOG(4,("Overlay: vertical scaling factor too large, clamping at %f\n", (float)65536 / viscalv)); } - if (viscalv >= (32 << 16)) + if (viscalv > (8 << 16)) { /* (non-inverse) factor too small, set factor to min. valid value */ - viscalv = 0x1ffffc; + viscalv = (8 << 16); LOG(4,("Overlay: vertical scaling factor too small, clamping at %f\n", (float)65536 / viscalv)); } /* AND below is required by hardware */ @@ -432,11 +349,7 @@ status_t nv_configure_bes /* do vertical clipping... */ - /* Setup vertical source start: first (sub)pixel contributing to output picture. - * Note: this exists of two parts: - * 1. setup fractional part (sign is always 'positive'); - * 2. setup relative base_adress, taking clipping on top (and zoom) into account. - * Both parts are done intertwined below. */ + /* Setup vertical source start: first (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. @@ -444,12 +357,7 @@ status_t nv_configure_bes /* 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' */ - weight = 0; - a1orgv = (uint32)((vuint32 *)ob->buffer); - a1orgv -= (uint32)((vuint32 *)si->framebuffer); - /* calculate origin adress */ - LOG(4,("Overlay: topleft corner of input bitmap (cardRAM offset) $%08x\n",a1orgv)); + v1srcstv = 0; /* check for destination vertical clipping at top side */ if (ow->v_start < crtc_vstart) { @@ -457,51 +365,30 @@ status_t nv_configure_bes * (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 */ - a1orgv += ((((ow->height - 2) * ifactor) >> 16) * ob->bytes_per_row); - weight = (ow->height - 2) * ifactor; + /* increase 'number of clipping pixels' with 'fixed value': + * 'total height - 2' of dest. picture in pixels * inverse scaling factor */ + v1srcstv = (ow->height - 2) * ifactor; } 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; + /* increase 'first contributing pixel' with: + * number of destination picture clipping pixels * inverse scaling factor */ + v1srcstv = (crtc_vstart - ow->v_start) * ifactor; } 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)); + v1srcstv += (((uint32)my_ov.v_start) << 16); + LOG(4,("Overlay: first vert. (sub)pixel of input bitmap contributing %f\n", v1srcstv / (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. */ + /* calculate inputbitmap origin adress */ + a1orgv = (uint32)((vuint32 *)ob->buffer); + a1orgv -= (uint32)((vuint32 *)si->framebuffer); + /* AND below is probably required by hardware. */ /* Buffer A topleft corner of field 1 (origin)(field 1 contains our full frames) */ - a1orgv &= 0x01fffff0; - - /* field 1 weight: AND below required by hardware, also make sure 'sign' is always 'positive' */ - v1wghtv = 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); - /* AND below required by hardware */ - v1srclstv &= 0x000003ff; + a1orgv &= 0xfffffff0; + LOG(4,("Overlay: topleft corner of input bitmap (cardRAM offset) $%08x\n",a1orgv)); /***************************** @@ -514,186 +401,120 @@ status_t nv_configure_bes ow->red.mask, ow->green.mask, ow->blue.mask, ow->alpha.mask)); - /************************* - *** setup BES control *** - *************************/ - - /* BES global control: setup functions */ - 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; + /***************** + *** log flags *** + *****************/ 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")); - } - - /* 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 fixed and turned on for GeForce overlay. */ /************************************* *** sync to BES (Back End Scaler) *** *************************************/ +//fixme if needed... (doesn't look like it) /* Make sure reprogramming the BES completes before the next retrace occurs, * to prevent register-update glitches (double buffer feature). */ - LOG(3,("Overlay: starting register programming beyond Vcount %d\n", CR1R(VCOUNT))); +// 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); +// while (CR1R(VCOUNT) > (si->dm.timing.v_total - 200)) snooze(4); /************************************** *** actually program the registers *** **************************************/ - 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); - + /* We only use buffer buffer 0: select it. (0x01 = buffer 0, 0x10 = buffer 1) */ + BESW(NV10_BUFSEL, 0x00000001); + /* setup buffer origin: GeForce uses subpixel precise clipping on left and top! (12.4 values) */ + BESW(NV10_0SRCREF, ((v1srcstv << 4) & 0xffff0000) | ((hsrcstv >> 12) & 0x0000ffff)); + /* setup buffersize */ + BESW(NV10_0SRCSIZE, ((ob->height << 16) | ob->width)); + /* setup source pitch including slopspace (in bytes), + * b16: select YUY2 (0 = YV12), b20: use colorkey, b24: no iturbt_709 */ + /* Note: + * source pitch granularity = 32 pixels on GeForce cards!! */ + BESW(NV10_0SRCPTCH, (((ob->width * 2) & 0x0000ffff) | (1 << 16) | (1 << 20) | (0 << 24))); + /* setup output window position */ + BESW(NV10_0DSTREF, ((vcoordv & 0xffff0000) | ((hcoordv & 0xffff0000) >> 16))); + /* setup output window size */ + BESW(NV10_0DSTSIZE, ( + (((vcoordv & 0x0000ffff) - ((vcoordv & 0xffff0000) >> 16) + 1) << 16) | + ((hcoordv & 0x0000ffff) - ((hcoordv & 0xffff0000) >> 16) + 1) + )); + /* setup BES memory-range mask */ + BESW(NV10_0MEMMASK, ((si->ps.memory_size << 20) - 1)); + /* unknown, but needed */ + BESW(NV10_0WHAT, 0x00000000); + /* setup horizontal scaling */ + BESW(NV10_0ISCALH, (hiscalv << 4)); + /* setup vertical scaling */ + BESW(NV10_0ISCALV, (viscalv << 4)); + /* setup (unclipped!) buffer startadress in RAM */ + BESW(NV10_0BUFADR, a1orgv); + /* enable BES (b0 = 0) */ + BESW(NV10_GENCTRL, 0x00000000); /************************** *** 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); - + switch(si->dm.space) + { + case B_RGB15_LITTLE: + BESW(NV10_COLKEY, ( + ((ow->blue.value & ow->blue.mask) << 0) | + ((ow->green.value & ow->green.mask) << 5) | + ((ow->red.value & ow->red.mask) << 10) | + ((ow->alpha.value & ow->alpha.mask) << 15) + )); + break; + case B_RGB16_LITTLE: + BESW(NV10_COLKEY, ( + ((ow->blue.value & ow->blue.mask) << 0) | + ((ow->green.value & ow->green.mask) << 5) | + ((ow->red.value & ow->red.mask) << 11) + /* this space has no alpha bits */ + )); + break; + case B_CMAP8: + case B_RGB32_LITTLE: + default: + BESW(NV10_COLKEY, ( + ((ow->blue.value & ow->blue.mask) << 0) | + ((ow->green.value & ow->green.mask) << 8) | + ((ow->red.value & ow->red.mask) << 16) | + ((ow->alpha.value & ow->alpha.mask) << 24) + )); + break; + } /************************* *** setup misc. stuff *** *************************/ - /* setup brightness and contrast to be 'neutral' (this is not implemented on G200) */ - BESW(LUMACTL, 0x00000080); - - /* setup source pitch including slopspace (in pixels); AND is required by hardware */ - BESW(PITCH, (ob->width & 0x00000fff)); + /* setup brightness, contrast and saturation to be 'neutral' */ + BESW(NV10_0BRICON, ((0x1000 << 16) | 0x1000)); + BESW(NV10_0SAT, ((0x0000 << 16) | 0x1000)); /* on a 500Mhz P3 CPU just logging a line costs 400uS (18-19 vcounts at 1024x768x60Hz)! * programming the registers above actually costs 180uS here */ - LOG(3,("Overlay: completed at Vcount %d\n", CR1R(VCOUNT))); +// LOG(3,("Overlay: completed at Vcount %d\n", CR1R(VCOUNT))); return B_OK; } status_t nv_release_bes() { - /* setup BES control: disable scaler */ - BESW(CTL, 0x00000000); + /* setup BES control: disable scaler (b0 = 1) */ + BESW(NV10_GENCTRL, 0x00000001); return B_OK; } diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index 35ebd5ae13..b8cec02378 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -1,6 +1,6 @@ /* CTRC functionality */ /* Author: - Rudolf Cornelissen 11/2002-7/2003 + Rudolf Cornelissen 11/2002-8/2003 */ #define MODULE_BIT 0x00040000 @@ -526,19 +526,42 @@ status_t nv_crtc_cursor_define(uint8* andMask,uint8* xorMask) return B_OK; } -/*position the cursor*/ -status_t nv_crtc_cursor_position(uint16 x ,uint16 y) +/* position the cursor */ +status_t nv_crtc_cursor_position(uint16 x, uint16 y) { - /* make sure we are in retrace on pre-NV10 cards to prevent distortions: - * no double buffering feature */ - if (si->ps.card_arch == NV04A) + uint16 yhigh; + + /* make sure we are beyond the first line of the cursorbitmap being drawn during + * updating the position to prevent distortions: no double buffering feature */ + /* Note: + * we need to return as quick as possible or some apps will exhibit lagging.. */ + + /* read the old cursor Y position */ + yhigh = ((DACR(CURPOS) & 0x0fff0000) >> 16); + /* make sure we will wait until we are below both the old and new Y position: + * visible cursorbitmap drawing needs to be done at least... */ + if (y > yhigh) yhigh = y; + + if (yhigh < (si->dm.timing.v_display - 16)) { - while (!(NV_REG32(NV32_RASTER) & 0x00010000)) + /* we have vertical lines below old and new cursorposition to spare. So we + * update the cursor postion 'mid-screen', but below that area. */ + while (((uint16)(NV_REG32(NV32_RASTER) & 0x000007ff)) < (yhigh + 16)) { - snooze(4); + snooze(10); + } + } + else + { + /* no room to spare, just wait for retrace (is relatively slow) */ + while ((NV_REG32(NV32_RASTER) & 0x000007ff) < si->dm.timing.v_display) + { + /* don't snooze much longer or retrace might get missed! */ + snooze(10); } } + /* update cursorposition */ DACW(CURPOS, ((x & 0x0fff) | ((y & 0x0fff) << 16))); return B_OK; diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index c58b05d9cb..2eae45afda 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -1,7 +1,7 @@ /* Authors: Mark Watson 12/1999, Apsed, - Rudolf Cornelissen 10/2002-7/2003 + Rudolf Cornelissen 10/2002-8/2003 */ #define MODULE_BIT 0x00008000 @@ -81,7 +81,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.03 running.\n")); + LOG(1,("POWERUP: nVidia (open)BeOS Accelerant 0.04 running.\n")); /* preset no laptop */ si->ps.laptop = false; @@ -738,6 +738,18 @@ status_t nv_general_bios_to_powergraphics() nv_crtc_dpms(false, false, false); nv_crtc_cursor_hide(); + /* power-up all nvidia hardware function blocks */ + /* bit 28: PVIDEO, + * bit 25: CRTC2, (> NV04A) + * bit 24: CRTC1, + * bit 20: framebuffer, + * bit 16: PPMI, + * bit 12: PGRAPH, + * bit 8: PFIFO, + * bit 4: PMEDIA, + * bit 0: TVOUT. (> NV04A) */ + NV_REG32(NV32_PWRUPCTRL) = 0x13111111; + /* set card to 'enhanced' mode: (only VGA standard registers used for NeoMagic cards) */ /* (keep) card enabled, set plain normal memory usage, no old VGA 'tricks' ... */ // CRTCW(MODECTL, 0xc3);