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

📄 via_ioctl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
      viaWaitBreadcrumb( vmesa, vmesa->lastDma );   if (light) return;   while(!viaCheckIdle(vmesa))      ;   via_release_pending_textures(vmesa);}/* Wait for command stream to be processed *and* the next vblank to * occur.  Equivalent to calling WAIT_IDLE() and then WaitVBlank, * except that WAIT_IDLE() will spin the CPU polling, while this is * IRQ driven. */static void viaWaitIdleVBlank(  __DRIdrawablePrivate *dPriv, 			       struct via_context *vmesa,			       GLuint value ){   GLboolean missed_target;   __DRIscreenPrivate *psp = dPriv->driScreenPriv;   VIA_FLUSH_DMA(vmesa);    if (!value)      return;   do {      if (value < vmesa->lastBreadcrumbRead ||	  vmesa->thrashing)	 viaSwapOutWork(vmesa);      driWaitForVBlank( dPriv, & missed_target );      if ( missed_target ) {	 vmesa->swap_missed_count++;	 (*psp->systemTime->getUST)( &vmesa->swap_missed_ust );      }   }    while (!viaCheckBreadcrumb(vmesa, value));	    vmesa->thrashing = 0;	/* reset flag on swap */   vmesa->swap_count++;      via_release_pending_textures( vmesa );}static void viaDoPageFlipLocked(struct via_context *vmesa, GLuint offset){   RING_VARS;   if (VIA_DEBUG & DEBUG_2D)      fprintf(stderr, "%s %x\n", __FUNCTION__, offset);   if (!vmesa->nDoneFirstFlip) {      vmesa->nDoneFirstFlip = GL_TRUE;      BEGIN_RING(4);      OUT_RING(HALCYON_HEADER2);      OUT_RING(0x00fe0000);      OUT_RING(0x0000000e);      OUT_RING(0x0000000e);      ADVANCE_RING();   }   BEGIN_RING(4);   OUT_RING( HALCYON_HEADER2 );   OUT_RING( 0x00fe0000 );   OUT_RING((HC_SubA_HFBBasL << 24) | (offset & 0xFFFFF8) | 0x2);   OUT_RING((HC_SubA_HFBDrawFirst << 24) |	    ((offset & 0xFF000000) >> 24) | 0x0100);   ADVANCE_RING();   vmesa->pfCurrentOffset = vmesa->sarea->pfCurrentOffset = offset;   viaFlushDmaLocked(vmesa, VIA_NO_CLIPRECTS); /* often redundant */}void viaResetPageFlippingLocked(struct via_context *vmesa){   if (VIA_DEBUG & DEBUG_2D)      fprintf(stderr, "%s\n", __FUNCTION__);   viaDoPageFlipLocked( vmesa, 0 );   if (vmesa->front.offset != 0) {      struct via_renderbuffer buffer_tmp;      memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));      memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));      memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));   }   assert(vmesa->front.offset == 0);   vmesa->doPageFlip = vmesa->allowPageFlip = 0;}/* * Copy the back buffer to the front buffer.  */void viaCopyBuffer(__DRIdrawablePrivate *dPriv){   struct via_context *vmesa =       (struct via_context *)dPriv->driContextPriv->driverPrivate;   __DRIscreenPrivate *psp = dPriv->driScreenPriv;   if (VIA_DEBUG & DEBUG_IOCTL)      fprintf(stderr, 	      "%s: lastSwap[1] %d lastSwap[0] %d lastWrite %d lastRead %d\n",	      __FUNCTION__,	      vmesa->lastSwap[1], 	      vmesa->lastSwap[0], 	      vmesa->lastBreadcrumbWrite,	      vmesa->lastBreadcrumbRead);   VIA_FLUSH_DMA(vmesa);   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&       vmesa->lastBreadcrumbWrite > 1)      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);   else      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[1]);   LOCK_HARDWARE(vmesa);   /* Catch and cleanup situation where we were pageflipping but have    * stopped.    */   if (dPriv->numClipRects && vmesa->sarea->pfCurrentOffset != 0) {      viaResetPageFlippingLocked(vmesa);      UNLOCK_HARDWARE(vmesa);      return;   }   viaDoSwapBuffers(vmesa, dPriv->pClipRects, dPriv->numClipRects);   vmesa->lastSwap[1] = vmesa->lastSwap[0];   vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;   viaEmitBreadcrumbLocked(vmesa);   UNLOCK_HARDWARE(vmesa);   (*psp->systemTime->getUST)( &vmesa->swap_ust );}void viaPageFlip(__DRIdrawablePrivate *dPriv){    struct via_context *vmesa =        (struct via_context *)dPriv->driContextPriv->driverPrivate;    struct via_renderbuffer buffer_tmp;    __DRIscreenPrivate *psp = dPriv->driScreenPriv;    VIA_FLUSH_DMA(vmesa);   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&       vmesa->lastBreadcrumbWrite > 1)      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);   else      viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastSwap[0]);    LOCK_HARDWARE(vmesa);    viaDoPageFlipLocked(vmesa, vmesa->back.offset);    vmesa->lastSwap[1] = vmesa->lastSwap[0];    vmesa->lastSwap[0] = vmesa->lastBreadcrumbWrite;    viaEmitBreadcrumbLocked(vmesa);    UNLOCK_HARDWARE(vmesa);    (*psp->systemTime->getUST)( &vmesa->swap_ust );    /* KW: FIXME: When buffers are freed, could free frontbuffer by     * accident:     */    memcpy(&buffer_tmp, &vmesa->back, sizeof(struct via_renderbuffer));    memcpy(&vmesa->back, &vmesa->front, sizeof(struct via_renderbuffer));    memcpy(&vmesa->front, &buffer_tmp, sizeof(struct via_renderbuffer));}#define VIA_CMDBUF_MAX_LAG 50000static int fire_buffer(struct via_context *vmesa){   drm_via_cmdbuffer_t bufI;   int ret;   bufI.buf = (char *)vmesa->dma;   bufI.size = vmesa->dmaLow;   if (vmesa->useAgp) {      drm_via_cmdbuf_size_t bSiz;      /* Do the CMDBUF_SIZE ioctl:       */      bSiz.func = VIA_CMDBUF_LAG;      bSiz.wait = 1;      bSiz.size = VIA_CMDBUF_MAX_LAG;      do {	 ret = drmCommandWriteRead(vmesa->driFd, DRM_VIA_CMDBUF_SIZE, 				   &bSiz, sizeof(bSiz));      } while (ret == -EAGAIN);      if (ret) {	 UNLOCK_HARDWARE(vmesa);	 fprintf(stderr, "%s: DRM_VIA_CMDBUF_SIZE returned %d\n",		 __FUNCTION__, ret);	 abort();	 return ret;      }      /* Actually fire the buffer:       */      do {	 ret = drmCommandWrite(vmesa->driFd, DRM_VIA_CMDBUFFER, 			       &bufI, sizeof(bufI));      } while (ret == -EAGAIN);      if (ret) {	 UNLOCK_HARDWARE(vmesa);	 fprintf(stderr, "%s: DRM_VIA_CMDBUFFER returned %d\n",		 __FUNCTION__, ret);	 abort();	 /* If this fails, the original code fell back to the PCI path. 	  */      }      else 	 return 0;      /* Fall through to PCI handling?!?       */      viaWaitIdleLocked(vmesa, GL_FALSE);   }	       ret = drmCommandWrite(vmesa->driFd, DRM_VIA_PCICMD, &bufI, sizeof(bufI));   if (ret) {      UNLOCK_HARDWARE(vmesa);      dump_dma(vmesa);      fprintf(stderr, "%s: DRM_VIA_PCICMD returned %d\n", __FUNCTION__, ret);       abort();   }   return ret;}/* Inserts the surface addresss and active cliprects one at a time * into the head of the DMA buffer being flushed.  Fires the buffer * for each cliprect. */static void via_emit_cliprect(struct via_context *vmesa,			      drm_clip_rect_t *b) {   struct via_renderbuffer *buffer = vmesa->drawBuffer;   GLuint *vb = (GLuint *)(vmesa->dma + vmesa->dmaCliprectAddr);   GLuint format = (vmesa->viaScreen->bitsPerPixel == 0x20 		    ? HC_HDBFM_ARGB8888 		    : HC_HDBFM_RGB565);   GLuint pitch = buffer->pitch;   GLuint offset = buffer->offset;   if (0)      fprintf(stderr, "emit cliprect for box %d,%d %d,%d\n", 	      b->x1, b->y1, b->x2, b->y2);   vb[0] = HC_HEADER2;   vb[1] = (HC_ParaType_NotTex << 16);   if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {      vb[2] = (HC_SubA_HClipTB << 24) | 0x0;      vb[3] = (HC_SubA_HClipLR << 24) | 0x0;   }   else {      vb[2] = (HC_SubA_HClipTB << 24) | (b->y1 << 12) | b->y2;      vb[3] = (HC_SubA_HClipLR << 24) | (b->x1 << 12) | b->x2;   }	       vb[4] = (HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF);   vb[5] = (HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000) >> 24);    vb[6] = (HC_SubA_HSPXYOS << 24);   vb[7] = (HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch;}static int intersect_rect(drm_clip_rect_t *out,                          drm_clip_rect_t *a,                          drm_clip_rect_t *b){    *out = *a;        if (0)       fprintf(stderr, "intersect %d,%d %d,%d and %d,%d %d,%d\n", 	       a->x1, a->y1, a->x2, a->y2,	       b->x1, b->y1, b->x2, b->y2);    if (b->x1 > out->x1) out->x1 = b->x1;    if (b->x2 < out->x2) out->x2 = b->x2;    if (out->x1 >= out->x2) return 0;    if (b->y1 > out->y1) out->y1 = b->y1;    if (b->y2 < out->y2) out->y2 = b->y2;    if (out->y1 >= out->y2) return 0;    return 1;}void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags){   int i;   RING_VARS;   if (VIA_DEBUG & (DEBUG_IOCTL|DEBUG_DMA))      fprintf(stderr, "%s\n", __FUNCTION__);   if (*(GLuint *)vmesa->driHwLock != (DRM_LOCK_HELD|vmesa->hHWContext) &&       *(GLuint *)vmesa->driHwLock !=        (DRM_LOCK_HELD|DRM_LOCK_CONT|vmesa->hHWContext)) {      fprintf(stderr, "%s called without lock held\n", __FUNCTION__);      abort();   }   if (vmesa->dmaLow == 0) {      return;   }   assert(vmesa->dmaLastPrim == 0);   /* viaFinishPrimitive can add up to 8 bytes beyond VIA_DMA_HIGHWATER:    */   if (vmesa->dmaLow > VIA_DMA_HIGHWATER + 8) {      fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);      abort();   }   switch (vmesa->dmaLow & 0x1F) {	   case 8:      BEGIN_RING_NOCHECK( 6 );      OUT_RING( HC_HEADER2 );      OUT_RING( (HC_ParaType_NotTex << 16) );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      ADVANCE_RING();      break;   case 16:      BEGIN_RING_NOCHECK( 4 );      OUT_RING( HC_HEADER2 );      OUT_RING( (HC_ParaType_NotTex << 16) );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      ADVANCE_RING();      break;       case 24:      BEGIN_RING_NOCHECK( 10 );      OUT_RING( HC_HEADER2 );      OUT_RING( (HC_ParaType_NotTex << 16) );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );      OUT_RING( HC_DUMMY );	      ADVANCE_RING();      break;       case 0:      break;   default:      if (VIA_DEBUG & DEBUG_IOCTL)	 fprintf(stderr, "%s: unaligned value for vmesa->dmaLow: %x\n",		 __FUNCTION__, vmesa->dmaLow);   }   vmesa->lastDma = vmesa->lastBreadcrumbWrite;   if (VIA_DEBUG & DEBUG_DMA)      dump_dma( vmesa );   if (flags & VIA_NO_CLIPRECTS) {      if (0) fprintf(stderr, "%s VIA_NO_CLIPRECTS\n", __FUNCTION__);      assert(vmesa->dmaCliprectAddr == ~0);      fire_buffer( vmesa );   }   else if (vmesa->dmaCliprectAddr == ~0) {      /* Contains only state.  Could just dump the packet?       */      if (0) fprintf(stderr, "%s: no dmaCliprectAddr\n", __FUNCTION__);      if (0) fire_buffer( vmesa );   }   else if (vmesa->numClipRects) {      drm_clip_rect_t *pbox = vmesa->pClipRects;      __DRIdrawablePrivate *dPriv = vmesa->driDrawable;      struct via_renderbuffer *const vrb = 	(struct via_renderbuffer *) dPriv->driverPrivate;      for (i = 0; i < vmesa->numClipRects; i++) {	 drm_clip_rect_t b;	 b.x1 = pbox[i].x1;	 b.x2 = pbox[i].x2;	 b.y1 = pbox[i].y1;	 b.y2 = pbox[i].y2;	 if (vmesa->scissor &&	     !intersect_rect(&b, &b, &vmesa->scissorRect)) 	    continue;	 via_emit_cliprect(vmesa, &b);	 if (fire_buffer(vmesa) != 0) {	    dump_dma( vmesa );	    goto done;	 }      }   } else {      if (0) fprintf(stderr, "%s: no cliprects\n", __FUNCTION__);      UNLOCK_HARDWARE(vmesa);      sched_yield();      LOCK_HARDWARE(vmesa);   } done:   /* Reset vmesa vars:    */   vmesa->dmaLow = 0;   vmesa->dmaCliprectAddr = ~0;   vmesa->newEmitState = ~0;}void viaWrapPrimitive( struct via_context *vmesa ){   GLenum renderPrimitive = vmesa->renderPrimitive;   GLenum hwPrimitive = vmesa->hwPrimitive;   if (VIA_DEBUG & DEBUG_PRIMS) fprintf(stderr, "%s\n", __FUNCTION__);      if (vmesa->dmaLastPrim)      viaFinishPrimitive( vmesa );      viaFlushDma(vmesa);   if (renderPrimitive != GL_POLYGON + 1)      viaRasterPrimitive( vmesa->glCtx,			  renderPrimitive,			  hwPrimitive );}void viaFlushDma(struct via_context *vmesa){   if (vmesa->dmaLow) {      assert(!vmesa->dmaLastPrim);      LOCK_HARDWARE(vmesa);       viaFlushDmaLocked(vmesa, 0);      UNLOCK_HARDWARE(vmesa);   }}static void viaFlush(GLcontext *ctx){    struct via_context *vmesa = VIA_CONTEXT(ctx);    VIA_FLUSH_DMA(vmesa);}static void viaFinish(GLcontext *ctx){    struct via_context *vmesa = VIA_CONTEXT(ctx);    VIA_FLUSH_DMA(vmesa);    viaWaitIdle(vmesa, GL_FALSE);}static void viaClearStencil(GLcontext *ctx,  int s){    return;}void viaInitIoctlFuncs(GLcontext *ctx){    ctx->Driver.Flush = viaFlush;    ctx->Driver.Clear = viaClear;    ctx->Driver.Finish = viaFinish;    ctx->Driver.ClearStencil = viaClearStencil;}

⌨️ 快捷键说明

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