990 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			990 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 2004 Keith Packard
 | 
						|
 * Copyright © 2005 Eric Anholt
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 *
 | 
						|
 * Based on mach64video.c by Keith Packard.
 | 
						|
 */
 | 
						|
/* $RCSId$ */
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
#include "ati.h"
 | 
						|
#include "ati_dma.h"
 | 
						|
#include "ati_draw.h"
 | 
						|
#include "ati_reg.h"
 | 
						|
#include "kaa.h"
 | 
						|
 | 
						|
#include <X11/extensions/Xv.h>
 | 
						|
#include "fourcc.h"
 | 
						|
 | 
						|
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 | 
						|
 | 
						|
static Atom xvBrightness, xvSaturation;
 | 
						|
 | 
						|
extern CARD8 ATIBltRop[16];
 | 
						|
 | 
						|
#define IMAGE_MAX_WIDTH		2048
 | 
						|
#define IMAGE_MAX_HEIGHT	2048
 | 
						|
 | 
						|
static void
 | 
						|
ATIStopVideo(KdScreenInfo *screen, pointer data, Bool exit)
 | 
						|
{
 | 
						|
	ScreenPtr pScreen = screen->pScreen;
 | 
						|
	ATIPortPrivPtr pPortPriv = (ATIPortPrivPtr)data;
 | 
						|
 | 
						|
	REGION_EMPTY(screen->pScreen, &pPortPriv->clip);   
 | 
						|
 | 
						|
	if (pPortPriv->off_screen) {
 | 
						|
		KdOffscreenFree (pScreen, pPortPriv->off_screen);
 | 
						|
		pPortPriv->off_screen = 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ATISetPortAttribute(KdScreenInfo *screen, Atom attribute, int value,
 | 
						|
    pointer data)
 | 
						|
{
 | 
						|
	return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ATIGetPortAttribute(KdScreenInfo *screen, Atom attribute, int *value,
 | 
						|
    pointer data)
 | 
						|
{
 | 
						|
	return BadMatch;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ATIQueryBestSize(KdScreenInfo *screen, Bool motion, short vid_w, short vid_h,
 | 
						|
    short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h,
 | 
						|
    pointer data)
 | 
						|
{
 | 
						|
	*p_w = drw_w;
 | 
						|
	*p_h = drw_h;
 | 
						|
}
 | 
						|
 | 
						|
/* ATIClipVideo -  
 | 
						|
 | 
						|
   Takes the dst box in standard X BoxRec form (top and left
 | 
						|
   edges inclusive, bottom and right exclusive).  The new dst
 | 
						|
   box is returned.  The source boundaries are given (x1, y1 
 | 
						|
   inclusive, x2, y2 exclusive) and returned are the new source 
 | 
						|
   boundaries in 16.16 fixed point. 
 | 
						|
*/
 | 
						|
 | 
						|
static void
 | 
						|
ATIClipVideo(BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2,
 | 
						|
    BoxPtr extents, INT32 width, INT32 height)
 | 
						|
{
 | 
						|
	INT32 vscale, hscale, delta;
 | 
						|
	int diff;
 | 
						|
 | 
						|
	hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
 | 
						|
	vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
 | 
						|
 | 
						|
	*x1 <<= 16; *x2 <<= 16;
 | 
						|
	*y1 <<= 16; *y2 <<= 16;
 | 
						|
 | 
						|
	diff = extents->x1 - dst->x1;
 | 
						|
	if (diff > 0) {
 | 
						|
		dst->x1 = extents->x1;
 | 
						|
		*x1 += diff * hscale;
 | 
						|
	}
 | 
						|
	diff = dst->x2 - extents->x2;
 | 
						|
	if (diff > 0) {
 | 
						|
		dst->x2 = extents->x2;
 | 
						|
		*x2 -= diff * hscale;
 | 
						|
	}
 | 
						|
	diff = extents->y1 - dst->y1;
 | 
						|
	if (diff > 0) {
 | 
						|
		dst->y1 = extents->y1;
 | 
						|
		*y1 += diff * vscale;
 | 
						|
	}
 | 
						|
	diff = dst->y2 - extents->y2;
 | 
						|
	if (diff > 0) {
 | 
						|
		dst->y2 = extents->y2;
 | 
						|
		*y2 -= diff * vscale;
 | 
						|
	}
 | 
						|
 | 
						|
	if (*x1 < 0) {
 | 
						|
		diff =  (- *x1 + hscale - 1)/ hscale;
 | 
						|
		dst->x1 += diff;
 | 
						|
		*x1 += diff * hscale;
 | 
						|
	}
 | 
						|
	delta = *x2 - (width << 16);
 | 
						|
	if (delta > 0) {
 | 
						|
		diff = (delta + hscale - 1)/ hscale;
 | 
						|
		dst->x2 -= diff;
 | 
						|
		*x2 -= diff * hscale;
 | 
						|
	}
 | 
						|
	if (*y1 < 0) {
 | 
						|
		diff =  (- *y1 + vscale - 1)/ vscale;
 | 
						|
		dst->y1 += diff;
 | 
						|
		*y1 += diff * vscale;
 | 
						|
	}
 | 
						|
	delta = *y2 - (height << 16);
 | 
						|
	if (delta > 0) {
 | 
						|
		diff = (delta + vscale - 1)/ vscale;
 | 
						|
		dst->y2 -= diff;
 | 
						|
		*y2 -= diff * vscale;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
R128DisplayVideo(KdScreenInfo *screen, ATIPortPrivPtr pPortPriv)
 | 
						|
{
 | 
						|
	ScreenPtr pScreen = screen->pScreen;
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	CARD32 dstDatatype, srcDatatype;
 | 
						|
	CARD32 dst_offset, dst_pitch;
 | 
						|
	int dstxoff, dstyoff;
 | 
						|
	PixmapPtr pPixmap = pPortPriv->pPixmap;
 | 
						|
	int bpp = pPixmap->drawable.bitsPerPixel;
 | 
						|
	RING_LOCALS;
 | 
						|
 | 
						|
	BoxPtr pBox = REGION_RECTS(&pPortPriv->clip);
 | 
						|
	int nBox = REGION_NUM_RECTS(&pPortPriv->clip);
 | 
						|
 | 
						|
	if (pPortPriv->id == FOURCC_UYVY)
 | 
						|
		srcDatatype = R128_DATATYPE_YVYU_422;
 | 
						|
	else
 | 
						|
		srcDatatype = R128_DATATYPE_VYUY_422;
 | 
						|
 | 
						|
	switch (bpp)
 | 
						|
	{
 | 
						|
	case 16:
 | 
						|
		if (pPixmap->drawable.depth == 15)
 | 
						|
			dstDatatype = R128_DATATYPE_ARGB1555;
 | 
						|
		else
 | 
						|
			dstDatatype = R128_DATATYPE_RGB565;
 | 
						|
		break;
 | 
						|
	case 32:
 | 
						|
		dstDatatype = R128_DATATYPE_ARGB8888;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	dst_offset = ((CARD8 *)pPixmap->devPrivate.ptr -
 | 
						|
	    pScreenPriv->screen->memory_base);
 | 
						|
	dst_pitch = pPixmap->devKind;
 | 
						|
#ifdef COMPOSITE
 | 
						|
	dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
 | 
						|
	dstyoff = -pPixmap->screen_y + pPixmap->drawable.y;
 | 
						|
#else
 | 
						|
	dstxoff = 0;
 | 
						|
	dstyoff = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
	BEGIN_DMA(18);
 | 
						|
	OUT_REG(ATI_REG_DST_PITCH_OFFSET,
 | 
						|
	    ((dst_pitch / bpp) << 21) | (dst_offset >> 5));
 | 
						|
	OUT_REG(ATI_REG_DP_GUI_MASTER_CNTL,
 | 
						|
	    ATI_GMC_DST_PITCH_OFFSET_CNTL |
 | 
						|
	    ATI_GMC_BRUSH_NONE |
 | 
						|
	    (dstDatatype << 8) |
 | 
						|
	    ATI_GMC_SRC_DATATYPE_COLOR |
 | 
						|
	    (ATIBltRop[GXcopy] << 16) |
 | 
						|
	    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_SBLEND_ONE |
 | 
						|
	    R128_DBLEND_ZERO);
 | 
						|
	OUT_REG(R128_REG_TEX_CNTL_C, R128_TEX_CACHE_FLUSH);
 | 
						|
	OUT_REG(R128_REG_SCALE_3D_DATATYPE, srcDatatype);
 | 
						|
 | 
						|
	OUT_RING(DMA_PACKET0(R128_REG_SCALE_PITCH, 5));
 | 
						|
	OUT_RING_REG(R128_REG_SCALE_PITCH, pPortPriv->src_pitch / 16);
 | 
						|
	OUT_RING_REG(R128_REG_SCALE_X_INC,
 | 
						|
	    (pPortPriv->src_w << 16) / pPortPriv->dst_w);
 | 
						|
	OUT_RING_REG(R128_REG_SCALE_Y_INC,
 | 
						|
	    (pPortPriv->src_h << 16) / pPortPriv->dst_h);
 | 
						|
	OUT_RING_REG(R128_REG_SCALE_HACC, 0x0);
 | 
						|
	OUT_RING_REG(R128_REG_SCALE_VACC, 0x0);
 | 
						|
 | 
						|
	END_DMA();
 | 
						|
 | 
						|
	while (nBox--) {
 | 
						|
		int srcX, srcY, dstX, dstY, srcw, srch, dstw, dsth;
 | 
						|
 | 
						|
		dstX = pBox->x1 + dstxoff;
 | 
						|
		dstY = pBox->y1 + dstyoff;
 | 
						|
		dstw = pBox->x2 - pBox->x1;
 | 
						|
		dsth = pBox->y2 - pBox->y1;
 | 
						|
		srcX = (pBox->x1 - pPortPriv->dst_x1) *
 | 
						|
		    pPortPriv->src_w / pPortPriv->dst_w;
 | 
						|
		srcY = (pBox->y1 - pPortPriv->dst_y1) *
 | 
						|
		    pPortPriv->src_h / pPortPriv->dst_h;
 | 
						|
		srcw = pPortPriv->src_w - srcX;
 | 
						|
		srch = pPortPriv->src_h - srcY;
 | 
						|
 | 
						|
		BEGIN_DMA(6);
 | 
						|
		OUT_RING(DMA_PACKET0(R128_REG_SCALE_SRC_HEIGHT_WIDTH, 2));
 | 
						|
		OUT_RING_REG(R128_REG_SCALE_SRC_HEIGHT_WIDTH,
 | 
						|
		    (srch << 16) | srcw);
 | 
						|
		OUT_RING_REG(R128_REG_SCALE_OFFSET_0, pPortPriv->src_offset +
 | 
						|
		    srcY * pPortPriv->src_pitch + srcX * 2);
 | 
						|
 | 
						|
		OUT_RING(DMA_PACKET0(R128_REG_SCALE_DST_X_Y, 2));
 | 
						|
		OUT_RING_REG(R128_REG_SCALE_DST_X_Y, (dstX << 16) | dstY);
 | 
						|
		OUT_RING_REG(R128_REG_SCALE_DST_HEIGHT_WIDTH,
 | 
						|
		    (dsth << 16) | dstw);
 | 
						|
		END_DMA();
 | 
						|
		pBox++;
 | 
						|
	}
 | 
						|
#ifdef DAMAGEEXT
 | 
						|
	/* XXX: Shouldn't this be in kxv.c instead? */
 | 
						|
	DamageDamageRegion(pPortPriv->pDraw, &pPortPriv->clip);
 | 
						|
#endif
 | 
						|
	kaaMarkSync(pScreen);
 | 
						|
}
 | 
						|
 | 
						|
union intfloat {
 | 
						|
	float f;
 | 
						|
	CARD32 i;
 | 
						|
};
 | 
						|
 | 
						|
struct blend_vertex {
 | 
						|
	union intfloat x, y;
 | 
						|
	union intfloat s0, t0;
 | 
						|
};
 | 
						|
 | 
						|
#define VTX_DWORD_COUNT 4
 | 
						|
 | 
						|
#define VTX_OUT(vtx)		\
 | 
						|
do {				\
 | 
						|
	OUT_RING(vtx.x.i);	\
 | 
						|
	OUT_RING(vtx.y.i);	\
 | 
						|
	OUT_RING(vtx.s0.i);	\
 | 
						|
	OUT_RING(vtx.t0.i);	\
 | 
						|
} while (0)
 | 
						|
 | 
						|
static void
 | 
						|
RadeonDisplayVideo(KdScreenInfo *screen, ATIPortPrivPtr pPortPriv)
 | 
						|
{
 | 
						|
	ScreenPtr pScreen = screen->pScreen;
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATICardInfo(pScreenPriv);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	struct blend_vertex vtx[4];
 | 
						|
	PixmapPtr pPixmap = pPortPriv->pPixmap;
 | 
						|
	CARD32 txformat;
 | 
						|
	CARD32 dst_offset, dst_pitch, dst_format;
 | 
						|
	int dstxoff, dstyoff, pixel_shift;
 | 
						|
	RING_LOCALS;
 | 
						|
 | 
						|
	BoxPtr pBox = REGION_RECTS(&pPortPriv->clip);
 | 
						|
	int nBox = REGION_NUM_RECTS(&pPortPriv->clip);
 | 
						|
 | 
						|
	switch (pPixmap->drawable.bitsPerPixel) {
 | 
						|
	case 16:
 | 
						|
		if (pPixmap->drawable.depth == 15)
 | 
						|
			dst_format = RADEON_COLOR_FORMAT_ARGB1555;
 | 
						|
		else
 | 
						|
			dst_format = RADEON_COLOR_FORMAT_RGB565;
 | 
						|
		pixel_shift = 1;
 | 
						|
		break;
 | 
						|
	case 32:
 | 
						|
		dst_format = RADEON_COLOR_FORMAT_ARGB8888;
 | 
						|
		pixel_shift = 2;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	dst_offset = ((CARD8 *)pPixmap->devPrivate.ptr -
 | 
						|
	    pScreenPriv->screen->memory_base);
 | 
						|
	dst_pitch = pPixmap->devKind;
 | 
						|
 | 
						|
#ifdef COMPOSITE
 | 
						|
	dstxoff = -pPixmap->screen_x + pPixmap->drawable.x;
 | 
						|
	dstyoff = -pPixmap->screen_y + pPixmap->drawable.y;
 | 
						|
#else
 | 
						|
	dstxoff = 0;
 | 
						|
	dstyoff = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
	/* Same for R100/R200 */
 | 
						|
	if (pPortPriv->id == FOURCC_UYVY)
 | 
						|
		txformat = RADEON_TXFORMAT_YVYU422;
 | 
						|
	else
 | 
						|
		txformat = RADEON_TXFORMAT_VYUY422;
 | 
						|
 | 
						|
	txformat |= RADEON_TXFORMAT_NON_POWER2;
 | 
						|
 | 
						|
	RadeonSwitchTo3D(atis);
 | 
						|
 | 
						|
	BEGIN_DMA(8);
 | 
						|
 | 
						|
	OUT_RING(DMA_PACKET0(RADEON_REG_PP_CNTL, 3));
 | 
						|
	OUT_RING_REG(RADEON_REG_PP_CNTL,
 | 
						|
	    RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE);
 | 
						|
	OUT_RING_REG(RADEON_REG_RB3D_CNTL,
 | 
						|
	    dst_format | RADEON_ALPHA_BLEND_ENABLE);
 | 
						|
	OUT_RING_REG(RADEON_REG_RB3D_COLOROFFSET, dst_offset);
 | 
						|
 | 
						|
	OUT_REG(RADEON_REG_RB3D_COLORPITCH, dst_pitch >> pixel_shift);
 | 
						|
 | 
						|
	OUT_REG(RADEON_REG_RB3D_BLENDCNTL,
 | 
						|
	    RADEON_SBLEND_GL_ONE | RADEON_DBLEND_GL_ZERO);
 | 
						|
 | 
						|
	END_DMA();
 | 
						|
 | 
						|
	if (atic->is_r200) {
 | 
						|
		BEGIN_DMA(17);
 | 
						|
 | 
						|
		OUT_REG(R200_REG_SE_VTX_FMT_0, R200_VTX_XY);
 | 
						|
		OUT_REG(R200_REG_SE_VTX_FMT_1,
 | 
						|
		    (2 << R200_VTX_TEX0_COMP_CNT_SHIFT));
 | 
						|
 | 
						|
		OUT_RING(DMA_PACKET0(R200_REG_PP_TXFILTER_0, 5));
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXFILTER_0,
 | 
						|
		    R200_MAG_FILTER_LINEAR |
 | 
						|
		    R200_MIN_FILTER_LINEAR |
 | 
						|
		    R200_YUV_TO_RGB);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXFORMAT_0, txformat);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXFORMAT_X_0, 0);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXSIZE_0,
 | 
						|
		    (pPixmap->drawable.width - 1) |
 | 
						|
		    ((pPixmap->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXPITCH_0, pPortPriv->src_pitch - 32);
 | 
						|
 | 
						|
		OUT_REG(R200_PP_TXOFFSET_0, pPortPriv->src_offset);
 | 
						|
 | 
						|
		OUT_RING(DMA_PACKET0(R200_REG_PP_TXCBLEND_0, 4));
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXCBLEND_0,
 | 
						|
		    R200_TXC_ARG_A_ZERO |
 | 
						|
		    R200_TXC_ARG_B_ZERO |
 | 
						|
		    R200_TXC_ARG_C_R0_COLOR |
 | 
						|
		    R200_TXC_OP_MADD);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXCBLEND2_0,
 | 
						|
		    R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXABLEND_0,
 | 
						|
		    R200_TXA_ARG_A_ZERO |
 | 
						|
		    R200_TXA_ARG_B_ZERO |
 | 
						|
		    R200_TXA_ARG_C_R0_ALPHA |
 | 
						|
		    R200_TXA_OP_MADD);
 | 
						|
		OUT_RING_REG(R200_REG_PP_TXABLEND2_0,
 | 
						|
		    R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0);
 | 
						|
 | 
						|
		END_DMA();
 | 
						|
	} else {
 | 
						|
//		BEGIN_DMA(11);
 | 
						|
		BEGIN_DMA(9);
 | 
						|
 | 
						|
		OUT_RING(DMA_PACKET0(RADEON_REG_PP_TXFILTER_0, 5));
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TXFILTER_0, RADEON_MAG_FILTER_LINEAR |
 | 
						|
		    RADEON_MIN_FILTER_LINEAR |
 | 
						|
		    RADEON_YUV_TO_RGB);
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TXFORMAT_0, txformat);
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TXOFFSET_0, pPortPriv->src_offset);
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TXCBLEND_0,
 | 
						|
		    RADEON_COLOR_ARG_A_ZERO |
 | 
						|
		    RADEON_COLOR_ARG_B_ZERO |
 | 
						|
		    RADEON_COLOR_ARG_C_T0_COLOR |
 | 
						|
		    RADEON_BLEND_CTL_ADD |
 | 
						|
		    RADEON_CLAMP_TX);
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TXABLEND_0,
 | 
						|
		    RADEON_ALPHA_ARG_A_ZERO |
 | 
						|
		    RADEON_ALPHA_ARG_B_ZERO |
 | 
						|
		    RADEON_ALPHA_ARG_C_T0_ALPHA |
 | 
						|
		    RADEON_BLEND_CTL_ADD |
 | 
						|
		    RADEON_CLAMP_TX);
 | 
						|
 | 
						|
		OUT_RING(DMA_PACKET0(RADEON_REG_PP_TEX_SIZE_0, 2));
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TEX_SIZE_0,
 | 
						|
		    (pPixmap->drawable.width - 1) |
 | 
						|
		    ((pPixmap->drawable.height - 1) << RADEON_TEX_VSIZE_SHIFT));
 | 
						|
		OUT_RING_REG(RADEON_REG_PP_TEX_PITCH_0,
 | 
						|
		    pPortPriv->src_pitch - 32);
 | 
						|
 | 
						|
