Пример #1
0
/**
 * Called by ctx->Driver.Clear.
 */
static void
brw_clear(struct gl_context *ctx, GLbitfield mask)
{
   struct brw_context *brw = brw_context(ctx);
   struct intel_context *intel = &brw->intel;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   bool partial_clear = ctx->Scissor.Enabled && !noop_scissor(ctx, fb);

   if (!_mesa_check_conditional_render(ctx))
      return;

   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
      intel->front_buffer_dirty = true;
   }

   intel_prepare_render(intel);
   brw_workaround_depthstencil_alignment(brw, partial_clear ? 0 : mask);

   if (mask & BUFFER_BIT_DEPTH) {
      if (brw_fast_clear_depth(ctx)) {
	 DBG("fast clear: depth\n");
	 mask &= ~BUFFER_BIT_DEPTH;
      }
   }

   GLbitfield tri_mask = mask & (BUFFER_BITS_COLOR |
				 BUFFER_BIT_STENCIL |
				 BUFFER_BIT_DEPTH);

   if (tri_mask) {
      debug_mask("tri", tri_mask);
      mask &= ~tri_mask;

      if (ctx->API == API_OPENGLES) {
         _mesa_meta_Clear(&intel->ctx, tri_mask);
      } else {
         _mesa_meta_glsl_Clear(&intel->ctx, tri_mask);
      }
   }

   /* Any strange buffers get passed off to swrast */
   if (mask) {
      debug_mask("swrast", mask);
      _swrast_Clear(ctx, mask);
   }
}
/**
 * Called by ctx->Driver.Clear.
 */
static void
brw_clear(struct gl_context *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);

   if (!_mesa_check_conditional_render(ctx))
      return;

   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
      intel->front_buffer_dirty = true;
   }

   intel_prepare_render(intel);

   if (mask & BUFFER_BIT_DEPTH) {
      if (brw_fast_clear_depth(ctx)) {
	 DBG("fast clear: depth\n");
	 mask &= ~BUFFER_BIT_DEPTH;
      }
   }

   GLbitfield tri_mask = mask & (BUFFER_BITS_COLOR |
				 BUFFER_BIT_STENCIL |
				 BUFFER_BIT_DEPTH);

   if (tri_mask) {
      debug_mask("tri", tri_mask);
      mask &= ~tri_mask;

      if (ctx->API == API_OPENGLES) {
         _mesa_meta_Clear(&intel->ctx, tri_mask);
      } else {
         _mesa_meta_glsl_Clear(&intel->ctx, tri_mask);
      }
   }

   /* Any strange buffers get passed off to swrast */
   if (mask) {
      debug_mask("swrast", mask);
      _swrast_Clear(ctx, mask);
   }
}
Пример #3
0
/* Clear the color and/or depth buffers.
 */
