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

📄 mgaioctl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * buffers call.  This is done to prevent queuing a second buffer swap	 * before the previous swap is executed.	 */	while ( 1 ) {	    if ( last_wrap < mmesa->sarea->last_wrap ||		 ( last_wrap == mmesa->sarea->last_wrap &&		   last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -				  mmesa->primary_offset) ) ) {		break;	    }	    if ( 0 ) {		wait++;		fprintf( stderr, "   last: head=0x%06x wrap=%d\n",			 last_frame, last_wrap );		fprintf( stderr, "   head: head=0x%06lx wrap=%d\n",			 (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),			 mmesa->sarea->last_wrap );	    }	    UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );	    UNLOCK_HARDWARE( mmesa );	    DO_USLEEP( 1 );	    LOCK_HARDWARE( mmesa );	}	if ( wait )	  fprintf( stderr, "\n" );	UNLOCK_HARDWARE( mmesa );    }}/* * Copy the back buffer to the front buffer. */void mgaCopyBuffer( __DRIdrawablePrivate *dPriv ){   mgaContextPtr mmesa;   drm_clip_rect_t *pbox;   GLint nbox;   GLint ret;   GLint i;   GLboolean   missed_target;   __DRIscreenPrivate *psp = dPriv->driScreenPriv;   assert(dPriv);   assert(dPriv->driContextPriv);   assert(dPriv->driContextPriv->driverPrivate);   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;   FLUSH_BATCH( mmesa );   mgaWaitForFrameCompletion( mmesa );   driWaitForVBlank( dPriv, & missed_target );   if ( missed_target ) {      mmesa->swap_missed_count++;      (void) (*psp->systemTime->getUST)( & mmesa->swap_missed_ust );   }   LOCK_HARDWARE( mmesa );   /* Use the frontbuffer cliprects    */   if (mmesa->dirty_cliprects & MGA_FRONT)      mgaUpdateRects( mmesa, MGA_FRONT );   pbox = dPriv->pClipRects;   nbox = dPriv->numClipRects;   for (i = 0 ; i < nbox ; )   {      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);      drm_clip_rect_t *b = mmesa->sarea->boxes;      mmesa->sarea->nbox = nr - i;      for ( ; i < nr ; i++)	 *b++ = pbox[i];      if (0)	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );      if ( ret ) {	 printf("send swap retcode = %d\n", ret);	 exit(1);      }   }   (void) mgaSetFence( mmesa, & mmesa->last_frame_fence );   UNLOCK_HARDWARE( mmesa );   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;   mmesa->swap_count++;   (void) (*psp->systemTime->getUST)( & mmesa->swap_ust );}/** * Implement the hardware-specific portion of \c glFinish. * * Flushes all pending commands to the hardware and wait for them to finish. *  * \param ctx  Context where the \c glFinish command was issued. * * \sa glFinish, mgaFlush, mgaFlushDMA */static void mgaFinish( GLcontext *ctx  ){    mgaContextPtr mmesa = MGA_CONTEXT(ctx);    uint32_t  fence;    LOCK_HARDWARE( mmesa );    if ( mmesa->vertex_dma_buffer != NULL ) {	mgaFlushVerticesLocked( mmesa );    }    if ( mgaSetFence( mmesa, & fence ) == 0 ) {	UNLOCK_HARDWARE( mmesa );	(void) mgaWaitFence( mmesa, fence, NULL );    }    else {	if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL) {	    fprintf(stderr, "mgaRegetLockQuiescent\n");	}	UPDATE_LOCK( mmesa, DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH );	UNLOCK_HARDWARE( mmesa );    }}/** * Flush all commands upto at least a certain point to the hardware. * * \note * The term "wait" in the name of this function is misleading.  It doesn't * actually wait for anything.  It just makes sure that the commands have * been flushed to the hardware. * * \warning * As the name implies, this function assumes that the hardware lock is * held on entry. */void mgaWaitAgeLocked( mgaContextPtr mmesa, int age  ){   if (GET_DISPATCH_AGE(mmesa) < age) {      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );   }}static GLboolean intersect_rect( drm_clip_rect_t *out,				 const drm_clip_rect_t *a,				 const drm_clip_rect_t *b ){   *out = *a;   if (b->x1 > out->x1) out->x1 = b->x1;   if (b->y1 > out->y1) out->y1 = b->y1;   if (b->x2 < out->x2) out->x2 = b->x2;   if (b->y2 < out->y2) out->y2 = b->y2;   return ((out->x1 < out->x2) && (out->y1 < out->y2));}static void age_mmesa( mgaContextPtr mmesa, int age ){   if (mmesa->CurrentTexObj[0]) mmesa->CurrentTexObj[0]->age = age;   if (mmesa->CurrentTexObj[1]) mmesa->CurrentTexObj[1]->age = age;}void mgaFlushVerticesLocked( mgaContextPtr mmesa ){   drm_clip_rect_t *pbox = mmesa->pClipRects;   int nbox = mmesa->numClipRects;   drmBufPtr buffer = mmesa->vertex_dma_buffer;   drm_mga_vertex_t vertex;   int i;   mmesa->vertex_dma_buffer = 0;   if (!buffer)      return;   if (mmesa->dirty_cliprects & mmesa->draw_buffer)      mgaUpdateRects( mmesa, mmesa->draw_buffer );   if (mmesa->dirty & ~MGA_UPLOAD_CLIPRECTS)      mgaEmitHwStateLocked( mmesa );   /* FIXME: Workaround bug in kernel module.    */   mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;   if (!nbox)      buffer->used = 0;   if (nbox >= MGA_NR_SAREA_CLIPRECTS)      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;#if 0   if (!buffer->used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS))   {      if (nbox == 1)	 mmesa->sarea->nbox = 0;      else	 mmesa->sarea->nbox = nbox;      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)	 fprintf(stderr, "Firing vertex -- case a nbox %d\n", nbox);      vertex.idx = buffer->idx;      vertex.used = buffer->used;      vertex.discard = 1;      drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,                        &vertex, sizeof(drmMGAVertex) );      age_mmesa(mmesa, mmesa->sarea->last_enqueue);   }   else#endif   {      for (i = 0 ; i < nbox ; )      {	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, nbox);	 drm_clip_rect_t *b = mmesa->sarea->boxes;	 int discard = 0;	 if (mmesa->scissor) {	    mmesa->sarea->nbox = 0;	    for ( ; i < nr ; i++) {	       *b = pbox[i];	       if (intersect_rect(b, b, &mmesa->scissor_rect)) {		  mmesa->sarea->nbox++;		  b++;	       }	    }	    /* Culled?	     */	    if (!mmesa->sarea->nbox) {	       if (nr < nbox) continue;	       buffer->used = 0;	    }	 } else {	    mmesa->sarea->nbox = nr - i;	    for ( ; i < nr ; i++)	       *b++ = pbox[i];	 }	 /* Finished with the buffer?	  */	 if (nr == nbox)	    discard = 1;	 mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS;         vertex.idx = buffer->idx;         vertex.used = buffer->used;         vertex.discard = discard;         drmCommandWrite( mmesa->driFd, DRM_MGA_VERTEX,                          &vertex, sizeof(vertex) );	 age_mmesa(mmesa, mmesa->sarea->last_enqueue);      }   }   mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS;}void mgaFlushVertices( mgaContextPtr mmesa ){   LOCK_HARDWARE( mmesa );   mgaFlushVerticesLocked( mmesa );   UNLOCK_HARDWARE( mmesa );}void mgaFireILoadLocked( mgaContextPtr mmesa,			 GLuint offset, GLuint length ){   if (!mmesa->iload_buffer) {      fprintf(stderr, "mgaFireILoad: no buffer\n");      return;   }   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "mgaFireILoad idx %d ofs 0x%x length %d\n",	      mmesa->iload_buffer->idx, (int)offset, (int)length );   mga_iload_dma_ioctl( mmesa, offset, length );}void mgaGetILoadBufferLocked( mgaContextPtr mmesa ){   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "mgaGetIloadBuffer (buffer now %p)\n",              (void *) mmesa->iload_buffer);   mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa );}/** * Implement the hardware-specific portion of \c glFlush. * * \param ctx  Context to be flushed. * * \sa glFlush, mgaFinish, mgaFlushDMA */static void mgaFlush( GLcontext *ctx ){    mgaContextPtr mmesa = MGA_CONTEXT( ctx );    LOCK_HARDWARE( mmesa );    if ( mmesa->vertex_dma_buffer != NULL ) {	mgaFlushVerticesLocked( mmesa );    }    UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );    UNLOCK_HARDWARE( mmesa );}int mgaFlushDMA( int fd, drmLockFlags flags ){   drm_lock_t lock;   int ret, i = 0;   memset( &lock, 0, sizeof(lock) );   lock.flags = flags & (DRM_LOCK_QUIESCENT | DRM_LOCK_FLUSH 			 | DRM_LOCK_FLUSH_ALL);   do {      ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(lock) );   } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );   if ( ret == 0 )      return 0;   if ( errno != EBUSY )      return -errno;   if ( lock.flags & DRM_LOCK_QUIESCENT ) {      /* Only keep trying if we need quiescence.       */      lock.flags &= ~(DRM_LOCK_FLUSH | DRM_LOCK_FLUSH_ALL);      do {         ret = drmCommandWrite( fd, DRM_MGA_FLUSH, &lock, sizeof(lock) );      } while ( ret && errno == EBUSY && i++ < DRM_MGA_IDLE_RETRY );   }   if ( ret == 0 ) {      return 0;   } else {      return -errno;   }}void mgaInitIoctlFuncs( struct dd_function_table *functions ){   functions->Clear = mgaClear;   functions->Flush = mgaFlush;   functions->Finish = mgaFinish;}

⌨️ 快捷键说明

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