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

📄 mga_dri.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.28 2003/02/08 21:26:58 dawes Exp $ *//* * Copyright 2000 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 * 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 * VA LINUX SYSTEMS AND/OR ITS 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: *    Keith Whitwell <keith@tungstengraphics.com> *    Gareth Hughes <gareth@valinux.com> */#include <errno.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <inttypes.h>#include "driver.h"#include "drm.h"#include "memops.h"#include "mga_reg.h"#include "mga.h"#include "mga_macros.h"#include "mga_dri.h"/* Quiescence, locking */#define MGA_TIMEOUT		2048static void MGAWaitForIdleDMA( struct DRIDriverContextRec *ctx, MGAPtr pMga ){   drm_lock_t lock;   int ret;   int i = 0;   memset( &lock, 0, sizeof(lock) );   for (;;) {      do {         /* first ask for quiescent and flush */         lock.flags = DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH;         do {	    ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,                                   &lock, sizeof( lock ) );         } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );         /* if it's still busy just try quiescent */         if ( ret == -EBUSY ) {             lock.flags = DRM_LOCK_QUIESCENT;            do {	       ret = drmCommandWrite( ctx->drmFD, DRM_MGA_FLUSH,                                      &lock, sizeof( lock ) );            } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );         }      } while ( ( ret == -EBUSY ) && ( i++ < MGA_TIMEOUT ) );      if ( ret == 0 )	 return;      fprintf( stderr,               "[dri] Idle timed out, resetting engine...\n" );      drmCommandNone( ctx->drmFD, DRM_MGA_RESET );   }}static unsigned int mylog2( unsigned int n ){   unsigned int log2 = 1;   while ( n > 1 ) n >>= 1, log2++;   return log2;}static int MGADRIAgpInit(struct DRIDriverContextRec *ctx, MGAPtr pMga){   unsigned long mode;   unsigned int vendor, device;   int ret, count, i;   if(pMga->agpSize < 12)pMga->agpSize = 12;   if(pMga->agpSize > 64)pMga->agpSize = 64; /* cap */   /* FIXME: Make these configurable...    */   pMga->agp.size = pMga->agpSize * 1024 * 1024;   pMga->warp.offset = 0;   pMga->warp.size = MGA_WARP_UCODE_SIZE;   pMga->primary.offset = (pMga->warp.offset +				    pMga->warp.size);   pMga->primary.size = 1024 * 1024;   pMga->buffers.offset = (pMga->primary.offset +				    pMga->primary.size);   pMga->buffers.size = MGA_NUM_BUFFERS * MGA_BUFFER_SIZE;   pMga->agpTextures.offset = (pMga->buffers.offset +                                    pMga->buffers.size);   pMga->agpTextures.size = pMga->agp.size -                                     pMga->agpTextures.offset;   if ( drmAgpAcquire( ctx->drmFD ) < 0 ) {     fprintf( stderr, "[agp] AGP not available\n" );      return 0;   }   mode   = drmAgpGetMode( ctx->drmFD );        /* Default mode */   vendor = drmAgpVendorId( ctx->drmFD );   device = drmAgpDeviceId( ctx->drmFD );   mode &= ~MGA_AGP_MODE_MASK;   switch ( pMga->agpMode ) {   case 4:      mode |= MGA_AGP_4X_MODE;   case 2:      mode |= MGA_AGP_2X_MODE;   case 1:   default:      mode |= MGA_AGP_1X_MODE;   }#if 0   fprintf( stderr,            "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",            mode, vendor, device,            ctx->pciVendor,            ctx->pciChipType );#endif   if ( drmAgpEnable( ctx->drmFD, mode ) < 0 ) {     fprintf( stderr, "[agp] AGP not enabled\n" );      drmAgpRelease( ctx->drmFD );      return 0;   }   if ( pMga->Chipset == PCI_CHIP_MGAG200 ) {      switch ( pMga->agpMode ) {      case 2:	 fprintf( stderr,		     "[drm] Enabling AGP 2x PLL encoding\n" );	 OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_ENABLE );	 break;      case 1:      default:	 fprintf( stderr,		     "[drm] Disabling AGP 2x PLL encoding\n" );	 OUTREG( MGAREG_AGP_PLL, MGA_AGP2XPLL_DISABLE );	 pMga->agpMode = 1;	 break;      }   }   ret = drmAgpAlloc( ctx->drmFD, pMga->agp.size,		      0, NULL, &pMga->agp.handle );   if ( ret < 0 ) {      fprintf( stderr, "[agp] Out of memory (%d)\n", ret );      drmAgpRelease( ctx->drmFD );      return 0;   }   fprintf( stderr,	       "[agp] %d kB allocated with handle 0x%08x\n",	       pMga->agp.size/1024, (unsigned int)pMga->agp.handle );   if ( drmAgpBind( ctx->drmFD, pMga->agp.handle, 0 ) < 0 ) {      fprintf( stderr, "[agp] Could not bind memory\n" );      drmAgpFree( ctx->drmFD, pMga->agp.handle );      drmAgpRelease( ctx->drmFD );      return 0;   }   /* WARP microcode space    */   if ( drmAddMap( ctx->drmFD,		   pMga->warp.offset,		   pMga->warp.size,		   DRM_AGP, DRM_READ_ONLY,		   &pMga->warp.handle ) < 0 ) {      fprintf( stderr,		  "[agp] Could not add WARP microcode mapping\n" );      return 0;   }   fprintf( stderr, 	       "[agp] WARP microcode handle = 0x%08x\n",	       pMga->warp.handle );   if ( drmMap( ctx->drmFD,		pMga->warp.handle,		pMga->warp.size,		&pMga->warp.map ) < 0 ) {      fprintf( stderr,		  "[agp] Could not map WARP microcode\n" );      return 0;   }   fprintf( stderr,	       "[agp] WARP microcode mapped at 0x%08lx\n",	       (unsigned long)pMga->warp.map );   /* Primary DMA space    */   if ( drmAddMap( ctx->drmFD,		   pMga->primary.offset,		   pMga->primary.size,		   DRM_AGP, DRM_READ_ONLY,		   &pMga->primary.handle ) < 0 ) {      fprintf( stderr,		  "[agp] Could not add primary DMA mapping\n" );      return 0;   }   fprintf( stderr, 	       "[agp] Primary DMA handle = 0x%08x\n",	       pMga->primary.handle );   if ( drmMap( ctx->drmFD,		pMga->primary.handle,		pMga->primary.size,		&pMga->primary.map ) < 0 ) {      fprintf( stderr,		  "[agp] Could not map primary DMA\n" );      return 0;   }   fprintf( stderr,	       "[agp] Primary DMA mapped at 0x%08lx\n",	       (unsigned long)pMga->primary.map );   /* DMA buffers    */   if ( drmAddMap( ctx->drmFD,		   pMga->buffers.offset,		   pMga->buffers.size,		   DRM_AGP, 0,		   &pMga->buffers.handle ) < 0 ) {      fprintf( stderr,		  "[agp] Could not add DMA buffers mapping\n" );      return 0;   }   fprintf( stderr, 	       "[agp] DMA buffers handle = 0x%08x\n",	       pMga->buffers.handle );   if ( drmMap( ctx->drmFD,		pMga->buffers.handle,		pMga->buffers.size,		&pMga->buffers.map ) < 0 ) {      fprintf( stderr,		  "[agp] Could not map DMA buffers\n" );      return 0;   }   fprintf( stderr,	       "[agp] DMA buffers mapped at 0x%08lx\n",	       (unsigned long)pMga->buffers.map );   count = drmAddBufs( ctx->drmFD,		       MGA_NUM_BUFFERS, MGA_BUFFER_SIZE,		       DRM_AGP_BUFFER, pMga->buffers.offset );   if ( count <= 0 ) {      fprintf( stderr,		  "[drm] failure adding %d %d byte DMA buffers\n",		  MGA_NUM_BUFFERS, MGA_BUFFER_SIZE );      return 0;   }   fprintf( stderr,	       "[drm] Added %d %d byte DMA buffers\n",	       count, MGA_BUFFER_SIZE );   i = mylog2(pMga->agpTextures.size / MGA_NR_TEX_REGIONS);   if(i < MGA_LOG_MIN_TEX_REGION_SIZE)      i = MGA_LOG_MIN_TEX_REGION_SIZE;   pMga->agpTextures.size = (pMga->agpTextures.size >> i) << i;   if ( drmAddMap( ctx->drmFD,                   pMga->agpTextures.offset,                   pMga->agpTextures.size,                   DRM_AGP, 0,                   &pMga->agpTextures.handle ) < 0 ) {      fprintf( stderr,                  "[agp] Could not add agpTexture mapping\n" );      return 0;   }/* should i map it ? */   fprintf( stderr,               "[agp] agpTexture handle = 0x%08x\n",               pMga->agpTextures.handle );   fprintf( stderr,               "[agp] agpTexture size: %d kb\n", pMga->agpTextures.size/1024 );   return 1;}static int MGADRIMapInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ){   pMga->registers.size = MGAIOMAPSIZE;   if ( drmAddMap( ctx->drmFD,		   (drm_handle_t)pMga->IOAddress,		   pMga->registers.size,		   DRM_REGISTERS, DRM_READ_ONLY,		   &pMga->registers.handle ) < 0 ) {      fprintf( stderr,		  "[drm] Could not add MMIO registers mapping\n" );      return 0;   }   fprintf( stderr,	       "[drm] Registers handle = 0x%08lx\n",	       pMga->registers.handle );   pMga->status.size = SAREA_MAX;   if ( drmAddMap( ctx->drmFD, 0, pMga->status.size,		   DRM_SHM, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL,		   &pMga->status.handle ) < 0 ) {      fprintf( stderr,		  "[drm] Could not add status page mapping\n" );      return 0;   }   fprintf( stderr, 	       "[drm] Status handle = 0x%08x\n",	       pMga->status.handle );   if ( drmMap( ctx->drmFD,		pMga->status.handle,		pMga->status.size,		&pMga->status.map ) < 0 ) {      fprintf( stderr,		  "[agp] Could not map status page\n" );      return 0;   }   fprintf( stderr,	       "[agp] Status page mapped at 0x%08lx\n",	       (unsigned long)pMga->status.map );   return 1;}static int MGADRIKernelInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ){   drm_mga_init_t init;   int ret;   memset( &init, 0, sizeof(init) );   init.func = MGA_INIT_DMA;   init.sarea_priv_offset = sizeof(drm_sarea_t);   switch ( pMga->Chipset ) {   case PCI_CHIP_MGAG550:   case PCI_CHIP_MGAG400:      init.chipset = MGA_CARD_TYPE_G400;      break;   case PCI_CHIP_MGAG200:   case PCI_CHIP_MGAG200_PCI:      init.chipset = MGA_CARD_TYPE_G200;      break;   default:      return 0;   }   init.sgram = 0; /* FIXME !pMga->HasSDRAM; */   switch (ctx->bpp)     {     case 16:       init.maccess = MGA_MACCESS_PW16;       break;     case 32:       init.maccess = MGA_MACCESS_PW32;       break;     default:       fprintf( stderr, "[mga] invalid bpp (%d)\n", ctx->bpp );       return 0;     }   init.fb_cpp		= ctx->bpp / 8;   init.front_offset	= pMga->frontOffset;   init.front_pitch	= pMga->frontPitch / init.fb_cpp;   init.back_offset	= pMga->backOffset;   init.back_pitch	= pMga->backPitch / init.fb_cpp;   init.depth_cpp	= ctx->bpp / 8;   init.depth_offset	= pMga->depthOffset;   init.depth_pitch	= pMga->depthPitch / init.depth_cpp;   init.texture_offset[0] = pMga->textureOffset;   init.texture_size[0] = pMga->textureSize;   init.fb_offset = ctx->shared.hFrameBuffer;   init.mmio_offset = pMga->registers.handle;   init.status_offset = pMga->status.handle;   init.warp_offset = pMga->warp.handle;   init.primary_offset = pMga->primary.handle;   init.buffers_offset = pMga->buffers.handle;   init.texture_offset[1] = pMga->agpTextures.handle;   init.texture_size[1] = pMga->agpTextures.size;   ret = drmCommandWrite( ctx->drmFD, DRM_MGA_INIT, &init, sizeof(init));   if ( ret < 0 ) {      fprintf( stderr,		  "[drm] Failed to initialize DMA! (%d)\n", ret );      return 0;   }   return 1;}static void MGADRIIrqInit(struct DRIDriverContextRec *ctx, MGAPtr pMga){  if (!pMga->irq)    {      pMga->irq = drmGetInterruptFromBusID(ctx->drmFD,                                           ctx->pciBus,                                           ctx->pciDevice,                                           ctx->pciFunc);      fprintf(stderr, "[drm] got IRQ %d\n", pMga->irq);    if((drmCtlInstHandler(ctx->drmFD, pMga->irq)) != 0)      {        fprintf(stderr,                "[drm] failure adding irq handler, "                "there is a device already using that irq\n"                "[drm] falling back to irq-free operation\n");        pMga->irq = 0;      }    else      {        pMga->reg_ien = INREG( MGAREG_IEN );      }    }  if (pMga->irq)    fprintf(stderr,            "[drm] dma control initialized, using IRQ %d\n",            pMga->irq);}static int MGADRIBuffersInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ){   pMga->drmBuffers = drmMapBufs( ctx->drmFD );   if ( !pMga->drmBuffers )     {       fprintf( stderr,                "[drm] Failed to map DMA buffers list\n" );       return 0;     }      fprintf( stderr,            "[drm] Mapped %d DMA buffers\n",            pMga->drmBuffers->count );   return 1;}static int MGAMemoryInit( struct DRIDriverContextRec *ctx, MGAPtr pMga ){   int        width_bytes = ctx->shared.virtualWidth * ctx->cpp;   int        bufferSize  = ((ctx->shared.virtualHeight * width_bytes			      + MGA_BUFFER_ALIGN)			     & ~MGA_BUFFER_ALIGN);   int        depthSize   = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes			      + MGA_BUFFER_ALIGN)			     & ~MGA_BUFFER_ALIGN);   int        l;   pMga->frontOffset = 0;   pMga->frontPitch = ctx->shared.virtualWidth * ctx->cpp;   fprintf(stderr, 	   "Using %d MB AGP aperture\n", pMga->agpSize);   fprintf(stderr, 	   "Using %d MB for vertex/indirect buffers\n", pMga->buffers.size>>20);   fprintf(stderr, 	   "Using %d MB for AGP textures\n", pMga->agpTextures.size>>20);   /* Front, back and depth buffers - everything else texture??    */   pMga->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;   if (pMga->textureSize < 0)       return 0;   l = mylog2( pMga->textureSize / MGA_NR_TEX_REGIONS );   if ( l < MGA_LOG_MIN_TEX_REGION_SIZE )      l = MGA_LOG_MIN_TEX_REGION_SIZE;   /* Round the texture size up to the nearest whole number of    * texture regions.  Again, be greedy about this, don't    * round down.    */   pMga->logTextureGranularity = l;   pMga->textureSize = (pMga->textureSize >> l) << l;   /* Set a minimum usable local texture heap size.  This will fit    * two 256x256x32bpp textures.    */   if (pMga->textureSize < 512 * 1024) {      pMga->textureOffset = 0;      pMga->textureSize = 0;   }   /* Reserve space for textures */   pMga->textureOffset = ((ctx->shared.fbSize - pMga->textureSize +			   MGA_BUFFER_ALIGN) &			  ~MGA_BUFFER_ALIGN);   /* Reserve space for the shared depth    * buffer.    */   pMga->depthOffset = ((pMga->textureOffset - depthSize +			 MGA_BUFFER_ALIGN) &			~MGA_BUFFER_ALIGN);   pMga->depthPitch = ctx->shared.virtualWidth * ctx->cpp;   pMga->backOffset = ((pMga->depthOffset - bufferSize +			MGA_BUFFER_ALIGN) &                        ~MGA_BUFFER_ALIGN);   pMga->backPitch = ctx->shared.virtualWidth * ctx->cpp;

⌨️ 快捷键说明

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