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

📄 r200_ioctl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
   }   UNLOCK_HARDWARE( rmesa );   if (!rect)   {       rmesa->hw.all_dirty = GL_TRUE;       rmesa->swap_count++;       (*psp->systemTime->getUST)( & ust );       if ( missed_target ) {	   rmesa->swap_missed_count++;	   rmesa->swap_missed_ust = ust - rmesa->swap_ust;       }       rmesa->swap_ust = ust;       sched_yield();   }}void r200PageFlip( __DRIdrawablePrivate *dPriv ){   r200ContextPtr rmesa;   GLint ret;   GLboolean   missed_target;   __DRIscreenPrivate *psp = dPriv->driScreenPriv;   assert(dPriv);   assert(dPriv->driContextPriv);   assert(dPriv->driContextPriv->driverPrivate);   rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;   if ( R200_DEBUG & DEBUG_IOCTL ) {      fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,	      rmesa->sarea->pfCurrentPage);   }   R200_FIREVERTICES( rmesa );   LOCK_HARDWARE( rmesa );   if (!dPriv->numClipRects) {      UNLOCK_HARDWARE( rmesa );      usleep( 10000 );		/* throttle invisible client 10ms */      return;   }   /* Need to do this for the perf box placement:    */   {      drm_clip_rect_t *box = dPriv->pClipRects;      drm_clip_rect_t *b = rmesa->sarea->boxes;      b[0] = box[0];      rmesa->sarea->nbox = 1;   }   /* Throttle the frame rate -- only allow a few pending swap buffers    * request at a time.    */   r200WaitForFrameCompletion( rmesa );   UNLOCK_HARDWARE( rmesa );   driWaitForVBlank( dPriv, & missed_target );   if ( missed_target ) {      rmesa->swap_missed_count++;      (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust );   }   LOCK_HARDWARE( rmesa );   ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );   UNLOCK_HARDWARE( rmesa );   if ( ret ) {      fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );      exit( 1 );   }   rmesa->swap_count++;   (void) (*psp->systemTime->getUST)( & rmesa->swap_ust );#if 000   if ( rmesa->sarea->pfCurrentPage == 1 ) {	 rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;	 rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch;   } else {	 rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;	 rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch;   }   R200_STATECHANGE( rmesa, ctx );   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset					   + rmesa->r200Screen->fbLocation;   rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;   if (rmesa->sarea->tiling_enabled) {      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;   }#else   /* Get ready for drawing next frame.  Update the renderbuffers'    * flippedOffset/Pitch fields so we draw into the right place.    */   driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,                        rmesa->sarea->pfCurrentPage);   r200UpdateDrawBuffer(rmesa->glCtx);#endif}/* ================================================================ * Buffer clear */static void r200Clear( GLcontext *ctx, GLbitfield mask ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;   GLuint flags = 0;   GLuint color_mask = 0;   GLint ret, i;   GLint cx, cy, cw, ch;   if ( R200_DEBUG & DEBUG_IOCTL ) {      fprintf( stderr, "r200Clear\n");   }   {      LOCK_HARDWARE( rmesa );      UNLOCK_HARDWARE( rmesa );      if ( dPriv->numClipRects == 0 ) 	 return;   }   r200Flush( ctx );   if ( mask & BUFFER_BIT_FRONT_LEFT ) {      flags |= RADEON_FRONT;      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];      mask &= ~BUFFER_BIT_FRONT_LEFT;   }   if ( mask & BUFFER_BIT_BACK_LEFT ) {      flags |= RADEON_BACK;      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];      mask &= ~BUFFER_BIT_BACK_LEFT;   }   if ( mask & BUFFER_BIT_DEPTH ) {      flags |= RADEON_DEPTH;      mask &= ~BUFFER_BIT_DEPTH;   }   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) {      flags |= RADEON_STENCIL;      mask &= ~BUFFER_BIT_STENCIL;   }   if ( mask ) {      if (R200_DEBUG & DEBUG_FALLBACKS)	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);      _swrast_Clear( ctx, mask );   }   if ( !flags )       return;   if (rmesa->using_hyperz) {      flags |= RADEON_USE_COMP_ZBUF;/*      if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200)	 flags |= RADEON_USE_HIERZ; */      if (!(rmesa->state.stencil.hwBuffer) ||	 ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&	    ((rmesa->state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) {	  flags |= RADEON_CLEAR_FASTZ;      }   }   LOCK_HARDWARE( rmesa );   /* compute region after locking: */   cx = ctx->DrawBuffer->_Xmin;   cy = ctx->DrawBuffer->_Ymin;   cw = ctx->DrawBuffer->_Xmax - cx;   ch = ctx->DrawBuffer->_Ymax - cy;   /* Flip top to bottom */   cx += dPriv->x;   cy  = dPriv->y + dPriv->h - cy - ch;   /* Throttle the number of clear ioctls we do.    */   while ( 1 ) {      drm_radeon_getparam_t gp;      int ret;      int clear;      gp.param = RADEON_PARAM_LAST_CLEAR;      gp.value = (int *)&clear;      ret = drmCommandWriteRead( rmesa->dri.fd,		      DRM_RADEON_GETPARAM, &gp, sizeof(gp) );      if ( ret ) {	 fprintf( stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, ret );	 exit(1);      }      /* Clear throttling needs more thought.       */      if ( rmesa->sarea->last_clear - clear <= 25 ) {	 break;      }            if (rmesa->do_usleeps) {	 UNLOCK_HARDWARE( rmesa );	 DO_USLEEP( 1 );	 LOCK_HARDWARE( rmesa );      }   }   /* Send current state to the hardware */   r200FlushCmdBufLocked( rmesa, __FUNCTION__ );   for ( i = 0 ; i < dPriv->numClipRects ; ) {      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );      drm_clip_rect_t *box = dPriv->pClipRects;      drm_clip_rect_t *b = rmesa->sarea->boxes;      drm_radeon_clear_t clear;      drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];      GLint n = 0;      if (cw != dPriv->w || ch != dPriv->h) {         /* clear subregion */	 for ( ; i < nr ; i++ ) {	    GLint x = box[i].x1;	    GLint y = box[i].y1;	    GLint w = box[i].x2 - x;	    GLint h = box[i].y2 - y;	    if ( x < cx ) w -= cx - x, x = cx;	    if ( y < cy ) h -= cy - y, y = cy;	    if ( x + w > cx + cw ) w = cx + cw - x;	    if ( y + h > cy + ch ) h = cy + ch - y;	    if ( w <= 0 ) continue;	    if ( h <= 0 ) continue;	    b->x1 = x;	    b->y1 = y;	    b->x2 = x + w;	    b->y2 = y + h;	    b++;	    n++;	 }      } else {         /* clear whole window */	 for ( ; i < nr ; i++ ) {	    *b++ = box[i];	    n++;	 }      }      rmesa->sarea->nbox = n;      clear.flags       = flags;      clear.clear_color = rmesa->state.color.clear;      clear.clear_depth = rmesa->state.depth.clear;	/* needed for hyperz */      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];      clear.depth_mask  = rmesa->state.stencil.clear;      clear.depth_boxes = depth_boxes;      n--;      b = rmesa->sarea->boxes;      for ( ; n >= 0 ; n-- ) {	 depth_boxes[n].f[CLEAR_X1] = (float)b[n].x1;	 depth_boxes[n].f[CLEAR_Y1] = (float)b[n].y1;	 depth_boxes[n].f[CLEAR_X2] = (float)b[n].x2;	 depth_boxes[n].f[CLEAR_Y2] = (float)b[n].y2;	 depth_boxes[n].f[CLEAR_DEPTH] = ctx->Depth.Clear;      }      ret = drmCommandWrite( rmesa->dri.fd, DRM_RADEON_CLEAR,			     &clear, sizeof(clear));      if ( ret ) {	 UNLOCK_HARDWARE( rmesa );	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );	 exit( 1 );      }   }   UNLOCK_HARDWARE( rmesa );   rmesa->hw.all_dirty = GL_TRUE;}void r200WaitForIdleLocked( r200ContextPtr rmesa ){    int ret;    int i = 0;        do {       ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE);       if (ret) 	  DO_USLEEP( 1 );    } while (ret && ++i < 100);        if ( ret < 0 ) {       UNLOCK_HARDWARE( rmesa );       fprintf( stderr, "Error: R200 timed out... exiting\n" );       exit( -1 );    }}static void r200WaitForIdle( r200ContextPtr rmesa ){   LOCK_HARDWARE(rmesa);   r200WaitForIdleLocked( rmesa );   UNLOCK_HARDWARE(rmesa);}void r200Flush( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT( ctx );   if (R200_DEBUG & DEBUG_IOCTL)      fprintf(stderr, "%s\n", __FUNCTION__);   if (rmesa->dma.flush)      rmesa->dma.flush( rmesa );   r200EmitState( rmesa );      if (rmesa->store.cmd_used)      r200FlushCmdBuf( rmesa, __FUNCTION__ );}/* Make sure all commands have been sent to the hardware and have * completed processing. */void r200Finish( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   r200Flush( ctx );   if (rmesa->do_irqs) {      LOCK_HARDWARE( rmesa );      r200EmitIrqLocked( rmesa );      UNLOCK_HARDWARE( rmesa );      r200WaitIrq( rmesa );   }   else       r200WaitForIdle( rmesa );}/* This version of AllocateMemoryMESA allocates only GART memory, and * only does so after the point at which the driver has been * initialized. * * Theoretically a valid context isn't required.  However, in this * implementation, it is, as I'm using the hardware lock to protect * the kernel data structures, and the current context to get the * device fd. */void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size,			     GLfloat readfreq, GLfloat writefreq, 			     GLfloat priority){   GET_CURRENT_CONTEXT(ctx);   r200ContextPtr rmesa;   int region_offset;   drm_radeon_mem_alloc_t alloc;   int ret;   if (R200_DEBUG & DEBUG_IOCTL)      fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, 	      writefreq, priority);   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map)      return NULL;   if (getenv("R200_NO_ALLOC"))      return NULL;   alloc.region = RADEON_MEM_REGION_GART;   alloc.alignment = 0;   alloc.size = size;   alloc.region_offset = &region_offset;   ret = drmCommandWriteRead( rmesa->r200Screen->driScreen->fd,			      DRM_RADEON_ALLOC,			      &alloc, sizeof(alloc));      if (ret) {      fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret);      return NULL;   }      {      char *region_start = (char *)rmesa->r200Screen->gartTextures.map;      return (void *)(region_start + region_offset);   }}/* Called via glXFreeMemoryMESA() */void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer){   GET_CURRENT_CONTEXT(ctx);   r200ContextPtr rmesa;   ptrdiff_t region_offset;   drm_radeon_mem_free_t memfree;   int ret;   if (R200_DEBUG & DEBUG_IOCTL)      fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->r200Screen->gartTextures.map) {      fprintf(stderr, "%s: no context\n", __FUNCTION__);      return;   }   region_offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;   if (region_offset < 0 ||        region_offset > rmesa->r200Screen->gartTextures.size) {      fprintf(stderr, "offset %d outside range 0..%d\n", region_offset,	      rmesa->r200Screen->gartTextures.size);      return;   }   memfree.region = RADEON_MEM_REGION_GART;   memfree.region_offset = region_offset;      ret = drmCommandWrite( rmesa->r200Screen->driScreen->fd,			  DRM_RADEON_FREE,			  &memfree, sizeof(memfree));      if (ret)       fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret);}/* Called via glXGetMemoryOffsetMESA() */GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer){   GET_CURRENT_CONTEXT(ctx);   r200ContextPtr rmesa;   GLuint card_offset;   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) {      fprintf(stderr, "%s: no context\n", __FUNCTION__);      return ~0;   }   if (!r200IsGartMemory( rmesa, pointer, 0 ))      return ~0;   card_offset = r200GartOffsetFromVirtual( rmesa, pointer );   return card_offset - rmesa->r200Screen->gart_base;}GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,			   GLint size ){   ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;   int valid = (size >= 0 &&		offset >= 0 &&		offset + size < rmesa->r200Screen->gartTextures.size);   if (R200_DEBUG & DEBUG_IOCTL)      fprintf(stderr, "r200IsGartMemory( %p ) : %d\n", pointer, valid );      return valid;}GLuint r200GartOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer ){   ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;   if (offset < 0 || offset > rmesa->r200Screen->gartTextures.size)      return ~0;   else      return rmesa->r200Screen->gart_texture_offset + offset;}void r200InitIoctlFuncs( struct dd_function_table *functions ){    functions->Clear = r200Clear;    functions->Finish = r200Finish;    functions->Flush = r200Flush;}

⌨️ 快捷键说明

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