516 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			516 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * $Id$
 | 
						|
 *
 | 
						|
 * Copyright © 2004 Damien Ciabrini
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Anders Carlsson not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Anders Carlsson makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * DAMIEN CIABRINI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
/* $Header$ */
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include "mga.h"
 | 
						|
#include "g400_common.h"
 | 
						|
 | 
						|
 | 
						|
static PicturePtr currentSrcPicture;
 | 
						|
static PicturePtr currentMaskPicture;
 | 
						|
static PixmapPtr currentSrc;
 | 
						|
static PixmapPtr currentMask;
 | 
						|
static int src_w2;
 | 
						|
static int src_h2;
 | 
						|
static int mask_w2;
 | 
						|
static int mask_h2;
 | 
						|
 | 
						|
struct blendinfo {
 | 
						|
	Bool dst_alpha;
 | 
						|
	Bool src_alpha;
 | 
						|
	CARD32 blend_cntl;
 | 
						|
};
 | 
						|
 | 
						|
static struct blendinfo mgaBlendOP[] = {
 | 
						|
	/* Clear */
 | 
						|
	{0, 0, MGA_SRC_ZERO			| MGA_DST_ZERO},
 | 
						|
	/* Src */
 | 
						|
	{0, 0, MGA_SRC_ONE			| MGA_DST_ZERO},
 | 
						|
	/* Dst */
 | 
						|
	{0, 0, MGA_SRC_ZERO			| MGA_DST_ONE},
 | 
						|
	/* Over */
 | 
						|
	{0, 1, MGA_SRC_ONE			| MGA_DST_ONE_MINUS_SRC_ALPHA},
 | 
						|
	/* OverReverse */
 | 
						|
	{1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA	| MGA_DST_ONE},
 | 
						|
	/* In */
 | 
						|
	{1, 0, MGA_SRC_DST_ALPHA		| MGA_DST_ZERO},
 | 
						|
	/* InReverse */
 | 
						|
	{0, 1, MGA_SRC_ZERO			| MGA_DST_SRC_ALPHA},
 | 
						|
	/* Out */
 | 
						|
	{1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA	| MGA_DST_ZERO},
 | 
						|
	/* OutReverse */
 | 
						|
	{0, 1, MGA_SRC_ZERO			| MGA_DST_ONE_MINUS_SRC_ALPHA},
 | 
						|
	/* Atop */
 | 
						|
	{1, 1, MGA_SRC_DST_ALPHA		| MGA_DST_ONE_MINUS_SRC_ALPHA},
 | 
						|
	/* AtopReverse */
 | 
						|
	{1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA	| MGA_DST_SRC_ALPHA},
 | 
						|
	/* Xor */
 | 
						|
	{1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA	| MGA_DST_ONE_MINUS_SRC_ALPHA},
 | 
						|
	/* Add */
 | 
						|
	{0, 0, MGA_SRC_ONE			| MGA_DST_ONE},
 | 
						|
};
 | 
						|
 | 
						|
struct formatinfo {
 | 
						|
	int fmt;
 | 
						|
	CARD32 card_fmt;
 | 
						|
};
 | 
						|
 | 
						|
static struct formatinfo texformats[] = {
 | 
						|
    {PICT_a8r8g8b8, MGA_TW32},
 | 
						|
    {PICT_x8r8g8b8, MGA_TW32},
 | 
						|
    {PICT_r5g6b5, MGA_TW16},
 | 
						|
    {PICT_a1r5g5b5, MGA_TW15},
 | 
						|
    {PICT_x1r5g5b5, MGA_TW15},
 | 
						|
    {PICT_a4r4g4b4, MGA_TW12},
 | 
						|
    {PICT_x4r4g4b4, MGA_TW12},
 | 
						|
    {PICT_a8, MGA_TW8A},
 | 
						|
};
 | 
						|
 | 
						|
static int
 | 
						|