//	        OUT_RING_REG(ATI_REG_WAIT_UNTIL, ATI_WAIT_CRTC_VLINE);
 | 
						|
 | 
						|
		END_DMA();
 | 
						|
	}
 | 
						|
 | 
						|
	while (nBox--) {
 | 
						|
		float srcX, srcY, dstX, dstY, srcw, srch, dstw, dsth;
 | 
						|
 | 
						|
		dstX = pBox->x1 + dstxoff;
 | 
						|
		dstY = pBox->y1 + dstyoff;
 | 
						|
		dstw = pBox->x2 - pBox->x1;
 | 
						|
		dsth = pBox->y2 - pBox->y1;
 | 
						|
		srcX = (pBox->x1 - pPortPriv->dst_x1) *
 | 
						|
		    pPortPriv->src_w / pPortPriv->dst_w;
 | 
						|
		srcY = (pBox->y1 - pPortPriv->dst_y1) *
 | 
						|
		    pPortPriv->src_h / pPortPriv->dst_h;
 | 
						|
		srcw = pPortPriv->src_w * (dstw / pPortPriv->dst_w);
 | 
						|
		srch = pPortPriv->src_h * (dsth / pPortPriv->dst_h);
 | 
						|
 | 
						|
		/*
 | 
						|
		 * rectangle:
 | 
						|
		 *
 | 
						|
		 *  +---------2
 | 
						|
		 *  |         |
 | 
						|
		 *  |         |
 | 
						|
		 *  0---------1
 | 
						|
		 */
 | 
						|
		
 | 
						|
		vtx[0].x.f = dstX;
 | 
						|
		vtx[0].y.f = dstY + dsth;
 | 
						|
		vtx[0].s0.f = srcX;
 | 
						|
		vtx[0].t0.f = srcY + srch;
 | 
						|
 | 
						|
		vtx[1].x.f = dstX + dstw;
 | 
						|
		vtx[1].y.f = dstY + dsth;
 | 
						|
		vtx[1].s0.f = srcX + srcw;
 | 
						|
		vtx[1].t0.f = srcY + srch;
 | 
						|
 | 
						|
		vtx[2].x.f = dstX + dstw;
 | 
						|
		vtx[2].y.f = dstY;
 | 
						|
		vtx[2].s0.f = srcX + srcw;
 | 
						|
		vtx[2].t0.f = srcY;
 | 
						|
 | 
						|
		if (atic->is_r100) {
 | 
						|
			BEGIN_DMA(3 * VTX_DWORD_COUNT + 3);
 | 
						|
			OUT_RING(DMA_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD,
 | 
						|
			    3 * VTX_DWORD_COUNT + 2));
 | 
						|
			OUT_RING(RADEON_CP_VC_FRMT_XY |
 | 
						|
			    RADEON_CP_VC_FRMT_ST0);
 | 
						|
			OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST |
 | 
						|
			    RADEON_CP_VC_CNTL_PRIM_WALK_RING |
 | 
						|
			    RADEON_CP_VC_CNTL_MAOS_ENABLE |
 | 
						|
			    RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE |
 | 
						|
			    (3 << RADEON_CP_VC_CNTL_NUM_SHIFT));
 | 
						|
		} else {
 | 
						|
			BEGIN_DMA(3 * VTX_DWORD_COUNT + 2);
 | 
						|
			OUT_RING(DMA_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2,
 | 
						|
			    3 * VTX_DWORD_COUNT + 1));
 | 
						|
			OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST |
 | 
						|
			    RADEON_CP_VC_CNTL_PRIM_WALK_RING |
 | 
						|
			    (3 << RADEON_CP_VC_CNTL_NUM_SHIFT));
 | 
						|
		}
 | 
						|
 | 
						|
		VTX_OUT(vtx[0]);
 | 
						|
		VTX_OUT(vtx[1]);
 | 
						|
		VTX_OUT(vtx[2]);
 | 
						|
		END_DMA();
 | 
						|
 | 
						|
		pBox++;
 | 
						|
	}
 | 
						|
