Mercurial > sdl-ios-xcode
diff src/video/fbcon/SDL_fbriva.c @ 133:5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Still missing colorkey and alpha blit support
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 31 Jul 2001 20:08:51 +0000 |
parents | |
children | f1550e1c4916 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/fbcon/SDL_fbriva.c Tue Jul 31 20:08:51 2001 +0000 @@ -0,0 +1,230 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_blit.h" +#include "SDL_fbriva.h" +#include "riva_mmio.h" +#include "riva_regs.h" + +#define PGRAPH_OFFSET 0x00400000 +#define FIFO_OFFSET 0x00800000 +#define ROP_OFFSET FIFO_OFFSET+0x00000000 +#define CLIP_OFFSET FIFO_OFFSET+0x00002000 +#define PATT_OFFSET FIFO_OFFSET+0x00004000 +#define PIXMAP_OFFSET FIFO_OFFSET+0x00006000 +#define BLT_OFFSET FIFO_OFFSET+0x00008000 +#define BITMAP_OFFSET FIFO_OFFSET+0x0000A000 +#define LINE_OFFSET FIFO_OFFSET+0x0000C000 +#define TRI03_OFFSET FIFO_OFFSET+0x0000E000 +#define PCIO_OFFSET 0x00601000 + +static int FifoEmptyCount = 0; +static int FifoFreeCount = 0; + +/* Wait for vertical retrace */ +static void WaitVBL(_THIS) +{ + volatile Uint8 *port = (Uint8 *)(mapped_io + PCIO_OFFSET + 0x3DA); + + while ( (*port & 0x08) ) + ; + while ( !(*port & 0x08) ) + ; +} +static void NV3WaitIdle(_THIS) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + while ( (Rop->FifoFree < FifoEmptyCount) || + (*(mapped_io + PGRAPH_OFFSET + 0x000006B0) & 0x01) ) + ; +} +static void NV4WaitIdle(_THIS) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + while ( (Rop->FifoFree < FifoEmptyCount) || + (*(mapped_io + PGRAPH_OFFSET + 0x00000700) & 0x01) ) + ; +} + +/* Sets video mem colorkey and accelerated blit function */ +static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) +{ + return(0); +} + +/* Sets per surface hardware alpha value */ +static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value) +{ + return(0); +} + +static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color) +{ + int dstX, dstY; + int dstW, dstH; + RivaBitmap *Bitmap = (RivaBitmap *)(mapped_io + BITMAP_OFFSET); + + /* Don't blit to the display surface when switched away */ + if ( dst == this->screen ) { + SDL_mutexP(hw_lock); + } + + /* Set up the X/Y base coordinates */ + dstW = rect->w; + dstH = rect->h; + FB_dst_to_xy(this, dst, &dstX, &dstY); + + /* Adjust for the current rectangle */ + dstX += rect->x; + dstY += rect->y; + + RIVA_FIFO_FREE(Bitmap, 1); + Bitmap->Color1A = color; + + RIVA_FIFO_FREE(Bitmap, 2); + Bitmap->UnclippedRectangle[0].TopLeft = (dstX << 16) | dstY; + Bitmap->UnclippedRectangle[0].WidthHeight = (dstW << 16) | dstH; + + FB_AddBusySurface(dst); + + if ( dst == this->screen ) { + SDL_mutexV(hw_lock); + } + return(0); +} + +static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_VideoDevice *this = current_video; + int srcX, srcY; + int dstX, dstY; + int dstW, dstH; + RivaScreenBlt *Blt = (RivaScreenBlt *)(mapped_io + BLT_OFFSET); + + /* FIXME: For now, only blit to display surface */ + if ( dst->pitch != SDL_VideoSurface->pitch ) { + return(src->map->sw_blit(src, srcrect, dst, dstrect)); + } + + /* Don't blit to the display surface when switched away */ + if ( dst == this->screen ) { + SDL_mutexP(hw_lock); + } + + /* Calculate source and destination base coordinates (in pixels) */ + dstW = dstrect->w; + dstH = dstrect->h; + FB_dst_to_xy(this, src, &srcX, &srcY); + FB_dst_to_xy(this, dst, &dstX, &dstY); + + /* Adjust for the current blit rectangles */ + srcX += srcrect->x; + srcY += srcrect->y; + dstX += dstrect->x; + dstY += dstrect->y; + + RIVA_FIFO_FREE(Blt, 3); + Blt->TopLeftSrc = (srcY << 16) | srcX; + Blt->TopLeftDst = (dstY << 16) | dstX; + Blt->WidthHeight = (dstH << 16) | dstW; + + FB_AddBusySurface(src); + FB_AddBusySurface(dst); + + if ( dst == this->screen ) { + SDL_mutexV(hw_lock); + } + return(0); +} + +static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst) +{ + int accelerated; + + /* Set initial acceleration on */ + src->flags |= SDL_HWACCEL; + + /* Set the surface attributes */ + if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + if ( ! this->info.blit_hw_A ) { + src->flags &= ~SDL_HWACCEL; + } + } + if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + if ( ! this->info.blit_hw_CC ) { + src->flags &= ~SDL_HWACCEL; + } + } + + /* Check to see if final surface blit is accelerated */ + accelerated = !!(src->flags & SDL_HWACCEL); + if ( accelerated ) { + src->map->hw_blit = HWAccelBlit; + } + return(accelerated); +} + +void FB_RivaAccel(_THIS, __u32 card) +{ + RivaRop *Rop = (RivaRop *)(mapped_io + ROP_OFFSET); + + /* We have hardware accelerated surface functions */ + this->CheckHWBlit = CheckHWBlit; + wait_vbl = WaitVBL; + switch (card) { + case FB_ACCEL_NV3: + wait_idle = NV3WaitIdle; + break; + case FB_ACCEL_NV4: + wait_idle = NV4WaitIdle; + break; + default: + /* Hmm... FIXME */ + break; + } + FifoEmptyCount = Rop->FifoFree; + + /* The Riva has an accelerated color fill */ + this->info.blit_fill = 1; + this->FillHWRect = FillHWRect; + + /* The Riva has accelerated normal and colorkey blits. */ + this->info.blit_hw = 1; +#if 0 /* Not yet implemented? */ + this->info.blit_hw_CC = 1; + this->SetHWColorKey = SetHWColorKey; +#endif + +#if 0 /* Not yet implemented? */ + /* The Riva has an accelerated alpha blit */ + this->info.blit_hw_A = 1; + this->SetHWAlpha = SetHWAlpha; +#endif +}