static void tdfxClear( GLcontext *ctx,
			 GLbitfield mask, GLboolean all,
			 GLint x, GLint y, GLint width, GLint height )
{
   tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx;
   GLbitfield softwareMask = mask & (DD_ACCUM_BIT);
   const GLuint stencil_size =
      fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0;

   if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s( %d, %d, %d, %d )\n",
	       __FUNCTION__, (int) x, (int) y, (int) width, (int) height );
   }

   /* Need this check to respond to glScissor and clipping updates */
   if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) ||
       (fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) {
      tdfxDDUpdateHwState(ctx);
   }

   /* we can't clear accum buffers */
   mask &= ~(DD_ACCUM_BIT);

   if (mask & DD_STENCIL_BIT) {
      if (!fxMesa->haveHwStencil || ctx->Stencil.WriteMask[0] != 0xff) {
         /* Napalm seems to have trouble with stencil write masks != 0xff */
         /* do stencil clear in software */
         mask &= ~(DD_STENCIL_BIT);
         softwareMask |= DD_STENCIL_BIT;
      }
   }

   if (fxMesa->glCtx->Visual.redBits != 8) {
      /* can only do color masking if running in 24/32bpp on Napalm */
      if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
          ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
         softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
         mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
      }
   }

   if (fxMesa->haveHwStencil) {
      /*
       * If we want to clear stencil, it must be enabled
       * in the HW, even if the stencil test is not enabled
       * in the OGL state.
       */
      LOCK_HARDWARE(fxMesa);
      if (mask & DD_STENCIL_BIT) {
	 fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff);
	 /* set stencil ref value = desired clear value */
	 fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS,
                                     fxMesa->Stencil.Clear, 0xff);
	 fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE,
                                   GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
	 fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);
      }
      else {
	 fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT);
      }
      UNLOCK_HARDWARE(fxMesa);
   }

   /*
    * This may be ugly, but it's needed in order to work around a number
    * of Glide bugs.
    */
   BEGIN_CLIP_LOOP(fxMesa);
   {
      /*
       * This could probably be done fancier but doing each possible case
       * explicitly is less error prone.
       */
      switch (mask & ~DD_STENCIL_BIT) {
      case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
	 /* back buffer & depth */
	 FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0) {
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
         }
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
	 /* XXX it appears that the depth buffer isn't cleared when
	  * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
	  * This is a work-around/
	  */
	 /* clear depth */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 FX_grColorMaskv_NoLock(ctx, false4);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 /* clear front */
	 FX_grColorMaskv_NoLock(ctx, true4);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case DD_BACK_LEFT_BIT:
	 /* back buffer only */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case DD_FRONT_LEFT_BIT:
	 /* front buffer only */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
	 /* front and back */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (ctx->Depth.Mask && ctx->Depth.Test) {
            fxMesa->Glide.grDepthMask(FXTRUE);
	 }
	 break;
      case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
	 /* clear front */
	 fxMesa->Glide.grDepthMask(FXFALSE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 /* clear back and depth */
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
         if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
            fxMesa->Glide.grDepthMask(FXFALSE);
	 }
	 break;
      case DD_DEPTH_BIT:
	 /* just the depth buffer */
	 fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
	 FX_grColorMaskv_NoLock(ctx, false4);
	 fxMesa->Glide.grDepthMask(FXTRUE);
	 if (stencil_size > 0)
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
	 else
            fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor,
                                        fxMesa->Color.ClearAlpha,
                                        fxMesa->Depth.Clear);
	 FX_grColorMaskv_NoLock(ctx, true4);
	 if (ctx->Color._DrawDestMask[0] & DD_FRONT_LEFT_BIT)
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
	 if (!ctx->Depth.Test || !ctx->Depth.Mask)
	    fxMesa->Glide.grDepthMask(FXFALSE);
	 break;
      default:
         /* clear no color buffers or depth buffer but might clear stencil */
	 if (stencil_size > 0 && (mask & DD_STENCIL_BIT)) {
            /* XXX need this RenderBuffer call to work around Glide bug */
            fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER);
            fxMesa->Glide.grDepthMask(FXFALSE);
            FX_grColorMaskv_NoLock(ctx, false4);
            fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
                                           fxMesa->Color.ClearAlpha,
                                           fxMesa->Depth.Clear,
                                           (FxU32) ctx->Stencil.Clear);
            if (ctx->Depth.Mask && ctx->Depth.Test) {
               fxMesa->Glide.grDepthMask(FXTRUE);
            }
            FX_grColorMaskv_NoLock(ctx, true4);
            if (ctx->Color._DrawDestMask[0] & DD_FRONT_LEFT_BIT)
               fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER);
         }
      }
   }
   END_CLIP_LOOP(fxMesa);

   if (fxMesa->haveHwStencil && (mask & DD_STENCIL_BIT)) {
      /* We changed the stencil state above.  Signal that we need to
       * upload it again.
       */
      fxMesa->dirty |= TDFX_UPLOAD_STENCIL;
   }

   if (softwareMask)
      _swrast_Clear( ctx, softwareMask, all, x, y, width, height );
}
Пример #4
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;
   }
}
Пример #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;
   }
}
Пример #6
0
static void i830Clear(GLcontext *ctx, GLbitfield mask, GLboolean all,
		      GLint cx1, GLint cy1, GLint cw, GLint ch)
{
   i830ContextPtr imesa = I830_CONTEXT( ctx );
   __DRIdrawablePrivate *dPriv = imesa->driDrawable;
   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
   drmI830Clear clear;
   GLbitfield tri_mask = 0;
   int i;
   GLint cx, cy;

   /* flip top to bottom */
   cy = dPriv->h-cy1-ch;
   cx = cx1 + imesa->drawX;
   cy += imesa->drawY;

   if(0) fprintf(stderr, "\nClearColor : 0x%08x\n", imesa->ClearColor);
   
   clear.flags = 0;
   clear.clear_color = imesa->ClearColor;
   clear.clear_depth = 0;
   clear.clear_colormask = 0;
   clear.clear_depthmask = 0;

   I830_FIREVERTICES( imesa );

   if (mask & DD_FRONT_LEFT_BIT) {
      if(colorMask == ~0) {
	 clear.flags |= I830_FRONT;
      } else {
	 tri_mask |= DD_FRONT_LEFT_BIT;
      }
      mask &= ~DD_FRONT_LEFT_BIT;
   }

   if (mask & DD_BACK_LEFT_BIT) {
      if(colorMask == ~0) {
	 clear.flags |= I830_BACK;
      } else {
	 tri_mask |= DD_BACK_LEFT_BIT;
      }
      mask &= ~DD_BACK_LEFT_BIT;
   }

   if (mask & DD_DEPTH_BIT) {
      clear.flags |= I830_DEPTH;
      clear.clear_depthmask = imesa->depth_clear_mask;
      clear.clear_depth = (GLuint)(ctx->Depth.Clear * imesa->ClearDepth);
      mask &= ~DD_DEPTH_BIT;
   }

   if((mask & DD_STENCIL_BIT) && imesa->hw_stencil) {
      if (ctx->Stencil.WriteMask != 0xff) {
	 tri_mask |= DD_STENCIL_BIT;
      } else {
	 clear.flags |= I830_DEPTH;
	 clear.clear_depthmask |= imesa->stencil_clear_mask;
	 clear.clear_depth |= imesa->stencil_clear_mask;
      }
      mask &= ~DD_STENCIL_BIT;
   }

   /* First check for clears that need to happen with triangles */
   if(tri_mask) {
      i830ClearWithTris(ctx, tri_mask, all, cx, cy, cw, ch);
   } else {
      mask |= tri_mask;
   }

   if (clear.flags) {
      LOCK_HARDWARE( imesa );

      for (i = 0 ; i < imesa->numClipRects ; ) 
      { 	 
	 int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects);
	 XF86DRIClipRectRec *box = imesa->pClipRects;	 
	 drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
	 int n = 0;

	 if (!all) {
	    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 {
	    for ( ; i < nr ; i++) {
	       *b++ = *(drm_clip_rect_t *)&box[i];
	       n++;
	    }
	 }

	 imesa->sarea->nbox = n;
	 drmCommandWrite(imesa->driFd, DRM_I830_CLEAR,
			 &clear, sizeof(drmI830Clear));
      }

      UNLOCK_HARDWARE( imesa );
      imesa->upload_cliprects = GL_TRUE;
   }

   if (mask)
      _swrast_Clear( ctx, mask, all, cx1, cy1, cw, ch );
}
void ffbDDClear(GLcontext *ctx, GLbitfield mask)
{
	ffbContextPtr fmesa = FFB_CONTEXT(ctx);
	__DRIdrawablePrivate *dPriv = fmesa->driDrawable;
	unsigned int stcmask = BUFFER_BIT_STENCIL;

#ifdef CLEAR_TRACE
	fprintf(stderr, "ffbDDClear: mask(%08x) \n", mask);
#endif
	if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS))
		stcmask = 0;

	if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH | stcmask)) {
		ffb_fbcPtr ffb = fmesa->regs;
		unsigned int fbc, ppc;

		fbc = (FFB_FBC_XE_ON);
		ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE |
		       FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_DISABLE |
		       FFB_PPC_APE_DISABLE | FFB_PPC_XS_WID |
		       FFB_PPC_ZS_CONST | FFB_PPC_CS_CONST);

		/* Y/X enables must be both on or both off. */
		if (mask & (BUFFER_BIT_DEPTH | stcmask)) {
			fbc |= (FFB_FBC_ZE_ON | FFB_FBC_YE_ON | FFB_FBC_WB_C);
		} else
			fbc |= FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF;

		/* All RGB enables must be both on or both off. */
		if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) {
			if (mask & BUFFER_BIT_FRONT_LEFT) {
				if (fmesa->back_buffer == 0)
					fbc |= FFB_FBC_WB_B;
				else
					fbc |= FFB_FBC_WB_A;
			}
			if (mask & BUFFER_BIT_BACK_LEFT) {
				if (fmesa->back_buffer == 0)
					fbc |= FFB_FBC_WB_A;
				else
					fbc |= FFB_FBC_WB_B;
			}
			fbc |= FFB_FBC_RGBE_ON;
		} else
			fbc |= FFB_FBC_RGBE_OFF;

		LOCK_HARDWARE(fmesa);

		if (dPriv->numClipRects) {
			FFBFifo(fmesa, 8);
			ffb->fbc = fbc;
			ffb->ppc = ppc;
			ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
			ffb->cmp = 0x80808080;
			ffb->rop = FFB_ROP_NEW;

			if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT))
				ffb->fg = fmesa->clear_pixel;
			if (mask & BUFFER_BIT_DEPTH)
				ffb->constz = fmesa->clear_depth;
			if (mask & stcmask)
				ffb->consty = fmesa->clear_stencil;

			ffb_do_clear(ctx, dPriv);

			FFBFifo(fmesa, 6);
			ffb->ppc = fmesa->ppc;
			ffb->fbc = fmesa->fbc;
			ffb->xclip = fmesa->xclip;
			ffb->cmp = fmesa->cmp;
			ffb->rop = fmesa->rop;
			ffb->drawop = fmesa->drawop;
			if (mask & stcmask)
				ffb->consty = fmesa->consty;
			fmesa->ffbScreen->rp_active = 1;
		}

		UNLOCK_HARDWARE(fmesa);

		mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT |
			  BUFFER_BIT_DEPTH | stcmask);
	}

	if (mask) 
		_swrast_Clear(ctx, mask);
}
Пример #8
0
static void
mgaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
            GLint cx, GLint cy, GLint cw, GLint ch )
{
   mgaContextPtr mmesa = MGA_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
   GLuint flags = 0;
   GLuint clear_color = mmesa->ClearColor;
   GLuint clear_depth = 0;
   GLuint color_mask = 0;
   GLuint depth_mask = 0;
   int ret;
   int i;
   static int nrclears;
   drmMGAClearRec clear;

   FLUSH_BATCH( mmesa );

   if ( mask & DD_FRONT_LEFT_BIT ) {
      flags |= MGA_FRONT;
      color_mask = mmesa->setup.plnwt;
      mask &= ~DD_FRONT_LEFT_BIT;
   }

   if ( mask & DD_BACK_LEFT_BIT ) {
      flags |= MGA_BACK;
      color_mask = mmesa->setup.plnwt;
      mask &= ~DD_BACK_LEFT_BIT;
   }

   if ( (mask & DD_DEPTH_BIT) && ctx->Depth.Mask ) {
      flags |= MGA_DEPTH;
      clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask);
      depth_mask |= mmesa->depth_clear_mask;
      mask &= ~DD_DEPTH_BIT;
   }

   if ( (mask & DD_STENCIL_BIT) && mmesa->hw_stencil ) {
      flags |= MGA_DEPTH;
      clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask);
      depth_mask |= mmesa->stencil_clear_mask;
      mask &= ~DD_STENCIL_BIT;
   }

   if ( flags ) {
      LOCK_HARDWARE( mmesa );

      if ( mmesa->dirty_cliprects )
	 mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) );

      /* flip top to bottom */
      cy = dPriv->h-cy-ch;
      cx += mmesa->drawX;
      cy += mmesa->drawY;

      if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	 fprintf( stderr, "Clear, bufs %x nbox %d\n",
		  (int)flags, (int)mmesa->numClipRects );

      for (i = 0 ; i < mmesa->numClipRects ; )
      {
	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);
	 XF86DRIClipRectPtr box = mmesa->pClipRects;
	 XF86DRIClipRectPtr b = mmesa->sarea->boxes;
	 int n = 0;

	 if (!all) {
	    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 {
	    for ( ; i < nr ; i++) {
	       *b++ = *(XF86DRIClipRectPtr)&box[i];
	       n++;
	    }
	 }


	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	    fprintf( stderr,
		     "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",
		     flags, clear_color, clear_depth, mmesa->sarea->nbox );

	 mmesa->sarea->nbox = n;

         clear.flags = flags;
         clear.clear_color = clear_color;
         clear.clear_depth = clear_depth;
         clear.color_mask = color_mask;
         clear.depth_mask = depth_mask;
         ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR,
                                 &clear, sizeof(drmMGAClearRec));
	 if ( ret ) {
	    fprintf( stderr, "send clear retcode = %d\n", ret );
	    exit( 1 );
	 }
	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )
	    fprintf( stderr, "finished clear %d\n", ++nrclears );
      }

      UNLOCK_HARDWARE( mmesa );
      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT;
   }

   if (mask) 
      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
}
Пример #9
0
/**
 * Called by ctx->Driver.Clear.
 */
static void
intelClear(struct gl_context *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);
   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]);
   GLbitfield tri_mask = 0;
   GLbitfield blit_mask = 0;
   GLbitfield swrast_mask = 0;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   struct intel_renderbuffer *irb;
   int i;

   if (!_mesa_check_conditional_render(ctx))
      return;

   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
      intel->front_buffer_dirty = GL_TRUE;
   }

   if (0)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* Get SW clears out of the way: Anything without an intel_renderbuffer */
   for (i = 0; i < BUFFER_COUNT; i++) {
      if (!(mask & (1 << i)))
	 continue;

      irb = intel_get_renderbuffer(fb, i);
      if (unlikely(!irb)) {
	 swrast_mask |= (1 << i);
	 mask &= ~(1 << i);
      }
   }
   if (unlikely(swrast_mask)) {
      debug_mask("swrast", swrast_mask);
      _swrast_Clear(ctx, swrast_mask);
   }

   /* HW color buffers (front, back, aux, generic FBO, etc) */
   if (intel->gen < 6 && colorMask == ~0) {
      /* clear all R,G,B,A */
      blit_mask |= (mask & BUFFER_BITS_COLOR);
   }
   else {
      /* glColorMask in effect */
      tri_mask |= (mask & BUFFER_BITS_COLOR);
   }

   /* Make sure we have up to date buffers before we start looking at
    * the tiling bits to determine how to clear. */
   intel_prepare_render(intel);

   /* HW stencil */
   if (mask & BUFFER_BIT_STENCIL) {
      const struct intel_region *stencilRegion
         = intel_get_rb_region(fb, BUFFER_STENCIL);
      if (stencilRegion) {
         /* have hw stencil */
         if (stencilRegion->tiling == I915_TILING_Y ||
	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
	    /* We have to use the 3D engine if we're clearing a partial mask
	     * of the stencil buffer, or if we're on a 965 which has a tiled
	     * depth/stencil buffer in a layout we can't blit to.
	     */
            tri_mask |= BUFFER_BIT_STENCIL;
         }
	 else if (intel->has_separate_stencil &&
	       stencilRegion->tiling == I915_TILING_NONE) {
	    /* The stencil buffer is actually W tiled, which the hardware
	     * cannot blit to. */
	    tri_mask |= BUFFER_BIT_STENCIL;
	 }
         else {
            /* clearing all stencil bits, use blitting */
            blit_mask |= BUFFER_BIT_STENCIL;
         }
      }
   }

   /* HW depth */
   if (mask & BUFFER_BIT_DEPTH) {
      const struct intel_region *irb = intel_get_rb_region(fb, BUFFER_DEPTH);

      /* clear depth with whatever method is used for stencil (see above) */
      if (irb->tiling == I915_TILING_Y || tri_mask & BUFFER_BIT_STENCIL)
         tri_mask |= BUFFER_BIT_DEPTH;
      else
         blit_mask |= BUFFER_BIT_DEPTH;
   }

   /* If we're doing a tri pass for depth/stencil, include a likely color
    * buffer with it.
    */
   if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
      int color_bit = _mesa_ffs(mask & BUFFER_BITS_COLOR);
      if (color_bit != 0) {
	 tri_mask |= blit_mask & (1 << (color_bit - 1));
	 blit_mask &= ~(1 << (color_bit - 1));
      }
   }

   /* Anything left, just use tris */
   tri_mask |= mask & ~blit_mask;

   if (blit_mask) {
      debug_mask("blit", blit_mask);
      tri_mask |= intelClearWithBlit(ctx, blit_mask);
   }

   if (tri_mask) {
      debug_mask("tri", tri_mask);
      if (ctx->Extensions.ARB_fragment_shader)
	 _mesa_meta_glsl_Clear(&intel->ctx, tri_mask);
      else
	 _mesa_meta_Clear(&intel->ctx, tri_mask);
   }
}
Пример #10
0
/* ================================================================
 * Buffer clear
 */
