Ejemplo n.º 1
0
/* Update the hardware state.  This is called if another context has
 * grabbed the hardware lock, which includes the X server.  This
 * function also updates the driver's window state after the X server
 * moves, resizes or restacks a window -- the change will be reflected
 * in the drawable position and clip rects.  Since the X server grabs
 * the hardware lock when it changes the window state, this routine will
 * automatically be called after such a change.
 */
void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
{
	__DRIdrawablePrivate *const drawable = radeon_get_drawable(rmesa);
	__DRIdrawablePrivate *const readable = radeon_get_readable(rmesa);
	__DRIscreenPrivate *sPriv = rmesa->dri.screen;

	drmGetLock(rmesa->dri.fd, rmesa->dri.hwContext, flags);

	/* The window might have moved, so we might need to get new clip
	 * rects.
	 *
	 * NOTE: This releases and regrabs the hw lock to allow the X server
	 * to respond to the DRI protocol request for new drawable info.
	 * Since the hardware state depends on having the latest drawable
	 * clip rects, all state checking must be done _after_ this call.
	 */
	if (drawable)
		DRI_VALIDATE_DRAWABLE_INFO(sPriv, drawable);
	if (readable && drawable != readable) {
		DRI_VALIDATE_DRAWABLE_INFO(sPriv, readable);
	}

	if (drawable && (rmesa->lastStamp != drawable->lastStamp)) {
		radeon_window_moved(rmesa);
		rmesa->lastStamp = drawable->lastStamp;
	}

	rmesa->vtbl.get_lock(rmesa);
}
Ejemplo n.º 2
0
void radeon_lock_hardware(radeonContextPtr radeon
#ifndef NDEBUG
		,const char* function
		,const char* file
		,const int line
#endif
		)
{
	char ret = 0;
	struct radeon_framebuffer *rfb = NULL;
	struct radeon_renderbuffer *rrb = NULL;

	if (radeon_get_drawable(radeon)) {
		rfb = radeon_get_drawable(radeon)->driverPrivate;

		if (rfb)
			rrb = radeon_get_renderbuffer(&rfb->base,
						      rfb->base._ColorDrawBufferIndexes[0]);
	}

	if (!radeon->radeonScreen->driScreen->dri2.enabled) {
		if (ATOMIC_INC_AND_FETCH(radeon->dri.hwLockCount) > 1)
		{
#ifndef NDEBUG
			if ( RADEON_DEBUG & RADEON_SANITY )
				fprintf(stderr, "*** %d times of recursive call to %s ***\n"
						"Original call was from %s (file: %s line: %d)\n"
						"Now call is coming from %s (file: %s line: %d)\n"
						, radeon->dri.hwLockCount, __FUNCTION__
						, ldebug.function, ldebug.file, ldebug.line
						, function, file, line
					   );
#endif
			return;
		}
		DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext,
			 (DRM_LOCK_HELD | radeon->dri.hwContext), ret );
		if (ret)
			radeonGetLock(radeon, 0);
#ifndef NDEBUG
		ldebug.function = function;
		ldebug.file = file;
		ldebug.line = line;
#endif
	}
}
Ejemplo n.º 3
0
static void radeonClear( GLcontext *ctx, GLbitfield mask )
{
   r100ContextPtr rmesa = R100_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
   GLuint flags = 0;
   GLuint color_mask = 0;
   GLuint orig_mask = mask;

   if ( RADEON_DEBUG & RADEON_IOCTL ) {
      fprintf( stderr, "radeonClear\n");
   }

   {
      LOCK_HARDWARE( &rmesa->radeon );
      UNLOCK_HARDWARE( &rmesa->radeon );
      if ( dPriv->numClipRects == 0 )
	 return;
   }

   radeon_firevertices(&rmesa->radeon);

   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) ) {
      flags |= RADEON_STENCIL;
      mask &= ~BUFFER_BIT_STENCIL;
   }

   if ( mask ) {
      if (RADEON_DEBUG & RADEON_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->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL)
         flags |= RADEON_USE_HIERZ; */
      if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
	    ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
	  flags |= RADEON_CLEAR_FASTZ;
      }
   }

   if (rmesa->radeon.radeonScreen->kernel_mm)
     radeonUserClear(ctx, orig_mask);
   else {
      radeonKernelClear(ctx, flags);
      rmesa->radeon.hw.all_dirty = GL_TRUE;
   }
}
Ejemplo n.º 4
0
static void radeonKernelClear(GLcontext *ctx, GLuint flags)
{
     r100ContextPtr rmesa = R100_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
   drm_radeon_sarea_t *sarea = rmesa->radeon.sarea;
   uint32_t clear;
   GLint ret, i;
   GLint cx, cy, cw, ch;

   radeonEmitState(&rmesa->radeon);

   LOCK_HARDWARE( &rmesa->radeon );

   /* 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 ) {
      int ret;
      drm_radeon_getparam_t gp;

      gp.param = RADEON_PARAM_LAST_CLEAR;
      gp.value = (int *)&clear;
      ret = drmCommandWriteRead( rmesa->radeon.dri.fd,
				 DRM_RADEON_GETPARAM, &gp, sizeof(gp) );

      if ( ret ) {
	 fprintf( stderr, "%s: drm_radeon_getparam_t: %d\n", __FUNCTION__, ret );
	 exit(1);
      }

      if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) {
	 break;
      }

      if ( rmesa->radeon.do_usleeps ) {
	 UNLOCK_HARDWARE( &rmesa->radeon );
	 DO_USLEEP( 1 );
	 LOCK_HARDWARE( &rmesa->radeon );
      }
   }

   /* Send current state to the hardware */
   rcommonFlushCmdBufLocked( &rmesa->radeon, __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->radeon.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 buffer */
	 for ( ; i < nr ; i++ ) {
	    *b++ = box[i];
	    n++;
	 }
      }

      rmesa->radeon.sarea->nbox = n;

      clear.flags       = flags;
      clear.clear_color = rmesa->radeon.state.color.clear;
      clear.clear_depth = rmesa->radeon.state.depth.clear;
      clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
      clear.depth_mask  = rmesa->radeon.state.stencil.clear;
      clear.depth_boxes = depth_boxes;

      n--;
      b = rmesa->radeon.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] =
	    (float)rmesa->radeon.state.depth.clear;
      }

      ret = drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_CLEAR,
			     &clear, sizeof(drm_radeon_clear_t));

      if ( ret ) {
	 UNLOCK_HARDWARE( &rmesa->radeon );
	 fprintf( stderr, "DRM_RADEON_CLEAR: return = %d\n", ret );
	 exit( 1 );
      }
   }
   UNLOCK_HARDWARE( &rmesa->radeon );
}
Ejemplo n.º 5
0
/* ================================================================
 * Buffer clear
 */
