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

📄 i810_dri.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * \file server/i810_dri.c * \brief File to perform the device-specific initialization tasks typically * done in the X server. * * Here they are converted to run in the client (or perhaps a standalone * process), and to work with the frame buffer device rather than the X * server infrastructure. *  * Copyright (C) 2004 Dave Airlie (airlied@linux.ie) */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include "driver.h"#include "drm.h"#include "i810.h"#include "i810_dri.h"#include "i810_reg.h"static int i810_pitches[] = {   512,   1024,   2048,   4096,   0};static int i810_pitch_flags[] = {   0x0,   0x1,   0x2,   0x3,   0};static unsigned int i810_drm_version = 0;static intI810AllocLow(I810MemRange * result, I810MemRange * pool, int size){   if (size > pool->Size)      return 0;   pool->Size -= size;   result->Size = size;   result->Start = pool->Start;   result->End = pool->Start += size;   return 1;}static intI810AllocHigh(I810MemRange * result, I810MemRange * pool, int size){   if (size > pool->Size)      return 0;   pool->Size -= size;   result->Size = size;   result->End = pool->End;   result->Start = pool->End -= size;   return 1;}/** * \brief Wait for free FIFO entries. * * \param ctx display handle. * \param entries number of free entries to wait. * * It polls the free entries from the chip until it reaches the requested value * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out. */static void I810WaitForFifo( const DRIDriverContext *ctx,			       int entries ){}/** * \brief Reset graphics card to known state. * * \param ctx display handle. * * Resets the values of several I810 registers. */static void I810EngineReset( const DRIDriverContext *ctx ){   unsigned char *I810MMIO = ctx->MMIOAddress;}/** * \brief Restore the drawing engine. * * \param ctx display handle * * Resets the graphics card and sets initial values for several registers of * the card's drawing engine. * * Turns on the i810 command processor engine (i.e., the ringbuffer). */static int I810EngineRestore( const DRIDriverContext *ctx ){   I810Ptr info = ctx->driverPrivate;   unsigned char *I810MMIO = ctx->MMIOAddress;   fprintf(stderr, "%s\n", __FUNCTION__);   return 1;}/** * \brief Shutdown the drawing engine. * * \param ctx display handle * * Turns off the command processor engine & restores the graphics card * to a state that fbdev understands. */static int I810EngineShutdown( const DRIDriverContext *ctx ){  drmI810Init info;  int ret;  memset(&info, 0, sizeof(drmI810Init));  info.func = I810_CLEANUP_DMA;    ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &info, sizeof(drmI810Init));  if (ret>0)  {    fprintf(stderr,"[dri] I810 DMA Cleanup failed\n");    return -errno;  }  return 0;}/** * \brief Compute base 2 logarithm. * * \param val value. *  * \return base 2 logarithm of \p val. */static int I810MinBits(int val){   int  bits;   if (!val) return 1;   for (bits = 0; val; val >>= 1, ++bits);   return bits;}static int I810DRIAgpPreInit( const DRIDriverContext *ctx, I810Ptr info){  if (drmAgpAcquire(ctx->drmFD) < 0) {    fprintf(stderr, "[gart] AGP not available\n");    return 0;  }      if (drmAgpEnable(ctx->drmFD, 0) < 0) {    fprintf(stderr, "[gart] AGP not enabled\n");    drmAgpRelease(ctx->drmFD);    return 0;  }}/** * \brief Initialize the AGP state * * \param ctx display handle. * \param info driver private data. * * \return one on success, or zero on failure. *  * Acquires and enables the AGP device. Reserves memory in the AGP space for * the ring buffer, vertex buffers and textures. Initialize the I810 * registers to point to that memory and add client mappings. */static int I810DRIAgpInit( const DRIDriverContext *ctx, I810Ptr info){   unsigned char *I810MMIO = ctx->MMIOAddress;   int            ret;   int            s, l;   unsigned long dcacheHandle;   unsigned long agpHandle;   int pitch_idx = 0;   int back_size = 0;   int sysmem_size = 0;   int width = ctx->shared.virtualWidth * ctx->cpp;   info->backHandle = DRM_AGP_NO_HANDLE;   info->zHandle = DRM_AGP_NO_HANDLE;   info->sysmemHandle = DRM_AGP_NO_HANDLE;   info->dcacheHandle = DRM_AGP_NO_HANDLE;   memset(&info->DcacheMem, 0, sizeof(I810MemRange));   memset(&info->BackBuffer, 0, sizeof(I810MemRange));   memset(&info->DepthBuffer, 0, sizeof(I810MemRange));      drmAgpAlloc(ctx->drmFD, 4096 * 1024, 1, NULL, &dcacheHandle);   info->dcacheHandle = dcacheHandle;      fprintf(stderr, "[agp] dcacheHandle : 0x%x\n", dcacheHandle);#define Elements(x) sizeof(x)/sizeof(*x)   for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)     if (width <= i810_pitches[pitch_idx])       break;      if (pitch_idx == Elements(i810_pitches)) {     fprintf(stderr,"[dri] Couldn't find depth/back buffer pitch\n");     exit(-1);   }   else   {     int lines = (ctx->shared.virtualWidth + 15) / 16 * 16;     back_size = i810_pitches[pitch_idx] * lines;     back_size = ((back_size + 4096 - 1) / 4096) * 4096;   }   sysmem_size = ctx->shared.fbSize;   fprintf(stderr,"sysmem_size is %lu back_size is %lu\n", sysmem_size, back_size);   if (dcacheHandle != DRM_AGP_NO_HANDLE) {     if (back_size > 4 * 1024 * 1024) {       fprintf(stderr,"[dri] Backsize is larger then 4 meg\n");       sysmem_size = sysmem_size - 2 * back_size;       drmAgpFree(ctx->drmFD, dcacheHandle);       info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;     } else {       sysmem_size = sysmem_size - back_size;     }   } else {     sysmem_size = sysmem_size - 2 * back_size;   }      info->SysMem.Start=0;   info->SysMem.Size = sysmem_size;   info->SysMem.End = sysmem_size;      if (dcacheHandle != DRM_AGP_NO_HANDLE) {      if (drmAgpBind(ctx->drmFD, dcacheHandle, info->DepthOffset) == 0) {	memset(&info->DcacheMem, 0, sizeof(I810MemRange));	fprintf(stderr,"[agp] GART: Found 4096K Z buffer memory\n");	info->DcacheMem.Start = info->DepthOffset;	 info->DcacheMem.Size = 1024 * 4096;	 info->DcacheMem.End =  info->DcacheMem.Start + info->DcacheMem.Size;      } else {	fprintf(stderr, "[agp] GART: dcache bind failed\n");	drmAgpFree(ctx->drmFD, dcacheHandle);	info->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;      }   } else {     fprintf(stderr, "[agp] GART: no dcache memory found\n");   }      drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);   info->backHandle = agpHandle;   if (agpHandle != DRM_AGP_NO_HANDLE) {      if (drmAgpBind(ctx->drmFD, agpHandle, info->BackOffset) == 0) {	fprintf(stderr, "[agp] Bound backbuffer memory\n");	info->BackBuffer.Start = info->BackOffset;	info->BackBuffer.Size = back_size;	info->BackBuffer.End = (info->BackBuffer.Start +				 info->BackBuffer.Size);      } else {	fprintf(stderr,"[agp] Unable to bind backbuffer.  Disabling DRI.\n");	return 0;      }   } else {     fprintf(stderr, "[dri] Unable to allocate backbuffer memory.  Disabling DRI.\n");     return 0;   }   if (dcacheHandle == DRM_AGP_NO_HANDLE) {     drmAgpAlloc(ctx->drmFD, back_size, 0, NULL, &agpHandle);     info->zHandle = agpHandle;     if (agpHandle != DRM_AGP_NO_HANDLE) {       if (drmAgpBind(ctx->drmFD, agpHandle, info->DepthOffset) == 0) {	 fprintf(stderr,"[agp] Bound depthbuffer memory\n");	 info->DepthBuffer.Start = info->DepthOffset;	 info->DepthBuffer.Size = back_size;	 info->DepthBuffer.End = (info->DepthBuffer.Start +				   info->DepthBuffer.Size);       } else {	 fprintf(stderr,"[agp] Unable to bind depthbuffer.  Disabling DRI.\n");	 return 0;       }     } else {       fprintf(stderr,"[agp] Unable to allocate depthbuffer memory.  Disabling DRI.\n");       return 0;     }   }   /* Now allocate and bind the agp space.  This memory will include the    * regular framebuffer as well as texture memory.    */   drmAgpAlloc(ctx->drmFD, sysmem_size, 0, NULL, &agpHandle);   info->sysmemHandle = agpHandle;      if (agpHandle != DRM_AGP_NO_HANDLE) {     if (drmAgpBind(ctx->drmFD, agpHandle, 0) == 0) {       fprintf(stderr, "[agp] Bound System Texture Memory\n");     } else {       fprintf(stderr, "[agp] Unable to bind system texture memory. Disabling DRI.\n");       return 0;     }   } else {     fprintf(stderr, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");     return 0;   }      info->auxPitch = i810_pitches[pitch_idx];   info->auxPitchBits = i810_pitch_flags[pitch_idx];      return 1;}/** * \brief Initialize the kernel data structures and enable the CP engine. * * \param ctx display handle. * \param info driver private data. * * \return non-zero on success, or zero on failure. * * This function is a wrapper around the DRM_I810_CP_INIT command, passing * all the parameters in a drmI810Init structure. */static int I810DRIKernelInit( const DRIDriverContext *ctx,			       I810Ptr info){   int cpp = ctx->bpp / 8;   drmI810Init  drmInfo;   int ret;   I810RingBuffer *ring = &(info->LpRing);   /* This is the struct passed to the kernel module for its initialization */   memset(&drmInfo, 0, sizeof(drmI810Init));      /* make sure we have at least 1.4 */   drmInfo.func             = I810_INIT_DMA_1_4;   drmInfo.ring_start = ring->mem.Start;   drmInfo.ring_end = ring->mem.End;   drmInfo.ring_size = ring->mem.Size;   drmInfo.mmio_offset         = (unsigned int)info->regs;   drmInfo.buffers_offset      = (unsigned int)info->buffer_map;   drmInfo.sarea_priv_offset   = sizeof(drm_sarea_t);   drmInfo.front_offset        = 0;   drmInfo.back_offset         = info->BackBuffer.Start;   drmInfo.depth_offset        = info->DepthBuffer.Start;   drmInfo.w                   = ctx->shared.virtualWidth;   drmInfo.h                   = ctx->shared.virtualHeight;   drmInfo.pitch               = info->auxPitch;   drmInfo.pitch_bits          = info->auxPitchBits;      ret = drmCommandWrite(ctx->drmFD, DRM_I810_INIT, &drmInfo, 			 sizeof(drmI810Init));   return ret >= 0;}/** * \brief Add a map for the vertex buffers that will be accessed by any * DRI-based clients. *  * \param ctx display handle. * \param info driver private data. * * \return one on success, or zero on failure. * * Calls drmAddBufs() with the previously allocated vertex buffers. */static int I810DRIBufInit( const DRIDriverContext *ctx, I810Ptr info ){   /* Initialize vertex buffers */   info->bufNumBufs = drmAddBufs(ctx->drmFD,				 I810_DMA_BUF_NR,				 I810_DMA_BUF_SZ,				 DRM_AGP_BUFFER,				 info->BufferMem.Start);   if (info->bufNumBufs <= 0) {      fprintf(stderr,	      "[drm] Could not create vertex/indirect buffers list\n");      return 0;   }   fprintf(stderr,	   "[drm] Added %d %d byte vertex/indirect buffers\n",	   info->bufNumBufs, I810_DMA_BUF_SZ);      return 1;}/** * \brief Install an IRQ handler. *  * \param ctx display handle. * \param info driver private data. * * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to * IRQ-free operation on failure. */static void I810DRIIrqInit(const DRIDriverContext *ctx,			     I810Ptr info){   if (!info->irq) {      info->irq = drmGetInterruptFromBusID(ctx->drmFD,					   ctx->pciBus,					   ctx->pciDevice,					   ctx->pciFunc);      if ((drmCtlInstHandler(ctx->drmFD, info->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");	 info->irq = 0;      }   }   if (info->irq)      fprintf(stderr,	      "[drm] dma control initialized, using IRQ %d\n",	      info->irq);}static int I810CheckDRMVersion( const DRIDriverContext *ctx,				  I810Ptr info ){   drmVersionPtr  version;   version = drmGetVersion(ctx->drmFD);   if (version) {      int req_minor, req_patch;      req_minor = 4;      req_patch = 0;	      i810_drm_version = (version->version_major<<16) | version->version_minor;      if (version->version_major != 1 ||	  version->version_minor < req_minor ||	  (version->version_minor == req_minor && 	   version->version_patchlevel < req_patch)) {	 /* Incompatible drm version */	 fprintf(stderr,		 "[dri] I810DRIScreenInit failed because of a version "		 "mismatch.\n"		 "[dri] i810.o kernel module version is %d.%d.%d "		 "but version 1.%d.%d or newer is needed.\n"		 "[dri] Disabling DRI.\n",		 version->version_major,		 version->version_minor,		 version->version_patchlevel,		 req_minor,		 req_patch);	 drmFreeVersion(version);	 return 0;      }      info->drmMinor = version->version_minor;      drmFreeVersion(version);   }   return 1;}

⌨️ 快捷键说明

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