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

📄 radeon_dri.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v 1.39 2003/11/06 18:38:00 tsi 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif/* * Authors: *   Kevin E. Martin <martin@xfree86.org> *   Rickard E. Faith <faith@valinux.com> *   Gareth Hughes <gareth@valinux.com> * */#include <string.h>#include <stdio.h>				/* Driver data structures */#include "radeon.h"#include "radeon_video.h"#include "radeon_reg.h"#include "radeon_macros.h"#include "radeon_dri.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"static size_t radeon_drm_page_size;static void RADEONDRITransitionTo2d(ScreenPtr pScreen);static void RADEONDRITransitionTo3d(ScreenPtr pScreen);static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);#ifdef USE_XAAstatic void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);#endif/* 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 = use_db; db >= 0; 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          = info->depthBits;		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)						: stencil) {		    pConfigs[i].stencilSize    = 8;		} else {		    pConfigs[i].stencilSize    = 0;		}		pConfigs[i].auxBuffers         = 0;		pConfigs[i].level              = 0;		if (accum ||		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {		   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 = use_db; db >= 0; 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;		pConfigs[i].depthSize          = info->depthBits;		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)						: stencil) {		    pConfigs[i].stencilSize    = 8;		} else {		    pConfigs[i].stencilSize    = 0;		}		pConfigs[i].auxBuffers         = 0;		pConfigs[i].level              = 0;		if (accum ||		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {		   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,				drm_context_t 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, drm_context_t 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);    RADEONSAREAPrivPtr pSAREAPriv;    RADEON_MARK_SYNC(info, pScrn);    pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);    if (pSAREAPriv->ctxOwner != DRIGetContext(pScrn->pScreen))	info->XInited3D = FALSE;    /* TODO: Fix this more elegantly.     * Sometimes (especially with multiple DRI clients), this code     * runs immediately after a DRI client issues a rendering command.     *     * The accel code regularly inserts WAIT_UNTIL_IDLE into the     * command buffer that is sent with the indirect buffer below.     * The accel code fails to set the 3D cache flush registers for     * the R300 before sending WAIT_UNTIL_IDLE. Sending a cache flush     * on these new registers is not necessary for pure 2D functionality,     * but it *is* necessary after 3D operations.     * Without the cache flushes before WAIT_UNTIL_IDLE, the R300 locks up.     *     * The CP_IDLE call into the DRM indirectly flushes all caches and     * thus avoids the lockup problem, but the solution is far from ideal.     * Better solutions could be:     *  - always flush caches when entering the X server     *  - track the type of rendering commands somewhere and issue     *    cache flushes when they change     * However, I don't feel confident enough with the control flow     * inside the X server to implement either fix. -- nh     */        /* On my computer (Radeon Mobility M10)       The fix below results in x11perf -shmput500 rate of 245.0/sec       which is lower than 264.0/sec I get without it.              Doing the same each time before indirect buffer is submitted       results in x11perf -shmput500 rate of 225.0/sec.              On the other hand, not using CP acceleration at all benchmarks       at 144.0/sec.             For now let us accept this as a lesser evil, especially as the       DRM driver for R300 is still in flux.              Once the code is more stable this should probably be moved into DRM driver.    */          if (info->ChipFamily>=CHIP_FAMILY_R300)        drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE);}/* 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

⌨️ 快捷键说明

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