summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/mach64/mach64_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/mach64/mach64_state.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/mach64/mach64_state.c654
1 files changed, 654 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/mach64/mach64_state.c b/Source/DirectFB/gfxdrivers/mach64/mach64_state.c
new file mode 100755
index 0000000..8e798cc
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/mach64/mach64_state.c
@@ -0,0 +1,654 @@
+/*
+ (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 <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ 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 <config.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+
+#include <gfx/convert.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "mach64.h"
+
+#include "mach64_state.h"
+
+
+void mach64_set_destination( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *destination = state->destination;
+ unsigned int pitch = state->dst.pitch / DFB_BYTES_PER_PIXEL( destination->config.format );
+
+ mdev->pix_width &= ~DST_PIX_WIDTH;
+ switch (destination->config.format) {
+ case DSPF_RGB332:
+ mdev->pix_width |= DST_PIX_WIDTH_8BPP;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mdev->pix_width |= DST_PIX_WIDTH_15BPP;
+ break;
+ case DSPF_RGB16:
+ mdev->pix_width |= DST_PIX_WIDTH_16BPP;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mdev->pix_width |= DST_PIX_WIDTH_32BPP;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, DST_OFF_PITCH, (state->dst.offset/8) | ((pitch/8) << 22) );
+}
+
+void mach64gt_set_destination( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *destination = state->destination;
+ unsigned int pitch = state->dst.pitch / DFB_BYTES_PER_PIXEL( destination->config.format );
+
+ mdev->pix_width &= ~DST_PIX_WIDTH;
+ switch (destination->config.format) {
+ case DSPF_RGB332:
+ mdev->pix_width |= DST_PIX_WIDTH_RGB332;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mdev->pix_width |= DST_PIX_WIDTH_ARGB1555;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ mdev->pix_width |= DST_PIX_WIDTH_ARGB4444;
+ break;
+ case DSPF_RGB16:
+ mdev->pix_width |= DST_PIX_WIDTH_RGB565;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mdev->pix_width |= DST_PIX_WIDTH_ARGB8888;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mdev->draw_blend &= ~DITHER_EN;
+ mdev->blit_blend &= ~DITHER_EN;
+ if (DFB_COLOR_BITS_PER_PIXEL( destination->config.format ) < 24) {
+ mdev->draw_blend |= DITHER_EN;
+ mdev->blit_blend |= DITHER_EN;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, DST_OFF_PITCH, (state->dst.offset/8) | ((pitch/8) << 22) );
+}
+
+void mach64_set_source( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *source = state->source;
+ unsigned int pitch = state->src.pitch / DFB_BYTES_PER_PIXEL( source->config.format );
+
+ if (MACH64_IS_VALID( m_source ))
+ return;
+
+ mdev->pix_width &= ~SRC_PIX_WIDTH;
+ switch (source->config.format) {
+ case DSPF_RGB332:
+ mdev->pix_width |= SRC_PIX_WIDTH_8BPP;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mdev->pix_width |= SRC_PIX_WIDTH_15BPP;
+ break;
+ case DSPF_RGB16:
+ mdev->pix_width |= SRC_PIX_WIDTH_16BPP;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mdev->pix_width |= SRC_PIX_WIDTH_32BPP;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, SRC_OFF_PITCH, (state->src.offset/8) | ((pitch/8) << 22) );
+
+ MACH64_VALIDATE( m_source );
+}
+
+void mach64gt_set_source( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *source = state->source;
+ unsigned int pitch = state->src.pitch / DFB_BYTES_PER_PIXEL( source->config.format );
+
+ if (MACH64_IS_VALID( m_source ))
+ return;
+
+ mdev->pix_width &= ~SRC_PIX_WIDTH;
+ switch (source->config.format) {
+ case DSPF_RGB332:
+ mdev->pix_width |= SRC_PIX_WIDTH_RGB332;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mdev->pix_width |= SRC_PIX_WIDTH_ARGB1555;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ mdev->pix_width |= SRC_PIX_WIDTH_ARGB4444;
+ break;
+ case DSPF_RGB16:
+ mdev->pix_width |= SRC_PIX_WIDTH_RGB565;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mdev->pix_width |= SRC_PIX_WIDTH_ARGB8888;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, SRC_OFF_PITCH, (state->src.offset/8) | ((pitch/8) << 22) );
+
+ MACH64_VALIDATE( m_source );
+}
+
+void mach64gt_set_source_scale( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *source = state->source;
+ unsigned int offset = state->src.offset;
+ unsigned int pitch = state->src.pitch;
+ int height = source->config.size.h;
+
+ if (MACH64_IS_VALID( m_source_scale ))
+ return;
+
+ mdev->pix_width &= ~SCALE_PIX_WIDTH;
+ switch (source->config.format) {
+ case DSPF_RGB332:
+ mdev->pix_width |= SCALE_PIX_WIDTH_RGB332;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mdev->pix_width |= SCALE_PIX_WIDTH_ARGB1555;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ mdev->pix_width |= SCALE_PIX_WIDTH_ARGB4444;
+ break;
+ case DSPF_RGB16:
+ mdev->pix_width |= SCALE_PIX_WIDTH_RGB565;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mdev->pix_width |= SCALE_PIX_WIDTH_ARGB8888;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mdev->blit_blend &= ~SCALE_PIX_EXPAND;
+ if (DFB_COLOR_BITS_PER_PIXEL( source->config.format ) < 24)
+ mdev->blit_blend |= SCALE_PIX_EXPAND;
+
+ mdev->field = source->field;
+ if (mdev->blit_deinterlace) {
+ if (mdev->field) {
+ if (source->config.caps & DSCAPS_SEPARATED) {
+ offset += height/2 * pitch;
+ } else {
+ offset += pitch;
+ pitch *= 2;
+ }
+ }
+ height /= 2;
+ }
+
+ mdev->source = source;
+
+ mdev->scale_offset = offset;
+ mdev->scale_pitch = pitch;
+
+ mdev->tex_offset = offset;
+ mdev->tex_pitch = direct_log2( pitch / DFB_BYTES_PER_PIXEL( source->config.format ) );
+ mdev->tex_height = direct_log2( height );
+ mdev->tex_size = MAX( mdev->tex_pitch, mdev->tex_height );
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, TEX_SIZE_PITCH, (mdev->tex_pitch << 0) |
+ (mdev->tex_size << 4) |
+ (mdev->tex_height << 8) );
+
+ if (mdev->chip >= CHIP_3D_RAGE_PRO) {
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, TEX_CNTL, TEX_CACHE_FLUSH );
+ }
+
+ MACH64_VALIDATE( m_source_scale );
+}
+
+void mach64_set_clip( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mach64_waitfifo( mdrv, mdev, 2 );
+ mach64_out32( mmio, SC_LEFT_RIGHT, (S13( state->clip.x2 ) << 16) | S13( state->clip.x1 ) );
+ mach64_out32( mmio, SC_TOP_BOTTOM, (S14( state->clip.y2 ) << 16) | S14( state->clip.y1 ) );
+}
+
+void mach64_set_color( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ DFBColor color = state->color;
+ u32 clr;
+
+ if (MACH64_IS_VALID( m_color ))
+ return;
+
+ if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ }
+
+ switch (state->destination->config.format) {
+ case DSPF_RGB332:
+ clr = PIXEL_RGB332( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_RGB555:
+ clr = PIXEL_RGB555( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_ARGB1555:
+ clr = PIXEL_ARGB1555( color.a,
+ color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_RGB444:
+ clr = PIXEL_RGB444( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_ARGB4444:
+ clr = PIXEL_ARGB4444( color.a,
+ color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_RGB16:
+ clr = PIXEL_RGB16( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_RGB32:
+ clr = PIXEL_RGB32( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_ARGB:
+ clr = PIXEL_ARGB( color.a,
+ color.r,
+ color.g,
+ color.b );
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, DP_FRGD_CLR, clr );
+
+ MACH64_VALIDATE( m_color );
+}
+
+void mach64_set_color_3d( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ DFBColor color = state->color;
+
+ if (MACH64_IS_VALID( m_color_3d ))
+ return;
+
+ if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ }
+
+ /* Some 3D color registers scaler registers are shared. */
+ mach64_waitfifo( mdrv, mdev, 7 );
+ mach64_out32( mmio, RED_X_INC, 0 );
+ mach64_out32( mmio, RED_START, color.r << 16 );
+ mach64_out32( mmio, GREEN_X_INC, 0 );
+ mach64_out32( mmio, GREEN_START, color.g << 16 );
+ mach64_out32( mmio, BLUE_X_INC, 0 );
+ mach64_out32( mmio, BLUE_START, color.b << 16 );
+ mach64_out32( mmio, ALPHA_START, color.a << 16 );
+
+ MACH64_INVALIDATE( m_color_tex | m_blit_blend );
+ MACH64_VALIDATE( m_color_3d );
+}
+
+void mach64_set_color_tex( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ DFBColor color = state->color;
+
+ if (MACH64_IS_VALID( m_color_tex ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ if (state->blittingflags & DSBLIT_COLORIZE) {
+ color.r = (color.r * (color.a + 1)) >> 8;
+ color.g = (color.g * (color.a + 1)) >> 8;
+ color.b = (color.b * (color.a + 1)) >> 8;
+ } else {
+ color.r = color.g = color.b = color.a;
+ }
+ }
+
+ /* Some 3D color registers scaler registers are shared. */
+ mach64_waitfifo( mdrv, mdev, 7 );
+ mach64_out32( mmio, RED_X_INC, 0 );
+ mach64_out32( mmio, RED_START, color.r << 16 );
+ mach64_out32( mmio, GREEN_X_INC, 0 );
+ mach64_out32( mmio, GREEN_START, color.g << 16 );
+ mach64_out32( mmio, BLUE_X_INC, 0 );
+ mach64_out32( mmio, BLUE_START, color.b << 16 );
+ mach64_out32( mmio, ALPHA_START, color.a << 16 );
+
+ MACH64_INVALIDATE( m_color_3d | m_blit_blend );
+ MACH64_VALIDATE( m_color_tex );
+}
+
+void mach64_set_src_colorkey( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MACH64_IS_VALID( m_srckey ))
+ return;
+
+ mach64_waitfifo( mdrv, mdev, 3 );
+ mach64_out32( mmio, CLR_CMP_MSK,
+ (1 << DFB_COLOR_BITS_PER_PIXEL( state->source->config.format )) - 1 );
+ mach64_out32( mmio, CLR_CMP_CLR, state->src_colorkey );
+ mach64_out32( mmio, CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_2D );
+
+ MACH64_VALIDATE( m_srckey );
+ MACH64_INVALIDATE( m_srckey_scale | m_dstkey | m_disable_key );
+}
+
+void mach64_set_src_colorkey_scale( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ u32 clr, msk;
+
+ if (MACH64_IS_VALID( m_srckey_scale ))
+ return;
+
+ if (mdev->chip < CHIP_3D_RAGE_PRO) {
+ switch (state->source->config.format) {
+ case DSPF_RGB332:
+ clr = ((state->src_colorkey & 0xE0) << 16) |
+ ((state->src_colorkey & 0x1C) << 11) |
+ ((state->src_colorkey & 0x03) << 6);
+ msk = 0xE0E0C0;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ clr = ((state->src_colorkey & 0x0F00) << 12) |
+ ((state->src_colorkey & 0x00F0) << 8) |
+ ((state->src_colorkey & 0x000F) << 4);
+ msk = 0xF0F0F0;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ clr = ((state->src_colorkey & 0x7C00) << 9) |
+ ((state->src_colorkey & 0x03E0) << 6) |
+ ((state->src_colorkey & 0x001F) << 3);
+ msk = 0xF8F8F8;
+ break;
+ case DSPF_RGB16:
+ clr = ((state->src_colorkey & 0xF800) << 8) |
+ ((state->src_colorkey & 0x07E0) << 5) |
+ ((state->src_colorkey & 0x001F) << 3);
+ msk = 0xF8FCF8;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ clr = state->src_colorkey;
+ msk = 0xFFFFFF;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+ } else {
+ clr = state->src_colorkey;
+ msk = (1 << DFB_COLOR_BITS_PER_PIXEL( state->source->config.format )) - 1;
+ }
+
+ mach64_waitfifo( mdrv, mdev, 3 );
+ mach64_out32( mmio, CLR_CMP_MSK, msk );
+ mach64_out32( mmio, CLR_CMP_CLR, clr );
+ mach64_out32( mmio, CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_SCALE );
+
+ MACH64_VALIDATE( m_srckey_scale );
+ MACH64_INVALIDATE( m_srckey | m_dstkey | m_disable_key );
+}
+
+void mach64_set_dst_colorkey( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MACH64_IS_VALID( m_dstkey ))
+ return;
+
+ mach64_waitfifo( mdrv, mdev, 3 );
+ mach64_out32( mmio, CLR_CMP_MSK,
+ (1 << DFB_COLOR_BITS_PER_PIXEL( state->destination->config.format )) - 1 );
+ mach64_out32( mmio, CLR_CMP_CLR, state->dst_colorkey );
+ mach64_out32( mmio, CLR_CMP_CNTL, CLR_CMP_FN_NOT_EQUAL | CLR_CMP_SRC_DEST );
+
+ MACH64_VALIDATE( m_dstkey );
+ MACH64_INVALIDATE( m_srckey | m_srckey_scale | m_disable_key );
+}
+
+void mach64_disable_colorkey( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MACH64_IS_VALID( m_disable_key ))
+ return;
+
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, CLR_CMP_CNTL, CLR_CMP_FN_FALSE );
+
+ MACH64_VALIDATE( m_disable_key );
+ MACH64_INVALIDATE( m_srckey | m_srckey_scale | m_dstkey );
+}
+
+static u32 mach64SourceBlend[] = {
+ ALPHA_BLND_SRC_ZERO,
+ ALPHA_BLND_SRC_ONE,
+ 0,
+ 0,
+ ALPHA_BLND_SRC_SRCALPHA,
+ ALPHA_BLND_SRC_INVSRCALPHA,
+ ALPHA_BLND_SRC_DSTALPHA,
+ ALPHA_BLND_SRC_INVDSTALPHA,
+ ALPHA_BLND_SRC_DSTCOLOR,
+ ALPHA_BLND_SRC_INVDSTCOLOR,
+ ALPHA_BLND_SAT
+};
+
+static u32 mach64DestBlend[] = {
+ ALPHA_BLND_DST_ZERO,
+ ALPHA_BLND_DST_ONE,
+ ALPHA_BLND_DST_SRCCOLOR,
+ ALPHA_BLND_DST_INVSRCCOLOR,
+ ALPHA_BLND_DST_SRCALPHA,
+ ALPHA_BLND_DST_INVSRCALPHA,
+ ALPHA_BLND_DST_DSTALPHA,
+ ALPHA_BLND_DST_INVDSTALPHA,
+ 0,
+ 0,
+ 0
+};
+
+void mach64_set_draw_blend( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MACH64_IS_VALID( m_draw_blend ))
+ return;
+
+ mdev->draw_blend &= DITHER_EN;
+ mdev->draw_blend |= ALPHA_FOG_EN_ALPHA |
+ mach64SourceBlend[state->src_blend - 1] |
+ mach64DestBlend [state->dst_blend - 1];
+
+ if (mdev->chip >= CHIP_3D_RAGE_PRO) {
+ /* FIXME: This is wrong. */
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, ALPHA_TST_CNTL, ALPHA_DST_SEL_DSTALPHA );
+ }
+
+ MACH64_VALIDATE( m_draw_blend );
+}
+
+void mach64_set_blit_blend( Mach64DriverData *mdrv,
+ Mach64DeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MACH64_IS_VALID( m_blit_blend ))
+ return;
+
+ mdev->blit_blend &= SCALE_PIX_EXPAND | DITHER_EN;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Disable dithering because it is applied even when
+ * the source pixels are completely transparent.
+ */
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->source->config.format ))
+ mdev->blit_blend &= ~DITHER_EN;
+
+ mdev->blit_blend |= ALPHA_FOG_EN_ALPHA |
+ mach64SourceBlend[state->src_blend - 1] |
+ mach64DestBlend [state->dst_blend - 1];
+
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->source->config.format )) {
+ mdev->blit_blend |= TEX_MAP_AEN;
+ } else {
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, ALPHA_START, 0xFF << 16 );
+ MACH64_INVALIDATE( m_color_3d | m_color_tex );
+ }
+ }
+
+ if (mdev->chip >= CHIP_3D_RAGE_PRO) {
+ /* FIXME: This is wrong. */
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, ALPHA_TST_CNTL, ALPHA_DST_SEL_DSTALPHA );
+ }
+ } else {
+ /* This needs to be set even without alpha blending.
+ * Otherwise alpha channel won't get copied.
+ */
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->source->config.format ))
+ mdev->blit_blend |= TEX_MAP_AEN;
+
+ if (mdev->chip >= CHIP_3D_RAGE_PRO) {
+ /* FIXME: This is wrong. */
+ mach64_waitfifo( mdrv, mdev, 1 );
+ mach64_out32( mmio, ALPHA_TST_CNTL, ALPHA_DST_SEL_SRCALPHA );
+ }
+ }
+
+ if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR))
+ mdev->blit_blend |= TEX_LIGHT_FCN_MODULATE;
+
+ MACH64_VALIDATE( m_blit_blend );
+}