cefcb7f123
- On R128, don't refer to an old Composite's mask transform when the current Composite doesn't have a mask. - Staticize some global variables in r128_composite.c.
624 lines
17 KiB
C
624 lines
17 KiB
C
/*
|
|
* Copyright © 2003 Eric Anholt, Anders Carlsson
|
|
*
|
|
* 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 Eric Anholt not be used in
|
|
* advertising or publicity pertaining to distribution of the software without
|
|
* specific, written prior permission. Eric Anholt makes no
|
|
* representations about the suitability of this software for any purpose. It
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
* EVENT SHALL ERIC ANHOLT 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$ */
|
|
|
|
#include "ati.h"
|
|
#include "ati_reg.h"
|
|
#include "ati_dma.h"
|
|
#include "ati_draw.h"
|
|
|
|
extern ATIScreenInfo *accel_atis;
|
|
extern CARD8 ATIBltRop[16];
|
|
|
|
static int src_pitch;
|
|
static int src_offset;
|
|
static int src_bpp;
|
|
static int widths[2] = {1,1};
|
|
static int heights[2] = {1,1};
|
|
static Bool is_repeat;
|
|
static Bool is_transform[2];
|
|
static PictTransform *transform[2];
|
|
|
|
struct blendinfo {
|
|
Bool dst_alpha;
|
|
Bool src_alpha;
|
|
CARD32 blendctl;
|
|
};
|
|
|
|
static struct blendinfo R128BlendOp[] = {
|
|
/* Clear */
|
|
{0, 0, R128_SBLEND_ZERO | R128_DBLEND_ZERO},
|
|
/* Src */
|
|
{0, 0, R128_SBLEND_ONE | R128_DBLEND_ZERO},
|
|
/* Dst */
|
|
{0, 0, R128_SBLEND_ZERO | R128_DBLEND_ONE},
|
|
/* Over */
|
|
{0, 1, R128_SBLEND_ONE | R128_DBLEND_INV_SRC_ALPHA},
|
|
/* OverReverse */
|
|
{1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ONE},
|
|
/* In */
|
|
{1, 0, R128_SBLEND_DST_ALPHA | R128_DBLEND_ZERO},
|
|
/* InReverse */
|
|
{0, 1, R128_SBLEND_ZERO | R128_DBLEND_SRC_ALPHA},
|
|
/* Out */
|
|
{1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ZERO},
|
|
/* OutReverse */
|
|
{0, 1, R128_SBLEND_ZERO | R128_DBLEND_INV_SRC_ALPHA},
|
|
/* Atop */
|
|
{1, 1, R128_SBLEND_DST_ALPHA | R128_DBLEND_INV_SRC_ALPHA},
|
|
/* AtopReverse */
|
|
{1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_SRC_ALPHA},
|
|
/* Xor */
|
|
{1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_INV_SRC_ALPHA},
|
|
/* Add */
|
|
{0, 0, R128_SBLEND_ONE | R128_DBLEND_ONE},
|
|
};
|
|
|
|
static Bool
|
|
R128GetDatatypePict(CARD32 format, CARD32 *type)
|
|
{
|
|
switch (format) {
|
|
case PICT_a1r5g5b5:
|
|
*type = R128_DATATYPE_ARGB1555;
|
|
return TRUE;
|
|
case PICT_r5g6b5:
|
|
*type = R128_DATATYPE_RGB565;
|
|
return TRUE;
|
|
case PICT_a8r8g8b8:
|
|
*type = R128_DATATYPE_ARGB8888;
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
Bool
|
|
R128PrepareBlend(int op, PicturePtr pSrcPicture, PicturePtr pDstPicture,
|
|
PixmapPtr pSrc, PixmapPtr pDst)
|
|
{
|
|
KdScreenPriv(pDst->drawable.pScreen);
|
|
ATIScreenInfo(pScreenPriv);
|
|
CARD32 dstDatatype, srcDatatype;
|
|
RING_LOCALS;
|
|
CARD32 xinc, yinc, dst_pitch_offset;
|
|
|
|
accel_atis = atis;
|
|
|
|
src_offset = (CARD8 *)pSrc->devPrivate.ptr -
|
|
pScreenPriv->screen->memory_base;
|
|
src_pitch = pSrc->devKind;
|
|
src_bpp = pSrc->drawable.bitsPerPixel;
|
|
is_repeat = pSrcPicture->repeat;
|
|
|
|
if (op >= sizeof(R128BlendOp)/sizeof(R128BlendOp[0]))
|
|
ATI_FALLBACK(("Unsupported op 0x%x\n", op));
|
|
if (pSrcPicture->repeat && (pSrc->drawable.width != 1 ||
|
|
pSrc->drawable.height != 1))
|
|
ATI_FALLBACK(("repeat unsupported\n"));
|
|
if (pSrcPicture->transform != NULL)
|
|
ATI_FALLBACK(("transform unsupported\n"));
|
|
if (!R128GetDatatypePict(pDstPicture->format, &dstDatatype))
|
|
ATI_FALLBACK(("Unsupported dest format 0x%x\n",
|
|
pDstPicture->format));
|
|
if (!R128GetDatatypePict(pSrcPicture->format, &srcDatatype))
|
|
ATI_FALLBACK(("Unsupported src format 0x%x\n",
|
|
pSrcPicture->format));
|
|
if (src_pitch % src_bpp != 0)
|
|
ATI_FALLBACK(("Bad src pitch 0x%x\n", src_pitch));
|
|
if (!ATIGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
|
|
return FALSE;
|
|
|
|
if (is_repeat) {
|
|
xinc = 0;
|
|
yinc = 0;
|
|
} else {
|
|
xinc = 65536;
|
|
yinc = 65536;
|
|
}
|
|
|
|
BEGIN_DMA(18);
|
|
OUT_REG(ATI_REG_DST_PITCH_OFFSET, dst_pitch_offset);
|
|
OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL,
|
|
ATI_GMC_DST_PITCH_OFFSET_CNTL |
|
|
ATI_GMC_BRUSH_SOLID_COLOR |
|
|
(dstDatatype << 8) |
|
|
ATI_GMC_SRC_DATATYPE_COLOR |
|
|
(ATIBltRop[GXcopy] << 16) |
|
|
ATI_DP_SRC_SOURCE_MEMORY |
|
|
R128_GMC_3D_FCN_EN |
|
|
ATI_GMC_CLR_CMP_CNTL_DIS |
|
|
R128_GMC_AUX_CLIP_DIS);
|
|
OUT_REG(ATI_REG_DP_CNTL,
|
|
ATI_DST_X_LEFT_TO_RIGHT | ATI_DST_Y_TOP_TO_BOTTOM );
|
|
OUT_REG(R128_REG_SCALE_3D_CNTL,
|
|
R128_SCALE_3D_SCALE |
|
|
R128_SCALE_PIX_REPLICATE |
|
|
R128BlendOp[op].blendctl |
|
|
R128_TEX_MAP_ALPHA_IN_TEXTURE);
|
|
OUT_REG(R128_REG_TEX_CNTL_C, R128_ALPHA_ENABLE | R128_TEX_CACHE_FLUSH);
|
|
OUT_REG(R128_REG_SCALE_3D_DATATYPE, srcDatatype);
|
|
|
|
/* R128_REG_SCALE_PITCH,
|
|
* R128_REG_SCALE_X_INC,
|
|
* R128_REG_SCALE_Y_INC,
|
|
* R128_REG_SCALE_HACC
|
|
* R128_REG_SCALE_VACC */
|
|
OUT_RING(DMA_PACKET0(R128_REG_SCALE_PITCH, 5));
|
|
OUT_RING(src_pitch / src_bpp);
|
|
OUT_RING(xinc);
|
|
OUT_RING(yinc);
|
|
OUT_RING(0x0);
|
|
OUT_RING(0x0);
|
|
END_DMA();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
R128Blend(int srcX, int srcY, int dstX, int dstY, int width, int height)
|
|
{
|
|
ATIScreenInfo *atis = accel_atis;
|
|
RING_LOCALS;
|
|
|
|
if (is_repeat) {
|
|
srcX = 0;
|
|
srcY = 0;
|
|
}
|
|
|
|
BEGIN_DMA(6);
|
|
/* R128_REG_SCALE_SRC_HEIGHT_WIDTH,
|
|
* R128_REG_SCALE_OFFSET_0
|
|
*/
|
|
OUT_RING(DMA_PACKET0(R128_REG_SCALE_SRC_HEIGHT_WIDTH, 2));
|
|
OUT_RING((height << 16) | width);
|
|
OUT_RING(src_offset + srcY * src_pitch + srcX * (src_bpp >> 3));
|
|
/* R128_REG_SCALE_DST_X_Y
|
|
* R128_REG_SCALE_DST_HEIGHT_WIDTH
|
|
*/
|
|
OUT_RING(DMA_PACKET0(R128_REG_SCALE_DST_X_Y, 2));
|
|
OUT_RING((dstX << 16) | dstY);
|
|
OUT_RING((height << 16) | width);
|
|
END_DMA();
|
|
}
|
|
|
|
void
|
|
R128DoneBlend(void)
|
|
{
|
|
}
|
|
|
|
static Bool
|
|
R128CheckCompositeTexture(PicturePtr pPict)
|
|
{
|
|
int w = pPict->pDrawable->width;
|
|
int h = pPict->pDrawable->height;
|
|
|
|
if (w > (1 << 10) || h > (1 << 10))
|
|
ATI_FALLBACK(("Picture w/h too large (%dx%d)\n", w, h));
|
|
if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0))
|
|
ATI_FALLBACK(("NPOT repeat unsupported (%dx%d)\n", w, h));
|
|
|
|
switch (pPict->format) {
|
|
case PICT_a8:
|
|
case PICT_a1r5g5b5:
|
|
case PICT_a4r4g4b4:
|
|
case PICT_r5g6b5:
|
|
case PICT_a8r8g8b8:
|
|
break;
|
|
default:
|
|
ATI_FALLBACK(("Unsupported picture format 0x%x\n",
|
|
pPict->format));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
R128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
|
PicturePtr pDstPicture)
|
|
{
|
|
CARD32 dstDatatype;
|
|
|
|
if (op >= sizeof(R128BlendOp)/sizeof(R128BlendOp[0]))
|
|
ATI_FALLBACK(("Unsupported op 0x%x\n", op));
|
|
if (pDstPicture->format == PICT_a8) {
|
|
if (R128BlendOp[op].src_alpha || R128BlendOp[op].dst_alpha ||
|
|
pMaskPicture != NULL)
|
|
ATI_FALLBACK(("alpha blending unsupported with "
|
|
"A8 dst?\n"));
|
|
} else if (!R128GetDatatypePict(pDstPicture->format, &dstDatatype)) {
|
|
ATI_FALLBACK(("Unsupported dest format 0x%x\n",
|
|
pDstPicture->format));
|
|
}
|
|
if (pMaskPicture != NULL && pMaskPicture->componentAlpha &&
|
|
R128BlendOp[op].src_alpha)
|
|
ATI_FALLBACK(("Component alpha not supported with source alpha "
|
|
"blending.\n"));
|
|
|
|
if (!R128CheckCompositeTexture(pSrcPicture))
|
|
return FALSE;
|
|
if (pMaskPicture != NULL && !R128CheckCompositeTexture(pMaskPicture))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
R128TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit, CARD32 *txsize,
|
|
CARD32 *tex_cntl_c)
|
|
{
|
|
int w = pPict->pDrawable->width;
|
|
int h = pPict->pDrawable->height;
|
|
int bytepp, shift, l2w, l2h, l2p;
|
|
int pitch;
|
|
|
|
pitch = pPix->devKind;
|
|
if ((pitch & (pitch - 1)) != 0)
|
|
ATI_FALLBACK(("NPOT pitch 0x%x unsupported\n", pitch));
|
|
|
|
switch (pPict->format) {
|
|
case PICT_a8:
|
|
/* DATATYPE_RGB8 appears to expand the value into the alpha
|
|
* channel like we want. We then blank out the R,G,B channels
|
|
* as necessary using the combiners.
|
|
*/
|
|
*tex_cntl_c = R128_DATATYPE_RGB8 << R128_TEX_DATATYPE_SHIFT;
|
|
break;
|
|
case PICT_a1r5g5b5:
|
|
*tex_cntl_c = R128_DATATYPE_ARGB1555 << R128_TEX_DATATYPE_SHIFT;
|
|
break;
|
|
case PICT_a4r4g4b4:
|
|
*tex_cntl_c = R128_DATATYPE_ARGB4444 << R128_TEX_DATATYPE_SHIFT;
|
|
break;
|
|
case PICT_r5g6b5:
|
|
*tex_cntl_c = R128_DATATYPE_RGB565 << R128_TEX_DATATYPE_SHIFT;
|
|
break;
|
|
case PICT_a8r8g8b8:
|
|
*tex_cntl_c = R128_DATATYPE_ARGB8888 << R128_TEX_DATATYPE_SHIFT;
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
bytepp = PICT_FORMAT_BPP(pPict->format) / 8;
|
|
|
|
*tex_cntl_c |= R128_MIP_MAP_DISABLE;
|
|
|
|
if (unit == 0)
|
|
shift = 0;
|
|
else {
|
|
shift = 16;
|
|
*tex_cntl_c |= R128_SEC_SELECT_SEC_ST;
|
|
}
|
|
|
|
/* ATILog2 returns -1 for value of 0 */
|
|
l2w = ATILog2(w - 1) + 1;
|
|
l2h = ATILog2(h - 1) + 1;
|
|
l2p = ATILog2(pPix->devKind / bytepp);
|
|
|
|
if (pPict->repeat && w == 1 && h == 1)
|
|
l2p = 0;
|
|
else if (pPict->repeat && l2p != l2w)
|
|
ATI_FALLBACK(("Repeat not supported for pitch != width\n"));
|
|
l2w = l2p;
|
|
|
|
widths[unit] = 1 << l2w;
|
|
heights[unit] = 1 << l2h;
|
|
*txsize |= l2p << (R128_TEX_PITCH_SHIFT + shift);
|
|
*txsize |= ((l2w > l2h) ? l2w : l2h) << (R128_TEX_SIZE_SHIFT + shift);
|
|
*txsize |= l2h << (R128_TEX_HEIGHT_SHIFT + shift);
|
|
|
|
if (pPict->transform != 0) {
|
|
is_transform[unit] = TRUE;
|
|
transform[unit] = pPict->transform;
|
|
} else {
|
|
is_transform[unit] = FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
R128PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
|
PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
|
|
{
|
|
KdScreenPriv(pDst->drawable.pScreen);
|
|
ATIScreenInfo(pScreenPriv);
|
|
CARD32 txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
|
|
CARD32 dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
|
|
int i;
|
|
RING_LOCALS;
|
|
|
|
accel_atis = atis;
|
|
|
|
if (pDstPicture->format == PICT_a8)
|
|
dstDatatype = R128_DATATYPE_Y8;
|
|
else
|
|
R128GetDatatypePict(pDstPicture->format, &dstDatatype);
|
|
|
|
if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c))
|
|
return FALSE;
|
|
if (pMask != NULL && !R128TextureSetup(pMaskPicture, pMask, 1, &txsize,
|
|
&sec_tex_cntl_c))
|
|
return FALSE;
|
|
else if (pMask == NULL)
|
|
is_transform[1] = FALSE;
|
|
|
|
if (!ATIGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
|
|
return FALSE;
|
|
|
|
BEGIN_DMA(12);
|
|
OUT_REG(R128_REG_SCALE_3D_CNTL,
|
|
R128_SCALE_3D_TEXMAP_SHADE |
|
|
R128_SCALE_PIX_REPLICATE |
|
|
R128_TEX_CACHE_SPLIT |
|
|
R128_TEX_MAP_ALPHA_IN_TEXTURE |
|
|
R128_TEX_CACHE_LINE_SIZE_4QW);
|
|
OUT_REG(ATI_REG_DST_PITCH_OFFSET, dst_pitch_offset);
|
|
OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL,
|
|
ATI_GMC_DST_PITCH_OFFSET_CNTL |
|
|
ATI_GMC_BRUSH_SOLID_COLOR |
|
|
(dstDatatype << 8) |
|
|
ATI_GMC_SRC_DATATYPE_COLOR |
|
|
(ATIBltRop[GXcopy] << 16) |
|
|
ATI_DP_SRC_SOURCE_MEMORY |
|
|
R128_GMC_3D_FCN_EN |
|
|
ATI_GMC_CLR_CMP_CNTL_DIS |
|
|
R128_GMC_AUX_CLIP_DIS |
|
|
ATI_GMC_WR_MSK_DIS);
|
|
OUT_REG(R128_REG_MISC_3D_STATE_CNTL,
|
|
R128_MISC_SCALE_3D_TEXMAP_SHADE |
|
|
R128_MISC_SCALE_PIX_REPLICATE |
|
|
R128_ALPHA_COMB_ADD_CLAMP |
|
|
R128BlendOp[op].blendctl);
|
|
OUT_REG(R128_REG_TEX_CNTL_C,
|
|
R128_TEXMAP_ENABLE |
|
|
((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
|
|
R128_ALPHA_ENABLE |
|
|
R128_TEX_CACHE_FLUSH);
|
|
OUT_REG(R128_REG_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
|
|
END_DMA();
|
|
|
|
/* IN operator: Without a mask, only the first texture unit is enabled.
|
|
* With a mask, we put the source in the first unit and have it pass
|
|
* through as input to the 2nd. The 2nd unit takes the incoming source
|
|
* pixel and modulates it with either the alpha or each of the channels
|
|
* in the mask, depending on componentAlpha.
|
|
*/
|
|
BEGIN_DMA(15);
|
|
/* R128_REG_PRIM_TEX_CNTL_C,
|
|
* R128_REG_PRIM_TEXTURE_COMBINE_CNTL_C,
|
|
* R128_REG_TEX_SIZE_PITCH_C,
|
|
* R128_REG_PRIM_TEX_0_OFFSET_C - R128_REG_PRIM_TEX_10_OFFSET_C
|
|
*/
|
|
OUT_RING(DMA_PACKET0(R128_REG_PRIM_TEX_CNTL_C, 14));
|
|
OUT_RING(prim_tex_cntl_c);
|
|
|
|
/* If this is the only stage and the dest is a8, route the alpha result
|
|
* to the color (red channel, in particular), too. Otherwise, be sure
|
|
* to zero out color channels of an a8 source.
|
|
*/
|
|
if (pMaskPicture == NULL && pDstPicture->format == PICT_a8)
|
|
color_factor = R128_COLOR_FACTOR_ALPHA;
|
|
else if (pSrcPicture->format == PICT_a8)
|
|
color_factor = R128_COLOR_FACTOR_CONST_COLOR;
|
|
else
|
|
color_factor = R128_COLOR_FACTOR_TEX;
|
|
|
|
if (PICT_FORMAT_A(pSrcPicture->format) == 0)
|
|
alpha_comb = R128_COMB_ALPHA_COPY_INP;
|
|
else
|
|
alpha_comb = R128_COMB_ALPHA_DIS;
|
|
|
|
OUT_RING(R128_COMB_COPY |
|
|
color_factor |
|
|
R128_INPUT_FACTOR_INT_COLOR |
|
|
alpha_comb |
|
|
R128_ALPHA_FACTOR_TEX_ALPHA |
|
|
R128_INP_FACTOR_A_CONST_ALPHA);
|
|
OUT_RING(txsize);
|
|
/* We could save some output by only writing the offset register that
|
|
* will actually be used. On the other hand, this is easy.
|
|
*/
|
|
for (i = 0; i <= 10; i++)
|
|
OUT_RING(((CARD8 *)pSrc->devPrivate.ptr -
|
|
pScreenPriv->screen->memory_base));
|
|
END_DMA();
|
|
|
|
if (pMask != NULL) {
|
|
BEGIN_DMA(14);
|
|
/* R128_REG_SEC_TEX_CNTL_C,
|
|
* R128_REG_SEC_TEXTURE_COMBINE_CNTL_C,
|
|
* R128_REG_SEC_TEX_0_OFFSET_C - R128_REG_SEC_TEX_10_OFFSET_C
|
|
*/
|
|
OUT_RING(DMA_PACKET0(R128_REG_SEC_TEX_CNTL_C, 13));
|
|
OUT_RING(sec_tex_cntl_c);
|
|
|
|
if (pDstPicture->format == PICT_a8) {
|
|
color_factor = R128_COLOR_FACTOR_ALPHA;
|
|
in_color_factor = R128_INPUT_FACTOR_PREV_ALPHA;
|
|
} else if (pMaskPicture->componentAlpha) {
|
|
color_factor = R128_COLOR_FACTOR_TEX;
|
|
in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
|
|
} else {
|
|
color_factor = R128_COLOR_FACTOR_ALPHA;
|
|
in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
|
|
}
|
|
|
|
OUT_RING(R128_COMB_MODULATE |
|
|
color_factor |
|
|
in_color_factor |
|
|
R128_COMB_ALPHA_MODULATE |
|
|
R128_ALPHA_FACTOR_TEX_ALPHA |
|
|
R128_INP_FACTOR_A_PREV_ALPHA);
|
|
for (i = 0; i <= 10; i++)
|
|
OUT_RING(((CARD8 *)pMask->devPrivate.ptr -
|
|
pScreenPriv->screen->memory_base));
|
|
END_DMA();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
union intfloat {
|
|
float f;
|
|
CARD32 i;
|
|
};
|
|
|
|
struct blend_vertex {
|
|
union intfloat x, y, z, w;
|
|
union intfloat s0, t0;
|
|
union intfloat s1, t1;
|
|
};
|
|
|
|
#define VTX_RING_COUNT 8
|
|
|
|
#define VTX_OUT(vtx) \
|
|
do { \
|
|
OUT_RING(vtx.x.i); \
|
|
OUT_RING(vtx.y.i); \
|
|
OUT_RING(vtx.z.i); \
|
|
OUT_RING(vtx.w.i); \
|
|
OUT_RING(vtx.s0.i); \
|
|
OUT_RING(vtx.t0.i); \
|
|
OUT_RING(vtx.s1.i); \
|
|
OUT_RING(vtx.t1.i); \
|
|
} while (0)
|
|
|
|
void
|
|
R128Composite(int srcX, int srcY, int maskX, int maskY, int dstX, int dstY,
|
|
int w, int h)
|
|
{
|
|
ATIScreenInfo *atis = accel_atis;
|
|
struct blend_vertex vtx[4];
|
|
int i;
|
|
int srcXend, srcYend, maskXend, maskYend;
|
|
RING_LOCALS;
|
|
|
|
/*ErrorF("R128Composite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
|
|
srcX, srcY, maskX, maskY,dstX, dstY, w, h);*/
|
|
|
|
if (is_transform[0]) {
|
|
PictVector v;
|
|
|
|
v.vector[0] = IntToxFixed(srcX);
|
|
v.vector[1] = IntToxFixed(srcY);
|
|
v.vector[3] = xFixed1;
|
|
PictureTransformPoint(transform[0], &v);
|
|
srcX = xFixedToInt(v.vector[0]);
|
|
srcY = xFixedToInt(v.vector[1]);
|
|
v.vector[0] = IntToxFixed(srcX + w);
|
|
v.vector[1] = IntToxFixed(srcY + h);
|
|
v.vector[3] = xFixed1;
|
|
PictureTransformPoint(transform[0], &v);
|
|
srcXend = xFixedToInt(v.vector[0]);
|
|
srcYend = xFixedToInt(v.vector[1]);
|
|
} else {
|
|
srcXend = srcX + w;
|
|
srcYend = srcY + h;
|
|
}
|
|
if (is_transform[1]) {
|
|
PictVector v;
|
|
|
|
v.vector[0] = IntToxFixed(maskX);
|
|
v.vector[1] = IntToxFixed(maskY);
|
|
v.vector[3] = xFixed1;
|
|
PictureTransformPoint(transform[1], &v);
|
|
maskX = xFixedToInt(v.vector[0]);
|
|
maskY = xFixedToInt(v.vector[1]);
|
|
v.vector[0] = IntToxFixed(maskX + w);
|
|
v.vector[1] = IntToxFixed(maskY + h);
|
|
v.vector[3] = xFixed1;
|
|
PictureTransformPoint(transform[1], &v);
|
|
maskXend = xFixedToInt(v.vector[0]);
|
|
maskYend = xFixedToInt(v.vector[1]);
|
|
} else {
|
|
maskXend = maskX + w;
|
|
maskYend = maskY + h;
|
|
}
|
|
vtx[0].x.f = dstX;
|
|
vtx[0].y.f = dstY;
|
|
vtx[0].z.f = 0.0;
|
|
vtx[0].w.f = 1.0;
|
|
vtx[0].s0.f = srcX;
|
|
vtx[0].t0.f = srcY;
|
|
vtx[0].s1.f = maskX;
|
|
vtx[0].t1.f = maskY;
|
|
|
|
vtx[1].x.f = dstX;
|
|
vtx[1].y.f = dstY + h;
|
|
vtx[1].z.f = 0.0;
|
|
vtx[1].w.f = 1.0;
|
|
vtx[1].s0.f = srcX;
|
|
vtx[1].t0.f = srcYend;
|
|
vtx[1].s1.f = maskX;
|
|
vtx[1].t1.f = maskYend;
|
|
|
|
vtx[2].x.f = dstX + w;
|
|
vtx[2].y.f = dstY + h;
|
|
vtx[2].z.f = 0.0;
|
|
vtx[2].w.f = 1.0;
|
|
vtx[2].s0.f = srcXend;
|
|
vtx[2].t0.f = srcYend;
|
|
vtx[2].s1.f = maskXend;
|
|
vtx[2].t1.f = maskYend;
|
|
|
|
vtx[3].x.f = dstX + w;
|
|
vtx[3].y.f = dstY;
|
|
vtx[3].z.f = 0.0;
|
|
vtx[3].w.f = 1.0;
|
|
vtx[3].s0.f = srcXend;
|
|
vtx[3].t0.f = srcY;
|
|
vtx[3].s1.f = maskXend;
|
|
vtx[3].t1.f = maskY;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
vtx[i].x.f += 0.0;
|
|
vtx[i].y.f += 0.125;
|
|
vtx[i].s0.f /= widths[0];
|
|
vtx[i].t0.f /= heights[0];
|
|
vtx[i].s1.f /= widths[1];
|
|
vtx[i].t1.f /= heights[1];
|
|
}
|
|
|
|
BEGIN_DMA(3 + 4 * VTX_RING_COUNT);
|
|
OUT_RING(DMA_PACKET3(ATI_CCE_PACKET3_3D_RNDR_GEN_PRIM,
|
|
2 + 4 * VTX_RING_COUNT));
|
|
OUT_RING(R128_CCE_VC_FRMT_RHW |
|
|
R128_CCE_VC_FRMT_S_T |
|
|
R128_CCE_VC_FRMT_S2_T2);
|
|
OUT_RING(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
|
|
R128_CCE_VC_CNTL_PRIM_WALK_RING |
|
|
(4 << R128_CCE_VC_CNTL_NUM_SHIFT));
|
|
|
|
VTX_OUT(vtx[0]);
|
|
VTX_OUT(vtx[1]);
|
|
VTX_OUT(vtx[2]);
|
|
VTX_OUT(vtx[3]);
|
|
|
|
END_DMA();
|
|
}
|
|
|
|
void
|
|
R128DoneComposite(void)
|
|
{
|
|
}
|