#ifdef DAMAGEEXT
 | 
						|
	/* XXX: Shouldn't this be in kxv.c instead? */
 | 
						|
	DamageDamageRegion(pPortPriv->pDraw, &pPortPriv->clip);
 | 
						|
#endif
 | 
						|
	kaaMarkSync(pScreen);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ATIVideoSave(ScreenPtr pScreen, KdOffscreenArea *area)
 | 
						|
{
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	ATIPortPrivPtr pPortPriv = atis->pAdaptor->pPortPrivates[0].ptr;
 | 
						|
 | 
						|
	if (pPortPriv->off_screen == area)
 | 
						|
		pPortPriv->off_screen = 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ATIPutImage(KdScreenInfo *screen, DrawablePtr pDraw,
 | 
						|
	       short src_x, short src_y,
 | 
						|
	       short drw_x, short drw_y,
 | 
						|
	       short src_w, short src_h,
 | 
						|
	       short drw_w, short drw_h,
 | 
						|
	       int id,
 | 
						|
	       unsigned char *buf,
 | 
						|
	       short width,
 | 
						|
	       short height,
 | 
						|
	       Bool sync,
 | 
						|
	       RegionPtr clipBoxes,
 | 
						|
	       pointer data)
 | 
						|
{
 | 
						|
	ScreenPtr pScreen = screen->pScreen;
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATICardInfo(pScreenPriv);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	ATIPortPrivPtr pPortPriv = (ATIPortPrivPtr)data;
 | 
						|
	char *mmio = atic->reg_base;
 | 
						|
	INT32 x1, x2, y1, y2;
 | 
						|
	int randr = RR_Rotate_0 /* XXX */;
 | 
						|
	int srcPitch, srcPitch2, dstPitch;
 | 
						|
	int top, left, npixels, nlines, size;
 | 
						|
	BoxRec dstBox;
 | 
						|
	int dst_width = width, dst_height = height;
 | 
						|
	int rot_x1, rot_y1, rot_x2, rot_y2;
 | 
						|
	int dst_x1, dst_y1, dst_x2, dst_y2;
 | 
						|
	int rot_src_w, rot_src_h, rot_drw_w, rot_drw_h;
 | 
						|
 | 
						|
	/* Clip */
 | 
						|
	x1 = src_x;
 | 
						|
	x2 = src_x + src_w;
 | 
						|
	y1 = src_y;
 | 
						|
	y2 = src_y + src_h;
 | 
						|
 | 
						|
	dstBox.x1 = drw_x;
 | 
						|
	dstBox.x2 = drw_x + drw_w;
 | 
						|
	dstBox.y1 = drw_y;
 | 
						|
	dstBox.y2 = drw_y + drw_h;
 | 
						|
 | 
						|
	ATIClipVideo(&dstBox, &x1, &x2, &y1, &y2,
 | 
						|
	    REGION_EXTENTS(pScreen, clipBoxes), width, height);
 | 
						|
 | 
						|
	src_w = (x2 - x1) >> 16;
 | 
						|
	src_h = (y2 - y1) >> 16;
 | 
						|
	drw_w = dstBox.x2 - dstBox.x1;
 | 
						|
	drw_h = dstBox.y2 - dstBox.y1;
 | 
						|
 | 
						|
	if ((x1 >= x2) || (y1 >= y2))
 | 
						|
		return Success;
 | 
						|
 | 
						|
	if (mmio == NULL)
 | 
						|
		return BadAlloc;
 | 
						|
 | 
						|
	if (randr & (RR_Rotate_0|RR_Rotate_180)) {
 | 
						|
		dst_width = width;
 | 
						|
		dst_height = height;
 | 
						|
		rot_src_w = src_w;
 | 
						|
		rot_src_h = src_h;
 | 
						|
		rot_drw_w = drw_w;
 | 
						|
		rot_drw_h = drw_h;
 | 
						|
	} else {
 | 
						|
		dst_width = height;
 | 
						|
		dst_height = width;
 | 
						|
		rot_src_w = src_h;
 | 
						|
		rot_src_h = src_w;
 | 
						|
		rot_drw_w = drw_h;
 | 
						|
		rot_drw_h = drw_w;
 | 
						|
	}
 | 
						|
 | 
						|
	switch (randr & RR_Rotate_All) {
 | 
						|
	case RR_Rotate_0:
 | 
						|
	default:
 | 
						|
		dst_x1 = dstBox.x1;
 | 
						|
		dst_y1 = dstBox.y1;
 | 
						|
		dst_x2 = dstBox.x2;
 | 
						|
		dst_y2 = dstBox.y2;
 | 
						|
		rot_x1 = x1;
 | 
						|
		rot_y1 = y1;
 | 
						|
		rot_x2 = x2;
 | 
						|
		rot_y2 = y2;
 | 
						|
		break;
 | 
						|
	case RR_Rotate_90:
 | 
						|
		dst_x1 = dstBox.y1;
 | 
						|
		dst_y1 = screen->height - dstBox.x2;
 | 
						|
		dst_x2 = dstBox.y2;
 | 
						|
		dst_y2 = screen->height - dstBox.x1;
 | 
						|
		rot_x1 = y1;
 | 
						|
		rot_y1 = (src_w << 16) - x2;
 | 
						|
		rot_x2 = y2;
 | 
						|
		rot_y2 = (src_w << 16) - x1;
 | 
						|
		break;
 | 
						|
	case RR_Rotate_180:
 | 
						|
		dst_x1 = screen->width - dstBox.x2;
 | 
						|
		dst_y1 = screen->height - dstBox.y2;
 | 
						|
		dst_x2 = screen->width - dstBox.x1;
 | 
						|
		dst_y2 = screen->height - dstBox.y1;
 | 
						|
		rot_x1 = (src_w << 16) - x2;
 | 
						|
		rot_y1 = (src_h << 16) - y2;
 | 
						|
		rot_x2 = (src_w << 16) - x1;
 | 
						|
		rot_y2 = (src_h << 16) - y1;
 | 
						|
		break;
 | 
						|
	case RR_Rotate_270:
 | 
						|
		dst_x1 = screen->width - dstBox.y2;
 | 
						|
		dst_y1 = dstBox.x1;
 | 
						|
		dst_x2 = screen->width - dstBox.y1;
 | 
						|
		dst_y2 = dstBox.x2;
 | 
						|
		rot_x1 = (src_h << 16) - y2;
 | 
						|
		rot_y1 = x1;
 | 
						|
		rot_x2 = (src_h << 16) - y1;
 | 
						|
		rot_y2 = x2;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	switch(id) {
 | 
						|
	case FOURCC_YV12:
 | 
						|
	case FOURCC_I420:
 | 
						|
		dstPitch = ((dst_width << 1) + 15) & ~15;
 | 
						|
		srcPitch = (width + 3) & ~3;
 | 
						|
		srcPitch2 = ((width >> 1) + 3) & ~3;
 | 
						|
		size = dstPitch * dst_height;
 | 
						|
		break;
 | 
						|
	case FOURCC_UYVY:
 | 
						|
	case FOURCC_YUY2:
 | 
						|
	default:
 | 
						|
		dstPitch = ((dst_width << 1) + 15) & ~15;
 | 
						|
		srcPitch = (width << 1);
 | 
						|
		srcPitch2 = 0;
 | 
						|
		size = dstPitch * dst_height;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	if (pPortPriv->off_screen != NULL && size != pPortPriv->size) {
 | 
						|
		KdOffscreenFree(screen->pScreen, pPortPriv->off_screen);
 | 
						|
		pPortPriv->off_screen = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	if (pPortPriv->off_screen == NULL) {
 | 
						|
		pPortPriv->off_screen = KdOffscreenAlloc(screen->pScreen,
 | 
						|
		    size * 2, 64, TRUE, ATIVideoSave, pPortPriv);
 | 
						|
		if (pPortPriv->off_screen == NULL)
 | 
						|
			return BadAlloc;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	if (pDraw->type == DRAWABLE_WINDOW)
 | 
						|
		pPortPriv->pPixmap =
 | 
						|
		    (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
 | 
						|
	else
 | 
						|
		pPortPriv->pPixmap = (PixmapPtr)pDraw;
 | 
						|
 | 
						|
	/* Migrate the pixmap to offscreen if necessary. */
 | 
						|
	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap))
 | 
						|
		kaaMoveInPixmap(pPortPriv->pPixmap);
 | 
						|
 | 
						|
	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap)) {
 | 
						|
		return BadAlloc;
 | 
						|
	}
 | 
						|
 | 
						|
	pPortPriv->src_offset = pPortPriv->off_screen->offset;
 | 
						|
	pPortPriv->src_addr = (CARD8 *)(pScreenPriv->screen->memory_base +
 | 
						|
	    pPortPriv->src_offset);
 | 
						|
	pPortPriv->src_pitch = dstPitch;
 | 
						|
	pPortPriv->size = size;
 | 
						|
	pPortPriv->pDraw = pDraw;
 | 
						|
 | 
						|
	/* copy data */
 | 
						|
	top = rot_y1 >> 16;
 | 
						|
	left = (rot_x1 >> 16) & ~1;
 | 
						|
	npixels = ((((rot_x2 + 0xffff) >> 16) + 1) & ~1) - left;
 | 
						|
 | 
						|
	/* Since we're probably overwriting the area that might still be used
 | 
						|
	 * for the last PutImage request, wait for idle.
 | 
						|
	 */
 | 
						|
	ATIWaitIdle(atis);
 | 
						|
 | 
						|
	switch(id) {
 | 
						|
	case FOURCC_YV12:
 | 
						|
	case FOURCC_I420:
 | 
						|
		top &= ~1;
 | 
						|
		nlines = ((((rot_y2 + 0xffff) >> 16) + 1) & ~1) - top;
 | 
						|
		KdXVCopyPlanarData(screen, buf, pPortPriv->src_addr, randr,
 | 
						|
		    srcPitch, srcPitch2, dstPitch, rot_src_w, rot_src_h,
 | 
						|
		    height, top, left, nlines, npixels, id);
 | 
						|
		break;
 | 
						|
	case FOURCC_UYVY:
 | 
						|
	case FOURCC_YUY2:
 | 
						|
	default:
 | 
						|
		nlines = ((rot_y2 + 0xffff) >> 16) - top;
 | 
						|
		KdXVCopyPackedData(screen, buf, pPortPriv->src_addr, randr,
 | 
						|
		    srcPitch, dstPitch, rot_src_w, rot_src_h, top, left,
 | 
						|
		    nlines, npixels);
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	/* update cliplist */
 | 
						|
	if (!REGION_EQUAL(screen->pScreen, &pPortPriv->clip, clipBoxes)) {
 | 
						|
		REGION_COPY(screen->pScreen, &pPortPriv->clip, clipBoxes);
 | 
						|
	}
 | 
						|
 | 
						|
	pPortPriv->id = id;
 | 
						|
	pPortPriv->src_x1 = rot_x1;
 | 
						|
	pPortPriv->src_y1 = rot_y1;
 | 
						|
	pPortPriv->src_x2 = rot_x2;
 | 
						|
	pPortPriv->src_y2 = rot_y2;
 | 
						|
	pPortPriv->src_w = rot_src_w;
 | 
						|
	pPortPriv->src_h = rot_src_h;
 | 
						|
	pPortPriv->dst_x1 = dst_x1;
 | 
						|
	pPortPriv->dst_y1 = dst_y1;
 | 
						|
	pPortPriv->dst_x2 = dst_x2;
 | 
						|
	pPortPriv->dst_y2 = dst_y2;
 | 
						|
	pPortPriv->dst_w = rot_drw_w;
 | 
						|
	pPortPriv->dst_h = rot_drw_h;
 | 
						|
 | 
						|
	if (atic->is_radeon)
 | 
						|
		RadeonDisplayVideo(screen, pPortPriv);
 | 
						|
	else
 | 
						|
		R128DisplayVideo(screen, pPortPriv);
 | 
						|
 | 
						|
	return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ATIReputImage(KdScreenInfo *screen, DrawablePtr pDraw, short drw_x, short drw_y,
 | 
						|
    RegionPtr clipBoxes, pointer data)
 | 
						|
{
 | 
						|
	ScreenPtr pScreen = screen->pScreen;
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATICardInfo(pScreenPriv);
 | 
						|
	ATIPortPrivPtr	pPortPriv = (ATIPortPrivPtr)data;
 | 
						|
	BoxPtr pOldExtents = REGION_EXTENTS(screen->pScreen, &pPortPriv->clip);
 | 
						|
	BoxPtr pNewExtents = REGION_EXTENTS(screen->pScreen, clipBoxes);
 | 
						|
 | 
						|
	if (pOldExtents->x1 != pNewExtents->x1 ||
 | 
						|
	    pOldExtents->x2 != pNewExtents->x2 ||
 | 
						|
	    pOldExtents->y1 != pNewExtents->y1 ||
 | 
						|
	    pOldExtents->y2 != pNewExtents->y2)
 | 
						|
		return BadMatch;
 | 
						|
 | 
						|
	if (pDraw->type == DRAWABLE_WINDOW)
 | 
						|
		pPortPriv->pPixmap =
 | 
						|
		    (*pScreen->GetWindowPixmap)((WindowPtr)pDraw);
 | 
						|
	else
 | 
						|
		pPortPriv->pPixmap = (PixmapPtr)pDraw;
 | 
						|
 | 
						|
	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap))
 | 
						|
		kaaMoveInPixmap(pPortPriv->pPixmap);
 | 
						|
 | 
						|
	if (!kaaPixmapIsOffscreen(pPortPriv->pPixmap)) {
 | 
						|
		ErrorF("err\n");
 | 
						|
		return BadAlloc;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	/* update cliplist */
 | 
						|
	if (!REGION_EQUAL(screen->pScreen, &pPortPriv->clip, clipBoxes))
 | 
						|
		REGION_COPY(screen->pScreen, &pPortPriv->clip, clipBoxes);
 | 
						|
 | 
						|
	/* XXX: What do the drw_x and drw_y here mean for us? */
 | 
						|
 | 
						|
	if (atic->is_radeon)
 | 
						|
		RadeonDisplayVideo(screen, pPortPriv);
 | 
						|
	else
 | 
						|
		R128DisplayVideo(screen, pPortPriv);
 | 
						|
 | 
						|
	return Success;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ATIQueryImageAttributes(KdScreenInfo *screen, int id, unsigned short *w,
 | 
						|
    unsigned short *h, int *pitches, int *offsets)
 | 
						|
{
 | 
						|
	int size, tmp;
 | 
						|
 | 
						|
	if (*w > IMAGE_MAX_WIDTH) 
 | 
						|
		*w = IMAGE_MAX_WIDTH;
 | 
						|
	if (*h > IMAGE_MAX_HEIGHT) 
 | 
						|
		*h = IMAGE_MAX_HEIGHT;
 | 
						|
 | 
						|
	*w = (*w + 1) & ~1;
 | 
						|
	if (offsets)
 | 
						|
		offsets[0] = 0;
 | 
						|
 | 
						|
	switch (id)
 | 
						|
	{
 | 
						|
	case FOURCC_YV12:
 | 
						|
	case FOURCC_I420:
 | 
						|
		*h = (*h + 1) & ~1;
 | 
						|
		size = (*w + 3) & ~3;
 | 
						|
		if (pitches) 
 | 
						|
			pitches[0] = size;
 | 
						|
		size *= *h;
 | 
						|
		if (offsets) 
 | 
						|
			offsets[1] = size;
 | 
						|
		tmp = ((*w >> 1) + 3) & ~3;
 | 
						|
		if (pitches) 
 | 
						|
			pitches[1] = pitches[2] = tmp;
 | 
						|
		tmp *= (*h >> 1);
 | 
						|
		size += tmp;
 | 
						|
		if (offsets) 
 | 
						|
			offsets[2] = size;
 | 
						|
		size += tmp;
 | 
						|
		break;
 | 
						|
	case FOURCC_UYVY:
 | 
						|
	case FOURCC_YUY2:
 | 
						|
	default:
 | 
						|
		size = *w << 1;
 | 
						|
		if (pitches) 
 | 
						|
			pitches[0] = size;
 | 
						|
		size *= *h;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	return size;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* client libraries expect an encoding */
 | 
						|
static KdVideoEncodingRec DummyEncoding[1] =
 | 
						|
{
 | 
						|
	{
 | 
						|
		0,
 | 
						|
		"XV_IMAGE",
 | 
						|
		IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
 | 
						|
		{1, 1}
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_FORMATS 3
 | 
						|
 | 
						|
static KdVideoFormatRec Formats[NUM_FORMATS] = 
 | 
						|
{
 | 
						|
	{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_ATTRIBUTES 0
 | 
						|
 | 
						|
static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
 | 
						|
{
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_IMAGES 4
 | 
						|
 | 
						|
static KdImageRec Images[NUM_IMAGES] =
 | 
						|
{
 | 
						|
	XVIMAGE_YUY2,
 | 
						|
	XVIMAGE_YV12,
 | 
						|
	XVIMAGE_I420,
 | 
						|
	XVIMAGE_UYVY
 | 
						|
};
 | 
						|
 | 
						|
static KdVideoAdaptorPtr 
 | 
						|
ATISetupImageVideo(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	KdVideoAdaptorPtr adapt;
 | 
						|
	ATIPortPrivPtr pPortPriv;
 | 
						|
	int i;
 | 
						|
 | 
						|
	atis->num_texture_ports = 16;
 | 
						|
 | 
						|
	adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) + atis->num_texture_ports *
 | 
						|
	    (sizeof(ATIPortPrivRec) + sizeof(DevUnion)));
 | 
						|
	if (adapt == NULL)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	adapt->type = XvWindowMask | XvInputMask | XvImageMask;
 | 
						|
	adapt->flags = VIDEO_CLIP_TO_VIEWPORT;
 | 
						|
	adapt->name = "ATI Texture Video";
 | 
						|
	adapt->nEncodings = 1;
 | 
						|
	adapt->pEncodings = DummyEncoding;
 | 
						|
	adapt->nFormats = NUM_FORMATS;
 | 
						|
	adapt->pFormats = Formats;
 | 
						|
	adapt->nPorts = atis->num_texture_ports;
 | 
						|
	adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
 | 
						|
 | 
						|
	pPortPriv =
 | 
						|
	    (ATIPortPrivPtr)(&adapt->pPortPrivates[atis->num_texture_ports]);
 | 
						|
 | 
						|
	for (i = 0; i < atis->num_texture_ports; i++)
 | 
						|
		adapt->pPortPrivates[i].ptr = &pPortPriv[i];
 | 
						|
 | 
						|
	adapt->nAttributes = NUM_ATTRIBUTES;
 | 
						|
	adapt->pAttributes = Attributes;
 | 
						|
	adapt->pImages = Images;
 | 
						|
	adapt->nImages = NUM_IMAGES;
 | 
						|
	adapt->PutVideo = NULL;
 | 
						|
	adapt->PutStill = NULL;
 | 
						|
	adapt->GetVideo = NULL;
 | 
						|
	adapt->GetStill = NULL;
 | 
						|
	adapt->StopVideo = ATIStopVideo;
 | 
						|
	adapt->SetPortAttribute = ATISetPortAttribute;
 | 
						|
	adapt->GetPortAttribute = ATIGetPortAttribute;
 | 
						|
	adapt->QueryBestSize = ATIQueryBestSize;
 | 
						|
	adapt->PutImage = ATIPutImage;
 | 
						|
	adapt->ReputImage = ATIReputImage;
 | 
						|
	adapt->QueryImageAttributes = ATIQueryImageAttributes;
 | 
						|
 | 
						|
	/* gotta uninit this someplace */
 | 
						|
	REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0); 
 | 
						|
 | 
						|
	atis->pAdaptor = adapt;
 | 
						|
 | 
						|
	xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
 | 
						|
	xvSaturation = MAKE_ATOM("XV_SATURATION");
 | 
						|
 | 
						|
	return adapt;
 | 
						|
}
 | 
						|
 | 
						|
Bool ATIInitVideo(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	ATICardInfo(pScreenPriv);
 | 
						|
	KdScreenInfo *screen = pScreenPriv->screen;
 | 
						|
	KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
 | 
						|
	KdVideoAdaptorPtr newAdaptor = NULL;
 | 
						|
	int num_adaptors;
 | 
						|
    
 | 
						|
	atis->pAdaptor = NULL;
 | 
						|
 | 
						|
	if (atic->reg_base == NULL)
 | 
						|
		return FALSE;
 | 
						|
	if (atic->is_r300)
 | 
						|
		return FALSE;
 | 
						|
 | 
						|
	num_adaptors = KdXVListGenericAdaptors(screen, &adaptors);
 | 
						|
 | 
						|
	newAdaptor = ATISetupImageVideo(pScreen);
 | 
						|
 | 
						|
	if (newAdaptor)  {
 | 
						|
		if (!num_adaptors) {
 | 
						|
			num_adaptors = 1;
 | 
						|
			adaptors = &newAdaptor;
 | 
						|
		} else {
 | 
						|
			newAdaptors = xalloc((num_adaptors + 1) * 
 | 
						|
			    sizeof(KdVideoAdaptorPtr *));
 | 
						|
			if (newAdaptors) {
 | 
						|
				memcpy(newAdaptors, adaptors, num_adaptors *
 | 
						|
				    sizeof(KdVideoAdaptorPtr));
 | 
						|
				newAdaptors[num_adaptors] = newAdaptor;
 | 
						|
				adaptors = newAdaptors;
 | 
						|
				num_adaptors++;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (num_adaptors)
 | 
						|
		KdXVScreenInit(pScreen, adaptors, num_adaptors);
 | 
						|
 | 
						|
	if (newAdaptors)
 | 
						|
		xfree(newAdaptors);
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ATIFiniVideo(ScreenPtr pScreen)
 | 
						|
{
 | 
						|
	KdScreenPriv(pScreen);
 | 
						|
	ATIScreenInfo(pScreenPriv);
 | 
						|
	KdVideoAdaptorPtr adapt = atis->pAdaptor;
 | 
						|
	ATIPortPrivPtr pPortPriv;
 | 
						|
	int i;
 | 
						|
 | 
						|
	if (!adapt)
 | 
						|
		return;
 | 
						|
 | 
						|
	for (i = 0; i < atis->num_texture_ports; i++) {
 | 
						|
		pPortPriv = (ATIPortPrivPtr)(&adapt->pPortPrivates[i].ptr);
 | 
						|
		REGION_UNINIT(pScreen, &pPortPriv->clip);
 | 
						|
	}
 | 
						|
	xfree(adapt);
 | 
						|
	atis->pAdaptor = NULL;
 | 
						|
}
 |