static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
			 GLint cx, GLint cy, GLint cw, GLint ch )
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
   GLuint flags = 0;
   GLuint color_mask = 0;
   GLint ret, i;

   if ( R200_DEBUG & DEBUG_IOCTL ) {
      fprintf( stderr, "%s:  all=%d cx=%d cy=%d cw=%d ch=%d\n",
	       __FUNCTION__, all, cx, cy, cw, ch );
   }

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

   r200Flush( ctx );

   if ( mask & DD_FRONT_LEFT_BIT ) {
      flags |= RADEON_FRONT;
      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
      mask &= ~DD_FRONT_LEFT_BIT;
   }

   if ( mask & DD_BACK_LEFT_BIT ) {
      flags |= RADEON_BACK;
      color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
      mask &= ~DD_BACK_LEFT_BIT;
   }

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

   if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) {
      flags |= RADEON_STENCIL;
      mask &= ~DD_STENCIL_BIT;
   }

   if ( mask ) {
      if (R200_DEBUG & DEBUG_FALLBACKS)
	 fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
   }

   if ( !flags ) 
      return;

   if (rmesa->using_hyperz) {
      flags |= RADEON_USE_COMP_ZBUF;
/*      if (rmesa->r200Screen->chipset & R200_CHIPSET_REAL_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;
      }
   }

   /* Flip top to bottom */
   cx += dPriv->x;
   cy  = dPriv->y + dPriv->h - cy - ch;

   LOCK_HARDWARE( rmesa );

   /* 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 ( !all ) {
	 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 {
	 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;
}
Пример #11
0
static void r128Clear( GLcontext *ctx, GLbitfield mask )
{
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    __DRIdrawablePrivate *dPriv = rmesa->driDrawable;
    drm_r128_clear_t clear;
    GLuint flags = 0;
    GLint i;
    GLint ret;
    GLuint depthmask = 0;
    GLint cx, cy, cw, ch;

    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
        fprintf( stderr, "%s:\n", __FUNCTION__ );
    }

    FLUSH_BATCH( rmesa );

    /* The only state change we care about here is the RGBA colormask
     * We'll just update that state, if needed.  If we do more then
     * there's some strange side-effects that the conformance tests find.
     */
    if ( rmesa->new_state & R128_NEW_MASKS) {
        const GLuint save_state = rmesa->new_state;
        rmesa->new_state = R128_NEW_MASKS;
        r128DDUpdateHWState( ctx );
        rmesa->new_state = save_state & ~R128_NEW_MASKS;
    }

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

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

    if ( ( mask & BUFFER_BIT_DEPTH ) && ctx->Depth.Mask ) {
        flags |= R128_DEPTH;
        /* if we're at 16 bits, extra plane mask won't hurt */
        depthmask |= 0x00ffffff;
        mask &= ~BUFFER_BIT_DEPTH;
    }

    if ( mask & BUFFER_BIT_STENCIL &&
            (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) ) {
        flags |= R128_DEPTH;
        depthmask |= ctx->Stencil.WriteMask[0] << 24;
        mask &= ~BUFFER_BIT_STENCIL;
    }

    if ( flags ) {

        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;

        /* FIXME: Do we actually need this?
         */
        if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) {
            r128EmitHwStateLocked( rmesa );
        }

        for ( i = 0 ; i < rmesa->numClipRects ; ) {
            GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , rmesa->numClipRects );
            drm_clip_rect_t *box = rmesa->pClipRects;
            drm_clip_rect_t *b = rmesa->sarea->boxes;
            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;

            if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) {
                fprintf( stderr,
                         "DRM_R128_CLEAR: flag 0x%x color %x depth %x nbox %d\n",
                         flags,
                         (GLuint)rmesa->ClearColor,
                         (GLuint)rmesa->ClearDepth,
                         rmesa->sarea->nbox );
            }

            clear.flags = flags;
            clear.clear_color = rmesa->ClearColor;
            clear.clear_depth = rmesa->ClearDepth;
            clear.color_mask = rmesa->setup.plane_3d_mask_c;
            clear.depth_mask = depthmask;

            ret = drmCommandWrite( rmesa->driFd, DRM_R128_CLEAR,
                                   &clear, sizeof(clear) );

            if ( ret ) {
                UNLOCK_HARDWARE( rmesa );
                fprintf( stderr, "DRM_R128_CLEAR: return = %d\n", ret );
                exit( 1 );
            }
        }

        UNLOCK_HARDWARE( rmesa );

        rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
    }

    if ( mask )
        _swrast_Clear( ctx, mask );
}
Пример #12
0
void intelClear(GLcontext *ctx, GLbitfield mask)
{
   intelContextPtr intel = INTEL_CONTEXT( ctx );
   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
   GLbitfield tri_mask = 0;
   GLbitfield blit_mask = 0;
   GLbitfield swrast_mask = 0;

   if (0)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* Take care of cliprects, which are handled differently for
    * clears, etc.
    */
   intelFlush( &intel->ctx );

   if (mask & BUFFER_BIT_FRONT_LEFT) {
      if (colorMask == ~0) {
	 blit_mask |= BUFFER_BIT_FRONT_LEFT;
      } 
      else {
	 tri_mask |= BUFFER_BIT_FRONT_LEFT;
      }
   }

   if (mask & BUFFER_BIT_BACK_LEFT) {
      if (colorMask == ~0) {
	 blit_mask |= BUFFER_BIT_BACK_LEFT;
      } 
      else {
	 tri_mask |= BUFFER_BIT_BACK_LEFT;
      }
   }

   if (mask & BUFFER_BIT_DEPTH) {
      blit_mask |= BUFFER_BIT_DEPTH;
   }

   if (mask & BUFFER_BIT_STENCIL) {
      if (!intel->hw_stencil) {
	 swrast_mask |= BUFFER_BIT_STENCIL;
      }
      else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
	 tri_mask |= BUFFER_BIT_STENCIL;
      } 
      else {
	 blit_mask |= BUFFER_BIT_STENCIL;
      }
   }

   swrast_mask |= (mask & BUFFER_BIT_ACCUM);

   if (blit_mask) 
      intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0);

   if (tri_mask) 
      intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0);

   if (swrast_mask)
      _swrast_Clear( ctx, swrast_mask );
}
Пример #13
0
static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
			       GLint cx, GLint cy, GLint cw, GLint ch )
{
   gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
   GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv;
   GLuint temp = 0;

   FLUSH_BATCH( gmesa );

   /* Update and emit any new state.  We need to do this here to catch
    * changes to the masks.
    * FIXME: Just update the masks?
    */
   if ( gmesa->new_state )
      gammaDDUpdateHWState( ctx );

#ifdef DO_VALIDATE
    /* Flush any partially filled buffers */
    FLUSH_DMA_BUFFER(gmesa);

    DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
		 gmesa->driScreen->drawLockID);
    VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
