/** * Called via the device driver's ctx->Driver.Clear() function if the * device driver can't clear one or more of the buffers itself. * \param buffers bitfield of BUFFER_BIT_* values indicating which * renderbuffers are to be cleared. * \param all if GL_TRUE, clear whole buffer, else clear specified region. */ void _swrast_Clear(struct gl_context *ctx, GLbitfield buffers) { const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL; #ifdef DEBUG_FOO { const GLbitfield legalBits = BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL | BUFFER_BIT_ACCUM | BUFFER_BIT_AUX0; assert((buffers & (~legalBits)) == 0); } #endif if (!_mesa_check_conditional_render(ctx)) return; /* don't clear */ if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived(ctx); if ((buffers & BUFFER_BITS_COLOR) && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) { clear_color_buffers(ctx); } if (buffers & BUFFER_BIT_ACCUM) { _mesa_clear_accum_buffer(ctx); } if (buffers & BUFFER_DS) { struct gl_renderbuffer *depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) { /* clear depth and stencil together */ _swrast_clear_depth_stencil_buffer(ctx); } else { /* clear depth, stencil separately */ if (buffers & BUFFER_BIT_DEPTH) { _swrast_clear_depth_buffer(ctx); } if (buffers & BUFFER_BIT_STENCIL) { _swrast_clear_stencil_buffer(ctx); } } } }
void _swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x, GLint y, GLint width, GLint height ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); #ifdef DEBUG { GLbitfield legalBits = DD_FRONT_LEFT_BIT | DD_FRONT_RIGHT_BIT | DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT | DD_DEPTH_BIT | DD_STENCIL_BIT | DD_ACCUM_BIT; assert((mask & (~legalBits)) == 0); } #endif RENDER_START(swrast,ctx); /* do software clearing here */ if (mask) { if (mask & ctx->Color.DrawDestMask) clear_color_buffers(ctx); if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx); if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx); if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx); } /* clear software-based alpha buffer(s) */ if ( (mask & GL_COLOR_BUFFER_BIT) && ctx->DrawBuffer->UseSoftwareAlphaBuffers && ctx->Color.ColorMask[ACOMP]) { _mesa_clear_alpha_buffers( ctx ); } RENDER_FINISH(swrast,ctx); }
/** * Called via the device driver's ctx->Driver.Clear() function if the * device driver can't clear one or more of the buffers itself. * \param buffers bitfield of BUFFER_BIT_* values indicating which * renderbuffers are to be cleared. * \param all if GL_TRUE, clear whole buffer, else clear specified region. */ void _swrast_Clear(struct gl_context *ctx, GLbitfield buffers) { #ifdef DEBUG_FOO { const GLbitfield legalBits = BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL | BUFFER_BIT_ACCUM | BUFFER_BIT_AUX0; assert((buffers & (~legalBits)) == 0); } #endif if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived(ctx); if (buffers & BUFFER_BITS_COLOR) { clear_color_buffers(ctx); } if (buffers & BUFFER_BIT_ACCUM) { _mesa_clear_accum_buffer(ctx); } if (buffers & BUFFER_BIT_DEPTH) { _swrast_clear_depth_buffer(ctx); } if (buffers & BUFFER_BIT_STENCIL) { _swrast_clear_stencil_buffer(ctx); } }
/** * Called via ctx->Driver.Clear() */ static void st_Clear(struct gl_context *ctx, GLbitfield mask) { struct st_context *st = st_context(ctx); struct gl_renderbuffer *depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; GLbitfield quad_buffers = 0x0; GLbitfield clear_buffers = 0x0; GLuint i; /* This makes sure the pipe has the latest scissor, etc values */ st_validate_state( st ); if (mask & BUFFER_BITS_COLOR) { for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; if (b >= 0 && mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0; if (!strb || !strb->surface) continue; if (is_color_disabled(ctx, colormask_index)) continue; if (is_scissor_enabled(ctx, rb) || is_color_masked(ctx, colormask_index)) quad_buffers |= PIPE_CLEAR_COLOR0 << i; else clear_buffers |= PIPE_CLEAR_COLOR0 << i; } } } if (mask & BUFFER_BIT_DEPTH) { struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface && ctx->Depth.Mask) { if (is_scissor_enabled(ctx, depthRb)) quad_buffers |= PIPE_CLEAR_DEPTH; else clear_buffers |= PIPE_CLEAR_DEPTH; } } if (mask & BUFFER_BIT_STENCIL) { struct st_renderbuffer *strb = st_renderbuffer(stencilRb); if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) { if (is_scissor_enabled(ctx, stencilRb) || is_stencil_masked(ctx, stencilRb)) quad_buffers |= PIPE_CLEAR_STENCIL; else clear_buffers |= PIPE_CLEAR_STENCIL; } } /* Always clear depth and stencil together. * This can only happen when the stencil writemask is not a full mask. */ if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL && clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) { quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL; clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; } /* Only use quad-based clearing for the renderbuffers which cannot * use pipe->clear. We want to always use pipe->clear for the other * renderbuffers, because it's likely to be faster. */ if (quad_buffers) { clear_with_quad(ctx, quad_buffers); } if (clear_buffers) { /* We can't translate the clear color to the colorbuffer format, * because different colorbuffers may have different formats. */ st->pipe->clear(st->pipe, clear_buffers, (union pipe_color_union*)&ctx->Color.ClearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } if (mask & BUFFER_BIT_ACCUM) _mesa_clear_accum_buffer(ctx); }
/** * Called via ctx->Driver.Clear() */ static void st_Clear(struct gl_context *ctx, GLbitfield mask) { static const GLbitfield BUFFER_BITS_DS = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); struct st_context *st = st_context(ctx); struct gl_renderbuffer *depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; GLbitfield quad_buffers = 0x0; GLbitfield clear_buffers = 0x0; GLuint i; /* This makes sure the pipe has the latest scissor, etc values */ st_validate_state( st ); if (mask & BUFFER_BITS_COLOR) { for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; if (mask & (1 << b)) { struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); if (!strb || !strb->surface) continue; if (check_clear_color_with_quad( ctx, rb )) quad_buffers |= PIPE_CLEAR_COLOR; else clear_buffers |= PIPE_CLEAR_COLOR; } } } if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) { /* clearing combined depth + stencil */ struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface) { if (check_clear_depth_stencil_with_quad(ctx, depthRb)) quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; else clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; } } else { /* separate depth/stencil clears */ /* I don't think truly separate buffers are actually possible in gallium or hw? */ if (mask & BUFFER_BIT_DEPTH) { struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface) { if (check_clear_depth_with_quad(ctx, depthRb, st->clear.enable_ds_separate)) quad_buffers |= PIPE_CLEAR_DEPTH; else clear_buffers |= PIPE_CLEAR_DEPTH; } } if (mask & BUFFER_BIT_STENCIL) { struct st_renderbuffer *strb = st_renderbuffer(stencilRb); if (strb->surface) { if (check_clear_stencil_with_quad(ctx, stencilRb, st->clear.enable_ds_separate)) quad_buffers |= PIPE_CLEAR_STENCIL; else clear_buffers |= PIPE_CLEAR_STENCIL; } } } /* * If we're going to use clear_with_quad() for any reason, use it for * everything possible. */ if (quad_buffers) { quad_buffers |= clear_buffers; clear_with_quad(ctx, quad_buffers & PIPE_CLEAR_COLOR, quad_buffers & PIPE_CLEAR_DEPTH, quad_buffers & PIPE_CLEAR_STENCIL); } else if (clear_buffers) { /* driver cannot know it can clear everything if the buffer * is a combined depth/stencil buffer but this wasn't actually * required from the visual. Hence fix this up to avoid potential * read-modify-write in the driver. */ union pipe_color_union clearColor; if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) && ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && (depthRb == stencilRb) && (ctx->DrawBuffer->Visual.depthBits == 0 || ctx->DrawBuffer->Visual.stencilBits == 0)) clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { st_translate_color(ctx->Color.ClearColor.f, ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, clearColor.f); } st->pipe->clear(st->pipe, clear_buffers, &clearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } if (mask & BUFFER_BIT_ACCUM) _mesa_clear_accum_buffer(ctx); }