/** * 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); } }
/* 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 ); }
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; } }
/* ================================================================ * 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; } }
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); }
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 ); }
/** * 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); } }
/* ================================================================ * 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; }
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 ); }
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 ); }
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 ); }
/** * 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); } }
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 ); }
/** * 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); } }