#endif

    if (mask & BUFFER_BIT_DEPTH) {
	 /* Turn off writes the FB */
	 CHECK_DMA_BUFFER(gmesa, 1);
	 WRITE(gmesa->buf, FBWriteMode, FBWriteModeDisable);

	 mask &= ~BUFFER_BIT_DEPTH;

	 /*
	  * Turn Rectangle2DControl off when the window is not clipped
	  * (i.e., the GID tests are not necessary).  This dramatically
	  * increases the performance of the depth clears.
	  */
	 if (!gmesa->NotClipped) {
	    CHECK_DMA_BUFFER(gmesa, 1);
	    WRITE(gmesa->buf, Rectangle2DControl, 1);
	 }

	 temp = (gmesa->LBReadMode & LBPartialProdMask) | LBWindowOriginBot;
	 if (gDRIPriv->numMultiDevices == 2) temp |= LBScanLineInt2;
	 
	 CHECK_DMA_BUFFER(gmesa, 5);
	 WRITE(gmesa->buf, LBReadMode, temp);
	 WRITE(gmesa->buf, DeltaMode, DM_DepthEnable);
	 WRITE(gmesa->buf, DepthMode, (DepthModeEnable |
					DM_Always |
					DM_SourceDepthRegister |
					DM_WriteMask));
	 WRITE(gmesa->buf, GLINTDepth, gmesa->ClearDepth);

	 /* Increment the frame count */
	 gmesa->FrameCount++;
#ifdef FAST_CLEAR_4
	 gmesa->FrameCount &= 0x0f;
#else
	 gmesa->FrameCount &= 0xff;
#endif

	 /* Force FCP to be written */
	 WRITE(gmesa->buf, GLINTWindow, (WindowEnable |
					  W_PassIfEqual |
					  (gmesa->Window & W_GIDMask) |
					  W_DepthFCP |
					  W_LBUpdateFromRegisters |
					  W_OverrideWriteFiltering |
					  (gmesa->FrameCount << 9)));

	/* Clear part of the depth and FCP buffers */
	{
	    int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
	    int x = gmesa->driDrawable->x;
	    int w = gmesa->driDrawable->w;
	    int h = gmesa->driDrawable->h;
#ifndef TURN_OFF_FCP
	    float hsub = h;

	    if (gmesa->WindowChanged) {
		gmesa->WindowChanged = GL_FALSE;
	    } else {
#ifdef FAST_CLEAR_4
		hsub /= 16;
#else
		hsub /= 256;
#endif

		/* Handle the case where the height < # of FCPs */
		if (hsub < 1.0) {
		    if (gmesa->FrameCount > h)
			gmesa->FrameCount = 0;
		    h = 1;
		    y += gmesa->FrameCount;
		} else {
		    h = (gmesa->FrameCount+1)*hsub;
		    h -= (int)(gmesa->FrameCount*hsub);
		    y += gmesa->FrameCount*hsub;
		}
	    }
#endif
	    if (h && w) {
#if 0
		CHECK_DMA_BUFFER(gmesa, 2);
		WRITE(gmesa->buf, Rectangle2DMode, ((h & 0xfff)<<12) |
						   (w & 0xfff) );
		WRITE(gmesa->buf, DrawRectangle2D, ((y & 0xffff)<<16) |
						   (x & 0xffff) );
#else
		CHECK_DMA_BUFFER(gmesa, 8);
		WRITE(gmesa->buf, StartXDom,   x<<16);
		WRITE(gmesa->buf, StartY,      y<<16);
		WRITE(gmesa->buf, StartXSub,   (x+w)<<16);
		WRITE(gmesa->buf, GLINTCount,  h);
		WRITE(gmesa->buf, dY,          1<<16);
		WRITE(gmesa->buf, dXDom,       0<<16);
		WRITE(gmesa->buf, dXSub,       0<<16);
		WRITE(gmesa->buf, Render,      0x00000040); /* NOT_DONE */
#endif
	    }
	}

	CHECK_DMA_BUFFER(gmesa, 6);
	WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
	WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
	WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
	WRITE(gmesa->buf, GLINTWindow, gmesa->Window);
	WRITE(gmesa->buf, FastClearDepth, gmesa->ClearDepth);
	WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);

	/* Turn on Depth FCP */
	if (gmesa->Window & W_DepthFCP) {
	    CHECK_DMA_BUFFER(gmesa, 1);
	    WRITE(gmesa->buf, WindowOr, (gmesa->FrameCount << 9));
	}

	/* Turn off GID clipping if window is not clipped */
	if (gmesa->NotClipped) {
	    CHECK_DMA_BUFFER(gmesa, 1);
	    WRITE(gmesa->buf, Rectangle2DControl, 0);
	}
    }

    if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) {
	int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
	int x = gmesa->driDrawable->x;
	int w = gmesa->driDrawable->w;
	int h = gmesa->driDrawable->h;

	mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);

	if (x < 0) { w -= -x; x = 0; }

	/* Turn on GID clipping if window is clipped */
	if (!gmesa->NotClipped) {
	    CHECK_DMA_BUFFER(gmesa, 1);
	    WRITE(gmesa->buf, Rectangle2DControl, 1);
	}

        CHECK_DMA_BUFFER(gmesa, 18);
        WRITE(gmesa->buf, FBBlockColor, gmesa->ClearColor);
        WRITE(gmesa->buf, ColorDDAMode, ColorDDADisable);
	WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
	WRITE(gmesa->buf, DepthMode, 0);
	WRITE(gmesa->buf, DeltaMode, 0);
	WRITE(gmesa->buf, AlphaBlendMode, 0);
