📄 radeon_accelfuncs.c
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accelfuncs.c,v 1.7tsi Exp $ *//* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. * * 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 on 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 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR * THEIR SUPPLIERS 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif/* * Authors: * Kevin E. Martin <martin@xfree86.org> * Rickard E. Faith <faith@valinux.com> * Alan Hourihane <alanh@fairlite.demon.co.uk> * Michel Dänzer <michel@daenzer.net> * * Credits: * * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source * code to his Radeon driver. Portions of this file are based on the * initialization code for that driver. * * References: * * !!!! FIXME !!!! * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April * 1999. * * RAGE 128 Software Development Manual (Technical Reference Manual P/N * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. * * Notes on unimplemented XAA optimizations: * * SetClipping: This has been removed as XAA expects 16bit registers * for full clipping. * TwoPointLine: The Radeon supports this. Not Bresenham. * DashedLine with non-power-of-two pattern length: Apparently, there is * no way to set the length of the pattern -- it is always * assumed to be 8 or 32 (or 1024?). * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference * Manual where it states that monochrome expansion of frame * buffer data is not supported. * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid * direct/indirect method. If we had more data registers, * then we could do better. If XAA supported a trigger write * address, the code would be simpler. * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 * pattern from frame buffer memory. * ImageWrites: Same as CPUToScreenColorExpandFill * */#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#endif#ifdef USE_XAA/* This callback is required for multiheader cards using XAA */static voidFUNC_NAME(RADEONRestoreAccelState)(ScrnInfoPtr pScrn){ /*RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO;*/#ifdef ACCEL_MMIO/* OUTREG(RADEON_DEFAULT_OFFSET, info->dst_pitch_offset);*/ /* FIXME: May need to restore other things, like BKGD_CLK FG_CLK... */ RADEONWaitForIdleMMIO(pScrn);#else /* ACCEL_CP *//* RADEONWaitForFifo(pScrn, 1); OUTREG(RADEON_DEFAULT_OFFSET, info->frontPitchOffset);*/ RADEONWaitForIdleMMIO(pScrn);#if 0 /* Not working yet */ RADEONMMIO_TO_CP(pScrn, info);#endif /* FIXME: May need to restore other things, like BKGD_CLK FG_CLK... */#endif}/* Setup for XAA SolidFill */static voidFUNC_NAME(RADEONSetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP[rop].pattern); BEGIN_ACCEL(4); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->dp_gui_master_cntl_clip); OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, color); OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); FINISH_ACCEL();}/* Subsequent XAA SolidFillRect * * Tests: xtest CH06/fllrctngl, xterm */static voidFUNC_NAME(RADEONSubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); BEGIN_ACCEL(3); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->dst_pitch_offset | ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); FINISH_ACCEL();}/* Setup for XAA solid lines */static voidFUNC_NAME(RADEONSetupForSolidLine)(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP[rop].pattern); if (info->ChipFamily >= CHIP_FAMILY_RV200) { BEGIN_ACCEL(1); OUT_ACCEL_REG(RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT); FINISH_ACCEL(); } BEGIN_ACCEL(3); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->dp_gui_master_cntl_clip); OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, color); OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); FINISH_ACCEL();}/* Subsequent XAA solid horizontal and vertical lines */static voidFUNC_NAME(RADEONSubsequentSolidHorVertLine)(ScrnInfoPtr pScrn, int x, int y, int len, int dir){ RADEONInfoPtr info = RADEONPTR(pScrn); int w = 1; int h = 1; ACCEL_PREAMBLE(); if (dir == DEGREES_0) w = len; else h = len; BEGIN_ACCEL(4); OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->dst_pitch_offset | ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); FINISH_ACCEL();}/* Subsequent XAA solid TwoPointLine line * * Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program * * [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for * Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] */static voidFUNC_NAME(RADEONSubsequentSolidTwoPointLine)(ScrnInfoPtr pScrn, int xa, int ya, int xb, int yb, int flags){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); /* TODO: Check bounds -- RADEON only has 14 bits */ if (!(flags & OMIT_LAST)) FUNC_NAME(RADEONSubsequentSolidHorVertLine)(pScrn, xb, yb, 1, DEGREES_0); BEGIN_ACCEL(3); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->dst_pitch_offset | ((info->tilingEnabled && (ya <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); OUT_ACCEL_REG(RADEON_DST_LINE_START, (ya << 16) | xa); OUT_ACCEL_REG(RADEON_DST_LINE_END, (yb << 16) | xb); FINISH_ACCEL();}/* Setup for XAA dashed lines * * Tests: xtest CH05/stdshs, XFree86/drwln * * NOTE: Since we can only accelerate lines with power-of-2 patterns of * length <= 32 */static voidFUNC_NAME(RADEONSetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask, int length, unsigned char *pattern){ RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 pat = *(CARD32 *)(pointer)pattern; ACCEL_PREAMBLE(); /* Save for determining whether or not to draw last pixel */ info->dashLen = length; info->dashPattern = pat;#if X_BYTE_ORDER == X_BIG_ENDIAN# define PAT_SHIFT(pat, shift) (pat >> shift)#else# define PAT_SHIFT(pat, shift) (pat << shift)#endif switch (length) { case 2: pat |= PAT_SHIFT(pat, 2); /* fall through */ case 4: pat |= PAT_SHIFT(pat, 4); /* fall through */ case 8: pat |= PAT_SHIFT(pat, 8); /* fall through */ case 16: pat |= PAT_SHIFT(pat, 16); } /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | (bg == -1 ? RADEON_GMC_BRUSH_32x1_MONO_FG_LA : RADEON_GMC_BRUSH_32x1_MONO_FG_BG) | RADEON_ROP[rop].pattern | RADEON_GMC_BYTE_LSB_TO_MSB); info->dash_fg = fg; info->dash_bg = bg; BEGIN_ACCEL((bg == -1) ? 4 : 5); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->dp_gui_master_cntl_clip); OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask); OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); if (bg != -1) OUT_ACCEL_REG(RADEON_DP_BRUSH_BKGD_CLR, bg); OUT_ACCEL_REG(RADEON_BRUSH_DATA0, pat); FINISH_ACCEL();}/* Helper function to draw last point for dashed lines */static voidFUNC_NAME(RADEONDashedLastPel)(ScrnInfoPtr pScrn, int x, int y, int fg){ RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 dp_gui_master_cntl = info->dp_gui_master_cntl_clip; ACCEL_PREAMBLE(); dp_gui_master_cntl &= ~RADEON_GMC_BRUSH_DATATYPE_MASK; dp_gui_master_cntl |= RADEON_GMC_BRUSH_SOLID_COLOR; dp_gui_master_cntl &= ~RADEON_GMC_SRC_DATATYPE_MASK; dp_gui_master_cntl |= RADEON_GMC_SRC_DATATYPE_COLOR; BEGIN_ACCEL(8); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, dp_gui_master_cntl); OUT_ACCEL_REG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->dst_pitch_offset | ((info->tilingEnabled && (y <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, fg); OUT_ACCEL_REG(RADEON_DST_Y_X, (y << 16) | x); OUT_ACCEL_REG(RADEON_DST_WIDTH_HEIGHT, (1 << 16) | 1); /* Restore old values */ OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, info->dp_gui_master_cntl_clip); OUT_ACCEL_REG(RADEON_DP_BRUSH_FRGD_CLR, info->dash_fg); FINISH_ACCEL();}/* Subsequent XAA dashed line */static voidFUNC_NAME(RADEONSubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn, int xa, int ya, int xb, int yb, int flags, int phase){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); /* TODO: Check bounds -- RADEON only has 14 bits */ if (!(flags & OMIT_LAST)) { int deltax = abs(xa - xb); int deltay = abs(ya - yb); int shift; if (deltax > deltay) shift = deltax; else shift = deltay; shift += phase; shift %= info->dashLen; if ((info->dashPattern >> shift) & 1) FUNC_NAME(RADEONDashedLastPel)(pScrn, xb, yb, info->dash_fg); else if (info->dash_bg != -1) FUNC_NAME(RADEONDashedLastPel)(pScrn, xb, yb, info->dash_bg); } BEGIN_ACCEL(4); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->dst_pitch_offset | ((info->tilingEnabled && (ya <= pScrn->virtualY)) ? RADEON_DST_TILE_MACRO : 0)); OUT_ACCEL_REG(RADEON_DST_LINE_START, (ya << 16) | xa); OUT_ACCEL_REG(RADEON_DST_LINE_PATCOUNT, phase); OUT_ACCEL_REG(RADEON_DST_LINE_END, (yb << 16) | xb); FINISH_ACCEL();}/* Set up for transparency * * Mmmm, Seems as though the transparency compare is opposite to r128. * It should only draw when source != trans_color, this is the opposite * of that. */static voidFUNC_NAME(RADEONSetTransparency)(ScrnInfoPtr pScrn, int trans_color){ RADEONInfoPtr info = RADEONPTR(pScrn); if ((trans_color != -1) || (info->XAAForceTransBlit == TRUE)) { ACCEL_PREAMBLE(); BEGIN_ACCEL(3); OUT_ACCEL_REG(RADEON_CLR_CMP_CLR_SRC, trans_color); OUT_ACCEL_REG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); OUT_ACCEL_REG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR | RADEON_CLR_CMP_SRC_SOURCE)); FINISH_ACCEL(); }}/* Setup for XAA screen-to-screen copy * * Tests: xtest CH06/fllrctngl (also tests transparency) */static voidFUNC_NAME(RADEONSetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int trans_color){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); info->xdir = xdir; info->ydir = ydir; /* Save for later clipping */ info->dp_gui_master_cntl_clip = (info->dp_gui_master_cntl | RADEON_GMC_BRUSH_NONE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -