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

📄 intel_batchbuffer.c

📁 显驱动 Intel英特尔G45G43G41G35G33G31G965Q963Q965GM965系列显卡最新X.Org驱动2.4.0版For Linux
💻 C
字号:
/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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 TUNGSTEN GRAPHICS 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. * **************************************************************************/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <signal.h>#include <fcntl.h>#include <dirent.h>#include <string.h>#include <assert.h>#include <sys/ioctl.h>#include <X11/Xlibint.h>#include <fourcc.h>#include <X11/extensions/Xv.h>#include <X11/extensions/Xvlib.h>#include <X11/extensions/XvMC.h>#include <X11/extensions/XvMClib.h>#include "intel_xvmc.h"#include "intel_batchbuffer.h"#define MI_BATCH_BUFFER_END     (0xA << 23)static int intelEmitIrqLocked(void){   drmI830IrqEmit ie;   int ret, seq;   ie.irq_seq = &seq;   ret = drmCommandWriteRead(xvmc_driver->fd, DRM_I830_IRQ_EMIT,                             &ie, sizeof(ie));   if ( ret ) {      fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret);      exit(1);   }   return seq;}static void intelWaitIrq(int seq){   int ret;   drmI830IrqWait iw;   iw.irq_seq = seq;   do {      ret = drmCommandWrite(xvmc_driver->fd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );   } while (ret == -EAGAIN || ret == -EINTR);   if (ret) {      fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret);      exit(1);   }}static void intelDestroyBatchBuffer(void){   if (xvmc_driver->alloc.offset) {       xvmc_driver->alloc.ptr = NULL;       xvmc_driver->alloc.offset = 0;   } else if (xvmc_driver->alloc.ptr) {      free(xvmc_driver->alloc.ptr);      xvmc_driver->alloc.ptr = NULL;   }   memset(&xvmc_driver->batch, 0, sizeof(xvmc_driver->batch));}Bool intelInitBatchBuffer(void){    if (drmMap(xvmc_driver->fd,		xvmc_driver->batchbuffer.handle,		xvmc_driver->batchbuffer.size,		(drmAddress *)&xvmc_driver->batchbuffer.map) != 0) {	XVMC_ERR("fail to map batch buffer\n");	return False;    }    if (xvmc_driver->batchbuffer.map) {	xvmc_driver->alloc.size = xvmc_driver->batchbuffer.size;	xvmc_driver->alloc.offset = xvmc_driver->batchbuffer.offset;	xvmc_driver->alloc.ptr = xvmc_driver->batchbuffer.map;    } else {	xvmc_driver->alloc.size = 8 * 1024;	xvmc_driver->alloc.offset = 0;	xvmc_driver->alloc.ptr = malloc(xvmc_driver->alloc.size);    }    xvmc_driver->alloc.active_buf = 0;    assert(xvmc_driver->alloc.ptr);    return True;}void intelFiniBatchBuffer(void){    if (xvmc_driver->batchbuffer.map) {        drmUnmap(xvmc_driver->batchbuffer.map, xvmc_driver->batchbuffer.size);        xvmc_driver->batchbuffer.map = NULL;    }    intelDestroyBatchBuffer();}static void intelBatchbufferRequireSpace(unsigned int sz){   if (xvmc_driver->batch.space < sz)      intelFlushBatch(TRUE);}void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags){   assert((bytes & 0x3) == 0);   intelBatchbufferRequireSpace(bytes);   memcpy(xvmc_driver->batch.ptr, data, bytes);   xvmc_driver->batch.ptr += bytes;   xvmc_driver->batch.space -= bytes;   assert(xvmc_driver->batch.space >= 0);}#define MI_FLUSH                ((0 << 29) | (4 << 23))#define FLUSH_MAP_CACHE         (1 << 0)#define FLUSH_RENDER_CACHE      (0 << 2)#define FLUSH_WRITE_DIRTY_STATE (1 << 4)static void intelRefillBatchLocked(Bool allow_unlock){   unsigned half = xvmc_driver->alloc.size >> 1;   unsigned buf = (xvmc_driver->alloc.active_buf ^= 1);   unsigned dword[2];   dword[0] = MI_FLUSH | FLUSH_WRITE_DIRTY_STATE | FLUSH_RENDER_CACHE | FLUSH_MAP_CACHE;   dword[1] = 0;   intelCmdIoctl((char *)&dword[0], sizeof(dword));   xvmc_driver->alloc.irq_emitted = intelEmitIrqLocked();   if (xvmc_driver->alloc.irq_emitted) {       intelWaitIrq(xvmc_driver->alloc.irq_emitted);   }   xvmc_driver->batch.start_offset = xvmc_driver->alloc.offset + buf * half;   xvmc_driver->batch.ptr = (unsigned char *)xvmc_driver->alloc.ptr + buf * half;   xvmc_driver->batch.size = half - 8;   xvmc_driver->batch.space = half - 8;   assert(xvmc_driver->batch.space >= 0);}static void intelFlushBatchLocked(Bool ignore_cliprects,				  Bool refill,				  Bool allow_unlock){   drmI830BatchBuffer batch;   if (xvmc_driver->batch.space != xvmc_driver->batch.size) {      batch.start = xvmc_driver->batch.start_offset;      batch.used = xvmc_driver->batch.size - xvmc_driver->batch.space;      batch.cliprects = 0;      batch.num_cliprects = 0;      batch.DR1 = 0;      batch.DR4 = 0;      if (xvmc_driver->alloc.offset) {          if ((batch.used & 0x4) == 0) {              ((int *)xvmc_driver->batch.ptr)[0] = 0;              ((int *)xvmc_driver->batch.ptr)[1] = MI_BATCH_BUFFER_END;              batch.used += 0x8;              xvmc_driver->batch.ptr += 0x8;          } else {              ((int *)xvmc_driver->batch.ptr)[0] = MI_BATCH_BUFFER_END;              batch.used += 0x4;              xvmc_driver->batch.ptr += 0x4;          }      }      xvmc_driver->batch.start_offset += batch.used;      xvmc_driver->batch.size -= batch.used;      if (xvmc_driver->batch.size < 8) {         refill = TRUE;         xvmc_driver->batch.space = xvmc_driver->batch.size = 0;      }      else {         xvmc_driver->batch.size -= 8;         xvmc_driver->batch.space = xvmc_driver->batch.size;      }      assert(xvmc_driver->batch.space >= 0);      assert(batch.start >= xvmc_driver->alloc.offset);      assert(batch.start < xvmc_driver->alloc.offset + xvmc_driver->alloc.size);      assert(batch.start + batch.used > xvmc_driver->alloc.offset);      assert(batch.start + batch.used <= xvmc_driver->alloc.offset + xvmc_driver->alloc.size);      if (xvmc_driver->alloc.offset) {          if (drmCommandWrite(xvmc_driver->fd, DRM_I830_BATCHBUFFER, &batch, sizeof(batch))) {              fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n",  -errno);              exit(1);          }      } else {         drmI830CmdBuffer cmd;         cmd.buf = (char *)xvmc_driver->alloc.ptr + batch.start;         cmd.sz = batch.used;         cmd.DR1 = batch.DR1;         cmd.DR4 = batch.DR4;         cmd.num_cliprects = batch.num_cliprects;         cmd.cliprects = batch.cliprects;         if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER,                              &cmd, sizeof(cmd))) {            fprintf(stderr, "DRM_I915_CMDBUFFER: %d\n",  -errno);            exit(1);         }      }   }   if (refill)      intelRefillBatchLocked(allow_unlock);}void intelFlushBatch(Bool refill ){   intelFlushBatchLocked(FALSE, refill, TRUE);}void intelCmdIoctl(char *buf, unsigned used){   drmI830CmdBuffer cmd;   cmd.buf = buf;   cmd.sz = used;   cmd.cliprects = 0;   cmd.num_cliprects = 0;   cmd.DR1 = 0;   cmd.DR4 = 0;   if (drmCommandWrite(xvmc_driver->fd, DRM_I830_CMDBUFFER,                        &cmd, sizeof(cmd))) {      fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n",  -errno);      exit(1);   }}

⌨️ 快捷键说明

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