#if 1
	WRITE(gmesa->buf, dY,          1<<16);
	WRITE(gmesa->buf, dXDom,       0<<16);
	WRITE(gmesa->buf, dXSub,       0<<16);
	WRITE(gmesa->buf, StartXSub,   (x+w)<<16);
	WRITE(gmesa->buf, GLINTCount,  h);
	WRITE(gmesa->buf, StartXDom,   x<<16);
	WRITE(gmesa->buf, StartY,      y<<16);
	WRITE(gmesa->buf, Render,      0x00000048); /* NOT_DONE */
#else
	WRITE(gmesa->buf, Rectangle2DMode, (((h & 0xfff)<<12) |
					      (w & 0xfff)));
	WRITE(gmesa->buf, DrawRectangle2D, (((y & 0xffff)<<16) |
					      (x & 0xffff)));
#endif
	WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
	WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
	WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode);
	WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);

	/* Turn off GID clipping if window is clipped */
	if (gmesa->NotClipped) {
	    CHECK_DMA_BUFFER(gmesa, 1);
	    WRITE(gmesa->buf, Rectangle2DControl, 0);
	}
    }

#ifdef DO_VALIDATE
    PROCESS_DMA_BUFFER_TOP_HALF(gmesa);

    DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
		   gmesa->driScreen->drawLockID);
    VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);

    PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
