From 338c4543518c53c283dc7e0f0b2b6ff7f838aced Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Sat, 27 Mar 2004 17:10:08 +0000 Subject: [PATCH] massive acc speedup, removed fill error, hardcursor OK git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7075 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/neomagic/InitAccelerant.c | 13 +++---- src/add-ons/accelerants/neomagic/Overlay.c | 14 +++++--- .../accelerants/neomagic/engine/nm_acc.c | 36 ++++++++++++------- .../accelerants/neomagic/engine/nm_crtc.c | 12 ++++--- .../accelerants/neomagic/engine/nm_general.c | 2 +- 5 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/add-ons/accelerants/neomagic/InitAccelerant.c b/src/add-ons/accelerants/neomagic/InitAccelerant.c index 62f77fc196..489b213410 100644 --- a/src/add-ons/accelerants/neomagic/InitAccelerant.c +++ b/src/add-ons/accelerants/neomagic/InitAccelerant.c @@ -4,7 +4,7 @@ Other authors: Mark Watson, - Rudolf Cornelissen 10/2002-1/2004. + Rudolf Cornelissen 10/2002-3/2004. */ #define MODULE_BIT 0x00800000 @@ -110,7 +110,6 @@ report success or failure. */ status_t INIT_ACCELERANT(int the_fd) { status_t result; - int pointer_reservation; //mem reserved for pointer int cnt; //used for iteration through the overlay buffers if (1) { @@ -161,15 +160,13 @@ status_t INIT_ACCELERANT(int the_fd) { si->cursor.y = 0; /* - Put the frame buffer immediately following the cursor data. We store this + Put the frame buffer at the beginning of the cardRAM because the acc engine + does not support offsets, or we lack info to get that ability. We store this info in a frame_buffer_config structure to make it convienient to return to the app_server later. */ - pointer_reservation = 0; - if (si->settings.hardcursor) pointer_reservation = si->ps.curmem_size; - - si->fbc.frame_buffer = (void *)((char *)si->framebuffer+pointer_reservation); - si->fbc.frame_buffer_dma = (void *)((char *)si->framebuffer_pci+pointer_reservation); + si->fbc.frame_buffer = si->framebuffer; + si->fbc.frame_buffer_dma = si->framebuffer_pci; /* count of issued parameters or commands */ si->engine.last_idle = si->engine.count = 0; diff --git a/src/add-ons/accelerants/neomagic/Overlay.c b/src/add-ons/accelerants/neomagic/Overlay.c index c0b825126f..de9c5e1b16 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/06-2003 */ +/* Written by Rudolf Cornelissen 05-2002/03-2004 */ /* 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' @@ -176,9 +176,10 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint /* calculate first free RAM adress in card: * Driver setup is as follows: - * card base: - hardware cursor bitmap (if used), - * directly above - screen memory for both heads */ - adress2 = (((uint32)((uint8*)si->fbc.frame_buffer)) + /* cursor already included here */ + * card base: - screen memory, + * free space: - used for overlay, + * card top: - hardware cursor bitmap (if used) */ + adress2 = (((uint32)((uint8*)si->fbc.frame_buffer)) + /* cursor not yet included here */ (si->fbc.bytes_per_row * si->dm.virtual_height)); /* size in bytes of screen(s) */ LOG(4,("Overlay: first free cardRAM virtual adress $%08x\n", adress2)); @@ -189,6 +190,9 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint /* calculate virtual memory adress that would be needed for a new bitmap */ adress = (((uint32)((uint8*)si->framebuffer)) + (si->ps.memory_size * 1024)); + /* take cursor into account (if it exists) */ + if(si->settings.hardcursor) adress -= si->ps.curmem_size; + LOG(4,("Overlay: last free cardRAM virtual adress $%08x\n", (adress - 1))); for (cnt = 0; cnt <= offset; cnt++) { adress -= si->overlay.myBufInfo[cnt].size; @@ -273,6 +277,8 @@ const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint /* calculate physical memory adress (for dma use) */ adress = (((uint32)((uint8*)si->framebuffer_pci)) + (si->ps.memory_size * 1024)); + /* take cursor into account (if it exists) */ + if(si->settings.hardcursor) adress -= si->ps.curmem_size; for (cnt = 0; cnt <= offset; cnt++) { adress -= si->overlay.myBufInfo[cnt].size; diff --git a/src/add-ons/accelerants/neomagic/engine/nm_acc.c b/src/add-ons/accelerants/neomagic/engine/nm_acc.c index a5e62f9b58..ea7b934d39 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_acc.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_acc.c @@ -23,11 +23,11 @@ blit status_t nm_acc_wait_idle() { /* wait until engine completely idle */ - while (ACCR(STATUS) & 0x00000001) - { - /* snooze a bit so I do not hammer the bus */ - snooze (100); - } + /* Note: + * because we have no FIFO functionality we have to make sure we return ASAP(!). + * snoozing() for just 1 microSecond already more than halfs the engine + * performance... */ + while (ACCR(STATUS) & 0x00000001); return B_OK; } @@ -101,11 +101,13 @@ status_t nm_acc_init() /* setup buffer startadress */ /* fixme when/if possible: - * not possible on all cards or not enough specs known :-/ (tried NM2160) - * workaround: place cursor bitmap _after_ screenbuffer instead of vice versa. */ + * not possible on all cards or not enough specs known. (tried NM2160) + * workaround: place cursor bitmap at _end_ of cardRAM instead of in _beginning_. */ /* setup clipping */ - /* apparantly not needed. */ + si->engine.control |= (1 << 26); + ACCW(CLIPLT, 0); + ACCW(CLIPRB, ((si->dm.virtual_height << 16) | (si->dm.virtual_width & 0x0000ffff))); return B_OK; } @@ -123,7 +125,7 @@ status_t nm_acc_blit(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint16 w,uint16 h) { /* start with upper left corner */ /* use ROP GXcopy (b16-19), and use XY coord. system (b24-25) */ - ACCW(BLTCNTL, si->engine.control | 0x830c0000); + ACCW(CONTROL, si->engine.control | 0x830c0000); /* send command and exexute */ ACCW(SRCSTARTOFF, ((ys << 16) | (xs & 0x0000ffff))); ACCW(DSTSTARTOFF, ((yd << 16) | (xd & 0x0000ffff))); @@ -133,7 +135,7 @@ status_t nm_acc_blit(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint16 w,uint16 h) { /* start with lower right corner */ /* use ROP GXcopy (b16-19), and use XY coord. system (b24-25) */ - ACCW(BLTCNTL, (si->engine.control | 0x830c0013)); + ACCW(CONTROL, (si->engine.control | 0x830c0013)); /* send command and exexute */ ACCW(SRCSTARTOFF, (((ys + h) << 16) | ((xs + w) & 0x0000ffff))); ACCW(DSTSTARTOFF, (((yd + h) << 16) | ((xd + w) & 0x0000ffff))); @@ -153,7 +155,7 @@ status_t nm_acc_setup_rectangle(uint32 color) nm_acc_wait_idle(); /* use ROP GXcopy (b16-19), use XY coord. system (b24-25), do foreground color (b3) */ - ACCW(BLTCNTL, (si->engine.control | 0x830c0008)); + ACCW(CONTROL, (si->engine.control | 0x830c0008)); /* setup color */ ACCW(FGCOLOR, color); @@ -162,6 +164,12 @@ status_t nm_acc_setup_rectangle(uint32 color) status_t nm_acc_rectangle(uint32 xs,uint32 xe,uint32 ys,uint32 yl) { + /* The engine does not take kindly if we try to let it fill a rect with + * zero width. Dano's app_server occasionally tries to let us do that though! + * Testable with BeRoMeter 1.2.6, all Ellipses tests. Effect of zero width fill: + * horizontal lines across the entire screen at top and bottom of ellipses. */ + if (xe == xs) return B_OK; + /* make sure the previous command (if any) is completed */ // does not work yet: // nm_acc_wait_fifo(2); @@ -185,7 +193,7 @@ status_t nm_acc_setup_rect_invert() nm_acc_wait_idle(); /* use ROP GXinvert (b16-19), use XY coord. system (b24-25), do foreground color (b3) */ - ACCW(BLTCNTL, (si->engine.control | 0x83050008)); + ACCW(CONTROL, (si->engine.control | 0x83050008)); /* reset color */ ACCW(FGCOLOR, 0); @@ -194,6 +202,10 @@ status_t nm_acc_setup_rect_invert() status_t nm_acc_rectangle_invert(uint32 xs,uint32 xe,uint32 ys,uint32 yl) { + /* The engine probably also does not take kindly if we try to let it invert a + * rect with zero width... (see nm_acc_rectangle() routine for explanation.) */ + if (xe == xs) return B_OK; + /* make sure the previous command (if any) is completed */ // does not work yet: // nm_acc_wait_fifo(4); diff --git a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c index 57b52b2678..678bc2475b 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_crtc.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_crtc.c @@ -569,14 +569,17 @@ status_t nm_crtc_cursor_init() { int i; uint32 * fb; - /* cursor bitmap will be stored at the start of the framebuffer */ - uint32 curadd = 0, curreg; + uint32 curadd, curreg; + + /* the cursor is at the end of cardRAM */ + curadd = ((si->ps.memory_size * 1024) - si->ps.curmem_size); /* set cursor bitmap adress on a 1kb boundary, and move the bits around * so they get placed at the correct registerbits */ - //fixme: NM2380 must have an extra bit for > 4Mb??? curreg = (((curadd >> 10) & 0x000f) << 8); curreg |= (((curadd >> 10) & 0x0ff0) >> 4); + /* NM2380 must have an extra bit for > 4Mb: assuming it to be on b12... */ + curreg |= ((curadd >> 10) & 0x1000); if (si->ps.card_type < NM2200) CR1W(CURADDRESS, curreg); @@ -650,8 +653,9 @@ status_t nm_crtc_cursor_define(uint8* andMask,uint8* xorMask) uint8 y; uint8 * cursor; - /*get a pointer to the cursor*/ + /* get a pointer to the cursor: it's at the end of cardRAM */ cursor = (uint8*) si->framebuffer; + cursor += ((si->ps.memory_size * 1024) - si->ps.curmem_size); /*draw the cursor*/ for(y=0;y<16;y++) diff --git a/src/add-ons/accelerants/neomagic/engine/nm_general.c b/src/add-ons/accelerants/neomagic/engine/nm_general.c index e71fcf63be..0d0bf40173 100644 --- a/src/add-ons/accelerants/neomagic/engine/nm_general.c +++ b/src/add-ons/accelerants/neomagic/engine/nm_general.c @@ -47,7 +47,7 @@ status_t nm_general_powerup() { status_t status; - LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.06-3 running.\n")); + LOG(1,("POWERUP: Neomagic (open)BeOS Accelerant 0.06-4 running.\n")); /* detect card type and power it up */ switch(CFGR(DEVID))