MGA_LOG2( int val )
 | 
						|
{
 | 
						|
    int ret = 0;
 | 
						|
    if (val==1) return 0;
 | 
						|
    while (val >> ret)
 | 
						|
	ret++;
 | 
						|
    
 | 
						|
    return ((1 << (ret-1)) == val) ? (ret-1) : ret;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static Bool
 | 
						|
mgaCheckSourceTexture (int		tmu,
 | 
						|
		       PicturePtr 	pPict)
 | 
						|
{
 | 
						|
    int w = pPict->pDrawable->width;
 | 
						|
    int h = pPict->pDrawable->height;
 | 
						|
    int i;
 | 
						|
    CARD32 texctl = 0;
 | 
						|
 | 
						|
    if ((w > 2047) || (h > 2047))
 | 
						|
	MGA_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
 | 
						|
 | 
						|
    for (i = 0; i < sizeof(texformats) / sizeof(texformats[0]); i++) {
 | 
						|
	if (texformats[i].fmt == pPict->format) {
 | 
						|
	    texctl = texformats[i].card_fmt;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (texctl == 0) {
 | 
						|
	MGA_FALLBACK(("Unsupported picture format 0x%x\n", pPict->format));
 | 
						|
    }
 | 
						|
 | 
						|
    if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
 | 
						|
	MGA_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
 | 
						|
 | 
						|
    if (pPict->filter != PictFilterNearest &&
 | 
						|
	pPict->filter != PictFilterBilinear)
 | 
						|
	MGA_FALLBACK(("Unsupported filter 0x%x\n", pPict->filter));
 | 
						|
    
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
PrepareSourceTexture (int		tmu,
 | 
						|
		      PicturePtr 	pSrcPicture,
 | 
						|
		      PixmapPtr 	pSrc)
 | 
						|
{
 | 
						|
    KdScreenPriv (pSrc->drawable.pScreen);  
 | 
						|
    int mem_base=(int)pScreenPriv->screen->memory_base;
 | 
						|
    int pitch = pSrc->devKind / (pSrc->drawable.bitsPerPixel >> 3); 
 | 
						|
    int i;
 | 
						|
 | 
						|
    int w = pSrc->drawable.width;
 | 
						|
    int h = pSrc->drawable.height;
 | 
						|
    int w_log2 = MGA_LOG2(w);
 | 
						|
    int h_log2 = MGA_LOG2(h);
 | 
						|
 | 
						|
    int texctl = MGA_PITCHLIN | ((pitch & (2048 - 1)) << 9) | 
 | 
						|
	MGA_CLAMPUV | MGA_NOPERSPECTIVE;  
 | 
						|
    int flags = 0;
 | 
						|
    int texctl2 = MGA_G400_TC2_MAGIC | flags;
 | 
						|
    
 | 
						|
    for (i = 0; i < sizeof(texformats) / sizeof(texformats[0]); i++) {
 | 
						|
	if (texformats[i].fmt == pSrcPicture->format) {
 | 
						|
	    texctl |= texformats[i].card_fmt;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (PICT_FORMAT_A(pSrcPicture->format) != 0) {
 | 
						|
	texctl |= MGA_TAKEY;
 | 
						|
    } else {
 | 
						|
	texctl |= MGA_TAMASK | MGA_TAKEY;
 | 
						|
    }
 | 
						|
	
 | 
						|
    if (pSrcPicture->repeat) {
 | 
						|
	texctl &= ~MGA_CLAMPUV;
 | 
						|
    }
 | 
						|
	
 | 
						|
    if (tmu == 1)
 | 
						|
	texctl2 |= MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1 | flags;
 | 
						|
  
 | 
						|
    mgaWaitAvail (6);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TEXCTL2, texctl2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TEXCTL, texctl);  
 | 
						|
    /* Source (texture) address + pitch */
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TEXORG, ((int)pSrc->devPrivate.ptr - mem_base));
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TEXWIDTH, (w-1)<<18 | ((8-w_log2)&63)<<9 | w_log2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TEXHEIGHT, (h-1)<<18 | ((8-h_log2)&63)<<9 | h_log2);
 | 
						|
    /* Set blit filtering flags */
 | 
						|
    if (pSrcPicture->filter == PictFilterBilinear) {
 | 
						|
      MGA_OUT32 (mmio, MGA_REG_TEXFILTER,
 | 
						|
		 (0x10<<21) | MGA_MAG_BILIN | MGA_MIN_BILIN);
 | 
						|
    } else {
 | 
						|
      MGA_OUT32 (mmio, MGA_REG_TEXFILTER,
 | 
						|
		 (0x10<<21) | MGA_MAG_NRST | MGA_MIN_NRST);
 | 
						|
    }
 | 
						|
 | 
						|
    if (tmu == 1) {
 | 
						|
	mgaWaitAvail (1);
 | 
						|
	MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | flags);
 | 
						|
    }
 | 
						|
    
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *  The formals params are the elements of the following matrix:
 | 
						|
 *
 | 
						|
 *     Dest            Transform             Src
 | 
						|
 *    coords                                coords
 | 
						|
 *   / Xdst \   / X_incx X_incy X_init \   / Xsrc \
 | 
						|
 *   | Ydst | = | Y_incx Y_incy Y_init | x | Ysrc |
 | 
						|
 *   \  1   /   \ H_incx H_incy H_init /   \  1   /
 | 
						|
 *
 | 
						|
 * matrix elements are 32bits fixed points (16.16)
 | 
						|
 * mga_fx_* is the size of the fixed point for the TMU
 | 
						|
 */
 | 
						|
static void
 | 
						|
setTMIncrementsRegs(int X_incx,
 | 
						|
		    int X_incy,
 | 
						|
		    int X_init,
 | 
						|
		    int Y_incx,
 | 
						|
		    int Y_incy,
 | 
						|
		    int Y_init,
 | 
						|
		    int H_incx,
 | 
						|
		    int H_incy,
 | 
						|
		    int H_init,
 | 
						|
		    int mga_fx_width_size,
 | 
						|
		    int mga_fx_height_size) {
 | 
						|
    int decalw = mga_fx_width_size - 16;
 | 
						|
    int decalh = mga_fx_height_size - 16;
 | 
						|
 | 
						|
    /* Convert 16 bits fixpoint -> MGA variable size fixpoint */
 | 
						|
    if (decalw >= 0) {
 | 
						|
	X_incx = X_incx << decalw;
 | 
						|
	X_incy = X_incy << decalw;
 | 
						|
	X_init = X_init << decalw;
 | 
						|
    } else {
 | 
						|
	decalw =- decalw;
 | 
						|
	X_incx = X_incx >> decalw;
 | 
						|
	X_incy = X_incy >> decalw;
 | 
						|
	X_init = X_init >> decalw;
 | 
						|
    }
 | 
						|
  
 | 
						|
    /* Convert 16 bits fixpoint -> MGA variable size fixpoint */
 | 
						|
    if (decalh >= 0) {
 | 
						|
	Y_incx = Y_incx << decalh;
 | 
						|
	Y_incy = Y_incy << decalh;
 | 
						|
	Y_init = Y_init << decalh;
 | 
						|
    } else {
 | 
						|
	decalh =- decalh;
 | 
						|
	Y_incx = Y_incx >> decalh;
 | 
						|
	Y_incy = Y_incy >> decalh;
 | 
						|
	Y_init = Y_init >> decalh;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Set TM registers */
 | 
						|
    mgaWaitAvail (9);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR0, X_incx); 
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR1, Y_incx); 
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR2, X_incy);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR3, Y_incy);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR4, H_incx); 
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR5, H_incy); 
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR6, X_init);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR7, Y_init);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TMR8, H_init); 
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
mgaCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
 | 
						|
		  PicturePtr pDstPicture)
 | 
						|
{
 | 
						|
    if (op >= sizeof(mgaBlendOP) / sizeof(mgaBlendOP[0]))
 | 
						|
	MGA_FALLBACK(("unsupported op %x", op));
 | 
						|
    if (!mgaCheckSourceTexture (0, pSrcPicture))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (pMaskPicture != NULL) {
 | 
						|
	if (PICT_FORMAT_A(pMaskPicture->format) == 0)
 | 
						|
	    MGA_FALLBACK(("Mask without alpha unsupported"));
 | 
						|
	if (!mgaCheckSourceTexture (1, pMaskPicture))
 | 
						|
	    return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pMaskPicture->componentAlpha)
 | 
						|
	MGA_FALLBACK(("Component alpha unsupported"));
 | 
						|
 | 
						|
    switch (pDstPicture->format) {
 | 
						|
    case PICT_a8:
 | 
						|
	MGA_FALLBACK(("render to A8 unsupported"));
 | 
						|
    }
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
#define C_ARG1_CUR		0x0
 | 
						|
#define C_ARG1_ALPHA		MGA_TDS_COLOR_ARG1_REPLICATEALPHA	
 | 
						|
#define C_ARG2_DIFFUSE		MGA_TDS_COLOR_ARG2_DIFFUSE
 | 
						|
#define C_ARG2_FCOL		MGA_TDS_COLOR_ARG2_FCOL
 | 
						|
#define C_ARG2_PREV		MGA_TDS_COLOR_ARG2_PREVSTAGE
 | 
						|
#define C_ARG1_INV		MGA_TDS_COLOR_ARG1_INV
 | 
						|
#define C_ARG2_INV		MGA_TDS_COLOR_ARG2_INV
 | 
						|
#define COLOR_MUL		MGA_TDS_COLOR_SEL_MUL
 | 
						|
#define COLOR_ARG1		MGA_TDS_COLOR_SEL_ARG1
 | 
						|
#define COLOR_ARG2		MGA_TDS_COLOR_SEL_ARG2
 | 
						|
#define A_ARG1_CUR		0x0
 | 
						|
#define A_ARG2_IGN		A_ARG2_DIFFUSE
 | 
						|
#define A_ARG2_FCOL		MGA_TDS_ALPHA_ARG2_FCOL
 | 
						|
#define A_ARG2_DIFFUSE		MGA_TDS_ALPHA_ARG2_DIFFUSE
 | 
						|
#define A_ARG2_PREV		MGA_TDS_ALPHA_ARG2_PREVSTAGE
 | 
						|
#define ALPHA_MUL		MGA_TDS_ALPHA_SEL_MUL
 | 
						|
#define ALPHA_ARG1		MGA_TDS_ALPHA_SEL_ARG1
 | 
						|
#define ALPHA_ARG2		MGA_TDS_ALPHA_SEL_ARG2
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
mgaPrepareComposite (int		op,
 | 
						|
		     PicturePtr		pSrcPicture,
 | 
						|
		     PicturePtr		pMaskPicture,
 | 
						|
		     PicturePtr		pDstPicture,
 | 
						|
		     PixmapPtr		pSrc,
 | 
						|
		     PixmapPtr		pMask,
 | 
						|
		     PixmapPtr		pDst)
 | 
						|
{
 | 
						|
    KdScreenPriv (pSrc->drawable.pScreen);  
 | 
						|
    int mem_base=(int)pScreenPriv->screen->memory_base;
 | 
						|
    int cmd, blendcntl;
 | 
						|
    int ds0, ds1;
 | 
						|
    
 | 
						|
    /* Init MGA (clipping) */
 | 
						|
    mgaSetup (pSrc->drawable.pScreen, pDst->drawable.bitsPerPixel, 1);
 | 
						|
 | 
						|
    /* Initialize fg color to 0, used in the src = A8 case */
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_FCOL, 0xff000000);
 | 
						|
        
 | 
						|
    /* Destination flags */
 | 
						|
    mgaWaitAvail (2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_DSTORG, ((int)pDst->devPrivate.ptr - mem_base));
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_PITCH,
 | 
						|
	       pDst->devKind / (pDst->drawable.bitsPerPixel >> 3));
 | 
						|
 | 
						|
	
 | 
						|
    /* Source(s) flags */
 | 
						|
    if (!PrepareSourceTexture (0, pSrcPicture, pSrc)) return FALSE;
 | 
						|
    if (pMask != NULL) {
 | 
						|
    	if (!PrepareSourceTexture (1, pMaskPicture, pMask)) return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Prepare multi-texture registers */
 | 
						|
    ds0=ds1=0;
 | 
						|
 | 
						|
    if (pSrcPicture->format == PICT_a8) {
 | 
						|
	/* C = 0	A = As */
 | 
						|
	/* MGA HW: A8 format makes RGB white. We use FCOL for the black
 | 
						|
	 * If FCOL was not 0, it would have been be premultiplied (RENDER)
 | 
						|
	 * color component would have been:
 | 
						|
	 *   C_ARG1_ALPHA | C_ARG2_FCOL | COLOR_MUL
 | 
						|
	 */
 | 
						|
	ds0=C_ARG2_FCOL | COLOR_ARG2 |
 | 
						|
	    A_ARG1_CUR | ALPHA_ARG1;
 | 
						|
	/* MGA HW: TMU1 must be enabled when DUALSTAGE0 contains something */
 | 
						|
	if (pMask == NULL) {
 | 
						|
	    if (!PrepareSourceTexture (1, pSrcPicture, pSrc)) return FALSE;
 | 
						|
	    ds1=C_ARG2_PREV | COLOR_ARG2 |
 | 
						|
		A_ARG2_PREV | ALPHA_ARG2;
 | 
						|
	}
 | 
						|
    } else {
 | 
						|
	/* C = Cs	A = As */
 | 
						|
	ds0=C_ARG1_CUR | COLOR_ARG1 |
 | 
						|
	    A_ARG1_CUR | ALPHA_ARG1;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (pMask != NULL) {
 | 
						|
	/* As or Am might be NULL. in this case we don't multiply because,
 | 
						|
	 * the alpha component holds garbage.
 | 
						|
	 */
 | 
						|
	int color,alpha;
 | 
						|
	if (PICT_FORMAT_A (pMaskPicture->format) == 0) {
 | 
						|
	    /* C = Cs */
 | 
						|
	    color = C_ARG2_PREV | COLOR_ARG2;
 | 
						|
	} else {
 | 
						|
	    /* C = Am * Cs */
 | 
						|
	    color = C_ARG1_ALPHA | C_ARG2_PREV | COLOR_MUL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (PICT_FORMAT_A (pMaskPicture->format) == 0) {
 | 
						|
	    /* A = As */
 | 
						|
	    alpha = A_ARG2_PREV | ALPHA_ARG2;
 | 
						|
	} else if (PICT_FORMAT_A (pSrcPicture->format) == 0) {
 | 
						|
	    /* A = Am */
 | 
						|
	    alpha = A_ARG1_CUR | ALPHA_ARG1;
 | 
						|
	} else {
 | 
						|
	    /* A = Am * As */
 | 
						|
	    alpha = A_ARG1_CUR | A_ARG2_PREV | ALPHA_MUL;
 | 
						|
	}
 | 
						|
	
 | 
						|
	ds1 = color | alpha;
 | 
						|
    }    
 | 
						|
    
 | 
						|
    /* MultiTexture modulation */
 | 
						|
    mgaWaitAvail (2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE0, ds0);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE1, ds1);
 | 
						|
 | 
						|
    
 | 
						|
    cmd = MGA_OPCOD_TEXTURE_TRAP | MGA_ATYPE_RSTR | 0x000c0000 |
 | 
						|
	MGA_DWGCTL_SHIFTZERO | MGA_DWGCTL_SGNZERO | MGA_DWGCTL_ARZERO |
 | 
						|
	MGA_ATYPE_I;
 | 
						|
    
 | 
						|
    blendcntl = mgaBlendOP[op].blend_cntl;
 | 
						|
    if (PICT_FORMAT_A(pDstPicture->format) == 0 && mgaBlendOP[op].dst_alpha) {
 | 
						|
	if ((blendcntl & MGA_SRC_BLEND_MASK) == MGA_SRC_DST_ALPHA)
 | 
						|
	    blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ONE;
 | 
						|
	else if ((blendcntl & MGA_SRC_BLEND_MASK) == MGA_SRC_ONE_MINUS_DST_ALPHA)
 | 
						|
	    blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ZERO;
 | 
						|
    }
 | 
						|
 | 
						|
    mgaWaitAvail (2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_DWGCTL, cmd);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_ALPHACTRL, MGA_ALPHACHANNEL | blendcntl);
 | 
						|
 | 
						|
    currentSrcPicture = pSrcPicture;
 | 
						|
    currentMaskPicture = pMaskPicture;
 | 
						|
    currentSrc = pSrc;
 | 
						|
    currentMask = pMask;
 | 
						|
    src_w2 = MGA_LOG2 (currentSrc->drawable.width);
 | 
						|
    src_h2 = MGA_LOG2 (currentSrc->drawable.height);
 | 
						|
    mask_w2 = MGA_LOG2 (currentMask->drawable.width);
 | 
						|
    mask_h2 = MGA_LOG2 (currentMask->drawable.height);
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
mgaComposite (int	srcX,
 | 
						|
	      int	srcY,
 | 
						|
	      int	maskX,
 | 
						|
	      int	maskY,
 | 
						|
	      int	dstX,
 | 
						|
	      int	dstY,
 | 
						|
	      int	width,
 | 
						|
	      int	height)
 | 
						|
{  
 | 
						|
    /* Source positions can be outside source textures' boundaries.
 | 
						|
     * We clamp the values here to avoid rendering glitches.
 | 
						|
     */
 | 
						|
    srcX=srcX % currentSrc->drawable.width;
 | 
						|
    srcY=srcY % currentSrc->drawable.height;
 | 
						|
    maskX=maskX % currentMask->drawable.width;
 | 
						|
    maskY=maskY % currentMask->drawable.height;
 | 
						|
    
 | 
						|
    if (currentSrcPicture->transform) {
 | 
						|
	setTMIncrementsRegs (currentSrcPicture->transform->matrix[0][0],
 | 
						|
			     currentSrcPicture->transform->matrix[0][1],
 | 
						|
			     currentSrcPicture->transform->matrix[0][2] +
 | 
						|
			     (srcX << 16),
 | 
						|
			     currentSrcPicture->transform->matrix[1][0],
 | 
						|
			     currentSrcPicture->transform->matrix[1][1],
 | 
						|
			     currentSrcPicture->transform->matrix[1][2] +
 | 
						|
			     (srcY << 16),
 | 
						|
			     currentSrcPicture->transform->matrix[2][0],
 | 
						|
			     currentSrcPicture->transform->matrix[2][1],
 | 
						|
			     currentSrcPicture->transform->matrix[2][2],
 | 
						|
			     20-src_w2, 20-src_h2);
 | 
						|
    } else {
 | 
						|
	setTMIncrementsRegs (1 << 16, 0, srcX << 16,
 | 
						|
			     0, 1 << 16, srcY << 16,
 | 
						|
			     0, 0, 0x10000,
 | 
						|
			     20-src_w2, 20-src_h2);
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (currentMask != NULL) {
 | 
						|
	mgaWaitAvail (1);
 | 
						|
	MGA_OUT32  (mmio, MGA_REG_TEXCTL2,
 | 
						|
		    MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1);
 | 
						|
	if (currentMaskPicture->transform) {
 | 
						|
	    setTMIncrementsRegs (currentMaskPicture->transform->matrix[0][0],
 | 
						|
				 currentMaskPicture->transform->matrix[0][1],
 | 
						|
				 currentMaskPicture->transform->matrix[0][2] +
 | 
						|
				 (maskX << 16),
 | 
						|
				 currentMaskPicture->transform->matrix[1][0],
 | 
						|
				 currentMaskPicture->transform->matrix[1][1],
 | 
						|
				 currentMaskPicture->transform->matrix[1][2] +
 | 
						|
				 (maskY << 16),
 | 
						|
				 currentMaskPicture->transform->matrix[2][0],
 | 
						|
				 currentMaskPicture->transform->matrix[2][1],
 | 
						|
				 currentMaskPicture->transform->matrix[2][2],
 | 
						|
				 20-mask_w2, 20-mask_h2);
 | 
						|
	} else {
 | 
						|
	    setTMIncrementsRegs (1 << 16, 0, maskX << 16,
 | 
						|
				 0, 1 << 16, maskY << 16,
 | 
						|
				 0, 0, 0x10000,
 | 
						|
				 20-mask_w2, 20-mask_h2);
 | 
						|
	}
 | 
						|
	
 | 
						|
	mgaWaitAvail (1);
 | 
						|
	MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX);
 | 
						|
    }  
 | 
						|
 | 
						|
    /* Destination Bounding Box
 | 
						|
     * (Boundary Right | Boundary Left, Y dest | Height)
 | 
						|
     */
 | 
						|
    mgaWaitAvail (2);
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_FXBNDRY,
 | 
						|
	       ((dstX + width) << 16) | (dstX & 0xffff));
 | 
						|
    MGA_OUT32 (mmio, MGA_REG_YDSTLEN | MGA_REG_EXEC,
 | 
						|
	       (dstY << 16) | (height & 0xffff));
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
mgaDoneComposite (void)
 | 
						|
{
 | 
						|
}
 |