#endif

   if ( mask )
      _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
}
Пример #14
0
/**
 * Called by ctx->Driver.Clear.
 */
static void
intelClear(GLcontext *ctx, GLbitfield mask)
{
   struct intel_context *intel = intel_context(ctx);
   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
   GLbitfield tri_mask = 0;
   GLbitfield blit_mask = 0;
   GLbitfield swrast_mask = 0;
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   GLuint i;

   if (0)
      fprintf(stderr, "%s\n", __FUNCTION__);

   /* HW color buffers (front, back, aux, generic FBO, etc) */
   if (colorMask == ~0) {
      /* clear all R,G,B,A */
      /* XXX FBO: need to check if colorbuffers are software RBOs! */
      blit_mask |= (mask & BUFFER_BITS_COLOR);
   }
   else {
      /* glColorMask in effect */
      tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
   }

   /* HW stencil */
   if (mask & BUFFER_BIT_STENCIL) {
      const struct intel_region *stencilRegion
         = intel_get_rb_region(fb, BUFFER_STENCIL);
      if (stencilRegion) {
         /* have hw stencil */
         if (IS_965(intel->intelScreen->deviceID) ||
	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
	    /* We have to use the 3D engine if we're clearing a partial mask
	     * of the stencil buffer, or if we're on a 965 which has a tiled
	     * depth/stencil buffer in a layout we can't blit to.
	     */
            tri_mask |= BUFFER_BIT_STENCIL;
         }
         else {
            /* clearing all stencil bits, use blitting */
            blit_mask |= BUFFER_BIT_STENCIL;
         }
      }
   }

   /* HW depth */
   if (mask & BUFFER_BIT_DEPTH) {
      /* clear depth with whatever method is used for stencil (see above) */
      if (IS_965(intel->intelScreen->deviceID) ||
	  tri_mask & BUFFER_BIT_STENCIL)
         tri_mask |= BUFFER_BIT_DEPTH;
      else
         blit_mask |= BUFFER_BIT_DEPTH;
   }

   /* If we're doing a tri pass for depth/stencil, include a likely color
    * buffer with it.
    */
   if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
      int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
      if (color_bit != 0) {
	 tri_mask |= blit_mask & (1 << (color_bit - 1));
	 blit_mask &= ~(1 << (color_bit - 1));
      }
   }

   /* SW fallback clearing */
   swrast_mask = mask & ~tri_mask & ~blit_mask;

   for (i = 0; i < BUFFER_COUNT; i++) {
      GLuint bufBit = 1 << i;
      if ((blit_mask | tri_mask) & bufBit) {
         if (!fb->Attachment[i].Renderbuffer->ClassID) {
            blit_mask &= ~bufBit;
            tri_mask &= ~bufBit;
            swrast_mask |= bufBit;
         }
      }
   }

   if (blit_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("blit clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (blit_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      intelClearWithBlit(ctx, blit_mask);
   }

   if (tri_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("tri clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (tri_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      intel_clear_tris(ctx, tri_mask);
   }

   if (swrast_mask) {
      if (INTEL_DEBUG & DEBUG_BLIT) {
	 DBG("swrast clear:");
	 for (i = 0; i < BUFFER_COUNT; i++) {
	    if (swrast_mask & (1 << i))
	       DBG(" %s", buffer_names[i]);
	 }
	 DBG("\n");
      }
      _swrast_Clear(ctx, swrast_mask);
   }
}
Пример #15
0
static void i810Clear( struct gl_context *ctx, GLbitfield mask )
{
   i810ContextPtr imesa = I810_CONTEXT( ctx );
   __DRIdrawable *dPriv = imesa->driDrawable;
   const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask[0]);
   drmI810Clear clear;
   unsigned int i;

   clear.flags = 0;
   clear.clear_color = imesa->ClearColor;
   clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE);

   I810_FIREVERTICES( imesa );
	
   if ((mask & BUFFER_BIT_FRONT_LEFT) && colorMask == ~0U) {
      clear.flags |= I810_FRONT;
      mask &= ~BUFFER_BIT_FRONT_LEFT;
   }

   if ((mask & BUFFER_BIT_BACK_LEFT) && colorMask == ~0U) {
      clear.flags |= I810_BACK;
      mask &= ~BUFFER_BIT_BACK_LEFT;
   }

   if (mask & BUFFER_BIT_DEPTH) {
      if (ctx->Depth.Mask) 
	 clear.flags |= I810_DEPTH;
      mask &= ~BUFFER_BIT_DEPTH;
   }

   if (clear.flags) {
      GLint cx, cy, cw, ch;

      LOCK_HARDWARE( imesa );

      /* 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 */
      cy = dPriv->h-cy-ch;
      cx += imesa->drawX;
      cy += imesa->drawY;

      for (i = 0 ; i < imesa->numClipRects ; ) 
      { 	 
	 unsigned int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects);
	 drm_clip_rect_t *box = imesa->pClipRects;	 
	 drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes;
	 int n = 0;

	 if (cw != dPriv->w || ch != dPriv->h) {
            /* clear sub region */
	    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++;
	    }
	 }

	 imesa->sarea->nbox = n;
         drmCommandWrite(imesa->driFd, DRM_I810_CLEAR,
                         &clear, sizeof(drmI810Clear));
      }

      UNLOCK_HARDWARE( imesa );
      imesa->upload_cliprects = GL_TRUE;
   }

   if (mask) 
      _swrast_Clear( ctx, mask );
}
Пример #16
0
/**
 * Called by ctx->Driver.Clear.
 */
