From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/savage/savage3d.c | 561 +++++++++++++++++++++++++++ 1 file changed, 561 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/savage/savage3d.c (limited to 'Source/DirectFB/gfxdrivers/savage/savage3d.c') diff --git a/Source/DirectFB/gfxdrivers/savage/savage3d.c b/Source/DirectFB/gfxdrivers/savage/savage3d.c new file mode 100755 index 0000000..4117b0e --- /dev/null +++ b/Source/DirectFB/gfxdrivers/savage/savage3d.c @@ -0,0 +1,561 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include "savage.h" +#include "savage_bci.h" +#include "savage3d.h" +#include "mmio.h" +#include "savage_streams_old.h" + + + +/* required implementations */ + +static DFBResult savage3DEngineSync( void *drv, void *dev ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + savage3D_waitidle( sdrv, sdev ); + + return DFB_OK; +} + +#define SAVAGE3D_DRAWING_FLAGS \ + (DSDRAW_NOFX) + +#define SAVAGE3D_DRAWING_FUNCTIONS \ + (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | DFXL_DRAWLINE) + +#define SAVAGE3D_BLITTING_FLAGS \ + (DSBLIT_SRC_COLORKEY) + +#define SAVAGE3D_BLITTING_FUNCTIONS \ + (DFXL_BLIT) + + +static inline void savage3D_validate_gbd( Savage3DDriverData *sdrv, + Savage3DDeviceData *sdev, + CardState *state ) +{ + u32 BitmapDescriptor; + CoreSurface *destination; + int bpp; + + + if (sdev->v_gbd) + return; + + destination = state->destination; + bpp = DFB_BYTES_PER_PIXEL(destination->config.format); + + BitmapDescriptor = BCI_BD_BW_DISABLE | 8 | 1; + BCI_BD_SET_BPP( BitmapDescriptor, bpp * 8 ); + BCI_BD_SET_STRIDE( BitmapDescriptor, state->dst.pitch / bpp ); + + /* strange effects if we don't wait here for the Savage3D being idle */ + savage3D_waitidle( sdrv, sdev ); + + savage3D_waitfifo( sdrv, sdev, 4 ); + + BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD1 ); + BCI_SEND( state->dst.offset ); + + BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD2 ); + BCI_SEND( BitmapDescriptor ); + + sdev->v_gbd = 1; +} + +static inline void savage3D_validate_pbd( Savage3DDriverData *sdrv, + Savage3DDeviceData *sdev, + CardState *state ) +{ + u32 BitmapDescriptor; + CoreSurface *source; + int bpp; + + + if (sdev->v_pbd) + return; + + source = state->source; + bpp = DFB_BYTES_PER_PIXEL(source->config.format); + + BitmapDescriptor = BCI_BD_BW_DISABLE; + BCI_BD_SET_BPP( BitmapDescriptor, bpp * 8 ); + BCI_BD_SET_STRIDE( BitmapDescriptor, state->src.pitch / bpp ); + + + savage3D_waitfifo( sdrv, sdev, 4 ); + + BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_PBD1 ); + BCI_SEND( state->src.offset ); + + BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_PBD2 ); + BCI_SEND( BitmapDescriptor ); + + sdev->v_pbd = 1; +} + +static inline void savage3D_validate_color( Savage3DDriverData *sdrv, + Savage3DDeviceData *sdev, + CardState *state ) +{ + if (sdev->v_color) + return; + + savage3D_waitfifo( sdrv, sdev, 2 ); + + BCI_SEND( BCI_CMD_NOP | BCI_CMD_SEND_COLOR ); + + switch (state->destination->config.format) { + case DSPF_A8: + BCI_SEND( state->color.a ); + break; + case DSPF_ARGB1555: + BCI_SEND( PIXEL_ARGB1555(state->color.a, + state->color.r, + state->color.g, + state->color.b) ); + break; + case DSPF_RGB16: + BCI_SEND( PIXEL_RGB16(state->color.r, + state->color.g, + state->color.b) ); + break; + case DSPF_RGB32: + BCI_SEND( PIXEL_RGB32(state->color.r, + state->color.g, + state->color.b) ); + break; + case DSPF_ARGB: + BCI_SEND( PIXEL_ARGB(state->color.a, + state->color.r, + state->color.g, + state->color.b) ); + break; + default: + D_ONCE( "unsupported destination format" ); + break; + } + + sdev->v_color = 1; +} + +static inline void savage3D_set_clip( Savage3DDriverData *sdrv, + Savage3DDeviceData *sdev, + DFBRegion *clip ) +{ + savage3D_waitfifo( sdrv, sdev, 3 ); + + BCI_SEND( BCI_CMD_NOP | BCI_CMD_CLIP_NEW ); + + BCI_SEND( BCI_CLIP_TL( clip->y1, clip->x1 ) ); + BCI_SEND( BCI_CLIP_BR( clip->y2, clip->x2 ) ); +} + +static void savage3DCheckState( void *drv, void *dev, + CardState *state, DFBAccelerationMask accel ) +{ + switch (state->destination->config.format) { + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + break; + default: + return; + } + + if (DFB_DRAWING_FUNCTION( accel )) { + if (state->drawingflags & ~SAVAGE3D_DRAWING_FLAGS) + return; + + state->accel |= SAVAGE3D_DRAWING_FUNCTIONS; + } + else { + if (state->source->config.format != state->destination->config.format) + return; + + if (state->blittingflags & ~SAVAGE3D_BLITTING_FLAGS) + return; + + state->accel |= SAVAGE3D_BLITTING_FUNCTIONS; + } +} + + +static void savage3DSetState( void *drv, void *dev, + GraphicsDeviceFuncs *funcs, + CardState *state, DFBAccelerationMask accel ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + if (state->mod_hw) { + if (state->mod_hw & SMF_DESTINATION) + sdev->v_gbd = sdev->v_color = 0; + else if (state->mod_hw & SMF_COLOR) + sdev->v_color = 0; + + if (state->mod_hw & SMF_SOURCE) + sdev->v_pbd = 0; + } + + savage3D_validate_gbd( sdrv, sdev, state ); + + switch (accel) { + case DFXL_FILLRECTANGLE: + case DFXL_DRAWRECTANGLE: + case DFXL_DRAWLINE: + case DFXL_FILLTRIANGLE: + savage3D_validate_color( sdrv, sdev, state ); + + state->set |= SAVAGE3D_DRAWING_FUNCTIONS; + break; + + case DFXL_BLIT: + case DFXL_STRETCHBLIT: + savage3D_validate_pbd( sdrv, sdev, state ); + + state->set |= SAVAGE3D_BLITTING_FUNCTIONS; + break; + + default: + D_BUG( "unexpected drawing/blitting function!" ); + return; + } + + if (state->mod_hw & SMF_BLITTING_FLAGS) { + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + sdev->Cmd_Src_Transparent = BCI_CMD_SRC_TRANSPARENT | + BCI_CMD_SEND_COLOR; + else + sdev->Cmd_Src_Transparent = 0; + } + + if (state->mod_hw & SMF_CLIP) + savage3D_set_clip( sdrv, sdev, &state->clip ); + + if (state->mod_hw & SMF_SRC_COLORKEY) + sdev->src_colorkey = state->src_colorkey; + + state->mod_hw = 0; +} + +static bool savage3DFillRectangle( void *drv, void *dev, DFBRectangle *rect ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + savage3D_waitfifo( sdrv, sdev, 3 ); + + BCI_SEND( BCI_CMD_RECT | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_X_Y(rect->x, rect->y) ); + BCI_SEND( BCI_W_H(rect->w, rect->h) ); + + return true; +} + +static bool savage3DDrawRectangle( void *drv, void *dev, DFBRectangle *rect ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + savage3D_waitfifo( sdrv, sdev, 12 ); + + /* first line */ + BCI_SEND( BCI_CMD_RECT | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_X_Y( rect->x, rect->y) ); + BCI_SEND( BCI_W_H( 1 , rect->h) ); + + /* second line */ + BCI_SEND( BCI_CMD_RECT | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_X_Y( rect->x, rect->y) ); + BCI_SEND( BCI_W_H( rect->w , 1 ) ); + + /* third line */ + BCI_SEND( BCI_CMD_RECT | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_X_Y( rect->x, rect->y+rect->h-1 ) ); + BCI_SEND( BCI_W_H( rect->w , 1 ) ); + + /* fourth line */ + BCI_SEND( BCI_CMD_RECT | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_X_Y( rect->x+rect->w-1, rect->y ) ); + BCI_SEND( BCI_W_H( 1 , rect->h ) ); + + return true; +} + +static bool savage3DDrawLine( void *drv, void *dev, DFBRegion *line ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + int dx, dy; + int min, max, xp, yp, ym; + + + dx = line->x2 - line->x1; + dy = line->y2 - line->y1; + + xp = (dx >= 0); + if (!xp) + dx = -dx; + + yp = (dy >= 0); + if (!yp) + dy = -dy; + + ym = (dy > dx); + if (ym) { + max = dy + 1; + min = dx; + } + else { + max = dx + 1; + min = dy; + } + + savage3D_waitfifo( sdrv, sdev, 4 ); + + BCI_SEND( BCI_CMD_LINE_LAST_PIXEL | BCI_CMD_CLIP_CURRENT | + BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | + BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID | (0xcc << 16) ); + + BCI_SEND( BCI_LINE_X_Y( line->x1, line->y1 ) ); + BCI_SEND( BCI_LINE_STEPS( 2 * (min - max), 2 * min ) ); + BCI_SEND( BCI_LINE_MISC( max, ym, xp, yp, 2 * min - max ) ); + + return true; +} + +static bool savage3DFillTriangle( void *drv, void *dev, DFBTriangle *tri ) +{ + return false; +} + +static bool savage3DBlit( void *drv, void *dev, + DFBRectangle *rect, int dx, int dy ) +{ + Savage3DDriverData *sdrv = (Savage3DDriverData*) drv; + Savage3DDeviceData *sdev = (Savage3DDeviceData*) dev; + + u32 cmd = ( BCI_CMD_RECT | sdev->Cmd_Src_Transparent | + BCI_CMD_CLIP_CURRENT | BCI_CMD_DEST_GBD | + BCI_CMD_SRC_PBD_COLOR | (0xcc << 16) ); + + if (dx < rect->x) { + cmd |= BCI_CMD_RECT_XP; + } + else { + dx += rect->w - 1; + rect->x += rect->w - 1; + } + + if (dy < rect->y) { + cmd |= BCI_CMD_RECT_YP; + } + else { + dy += rect->h - 1; + rect->y += rect->h - 1; + } + + savage3D_waitfifo( sdrv, sdev, sdev->Cmd_Src_Transparent ? 5 : 4 ); + + BCI_SEND( cmd ); + + /* we always have to send the colorkey, + but at least it does not clobber the fill color */ + if (sdev->Cmd_Src_Transparent) + BCI_SEND( sdev->src_colorkey ); + + BCI_SEND( BCI_X_Y( rect->x, rect->y ) ); + BCI_SEND( BCI_X_Y( dx, dy ) ); + BCI_SEND( BCI_W_H( rect->w, rect->h ) ); + + return true; +} + +static bool savage3DStretchBlit( void *drv, void *dev, + DFBRectangle *sr, DFBRectangle *dr ) +{ + return false; +} + +static void savage3DAfterSetVar( void *drv, void *dev ) +{ +} + +/* exported symbols */ + +void +savage3d_get_info( CoreGraphicsDevice *device, + GraphicsDriverInfo *info ) +{ + info->version.major = 0; + info->version.minor = 3; + + info->driver_data_size = sizeof (Savage3DDriverData); + info->device_data_size = sizeof (Savage3DDeviceData); +} + +DFBResult +savage3d_init_driver( CoreGraphicsDevice *device, + GraphicsDeviceFuncs *funcs, + void *driver_data ) +{ + funcs->CheckState = savage3DCheckState; + funcs->SetState = savage3DSetState; + funcs->EngineSync = savage3DEngineSync; + funcs->AfterSetVar = savage3DAfterSetVar; + + funcs->FillRectangle = savage3DFillRectangle; + funcs->DrawRectangle = savage3DDrawRectangle; + funcs->DrawLine = savage3DDrawLine; + funcs->FillTriangle = savage3DFillTriangle; + funcs->Blit = savage3DBlit; + funcs->StretchBlit = savage3DStretchBlit; + + return DFB_OK; +} + +DFBResult +savage3d_init_device( CoreGraphicsDevice *device, + GraphicsDeviceInfo *device_info, + void *driver_data, + void *device_data ) +{ + SavageDriverData *sdrv = (SavageDriverData*) driver_data; + volatile u8 *mmio = sdrv->mmio_base; + + unsigned long cobIndex; /* size index */ + unsigned long cobSize; /* size in bytes */ + unsigned long cobOffset; /* offset in frame buffer */ + + /* fill device info */ + snprintf( device_info->name, + DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Savage3D Series" ); + + snprintf( device_info->vendor, + DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "S3" ); + + + device_info->caps.flags = CCF_CLIPPING; + device_info->caps.accel = SAVAGE3D_DRAWING_FUNCTIONS | + SAVAGE3D_BLITTING_FUNCTIONS; + device_info->caps.drawing = SAVAGE3D_DRAWING_FLAGS; + device_info->caps.blitting = SAVAGE3D_BLITTING_FLAGS; + + device_info->limits.surface_byteoffset_alignment = 2048; + device_info->limits.surface_pixelpitch_alignment = 32; + + + cobIndex = 7; + cobSize = 0x400 << cobIndex; + cobOffset = dfb_gfxcard_reserve_memory( device, cobSize ); + + + /* savage_out32( 0x8504, 0x00008000 ); */ + + /* Disable BCI */ + savage_out32( mmio, 0x48C18, + savage_in32( mmio, 0x48C18 ) & 0x3FF0); + + /* Setup BCI command overflow buffer */ + savage_out32( mmio, 0x48C14, (cobOffset >> 11) | (cobIndex << 29)); + + /* Program shadow status update. */ + savage_out32( mmio, 0x48C10, 0x78207220); + savage_out32( mmio, 0x48C0C, 0); + + /* Enable BCI and command overflow buffer */ + savage_out32( mmio, 0x48C18, savage_in32( mmio, 0x48C18 ) | 0x0C); + + return DFB_OK; +} + +void +savage3d_close_device( CoreGraphicsDevice *device, + void *driver_data, + void *device_data ) +{ +} + +void +savage3d_close_driver( CoreGraphicsDevice *device, + void *driver_data ) +{ +} + -- cgit