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

📄 r128_accel.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.17 2003/10/03 20:11:11 herrb Exp $ *//* * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, *                      Precision Insight, Inc., Cedar Park, Texas, 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, PRECISION INSIGHT, 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: *   Rickard E. Faith <faith@valinux.com> *   Kevin E. Martin <martin@valinux.com> *   Alan Hourihane <alanh@fairlite.demon.co.uk> * * Credits: * *   Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for *   providing source code to their 3.3.x Rage 128 driver.  Portions of *   this file are based on the acceleration code for that driver. * * References: * *   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:   The Rage128 doesn't support the full 16bit registers needed *                  for XAA clip rect support. *   SolidFillTrap: This will probably work if we can compute the correct *                  Bresenham error values. *   TwoPointLine:  The Rage 128 supports Bresenham lines instead. *   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. * (Alan Hourihane) Update. We now use purely indirect and clip the full *                  rectangle. Seems as the direct method has some problems *                  with this, although this indirect method is much faster *                  than the old method of setting up the engine per scanline. *                  This code was the basis of the Radeon work we did. *   Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 *                  pattern from frame buffer memory. *   ImageWrites:   See CPUToScreenColorExpandFill. * */#define R128_TRAPEZOIDS 0       /* Trapezoids don't work               */				/* Driver data structures */#include <errno.h>#include "r128.h"#include "r128_reg.h"#include "r128_probe.h"#ifdef XF86DRI#include "r128_sarea.h"#define _XF86DRI_SERVER_#include "r128_dri.h"#include "r128_common.h"#endif				/* Line support */#include "miline.h"				/* X and server generic header files */#include "xf86.h"static struct {    int rop;    int pattern;} R128_ROP[] = {    { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear        */    { R128_ROP3_DSa,  R128_ROP3_DPa  }, /* Gxand          */    { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse   */    { R128_ROP3_S,    R128_ROP3_P    }, /* GXcopy         */    { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted  */    { R128_ROP3_D,    R128_ROP3_D    }, /* GXnoop         */    { R128_ROP3_DSx,  R128_ROP3_DPx  }, /* GXxor          */    { R128_ROP3_DSo,  R128_ROP3_DPo  }, /* GXor           */    { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor          */    { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv        */    { R128_ROP3_Dn,   R128_ROP3_Dn   }, /* GXinvert       */    { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse    */    { R128_ROP3_Sn,   R128_ROP3_Pn   }, /* GXcopyInverted */    { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted   */    { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand         */    { R128_ROP3_ONE,  R128_ROP3_ONE  }  /* GXset          */};extern int getR128EntityIndex(void);/* Flush all dirty data in the Pixel Cache to memory. */void R128EngineFlush(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    int           i;    OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL);    for (i = 0; i < R128_TIMEOUT; i++) {	if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break;    }}/* Reset graphics card to known state. */void R128EngineReset(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    CARD32        clock_cntl_index;    CARD32        mclk_cntl;    CARD32        gen_reset_cntl;    R128EngineFlush(pScrn);    clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX);    mclk_cntl        = INPLL(pScrn, R128_MCLK_CNTL);    OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);    gen_reset_cntl   = INREG(R128_GEN_RESET_CNTL);    OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);    INREG(R128_GEN_RESET_CNTL);    OUTREG(R128_GEN_RESET_CNTL,	gen_reset_cntl & (CARD32)(~R128_SOFT_RESET_GUI));    INREG(R128_GEN_RESET_CNTL);    OUTPLL(R128_MCLK_CNTL,        mclk_cntl);    OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index);    OUTREG(R128_GEN_RESET_CNTL,   gen_reset_cntl);}/* The FIFO has 64 slots.  This routines waits until at least `entries' of   these slots are empty. */void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    int           i;    for (;;) {	for (i = 0; i < R128_TIMEOUT; i++) {	    info->fifo_slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;	    if (info->fifo_slots >= entries) return;	}	R128TRACE(("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n",		   INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,		   INREG(R128_GUI_STAT),		   INREG(R128_GUI_PROBE)));	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "FIFO timed out, resetting engine...\n");	R128EngineReset(pScrn);#ifdef XF86DRI	R128CCE_RESET(pScrn, info);	if (info->directRenderingEnabled) {	    R128CCE_START(pScrn, info);	}#endif    }}/* Wait for the graphics engine to be completely idle: the FIFO has   drained, the Pixel Cache is flushed, and the engine is idle.  This is a   standard "sync" function that will make the hardware "quiescent". */void R128WaitForIdle(ScrnInfoPtr pScrn){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    int           i;    R128WaitForFifoFunction(pScrn, 64);    for (;;) {	for (i = 0; i < R128_TIMEOUT; i++) {	    if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) {		R128EngineFlush(pScrn);		return;	    }	}	R128TRACE(("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n",		   INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK,		   INREG(R128_GUI_STAT),		   INREG(R128_GUI_PROBE)));	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "Idle timed out, resetting engine...\n");#ifdef XF86DRI        R128CCE_STOP(pScrn, info);#endif	R128EngineReset(pScrn);#ifdef XF86DRI	R128CCE_RESET(pScrn, info);	if (info->directRenderingEnabled) {	    R128CCE_START(pScrn, info);	}#endif    }}#ifdef XF86DRI/* Wait until the CCE is completely idle: the FIFO has drained and the * CCE is idle. */void R128CCEWaitForIdle(ScrnInfoPtr pScrn){    R128InfoPtr info = R128PTR(pScrn);    int         ret, i;    FLUSH_RING();    for (;;) {        i = 0;        do {            ret = drmCommandNone(info->drmFD, DRM_R128_CCE_IDLE);        } while ( ret && errno == EBUSY && i++ < (R128_IDLE_RETRY * R128_IDLE_RETRY) );	if (ret && ret != -EBUSY) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		       "%s: CCE idle %d\n", __FUNCTION__, ret);	}	if (i > R128_IDLE_RETRY) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		       "%s: (DEBUG) CCE idle took i = %d\n", __FUNCTION__, i);	}	if (ret == 0) return;	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "Idle timed out, resetting engine...\n");	R128CCE_STOP(pScrn, info);	R128EngineReset(pScrn);	/* Always restart the engine when doing CCE 2D acceleration */	R128CCE_RESET(pScrn, info);	R128CCE_START(pScrn, info);    }}int R128CCEStop(ScrnInfoPtr pScrn){    R128InfoPtr    info = R128PTR(pScrn);    drmR128CCEStop stop;    int            ret, i;    stop.flush = 1;    stop.idle  = 1;    ret = drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP,                           &stop, sizeof(drmR128CCEStop) );    if ( ret == 0 ) {        return 0;    } else if ( errno != EBUSY ) {        return -errno;    }    stop.flush = 0;    i = 0;    do {        ret = drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP,                               &stop, sizeof(drmR128CCEStop) );    } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );    if ( ret == 0 ) {        return 0;    } else if ( errno != EBUSY ) {        return -errno;    }    stop.idle = 0;    if ( drmCommandWrite( info->drmFD, DRM_R128_CCE_STOP,                          &stop, sizeof(drmR128CCEStop) )) {        return -errno;    } else {        return 0;    }}#endif/* Setup for XAA SolidFill. */static void R128SetupForSolidFill(ScrnInfoPtr pScrn,				  int color, int rop, unsigned int planemask){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128WaitForFifo(pScrn, 4);    OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl				     | R128_GMC_BRUSH_SOLID_COLOR				     | R128_GMC_SRC_DATATYPE_COLOR				     | R128_ROP[rop].pattern));    OUTREG(R128_DP_BRUSH_FRGD_CLR,  color);    OUTREG(R128_DP_WRITE_MASK,      planemask);    OUTREG(R128_DP_CNTL,            (R128_DST_X_LEFT_TO_RIGHT				     | R128_DST_Y_TOP_TO_BOTTOM));}/* Subsequent XAA SolidFillRect.   Tests: xtest CH06/fllrctngl, xterm*/static void  R128SubsequentSolidFillRect(ScrnInfoPtr pScrn,					 int x, int y, int w, int h){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128WaitForFifo(pScrn, 2);    OUTREG(R128_DST_Y_X,          (y << 16) | x);    OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h);}/* Setup for XAA solid lines. */static void R128SetupForSolidLine(ScrnInfoPtr pScrn,				  int color, int rop, unsigned int planemask){    R128InfoPtr   info      = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128WaitForFifo(pScrn, 3);    OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl				     | R128_GMC_BRUSH_SOLID_COLOR				     | R128_GMC_SRC_DATATYPE_COLOR				     | R128_ROP[rop].pattern));    OUTREG(R128_DP_BRUSH_FRGD_CLR,  color);    OUTREG(R128_DP_WRITE_MASK,      planemask);}/* Subsequent XAA solid Bresenham 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.]

⌨️ 快捷键说明

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