static void
brw_clear(struct gl_context *ctx, GLbitfield mask)
{
   struct brw_context *brw = brw_context(ctx);
   struct gl_framebuffer *fb = ctx->DrawBuffer;
   const struct gen_device_info *devinfo = &brw->screen->devinfo;
   bool partial_clear = ctx->Scissor.EnableFlags && !noop_scissor(fb);

   if (!_mesa_check_conditional_render(ctx))
      return;

   if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
      brw->front_buffer_dirty = true;
   }

   intel_prepare_render(brw);
   brw_workaround_depthstencil_alignment(brw, partial_clear ? 0 : mask);

   if (mask & BUFFER_BIT_DEPTH) {
      if (brw_fast_clear_depth(ctx)) {
	 DBG("fast clear: depth\n");
	 mask &= ~BUFFER_BIT_DEPTH;
      }
   }

   if (mask & BUFFER_BIT_STENCIL) {
      struct intel_renderbuffer *stencil_irb =
         intel_get_renderbuffer(fb, BUFFER_STENCIL);
      struct intel_mipmap_tree *mt = stencil_irb->mt;
      if (mt && mt->stencil_mt)
         mt->stencil_mt->r8stencil_needs_update = true;
   }

   if (mask & BUFFER_BITS_COLOR) {
      brw_blorp_clear_color(brw, fb, mask, partial_clear,
                            ctx->Color.sRGBEnabled);
      debug_mask("blorp color", mask & BUFFER_BITS_COLOR);
      mask &= ~BUFFER_BITS_COLOR;
   }

   if (devinfo->gen >= 6 && (mask & BUFFER_BITS_DEPTH_STENCIL)) {
      brw_blorp_clear_depth_stencil(brw, fb, mask, partial_clear);
      debug_mask("blorp depth/stencil", mask & BUFFER_BITS_DEPTH_STENCIL);
      mask &= ~BUFFER_BITS_DEPTH_STENCIL;
   }

   GLbitfield tri_mask = mask & (BUFFER_BIT_STENCIL |
                                 BUFFER_BIT_DEPTH);

   if (tri_mask) {
      debug_mask("tri", tri_mask);
      mask &= ~tri_mask;
      _mesa_meta_glsl_Clear(&brw->ctx, tri_mask);
   }

   /* Any strange buffers get passed off to swrast.  The only thing that
    * should be left at this point is the accumulation buffer.
    */
   assert((mask & ~BUFFER_BIT_ACCUM) == 0);
   if (mask) {
      debug_mask("swrast", mask);
      _swrast_Clear(ctx, mask);
   }
}