static void r200Clear( struct gl_context *ctx, GLbitfield mask )
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
   GLuint flags = 0;
   GLuint orig_mask = mask;

   if ( R200_DEBUG & RADEON_IOCTL ) {
	   if (rmesa->radeon.sarea)
	       fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
	   else
	       fprintf( stderr, "r200Clear %x radeon->sarea is NULL\n", mask);
   }

   {
      LOCK_HARDWARE( &rmesa->radeon );
      UNLOCK_HARDWARE( &rmesa->radeon );
      if ( dPriv->numClipRects == 0 )
	 return;
   }

   radeonFlush( ctx );

   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
      flags |= RADEON_FRONT;
      mask &= ~BUFFER_BIT_FRONT_LEFT;
   }

   if ( mask & BUFFER_BIT_BACK_LEFT ) {
      flags |= RADEON_BACK;
      mask &= ~BUFFER_BIT_BACK_LEFT;
   }

   if ( mask & BUFFER_BIT_DEPTH ) {
      flags |= RADEON_DEPTH;
      mask &= ~BUFFER_BIT_DEPTH;
   }

   if ( (mask & BUFFER_BIT_STENCIL) ) {
      flags |= RADEON_STENCIL;
      mask &= ~BUFFER_BIT_STENCIL;
   }

   if ( mask ) {
      if (R200_DEBUG & RADEON_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->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200)
	 flags |= RADEON_USE_HIERZ; */
      if (!((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
	    ((rmesa->radeon.state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) {
	  flags |= RADEON_CLEAR_FASTZ;
      }
   }

   if (rmesa->radeon.radeonScreen->kernel_mm)
      radeonUserClear(ctx, orig_mask);
   else {
      r200KernelClear(ctx, flags);
      rmesa->radeon.hw.all_dirty = GL_TRUE;
   }
}