⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_render.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2004 Eric Anholt * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: *    Eric Anholt <anholt@FreeBSD.org> *    Hui Yu <hyu@ati.com> * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#ifdef USE_XAA#include "dixstruct.h"#include "xaa.h"#include "xaalocal.h"#ifndef RENDER_GENERIC_HELPER#define RENDER_GENERIC_HELPERstruct blendinfo {	Bool dst_alpha;	Bool src_alpha;	CARD32 blend_cntl;};/* The first part of blend_cntl corresponds to Fa from the render "protocol" * document, and the second part to Fb. */static const struct blendinfo RadeonBlendOp[] = {    /* Clear */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ZERO},    /* Src */    {0, 0, RADEON_SRC_BLEND_GL_ONE |	   RADEON_DST_BLEND_GL_ZERO},    /* Dst */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ONE},    /* Over */    {0, 1, RADEON_SRC_BLEND_GL_ONE |	   RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},    /* OverReverse */    {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA |	   RADEON_DST_BLEND_GL_ONE},    /* In */    {1, 0, RADEON_SRC_BLEND_GL_DST_ALPHA |	   RADEON_DST_BLEND_GL_ZERO},    /* InReverse */    {0, 1, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_SRC_ALPHA},    /* Out */    {1, 0, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA |	   RADEON_DST_BLEND_GL_ZERO},    /* OutReverse */    {0, 1, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},    /* Atop */    {1, 1, RADEON_SRC_BLEND_GL_DST_ALPHA |	   RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},    /* AtopReverse */    {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA |	   RADEON_DST_BLEND_GL_SRC_ALPHA},    /* Xor */    {1, 1, RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA |	   RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA},    /* Add */    {0, 0, RADEON_SRC_BLEND_GL_ONE |	   RADEON_DST_BLEND_GL_ONE},    /* Saturate */    {1, 1, RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE |	   RADEON_DST_BLEND_GL_ONE},    {0, 0, 0},    {0, 0, 0},    /* DisjointClear */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ZERO},    /* DisjointSrc */    {0, 0, RADEON_SRC_BLEND_GL_ONE |	   RADEON_DST_BLEND_GL_ZERO},    /* DisjointDst */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ONE},    /* DisjointOver unsupported */    {0, 0, 0},    /* DisjointOverReverse */    {1, 1, RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE |	   RADEON_DST_BLEND_GL_ONE},    /* DisjointIn unsupported */    {0, 0, 0},    /* DisjointInReverse unsupported */    {0, 0, 0},    /* DisjointOut unsupported */    {1, 1, RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE |	   RADEON_DST_BLEND_GL_ZERO},    /* DisjointOutReverse unsupported */    {0, 0, 0},    /* DisjointAtop unsupported */    {0, 0, 0},    /* DisjointAtopReverse unsupported */    {0, 0, 0},    /* DisjointXor unsupported */    {0, 0, 0},    {0, 0, 0},    {0, 0, 0},    {0, 0, 0},    {0, 0, 0},    /* ConjointClear */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ZERO},    /* ConjointSrc */    {0, 0, RADEON_SRC_BLEND_GL_ONE |	   RADEON_DST_BLEND_GL_ZERO},    /* ConjointDst */    {0, 0, RADEON_SRC_BLEND_GL_ZERO |	   RADEON_DST_BLEND_GL_ONE},};#define RadeonOpMax (sizeof(RadeonBlendOp) / sizeof(RadeonBlendOp[0]))/* Note on texture formats: * TXFORMAT_Y8 expands to (Y,Y,Y,1).  TXFORMAT_I8 expands to (I,I,I,I) * The RADEON and R200 TXFORMATS we use are the same on r100/r200. */static CARD32 RADEONTextureFormats[] = {    PICT_a8r8g8b8,    PICT_a8,    PICT_x8r8g8b8,    PICT_r5g6b5,    PICT_a1r5g5b5,    PICT_x1r5g5b5,    0};static CARD32 RADEONDstFormats[] = {    PICT_a8r8g8b8,    PICT_x8r8g8b8,    PICT_r5g6b5,    PICT_a1r5g5b5,    PICT_x1r5g5b5,    0};static CARD32RadeonGetTextureFormat(CARD32 format){    switch (format) {    case PICT_a8r8g8b8:	return RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP;    case PICT_a8:	return RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP;    case PICT_x8r8g8b8:	return RADEON_TXFORMAT_ARGB8888;    case PICT_r5g6b5:	return RADEON_TXFORMAT_RGB565;    case PICT_a1r5g5b5:	return RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP;    case PICT_x1r5g5b5:	return RADEON_TXFORMAT_ARGB1555;    default:	return 0;    }}static CARD32RadeonGetColorFormat(CARD32 format){    switch (format) {    case PICT_a8r8g8b8:    case PICT_x8r8g8b8:	return RADEON_COLOR_FORMAT_ARGB8888;    case PICT_r5g6b5:	return RADEON_COLOR_FORMAT_RGB565;    case PICT_a1r5g5b5:    case PICT_x1r5g5b5:	return RADEON_COLOR_FORMAT_ARGB1555;    default:	return 0;    }}/* Returns a RADEON_RB3D_BLENDCNTL value, or 0 if the operation is not * supported */static CARD32RadeonGetBlendCntl(CARD8 op, CARD32 dstFormat){    CARD32 blend_cntl;    if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0)	return 0;    blend_cntl = RadeonBlendOp[op].blend_cntl;	    if (RadeonBlendOp[op].dst_alpha && !PICT_FORMAT_A(dstFormat)) {	CARD32 srcblend = blend_cntl & RADEON_SRC_BLEND_MASK;	/* If there's no destination alpha channel, we need to wire the blending	 * to treat the alpha channel as always 1.	 */	if (srcblend == RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA ||	    srcblend == RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE)	    blend_cntl = (blend_cntl & ~RADEON_SRC_BLEND_MASK) |			 RADEON_SRC_BLEND_GL_ZERO;	else if (srcblend == RADEON_SRC_BLEND_GL_DST_ALPHA)	    blend_cntl = (blend_cntl & ~RADEON_SRC_BLEND_MASK) |			 RADEON_SRC_BLEND_GL_ONE;    }    return blend_cntl;}static __inline__ CARD32 F_TO_DW(float val){    union {	float f;	CARD32 l;    } tmp;    tmp.f = val;    return tmp.l;}/* Compute log base 2 of val. */static __inline__ intATILog2(int val){	int bits;	for (bits = 0; val != 0; val >>= 1, ++bits)		;	return bits - 1;}static voidRemoveLinear (FBLinearPtr linear){   RADEONInfoPtr info = (RADEONInfoPtr)(linear->devPrivate.ptr);   info->RenderTex = NULL; }static voidRenderCallback (ScrnInfoPtr pScrn){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    if ((currentTime.milliseconds > info->RenderTimeout) && info->RenderTex) {	xf86FreeOffscreenLinear(info->RenderTex);	info->RenderTex = NULL;    }    if (!info->RenderTex)	info->RenderCallback = NULL;}static BoolAllocateLinear (   ScrnInfoPtr pScrn,   int sizeNeeded){   RADEONInfoPtr  info       = RADEONPTR(pScrn);   int cpp = info->CurrentLayout.bitsPerPixel / 8;   info->RenderTimeout = currentTime.milliseconds + 30000;   info->RenderCallback = RenderCallback;   /* XAA allocates in units of pixels at the screen bpp, so adjust size    * appropriately.    */   sizeNeeded = (sizeNeeded + cpp - 1) / cpp;   if (info->RenderTex) {	if (info->RenderTex->size >= sizeNeeded)	   return TRUE;	else {	   if (xf86ResizeOffscreenLinear(info->RenderTex, sizeNeeded))		return TRUE;	   xf86FreeOffscreenLinear(info->RenderTex);	   info->RenderTex = NULL;	}   }   info->RenderTex = xf86AllocateOffscreenLinear(pScrn->pScreen, sizeNeeded, 32,						 NULL, RemoveLinear, info);   return (info->RenderTex != NULL);}#if X_BYTE_ORDER == X_BIG_ENDIANstatic Bool RADEONSetupRenderByteswap(ScrnInfoPtr pScrn, int tex_bytepp){    RADEONInfoPtr info = RADEONPTR(pScrn);    unsigned char *RADEONMMIO = info->MMIO;    CARD32 swapper = info->ModeReg.surface_cntl;    swapper &= ~(RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP |		 RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP);    /* Set up byte swapping for the framebuffer aperture as needed */    switch (tex_bytepp) {    case 1:	break;    case 2:	swapper |= RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP;	break;    case 4:	swapper |= RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP;	break;    default:	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Don't know what to do for "		   "tex_bytepp == %d!\n", __func__, tex_bytepp);	return FALSE;    }    OUTREG(RADEON_SURFACE_CNTL, swapper);    return TRUE;}static void RADEONRestoreByteswap(RADEONInfoPtr info){    unsigned char *RADEONMMIO = info->MMIO;    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);}#endif	/* X_BYTE_ORDER == X_BIG_ENDIAN */#endif	/* RENDER_GENERIC_HELPER */#if defined(ACCEL_MMIO) && defined(ACCEL_CP)#error Cannot define both MMIO and CP acceleration!#endif#if !defined(UNIXCPP) || defined(ANSICPP)#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix#else#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix#endif#ifdef ACCEL_MMIO#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO)#else#ifdef ACCEL_CP#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP)#else#error No accel type defined!#endif#endifstatic Bool FUNC_NAME(R100SetupTexture)(	ScrnInfoPtr pScrn,	CARD32 format,	CARD8 *src,	int src_pitch,	unsigned int width,	unsigned int height,	int flags){    RADEONInfoPtr info = RADEONPTR(pScrn);    CARD8 *dst;    CARD32 tex_size = 0, txformat;    int dst_pitch, offset, size, tex_bytepp;#ifdef ACCEL_CP    CARD32 buf_pitch, dst_pitch_off;    int x, y;    unsigned int hpass;    CARD8 *tmp_dst;#endif    ACCEL_PREAMBLE();    /* render repeat is broken - fix in stable tree by falling back */    if (flags & XAA_RENDER_REPEAT)	return FALSE;    if ((width > 2048) || (height > 2048))	return FALSE;    txformat = RadeonGetTextureFormat(format);    tex_bytepp = PICT_FORMAT_BPP(format) >> 3;#ifndef ACCEL_CP#if X_BYTE_ORDER == X_BIG_ENDIAN    if (!RADEONSetupRenderByteswap(pScrn, tex_bytepp)) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: RADEONSetupRenderByteswap() "		   "failed!\n", __func__);	return FALSE;    }#endif#endif    dst_pitch = (width * tex_bytepp + 63) & ~63;    size = dst_pitch * height;    if (!AllocateLinear(pScrn, size))	return FALSE;    if (flags & XAA_RENDER_REPEAT) {	txformat |= ATILog2(width) << RADEON_TXFORMAT_WIDTH_SHIFT;	txformat |= ATILog2(height) << RADEON_TXFORMAT_HEIGHT_SHIFT;    } else {	tex_size = ((height - 1) << 16) | (width - 1);	txformat |= RADEON_TXFORMAT_NON_POWER2;    }    offset = info->RenderTex->offset * pScrn->bitsPerPixel / 8;    dst = (CARD8*)(info->FB + offset);    /* Upload texture to card. */#ifdef ACCEL_CP    RADEONHostDataParams( pScrn, dst, dst_pitch, tex_bytepp, &dst_pitch_off, &x, &y );    while ( height )    {    	tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width,				      dst_pitch_off, &buf_pitch,				      x, &y, &height, &hpass );	RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src,				    hpass, buf_pitch, src_pitch );	src += hpass * src_pitch;    }    RADEON_PURGE_CACHE();    RADEON_WAIT_UNTIL_IDLE();#else    if (info->accel->NeedToSync)	info->accel->Sync(pScrn);    while (height--) {	memcpy(dst, src, width * tex_bytepp);	src += src_pitch;	dst += dst_pitch;    }#if X_BYTE_ORDER == X_BIG_ENDIAN    RADEONRestoreByteswap(info);#endif#endif	/* ACCEL_CP */    BEGIN_ACCEL(5);    OUT_ACCEL_REG(RADEON_PP_TXFORMAT_0, txformat);    OUT_ACCEL_REG(RADEON_PP_TEX_SIZE_0, tex_size);    OUT_ACCEL_REG(RADEON_PP_TEX_PITCH_0, dst_pitch - 32);    OUT_ACCEL_REG(RADEON_PP_TXOFFSET_0, offset + info->fbLocation +					pScrn->fbOffset);    OUT_ACCEL_REG(RADEON_PP_TXFILTER_0, RADEON_MAG_FILTER_LINEAR |					RADEON_MIN_FILTER_LINEAR |					RADEON_CLAMP_S_WRAP |					RADEON_CLAMP_T_WRAP);    FINISH_ACCEL();    return TRUE;}static BoolFUNC_NAME(R100SetupForCPUToScreenAlphaTexture) (	ScrnInfoPtr	pScrn,	int		op,	CARD16		red,	CARD16		green,	CARD16		blue,	CARD16		alpha,	CARD32		maskFormat,	CARD32		dstFormat,	CARD8		*alphaPtr,	int		alphaPitch,	int		width,	int		height,	int		flags) {    RADEONInfoPtr info = RADEONPTR(pScrn);    CARD32 colorformat, srccolor, blend_cntl;    ACCEL_PREAMBLE();    blend_cntl = RadeonGetBlendCntl(op, dstFormat);    if (blend_cntl == 0)	return FALSE;    if (!info->XInited3D)	RADEONInit3DEngine(pScrn);    if (!FUNC_NAME(R100SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch,				     width, height, flags))	return FALSE;    colorformat = RadeonGetColorFormat(dstFormat);    srccolor = ((alpha & 0xff00) << 16) | ((red & 0xff00) << 8) | (blue >> 8) |	(green & 0xff00);    BEGIN_ACCEL(7);    OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE);    OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE |				  RADEON_TEX_BLEND_0_ENABLE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -