summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/matrox/matrox_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/matrox/matrox_state.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/matrox/matrox_state.c810
1 files changed, 810 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_state.c b/Source/DirectFB/gfxdrivers/matrox/matrox_state.c
new file mode 100755
index 0000000..ceeffa5
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/matrox/matrox_state.c
@@ -0,0 +1,810 @@
+/*
+ (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 <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/palette.h>
+
+#include <gfx/convert.h>
+
+#include "regs.h"
+#include "mmio.h"
+#include "matrox.h"
+
+#include "matrox_state.h"
+
+#define MGA_KEYMASK(format) ((1 << DFB_COLOR_BITS_PER_PIXEL(format)) - 1)
+
+static void matrox_calc_offsets( MatroxDeviceData *mdev,
+ CoreSurface *surface,
+ CoreSurfaceBufferLock *lock,
+ bool unit_pixel,
+ int offset[2][3] )
+{
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL( surface->config.format );
+ int pitch;
+
+ if (unit_pixel) {
+ offset[0][0] = lock->offset / bytes_per_pixel;
+ pitch = lock->pitch / bytes_per_pixel;
+ } else {
+ offset[0][0] = mdev->fb.offset + lock->offset;
+ pitch = lock->pitch;
+ }
+
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[0][1] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][2] = 0;
+ break;
+ case DSPF_I420:
+ offset[0][1] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][2] = offset[0][1] + surface->config.size.h/2 * pitch/2;
+ break;
+ case DSPF_YV12:
+ offset[0][2] = offset[0][0] + surface->config.size.h * pitch;
+ offset[0][1] = offset[0][2] + surface->config.size.h/2 * pitch/2;
+ break;
+ default:
+ offset[0][1] = 0;
+ offset[0][2] = 0;
+ }
+
+ D_ASSERT( offset[0][0] % 64 == 0 );
+ D_ASSERT( offset[0][1] % 64 == 0 );
+ D_ASSERT( offset[0][2] % 64 == 0 );
+
+ if (mdev->blit_fields || mdev->blit_deinterlace) {
+ if (surface->config.caps & DSCAPS_SEPARATED) {
+ offset[1][0] = offset[0][0] + surface->config.size.h/2 * pitch;
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[1][1] = offset[0][1] + surface->config.size.h/4 * pitch;
+ offset[1][2] = 0;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ offset[1][1] = offset[0][1] + surface->config.size.h/4 * pitch/2;
+ offset[1][2] = offset[0][2] + surface->config.size.h/4 * pitch/2;
+ break;
+ default:
+ offset[1][1] = 0;
+ offset[1][2] = 0;
+ }
+ } else {
+ offset[1][0] = offset[0][0] + pitch;
+ switch (surface->config.format) {
+ case DSPF_NV12:
+ case DSPF_NV21:
+ offset[1][1] = offset[0][1] + pitch;
+ offset[1][2] = 0;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ offset[1][1] = offset[0][1] + pitch/2;
+ offset[1][2] = offset[0][2] + pitch/2;
+ break;
+ default:
+ offset[1][1] = 0;
+ offset[1][2] = 0;
+ }
+ }
+
+ D_ASSERT( offset[1][0] % 64 == 0 );
+ D_ASSERT( offset[1][1] % 64 == 0 );
+ D_ASSERT( offset[1][2] % 64 == 0 );
+ }
+}
+
+void matrox_validate_destination( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *destination = state->destination;
+ CoreSurfaceBuffer *depth_buffer = NULL;//destination->depth_buffer;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL( destination->config.format );
+
+ if (MGA_IS_VALID( m_destination ))
+ return;
+
+ mdev->dst_pitch = state->dst.pitch / bytes_per_pixel;
+
+ mdev->depth_buffer = depth_buffer != NULL;
+
+ if (destination->config.format == DSPF_YUY2 || destination->config.format == DSPF_UYVY)
+ mdev->dst_pitch /= 2;
+
+ if (mdev->blit_fields && !(destination->config.caps & DSCAPS_SEPARATED))
+ mdev->dst_pitch *= 2;
+
+ D_ASSERT( mdev->dst_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, destination, &state->dst, mdev->old_matrox, mdev->dst_offset );
+
+ mga_waitfifo( mdrv, mdev, depth_buffer ? 4 : 3 );
+
+ mga_out32( mmio, mdev->dst_offset[0][0], mdev->old_matrox ? YDSTORG : DSTORG );
+ mga_out32( mmio, mdev->dst_pitch, PITCH );
+
+#if 0
+ if (depth_buffer)
+ mga_out32( mmio, depth_buffer->video.offset, ZORG );
+#endif
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_ALUT44:
+ case DSPF_LUT8:
+ case DSPF_RGB332:
+ mga_out32( mmio, PW8, MACCESS );
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ mga_out32( mmio, PW16 | DIT555, MACCESS );
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGB16:
+ mga_out32( mmio, PW16, MACCESS );
+ break;
+ case DSPF_RGB24:
+ mga_out32( mmio, PW24, MACCESS );
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ mga_out32( mmio, PW32, MACCESS );
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ mga_out32( mmio, PW8 | BYPASS332 | NODITHER, MACCESS );
+ break;
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ mga_out32( mmio, PW32 | NODITHER, MACCESS );
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ break;
+ }
+
+ MGA_VALIDATE( m_destination );
+}
+
+void matrox_set_clip( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ DFBRegion *clip )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ mga_waitfifo( mdrv, mdev, 3 );
+
+ if (mdev->old_matrox) {
+ mga_out32( mmio, (mdev->dst_offset[0][0] +
+ mdev->dst_pitch * clip->y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_offset[0][0] +
+ mdev->dst_pitch * clip->y2) & 0xFFFFFF, YBOT );
+ }
+ else {
+ mga_out32( mmio, (mdev->dst_pitch * clip->y1) & 0xFFFFFF, YTOP );
+ mga_out32( mmio, (mdev->dst_pitch * clip->y2) & 0xFFFFFF, YBOT );
+ }
+
+ mga_out32( mmio, ((clip->x2 & 0x0FFF) << 16) | (clip->x1 & 0x0FFF), CXBNDRY );
+}
+
+void matrox_validate_drawColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MGA_IS_VALID( m_drawColor ))
+ 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;
+ }
+
+ mga_waitfifo( mdrv, mdev, 4 );
+
+ mga_out32( mmio, U8_TO_F0915(color.a), ALPHASTART );
+ mga_out32( mmio, U8_TO_F0915(color.r), DR4 );
+ mga_out32( mmio, U8_TO_F0915(color.g), DR8 );
+ mga_out32( mmio, U8_TO_F0915(color.b), DR12 );
+
+ MGA_VALIDATE( m_drawColor );
+ MGA_INVALIDATE( m_blitColor );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+void matrox_validate_blitColor( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ if (MGA_IS_VALID( m_blitColor ))
+ return;
+
+ if (state->blittingflags & DSBLIT_COLORIZE) {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ 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 {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR)
+ color.r = color.g = color.b = color.a;
+ else
+ color.r = color.g = color.b = 0xff;
+ }
+
+ mga_waitfifo( mdrv, mdev, 4 );
+
+ mga_out32( mmio, U8_TO_F0915(color.a), ALPHASTART );
+ mga_out32( mmio, U8_TO_F0915(color.r), DR4 );
+ mga_out32( mmio, U8_TO_F0915(color.g), DR8 );
+ mga_out32( mmio, U8_TO_F0915(color.b), DR12 );
+
+ MGA_VALIDATE( m_blitColor );
+ MGA_INVALIDATE( m_drawColor );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+void matrox_validate_color( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ DFBColor color = state->color;
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 fcol;
+ u8 cb, cr;
+
+ if (MGA_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_ALUT44:
+ fcol = (color.a & 0xF0) | state->color_index;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_LUT8:
+ fcol = state->color_index;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB332:
+ fcol = PIXEL_RGB332( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB444:
+ fcol = PIXEL_RGB444( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_ARGB4444:
+ fcol = PIXEL_ARGB4444( color.a,
+ color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB555:
+ fcol = PIXEL_RGB555( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_ARGB1555:
+ fcol = PIXEL_ARGB1555( color.a,
+ color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB16:
+ fcol = PIXEL_RGB16( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 16;
+ break;
+ case DSPF_RGB24:
+ fcol = PIXEL_RGB32( color.r,
+ color.g,
+ color.b );
+ fcol |= fcol << 24;
+ break;
+ case DSPF_RGB32:
+ fcol = PIXEL_RGB32( color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_ARGB:
+ fcol = PIXEL_ARGB( color.a,
+ color.r,
+ color.g,
+ color.b );
+ break;
+ case DSPF_A8:
+ fcol = color.a;
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cb << 24) | (cb << 16) | (cb << 8) | cb;
+ mdev->color[2] = (cr << 24) | (cr << 16) | (cr << 8) | cr;
+ break;
+ case DSPF_NV12:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cr << 24) | (cb << 16) | (cr << 8) | cb;
+ break;
+ case DSPF_NV21:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol |= fcol << 8;
+ fcol |= fcol << 16;
+ mdev->color[0] = fcol;
+ mdev->color[1] = (cb << 24) | (cr << 16) | (cb << 8) | cr;
+ break;
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol = PIXEL_YUY2( fcol, cb, cr );
+ break;
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color.r,
+ color.g,
+ color.b,
+ fcol, cb, cr );
+ fcol = PIXEL_UYVY( fcol, cb, cr );
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ return;
+ }
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, fcol, FCOL );
+
+ MGA_VALIDATE( m_color );
+ MGA_INVALIDATE( m_srckey );
+}
+
+static u32 matroxSourceBlend[] = {
+ SRC_ZERO, /* DSBF_ZERO */
+ SRC_ONE, /* DSBF_ONE */
+ 0, /* DSBF_SRCCOLOR */
+ 0, /* DSBF_INVSRCCOLOR */
+ SRC_ALPHA, /* DSBF_SRCALPHA */
+ SRC_ONE_MINUS_SRC_ALPHA, /* DSBF_INVSRCALPHA */
+ SRC_DST_ALPHA, /* DSBF_DESTALPHA */
+ SRC_ONE_MINUS_DST_ALPHA, /* DSBF_INVDESTALPHA */
+ SRC_DST_COLOR, /* DSBF_DESTCOLOR */
+ SRC_ONE_MINUS_DST_COLOR, /* DSBF_INVDESTCOLOR */
+ SRC_SRC_ALPHA_SATURATE /* DSBF_SRCALPHASAT */
+};
+
+static u32 matroxDestBlend[] = {
+ DST_ZERO, /* DSBF_ZERO */
+ DST_ONE, /* DSBF_ONE */
+ DST_SRC_COLOR, /* DSBF_SRCCOLOR */
+ DST_ONE_MINUS_SRC_COLOR, /* DSBF_INVSRCCOLOR */
+ DST_SRC_ALPHA, /* DSBF_SRCALPHA */
+ DST_ONE_MINUS_SRC_ALPHA, /* DSBF_INVSRCALPHA */
+ DST_DST_ALPHA, /* DSBF_DESTALPHA */
+ DST_ONE_MINUS_DST_ALPHA, /* DSBF_INVDESTALPHA */
+ 0, /* DSBF_DESTCOLOR */
+ 0, /* DSBF_INVDESTCOLOR */
+ 0 /* DSBF_SRCALPHASAT */
+};
+
+void matrox_validate_drawBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 alphactrl;
+
+ if (MGA_IS_VALID( m_drawBlend ))
+ return;
+
+ alphactrl = matroxSourceBlend[state->src_blend - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ ALPHACHANNEL | DIFFUSEDALPHA;
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, alphactrl, ALPHACTRL );
+
+ MGA_VALIDATE( m_drawBlend );
+ MGA_INVALIDATE( m_blitBlend );
+}
+
+static u32 matroxAlphaSelect[] = {
+ 0,
+ 0,
+ DIFFUSEDALPHA,
+ MODULATEDALPHA
+};
+
+void matrox_validate_blitBlend( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+
+ u32 alphactrl;
+
+ if (MGA_IS_VALID( m_blitBlend ))
+ return;
+
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA))
+ {
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY)
+ /* src_blend == ONE and dst_blend == INVSRCALPHA/INVSRCCOLOR */
+ alphactrl = matroxSourceBlend[DSBF_SRCALPHA - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ VIDEOALPHA;
+ else
+ alphactrl = matroxSourceBlend[state->src_blend - 1] |
+ matroxDestBlend [state->dst_blend - 1] |
+ ALPHACHANNEL;
+
+ if (state->source->config.format == DSPF_RGB32) {
+ alphactrl |= DIFFUSEDALPHA;
+
+ if (! (state->blittingflags & DSBLIT_BLEND_COLORALPHA)) {
+ mga_out32( mmio, U8_TO_F0915(0xff), ALPHASTART );
+ MGA_INVALIDATE( m_drawColor | m_blitColor );
+ }
+ }
+ else
+ alphactrl |= matroxAlphaSelect [state->blittingflags & 3];
+ }
+ else {
+ alphactrl = SRC_ONE | DST_ZERO | ALPHACHANNEL;
+
+ if (state->source->config.format == DSPF_RGB32) {
+ alphactrl |= DIFFUSEDALPHA;
+
+ mga_out32( mmio, U8_TO_F0915(0xff), ALPHASTART );
+ MGA_INVALIDATE( m_drawColor | m_blitColor );
+ }
+ }
+
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, alphactrl, ALPHACTRL );
+
+ MGA_VALIDATE( m_blitBlend );
+ MGA_INVALIDATE( m_drawBlend );
+}
+
+static void matrox_tlutload( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CorePalette *palette )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ volatile u16 *dst = dfb_gfxcard_memory_virtual( NULL, mdev->tlut_offset );
+ unsigned int i;
+
+ for (i = 0; i < palette->num_entries; i++)
+ *dst++ = PIXEL_RGB16( palette->entries[i].r,
+ palette->entries[i].g,
+ palette->entries[i].b );
+
+ mga_waitfifo( mdrv, mdev, mdev->old_matrox ? 8 : 9 );
+ mga_out32( mmio, BLTMOD_BU32RGB | BOP_COPY | SHFTZERO |
+ SGNZERO | LINEAR | ATYPE_RSTR | OP_BITBLT, DWGCTL );
+ mga_out32( mmio, 1024, PITCH );
+ if (mdev->old_matrox) {
+ mga_out32( mmio, mdev->tlut_offset / 2, AR3 );
+ mga_out32( mmio, palette->num_entries, AR0 );
+ mga_out32( mmio, 0, YDSTORG );
+ }
+ else {
+ mga_out32( mmio, 0, AR3 );
+ mga_out32( mmio, palette->num_entries, AR0 );
+ mga_out32( mmio, mdev->fb.offset + mdev->tlut_offset, SRCORG );
+ mga_out32( mmio, 0, DSTORG );
+
+ MGA_INVALIDATE( m_source );
+ }
+ mga_out32( mmio, 0, FXBNDRY );
+ mga_out32( mmio, PW16 | TLUTLOAD, MACCESS );
+ mga_out32( mmio, palette->num_entries, YDSTLEN | EXECUTE );
+
+ MGA_INVALIDATE( m_destination );
+}
+
+void matrox_validate_Source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL(surface->config.format);
+ u32 texctl = 0, texctl2 = 0;
+
+ if (MGA_IS_VALID( m_Source ))
+ return;
+
+ mdev->src_pitch = state->src.pitch / bytes_per_pixel;
+ mdev->field = surface->field;
+ mdev->w = surface->config.size.w;
+ mdev->h = surface->config.size.h;
+
+ if (state->destination->config.format == DSPF_YUY2 || state->destination->config.format == DSPF_UYVY) {
+ mdev->w /= 2;
+ mdev->src_pitch /= 2;
+ }
+
+ if (mdev->blit_deinterlace || mdev->blit_fields) {
+ mdev->h /= 2;
+ if (!(surface->config.caps & DSCAPS_SEPARATED))
+ mdev->src_pitch *= 2;
+ }
+
+ D_ASSERT( mdev->src_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, surface, &state->src, false, mdev->src_offset );
+
+ if (mdev->blit_deinterlace && mdev->field) {
+ mdev->src_offset[0][0] = mdev->src_offset[1][0];
+ mdev->src_offset[0][1] = mdev->src_offset[1][1];
+ mdev->src_offset[0][2] = mdev->src_offset[1][2];
+ }
+
+ mdev->w2 = mga_log2( mdev->w );
+ mdev->h2 = mga_log2( mdev->h );
+
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
+ texctl = TAMASK;
+ else
+ texctl = TAKEY;
+
+ switch (surface->config.format) {
+ case DSPF_YUY2:
+ texctl |= (state->destination->config.format == DSPF_YUY2) ? TW32 : TW422;
+ break;
+ case DSPF_UYVY:
+ texctl |= (state->destination->config.format == DSPF_UYVY) ? TW32 : TW422UYVY;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_A8:
+ texctl |= TW8A;
+ break;
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ texctl |= TW12;
+ break;
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ texctl |= TW15;
+ break;
+ case DSPF_RGB16:
+ texctl |= TW16;
+ break;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ texctl |= TW32;
+ break;
+ case DSPF_LUT8:
+ matrox_tlutload( mdrv, mdev, surface->palette );
+ texctl |= TW8;
+ break;
+ case DSPF_RGB332:
+ matrox_tlutload( mdrv, mdev, mdev->rgb332_palette );
+ texctl |= TW8;
+ break;
+ default:
+ D_BUG( "unexpected pixelformat!" );
+ break;
+ }
+
+ texctl |= ((mdev->src_pitch << 9) & TPITCHEXT) | TPITCHLIN;
+
+ if (1 << mdev->w2 != mdev->w || 1 << mdev->h2 != mdev->h)
+ texctl |= CLAMPUV;
+
+ if (state->blittingflags & (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR))
+ texctl |= TMODULATE;
+ else
+ texctl2 |= DECALDIS;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ texctl |= DECALCKEY | STRANS;
+ else
+ texctl2 |= CKSTRANSDIS;
+
+ if (surface->config.format == DSPF_A8)
+ texctl2 |= IDECAL | DECALDIS;
+
+ mdev->texctl = texctl;
+
+ mga_waitfifo( mdrv, mdev, 5 );
+ mga_out32( mmio, texctl, TEXCTL );
+ mga_out32( mmio, texctl2, TEXCTL2 );
+
+ mga_out32( mmio, ( (((u32)(mdev->w - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->w2) & 0x3f) << 9) |
+ (((u32)(mdev->w2 + 4) & 0x3f) ) ), TEXWIDTH );
+
+ mga_out32( mmio, ( (((u32)(mdev->h - 1) & 0x7ff) << 18) |
+ (((u32)(4 - mdev->h2) & 0x3f) << 9) |
+ (((u32)(mdev->h2 + 4) & 0x3f) ) ), TEXHEIGHT );
+
+ mga_out32( mmio, mdev->src_offset[0][0], TEXORG );
+
+ MGA_VALIDATE( m_Source );
+}
+
+void matrox_validate_source( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ int bytes_per_pixel = DFB_BYTES_PER_PIXEL(surface->config.format);
+
+ if (MGA_IS_VALID( m_source ))
+ return;
+
+ mdev->src_pitch = state->src.pitch / bytes_per_pixel;
+
+ if (state->destination->config.format == DSPF_YUY2 || state->destination->config.format == DSPF_UYVY)
+ mdev->src_pitch /= 2;
+
+ if (mdev->blit_fields && !(surface->config.caps & DSCAPS_SEPARATED))
+ mdev->src_pitch *= 2;
+
+ D_ASSERT( mdev->src_pitch % 32 == 0 );
+
+ matrox_calc_offsets( mdev, surface, &state->src, mdev->old_matrox, mdev->src_offset );
+
+ if (!mdev->old_matrox) {
+ mga_waitfifo( mdrv, mdev, 1 );
+ mga_out32( mmio, mdev->src_offset[0][0], SRCORG );
+ }
+
+ MGA_VALIDATE( m_source );
+}
+
+void matrox_validate_SrcKey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ u32 key;
+ u32 mask;
+
+ if (MGA_IS_VALID( m_SrcKey ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ mask = MGA_KEYMASK(surface->config.format);
+ key = state->src_colorkey & mask;
+ } else {
+ mask = 0;
+ key = 0xFFFF;
+ }
+
+ mga_waitfifo( mdrv, mdev, 2);
+
+ mga_out32( mmio, ((mask & 0xFFFF) << 16) | (key & 0xFFFF), TEXTRANS );
+ mga_out32( mmio, (mask & 0xFFFF0000) | (key >> 16), TEXTRANSHIGH );
+
+ MGA_VALIDATE( m_SrcKey );
+}
+
+void matrox_validate_srckey( MatroxDriverData *mdrv,
+ MatroxDeviceData *mdev,
+ CardState *state )
+{
+ volatile u8 *mmio = mdrv->mmio_base;
+ CoreSurface *surface = state->source;
+ u32 key;
+ u32 mask;
+
+ if (MGA_IS_VALID( m_srckey ))
+ return;
+
+ mask = MGA_KEYMASK(surface->config.format);
+ key = state->src_colorkey & mask;
+
+ switch (DFB_BYTES_PER_PIXEL(state->source->config.format)) {
+ case 1:
+ mask |= mask << 8;
+ key |= key << 8;
+ case 2:
+ mask |= mask << 16;
+ key |= key << 16;
+ }
+
+ mga_waitfifo( mdrv, mdev, 2);
+ mga_out32( mmio, mask, BCOL );
+ mga_out32( mmio, key, FCOL );
+
+ MGA_VALIDATE( m_srckey );
+ MGA_INVALIDATE( m_color );
+}
+