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

📄 radeon_dri.c

📁 ati driver
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.38 2003/09/28 20:15:55 alanh Exp $ *//* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, *                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. *//* * Authors: *   Kevin E. Martin <martin@xfree86.org> *   Rickard E. Faith <faith@valinux.com> *   Gareth Hughes <gareth@valinux.com> * */				/* Driver data structures */#include "radeon.h"#include "radeon_macros.h"#include "radeon_dri.h"#include "radeon_reg.h"#include "radeon_version.h"				/* X and server generic header files */#include "xf86.h"#include "xf86PciInfo.h"#include "windowstr.h"#include "shadowfb.h"				/* GLX/DRI/DRM definitions */#define _XF86DRI_SERVER_#include "GL/glxtokens.h"#include "sarea.h"#include "radeon_sarea.h"/* HACK - for now, put this here... *//* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */#if defined(__alpha__)# define DRM_PAGE_SIZE 8192#elif defined(__ia64__)# define DRM_PAGE_SIZE getpagesize()#else# define DRM_PAGE_SIZE 4096#endifstatic Bool RADEONDRICloseFullScreen(ScreenPtr pScreen);static Bool RADEONDRIOpenFullScreen(ScreenPtr pScreen);static void RADEONDRITransitionTo2d(ScreenPtr pScreen);static void RADEONDRITransitionTo3d(ScreenPtr pScreen);static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);/* Initialize the visual configs that are supported by the hardware. * These are combined with the visual configs that the indirect * rendering core supports, and the intersection is exported to the * client. */static Bool RADEONInitVisualConfigs(ScreenPtr pScreen){    ScrnInfoPtr          pScrn             = xf86Screens[pScreen->myNum];    RADEONInfoPtr        info              = RADEONPTR(pScrn);    int                  numConfigs        = 0;    __GLXvisualConfig   *pConfigs          = 0;    RADEONConfigPrivPtr  pRADEONConfigs    = 0;    RADEONConfigPrivPtr *pRADEONConfigPtrs = 0;    int                  i, accum, stencil, db, use_db;    use_db = !info->noBackBuffer ? 1 : 0;    switch (info->CurrentLayout.pixel_code) {    case 8:  /* 8bpp mode is not support */    case 15: /* FIXME */    case 24: /* FIXME */	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[dri] RADEONInitVisualConfigs failed "		   "(depth %d not supported).  "		   "Disabling DRI.\n", info->CurrentLayout.pixel_code);	return FALSE;#define RADEON_USE_ACCUM   1#define RADEON_USE_STENCIL 1    case 16:	numConfigs = 1;	if (RADEON_USE_ACCUM)   numConfigs *= 2;	if (RADEON_USE_STENCIL) numConfigs *= 2;	if (use_db)             numConfigs *= 2;	if (!(pConfigs	      = (__GLXvisualConfig *)xcalloc(sizeof(__GLXvisualConfig),					     numConfigs))) {	    return FALSE;	}	if (!(pRADEONConfigs	      = (RADEONConfigPrivPtr)xcalloc(sizeof(RADEONConfigPrivRec),					     numConfigs))) {	    xfree(pConfigs);	    return FALSE;	}	if (!(pRADEONConfigPtrs	      = (RADEONConfigPrivPtr *)xcalloc(sizeof(RADEONConfigPrivPtr),					       numConfigs))) {	    xfree(pConfigs);	    xfree(pRADEONConfigs);	    return FALSE;	}	i = 0;	for (db = 0; db <= use_db; db++) {	  for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) {	    for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) {		pRADEONConfigPtrs[i] = &pRADEONConfigs[i];		pConfigs[i].vid                = (VisualID)(-1);		pConfigs[i].class              = -1;		pConfigs[i].rgba               = TRUE;		pConfigs[i].redSize            = 5;		pConfigs[i].greenSize          = 6;		pConfigs[i].blueSize           = 5;		pConfigs[i].alphaSize          = 0;		pConfigs[i].redMask            = 0x0000F800;		pConfigs[i].greenMask          = 0x000007E0;		pConfigs[i].blueMask           = 0x0000001F;		pConfigs[i].alphaMask          = 0x00000000;		if (accum) { /* Simulated in software */		    pConfigs[i].accumRedSize   = 16;		    pConfigs[i].accumGreenSize = 16;		    pConfigs[i].accumBlueSize  = 16;		    pConfigs[i].accumAlphaSize = 0;		} else {		    pConfigs[i].accumRedSize   = 0;		    pConfigs[i].accumGreenSize = 0;		    pConfigs[i].accumBlueSize  = 0;		    pConfigs[i].accumAlphaSize = 0;		}		if (db)		    pConfigs[i].doubleBuffer   = TRUE;		else		    pConfigs[i].doubleBuffer   = FALSE;		pConfigs[i].stereo             = FALSE;		pConfigs[i].bufferSize         = 16;		pConfigs[i].depthSize          = 16;		if (stencil)		    pConfigs[i].stencilSize    = 8;		else		    pConfigs[i].stencilSize    = 0;		pConfigs[i].auxBuffers         = 0;		pConfigs[i].level              = 0;		if (accum) {		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;		} else {		   pConfigs[i].visualRating    = GLX_NONE;		}		pConfigs[i].transparentPixel   = GLX_NONE;		pConfigs[i].transparentRed     = 0;		pConfigs[i].transparentGreen   = 0;		pConfigs[i].transparentBlue    = 0;		pConfigs[i].transparentAlpha   = 0;		pConfigs[i].transparentIndex   = 0;		i++;	    }	  }	}	break;    case 32:	numConfigs = 1;	if (RADEON_USE_ACCUM)   numConfigs *= 2;	if (RADEON_USE_STENCIL) numConfigs *= 2;	if (use_db)             numConfigs *= 2;	if (!(pConfigs	      = (__GLXvisualConfig *)xcalloc(sizeof(__GLXvisualConfig),					     numConfigs))) {	    return FALSE;	}	if (!(pRADEONConfigs	      = (RADEONConfigPrivPtr)xcalloc(sizeof(RADEONConfigPrivRec),					     numConfigs))) {	    xfree(pConfigs);	    return FALSE;	}	if (!(pRADEONConfigPtrs	      = (RADEONConfigPrivPtr *)xcalloc(sizeof(RADEONConfigPrivPtr),					       numConfigs))) {	    xfree(pConfigs);	    xfree(pRADEONConfigs);	    return FALSE;	}	i = 0;	for (db = 0; db <= use_db; db++) {	  for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) {	    for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) {		pRADEONConfigPtrs[i] = &pRADEONConfigs[i];		pConfigs[i].vid                = (VisualID)(-1);		pConfigs[i].class              = -1;		pConfigs[i].rgba               = TRUE;		pConfigs[i].redSize            = 8;		pConfigs[i].greenSize          = 8;		pConfigs[i].blueSize           = 8;		pConfigs[i].alphaSize          = 8;		pConfigs[i].redMask            = 0x00FF0000;		pConfigs[i].greenMask          = 0x0000FF00;		pConfigs[i].blueMask           = 0x000000FF;		pConfigs[i].alphaMask          = 0xFF000000;		if (accum) { /* Simulated in software */		    pConfigs[i].accumRedSize   = 16;		    pConfigs[i].accumGreenSize = 16;		    pConfigs[i].accumBlueSize  = 16;		    pConfigs[i].accumAlphaSize = 16;		} else {		    pConfigs[i].accumRedSize   = 0;		    pConfigs[i].accumGreenSize = 0;		    pConfigs[i].accumBlueSize  = 0;		    pConfigs[i].accumAlphaSize = 0;		}		if (db)		    pConfigs[i].doubleBuffer   = TRUE;		else		    pConfigs[i].doubleBuffer   = FALSE;		pConfigs[i].stereo             = FALSE;		pConfigs[i].bufferSize         = 32;		if (stencil) {		    pConfigs[i].depthSize      = 24;		    pConfigs[i].stencilSize    = 8;		} else {		    pConfigs[i].depthSize      = 24;		    pConfigs[i].stencilSize    = 0;		}		pConfigs[i].auxBuffers         = 0;		pConfigs[i].level              = 0;		if (accum) {		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;		} else {		   pConfigs[i].visualRating    = GLX_NONE;		}		pConfigs[i].transparentPixel   = GLX_NONE;		pConfigs[i].transparentRed     = 0;		pConfigs[i].transparentGreen   = 0;		pConfigs[i].transparentBlue    = 0;		pConfigs[i].transparentAlpha   = 0;		pConfigs[i].transparentIndex   = 0;		i++;	    }	  }	}	break;    }    info->numVisualConfigs   = numConfigs;    info->pVisualConfigs     = pConfigs;    info->pVisualConfigsPriv = pRADEONConfigs;    GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pRADEONConfigPtrs);    return TRUE;}/* Create the Radeon-specific context information */static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual,				drmContext hwContext, void *pVisualConfigPriv,				DRIContextType contextStore){#ifdef PER_CONTEXT_SAREA    ScrnInfoPtr          pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr        info  = RADEONPTR(pScrn);    RADEONDRIContextPtr  ctx_info;    ctx_info = (RADEONDRIContextPtr)contextStore;    if (!ctx_info) return FALSE;    if (drmAddMap(info->drmFD, 0,		  info->perctx_sarea_size,		  DRM_SHM,		  DRM_REMOVABLE,		  &ctx_info->sarea_handle) < 0) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO,		   "[dri] could not create private sarea for ctx id (%d)\n",		   (int)hwContext);	return FALSE;    }    if (drmAddContextPrivateMapping(info->drmFD, hwContext,				    ctx_info->sarea_handle) < 0) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO,		   "[dri] could not associate private sarea to ctx id (%d)\n",		   (int)hwContext);	drmRmMap(info->drmFD, ctx_info->sarea_handle);	return FALSE;    }    ctx_info->ctx_id = hwContext;#endif    return TRUE;}/* Destroy the Radeon-specific context information */static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext,				 DRIContextType contextStore){#ifdef PER_CONTEXT_SAREA    ScrnInfoPtr          pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr        info = RADEONPTR(pScrn);    RADEONDRIContextPtr  ctx_info;    ctx_info = (RADEONDRIContextPtr)contextStore;    if (!ctx_info) return;    if (drmRmMap(info->drmFD, ctx_info->sarea_handle) < 0) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO,		   "[dri] could not remove private sarea for ctx id (%d)\n",		   (int)hwContext);    }#endif}/* Called when the X server is woken up to allow the last client's * context to be saved and the X server's context to be loaded.  This is * not necessary for the Radeon since the client detects when it's * context is not currently loaded and then load's it itself.  Since the * registers to start and stop the CP are privileged, only the X server * can start/stop the engine. */static void RADEONEnterServer(ScreenPtr pScreen){    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr  info  = RADEONPTR(pScrn);    if (info->accel) info->accel->NeedToSync = TRUE;}/* Called when the X server goes to sleep to allow the X server's * context to be saved and the last client's context to be loaded.  This * is not necessary for the Radeon since the client detects when it's * context is not currently loaded and then load's it itself.  Since the * registers to start and stop the CP are privileged, only the X server * can start/stop the engine. */static void RADEONLeaveServer(ScreenPtr pScreen){    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr  info  = RADEONPTR(pScrn);    RING_LOCALS;    /* The CP is always running, but if we've generated any CP commands     * we must flush them to the kernel module now.     */    if (info->CPInUse) {	RADEON_FLUSH_CACHE();	RADEON_WAIT_UNTIL_IDLE();	RADEONCPReleaseIndirect(pScrn);	info->CPInUse = FALSE;    }}/* Contexts can be swapped by the X server if necessary.  This callback * is currently only used to perform any functions necessary when * entering or leaving the X server, and in the future might not be * necessary. */static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,				 DRIContextType oldContextType,				 void *oldContext,				 DRIContextType newContextType,				 void *newContext){    if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&	(newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */	RADEONEnterServer(pScreen);    }    if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&	(newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */	RADEONLeaveServer(pScreen);    }}/* The Radeon has depth tiling on all the time, so we have to convert * the x,y coordinates into the memory bus address (mba) in the same * manner as the engine.  In each case, the linear block address (ba) * is calculated, and then wired with x and y to produce the final * memory address. */static CARD32 radeon_mba_z16(RADEONInfoPtr info, int x, int y){    CARD32  pitch   = info->frontPitch;    CARD32  address = 0;			/* a[0]    = 0           */    CARD32  ba;    ba = (y / 16) * (pitch / 32) + (x / 32);    address |= (x & 0x7) << 1;			/* a[1..3] = x[0..2]     */    address |= (y & 0x7) << 4;			/* a[4..6] = y[0..2]     */    address |= (x & 0x8) << 4;			/* a[7]    = x[3]        */    address |= (ba & 0x3) << 8;			/* a[8..9] = ba[0..1]    */    address |= (y & 0x8) << 7;			/* a[10]   = y[3]        */    address |= ((x & 0x10) ^ (y & 0x10)) << 7;	/* a[11]   = x[4] ^ y[4] */    address |= (ba & ~0x3u) << 10;		/* a[12..] = ba[2..]     */    return address;}static CARD32 radeon_mba_z32(RADEONInfoPtr info, int x, int y){    CARD32  pitch   = info->frontPitch;    CARD32  address = 0;			/* a[0..1] = 0           */    CARD32  ba;    ba = (y / 16) * (pitch / 16) + (x / 16);    address |= (x & 0x7) << 2;			/* a[2..4] = x[0..2]     */    address |= (y & 0x3) << 5;			/* a[5..6] = y[0..1]     */    address |=	(((x & 0x10) >> 2) ^ (y & 0x4)) << 5;	/* a[7]    = x[4] ^ y[2] */    address |= (ba & 0x3) << 8;			/* a[8..9] = ba[0..1]    */    address |= (y & 0x8) << 7;			/* a[10]   = y[3]        */    address |=	(((x & 0x8) << 1) ^ (y & 0x10)) << 7;	/* a[11]   = x[3] ^ y[4] */    address |= (ba & ~0x3u) << 10;		/* a[12..] = ba[2..]     */    return address;}/* 16-bit depth buffer functions */#define WRITE_DEPTH16(_x, _y, d)					\    *(CARD16 *)(pointer)(buf + radeon_mba_z16(info, (_x), (_y))) = (d)#define READ_DEPTH16(d, _x, _y)						\    (d) = *(CARD16 *)(pointer)(buf + radeon_mba_z16(info, (_x), (_y)))/* 24 bit depth, 8 bit stencil depthbuffer functions */#define WRITE_DEPTH32(_x, _y, d)					\do {									\    CARD32 tmp =							\	*(CARD32 *)(pointer)(buf + radeon_mba_z32(info, (_x), (_y)));	\    tmp &= 0xff000000;							\    tmp |= ((d) & 0x00ffffff);						\    *(CARD32 *)(pointer)(buf + radeon_mba_z32(info, (_x), (_y))) = tmp;	\} while (0)#define READ_DEPTH32(d, _x, _y)						\    d = (*(CARD32 *)(pointer)(buf + radeon_mba_z32(info, (_x), (_y)))	\	 & 0x00ffffff)/* Screen to screen copy of data in the depth buffer */static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn,					  int xa, int ya,					  int xb, int yb,					  int w, int h){

⌨️ 快捷键说明

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