From dd43fd34c1d5ccbfbc0654222f23e2bc855b4057 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Mon, 10 Jan 2005 13:04:17 +0000 Subject: [PATCH] added cursor HW bug workaround for NV40 and higher on CRTC1; added seperate acc file for DMA test setup for NV40 and higher (for now). The driver now works by default on NV40 and higher, but without acceleration. If someone tests using overlay, let me know if it actually works: NV43 seems to have a new engine, NV40 _might_ still have the old, and so, useable engine. NV40-plus overlay is something we will NOT have any time soon! git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10651 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/accelerants/nvidia/Acceleration.c | 233 +++++++++++++----- .../accelerants/nvidia/EngineManagment.c | 15 +- .../accelerants/nvidia/GetAccelerantHook.c | 10 +- .../accelerants/nvidia/SetDisplayMode.c | 11 +- src/add-ons/accelerants/nvidia/engine/Jamfile | 1 + .../accelerants/nvidia/engine/nv_acc.c | 2 +- .../accelerants/nvidia/engine/nv_acc_dma.c | 92 +++++++ .../accelerants/nvidia/engine/nv_crtc.c | 10 + .../accelerants/nvidia/engine/nv_proto.h | 9 + 9 files changed, 312 insertions(+), 71 deletions(-) create mode 100644 src/add-ons/accelerants/nvidia/engine/nv_acc_dma.c diff --git a/src/add-ons/accelerants/nvidia/Acceleration.c b/src/add-ons/accelerants/nvidia/Acceleration.c index c5c91390bf..4aaa458c13 100644 --- a/src/add-ons/accelerants/nvidia/Acceleration.c +++ b/src/add-ons/accelerants/nvidia/Acceleration.c @@ -3,37 +3,70 @@ This file may be used under the terms of the Be Sample Code License. Other authors: - Rudolf Cornelissen 9/2003. + Rudolf Cornelissen 9/2003-1/2005. +*/ + +/* + note: + attempting DMA on NV40 and higher because without it I can't get it going ATM. + Later on this can become a nv.settings switch, and maybe later we can even + forget about non-DMA completely (depends on 3D acceleration attempts). */ #define MODULE_BIT 0x40000000 #include "acc_std.h" -void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count) { +void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count) +{ int i; - /* init acc engine for blit function */ - nv_acc_setup_blit(); - - /* do each blit */ - i=0; - while (count--) + if(si->ps.card_arch < NV40A) { - nv_acc_blit - ( - list[i].src_left, - list[i].src_top, - list[i].dest_left, - list[i].dest_top, - list[i].width, - list[i].height - ); - i++; + /* init acc engine for blit function */ + nv_acc_setup_blit(); + + /* do each blit */ + i=0; + while (count--) + { + nv_acc_blit + ( + list[i].src_left, + list[i].src_top, + list[i].dest_left, + list[i].dest_top, + list[i].width, + list[i].height + ); + i++; + } + } + else + { + /* init acc engine for blit function */ + nv_acc_setup_blit_dma(); + + /* do each blit */ + i=0; + while (count--) + { + nv_acc_blit_dma + ( + list[i].src_left, + list[i].src_top, + list[i].dest_left, + list[i].dest_top, + list[i].width, + list[i].height + ); + i++; + } } } -void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT(engine_token *et, scaled_blit_params *list, uint32 count) { +void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT(engine_token *et, scaled_blit_params *list, uint32 count) +{ int i; /* do each blit */ @@ -55,7 +88,8 @@ void SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT(engine_token *et, scaled_blit_params } } -void SCREEN_TO_SCREEN_TRANSPARENT_BLIT(engine_token *et, uint32 transparent_colour, blit_params *list, uint32 count) { +void SCREEN_TO_SCREEN_TRANSPARENT_BLIT(engine_token *et, uint32 transparent_colour, blit_params *list, uint32 count) +{ int i; /* do each blit */ @@ -76,65 +110,134 @@ void SCREEN_TO_SCREEN_TRANSPARENT_BLIT(engine_token *et, uint32 transparent_colo } } -void FILL_RECTANGLE(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count) { +void FILL_RECTANGLE(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count) +{ int i; - /* init acc engine for fill function */ - nv_acc_setup_rectangle(colorIndex); - - /* draw each rectangle */ - i=0; - while (count--) + if(si->ps.card_arch < NV40A) { - nv_acc_rectangle - ( - list[i].left, - (list[i].right)+1, - list[i].top, - (list[i].bottom-list[i].top)+1 - ); - i++; + /* init acc engine for fill function */ + nv_acc_setup_rectangle(colorIndex); + + /* draw each rectangle */ + i=0; + while (count--) + { + nv_acc_rectangle + ( + list[i].left, + (list[i].right)+1, + list[i].top, + (list[i].bottom-list[i].top)+1 + ); + i++; + } + } + else + { + /* init acc engine for fill function */ + nv_acc_setup_rectangle_dma(colorIndex); + + /* draw each rectangle */ + i=0; + while (count--) + { + nv_acc_rectangle_dma + ( + list[i].left, + (list[i].right)+1, + list[i].top, + (list[i].bottom-list[i].top)+1 + ); + i++; + } } } -void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count) { +void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count) +{ int i; - /* init acc engine for invert function */ - nv_acc_setup_rect_invert(); - - /* invert each rectangle */ - i=0; - while (count--) + if(si->ps.card_arch < NV40A) { - nv_acc_rectangle_invert - ( - list[i].left, - (list[i].right)+1, - list[i].top, - (list[i].bottom-list[i].top)+1 - ); - i++; + /* init acc engine for invert function */ + nv_acc_setup_rect_invert(); + + /* invert each rectangle */ + i=0; + while (count--) + { + nv_acc_rectangle_invert + ( + list[i].left, + (list[i].right)+1, + list[i].top, + (list[i].bottom-list[i].top)+1 + ); + i++; + } + } + else + { + /* init acc engine for invert function */ + nv_acc_setup_rect_invert_dma(); + + /* invert each rectangle */ + i=0; + while (count--) + { + nv_acc_rectangle_invert_dma + ( + list[i].left, + (list[i].right)+1, + list[i].top, + (list[i].bottom-list[i].top)+1 + ); + i++; + } } } -void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count) { +void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count) +{ int i; - /* init acc engine for fill function */ - nv_acc_setup_rectangle(colorIndex); - - /* draw each span */ - i=0; - while (count--) + if(si->ps.card_arch < NV40A) { - nv_acc_rectangle - ( - list[i+1], - list[i+2]+1, - list[i], - 1 - ); - i+=3; + /* init acc engine for fill function */ + nv_acc_setup_rectangle(colorIndex); + + /* draw each span */ + i=0; + while (count--) + { + nv_acc_rectangle + ( + list[i+1], + list[i+2]+1, + list[i], + 1 + ); + i+=3; + } + } + else + { + /* init acc engine for fill function */ + nv_acc_setup_rectangle_dma(colorIndex); + + /* draw each span */ + i=0; + while (count--) + { + nv_acc_rectangle_dma + ( + list[i+1], + list[i+2]+1, + list[i], + 1 + ); + i+=3; + } } } diff --git a/src/add-ons/accelerants/nvidia/EngineManagment.c b/src/add-ons/accelerants/nvidia/EngineManagment.c index 9a028832cc..36df66a6e1 100644 --- a/src/add-ons/accelerants/nvidia/EngineManagment.c +++ b/src/add-ons/accelerants/nvidia/EngineManagment.c @@ -7,6 +7,13 @@ Rudolf Cornelissen 3/2004-12/2004 */ +/* + note: + attempting DMA on NV40 and higher because without it I can't get it going ATM. + Later on this can become a nv.settings switch, and maybe later we can even + forget about non-DMA completely (depends on 3D acceleration attempts). +*/ + #define MODULE_BIT 0x10000000 #include "acc_std.h" @@ -28,7 +35,8 @@ status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, en if (st) SYNC_TO_TOKEN(st); /* make sure all needed engine cmd's are mapped to the FIFO */ - nv_acc_assert_fifo(); + if (si->ps.card_arch < NV40A) + nv_acc_assert_fifo(); /* return an engine token */ *et = &nv_engine_token; @@ -48,7 +56,10 @@ status_t RELEASE_ENGINE(engine_token *et, sync_token *st) void WAIT_ENGINE_IDLE(void) { /*wait for the engine to be totally idle*/ - nv_acc_wait_idle(); + if (si->ps.card_arch < NV40A) + nv_acc_wait_idle(); + else + nv_acc_wait_idle_dma(); } status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st) diff --git a/src/add-ons/accelerants/nvidia/GetAccelerantHook.c b/src/add-ons/accelerants/nvidia/GetAccelerantHook.c index f26aeb93a6..e665867c25 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/2004 + Rudolf Cornelissen 10/2002-1/2005 */ #define MODULE_BIT 0x08000000 @@ -127,6 +127,7 @@ void * get_accelerant_hook(uint32 feature, void *data) } #undef CHKO #undef CHKA +#undef CHKD #undef HOOK #undef ZERO #undef HRDC @@ -206,6 +207,13 @@ status_t check_acc_capability(uint32 feature) break; } + //fixme: + if(si->ps.card_arch >= NV40A) + { + LOG(4, ("Acc: Acc not setup yet; not exporting hook %s.\n", msg)); + return B_ERROR; + } + /* hardware acceleration is only supported in modes with upto a certain * memory pitch.. */ if (si->acc_mode) diff --git a/src/add-ons/accelerants/nvidia/SetDisplayMode.c b/src/add-ons/accelerants/nvidia/SetDisplayMode.c index a435489526..6b0f42db01 100644 --- a/src/add-ons/accelerants/nvidia/SetDisplayMode.c +++ b/src/add-ons/accelerants/nvidia/SetDisplayMode.c @@ -6,7 +6,7 @@ Other authors: Mark Watson, Apsed, - Rudolf Cornelissen 11/2002-4/2004 + Rudolf Cornelissen 11/2002-1/2005 */ #define MODULE_BIT 0x00200000 @@ -310,7 +310,14 @@ status_t SET_DISPLAY_MODE(display_mode *mode_to_set) if (target.flags & DUALHEAD_BITS) head2_dpms(display,h,v); /* set up acceleration for this mode */ - nv_acc_init(); + /* note: + * attempting DMA on NV40 and higher because without it I can't get it going ATM. + * Later on this can become a nv.settings switch, and maybe later we can even + * forget about non-DMA completely (depends on 3D acceleration attempts). */ + if (si->ps.card_arch < NV40) + nv_acc_init(); + else + nv_acc_init_dma(); /* set up overlay unit for this mode */ nv_bes_init(); diff --git a/src/add-ons/accelerants/nvidia/engine/Jamfile b/src/add-ons/accelerants/nvidia/engine/Jamfile index cc20be1dc8..3a2cb6882d 100644 --- a/src/add-ons/accelerants/nvidia/engine/Jamfile +++ b/src/add-ons/accelerants/nvidia/engine/Jamfile @@ -5,6 +5,7 @@ UsePrivateHeaders [ FDirName graphics nvidia ] ; StaticLibrary nvidia_engine : nv_acc.c + nv_acc_dma.c nv_bes.c nv_brooktreetv.c nv_crtc.c diff --git a/src/add-ons/accelerants/nvidia/engine/nv_acc.c b/src/add-ons/accelerants/nvidia/engine/nv_acc.c index 82794ee36a..fcd95ccd6b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_acc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_acc.c @@ -352,7 +352,7 @@ status_t nv_acc_init() /* disable specific functions, but enable SETUP_SPARE2 register */ ACCW(NV10_DEBUG4, 0x00008000); /* set limit_viol_pix_adress(?): more likely something unknown.. */ - ACCW(NV4X_WHAT2, 0x00be3c5f); + ACCW(NV25_WHAT0, 0x00be3c5f); /* unknown.. */ switch (si->ps.card_type) { diff --git a/src/add-ons/accelerants/nvidia/engine/nv_acc_dma.c b/src/add-ons/accelerants/nvidia/engine/nv_acc_dma.c new file mode 100644 index 0000000000..a2b91790fd --- /dev/null +++ b/src/add-ons/accelerants/nvidia/engine/nv_acc_dma.c @@ -0,0 +1,92 @@ +/* NV Acceleration functions */ + +/* Author: + Rudolf Cornelissen 8/2003-1/2005. + + This code was possible thanks to: + - the Linux XFree86 NV driver, + - the Linux UtahGLX 3D driver. +*/ + +/* + note: + attempting DMA on NV40 and higher because without it I can't get it going ATM. + Later on this can become a nv.settings switch, and maybe later we can even + forget about non-DMA completely (depends on 3D acceleration attempts). +*/ + +#define MODULE_BIT 0x00080000 + +#include "nv_std.h" + +/*acceleration notes*/ + +/*functions Be's app_server uses: +fill span (horizontal only) +fill rectangle (these 2 are very similar) +invert rectangle +blit +*/ + +status_t nv_acc_wait_idle_dma() +{ + /* wait until engine completely idle */ + //fixme: implement. + + return B_OK; +} + +/* AFAIK this must be done for every new screenmode. + * Engine required init. */ +status_t nv_acc_init_dma() +{ + //fixme: implement. + + return B_ERROR; +} + +/* screen to screen blit - i.e. move windows around and scroll within them. */ +status_t nv_acc_setup_blit_dma() +{ + //fixme: implement. + + return B_ERROR; +} + +status_t nv_acc_blit_dma(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint16 w,uint16 h) +{ + //fixme: implement. + + return B_ERROR; +} + +/* rectangle fill - i.e. workspace and window background color */ +/* span fill - i.e. (selected) menuitem background color (Dano) */ +status_t nv_acc_setup_rectangle_dma(uint32 color) +{ + //fixme: implement. + + return B_ERROR; +} + +status_t nv_acc_rectangle_dma(uint32 xs,uint32 xe,uint32 ys,uint32 yl) +{ + //fixme: implement. + + return B_ERROR; +} + +/* rectangle invert - i.e. text cursor and text selection */ +status_t nv_acc_setup_rect_invert_dma() +{ + //fixme: implement. + + return B_ERROR; +} + +status_t nv_acc_rectangle_invert_dma(uint32 xs,uint32 xe,uint32 ys,uint32 yl) +{ + //fixme: implement. + + return B_ERROR; +} diff --git a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c index bf37dd11bc..2f3a517f76 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_crtc.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_crtc.c @@ -723,6 +723,11 @@ status_t nv_crtc_cursor_show() /* b0 = 1 enables cursor */ CRTCW(CURCTL0, (CRTCR(CURCTL0) | 0x01)); + /* workaround for hardware bug confirmed existing on NV43: + * Cursor visibility is not updated without a position update if its hardware + * retrace sync is enabled. */ + if (si->ps.card_arch == NV40A) DACW(CURPOS, (DACR(CURPOS))); + return B_OK; } @@ -736,6 +741,11 @@ status_t nv_crtc_cursor_hide() /* b0 = 0 disables cursor */ CRTCW(CURCTL0, (CRTCR(CURCTL0) & 0xfe)); + /* workaround for hardware bug confirmed existing on NV43: + * Cursor visibility is not updated without a position update if its hardware + * retrace sync is enabled. */ + if (si->ps.card_arch == NV40A) DACW(CURPOS, (DACR(CURPOS))); + return B_OK; } diff --git a/src/add-ons/accelerants/nvidia/engine/nv_proto.h b/src/add-ons/accelerants/nvidia/engine/nv_proto.h index 1f1eca955e..8db68f1b4b 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_proto.h +++ b/src/add-ons/accelerants/nvidia/engine/nv_proto.h @@ -113,6 +113,15 @@ status_t nv_acc_transparent_blit(uint16,uint16,uint16, uint16,uint16,uint16, uin status_t nv_acc_video_blit(uint16 xs,uint16 ys,uint16 ws, uint16 hs, uint16 xd,uint16 yd,uint16 wd,uint16 hd); status_t nv_acc_wait_idle(void); +/* DMA versions */ +status_t nv_acc_init_dma(void); +status_t nv_acc_setup_blit_dma(void); +status_t nv_acc_blit_dma(uint16,uint16,uint16, uint16,uint16,uint16 ); +status_t nv_acc_setup_rectangle_dma(uint32 color); +status_t nv_acc_rectangle_dma(uint32 xs,uint32 xe,uint32 ys,uint32 yl); +status_t nv_acc_setup_rect_invert_dma(void); +status_t nv_acc_rectangle_invert_dma(uint32 xs,uint32 xe,uint32 ys,uint32 yl); +status_t nv_acc_wait_idle_dma(void); /* backend scaler functions */ status_t check_overlay_capability(uint32 feature);